void OnDied(UnitPointer mKiller)
	{
		if(!mKiller)
			return;

		if (mKiller->IsPlayer()) 
		{
			QuestLogEntry *en = NULL;
			en = (TO_PLAYER(mKiller))->GetQuestLogForEntry(10703);
			if (en == NULL)
			{
				en = (TO_PLAYER(mKiller))->GetQuestLogForEntry(10702);
				if (en == NULL)
				{
					return;
				}
			}

			if(en->GetMobCount(0) < en->GetQuest()->required_mobcount[0])
			{
				uint32 newcount = en->GetMobCount(0) + 1;
				en->SetMobCount(0, newcount);
				en->SendUpdateAddKill(0);
				en->UpdatePlayerFields();
			}
		}
		return;
	}
void ArathiBasin::HookOnPlayerKill(PlayerPointer plr, UnitPointer pVictim)
{
	if(pVictim->IsPlayer())
	{
		plr->m_bgScore.KillingBlows++;
		UpdatePvPData();
	}
}
void Arena::HookOnPlayerKill(PlayerPointer plr, UnitPointer pVictim)
{
	if( !pVictim->IsPlayer() )
		return;

	plr->m_bgScore.KillingBlows++;
	UpdatePlayerCounts();
}
	void OnDied(UnitPointer mKiller)
	{
		if ( mKiller->IsPlayer() )
		{
			QuestLogEntry *pQuest = TO_PLAYER(mKiller)->GetQuestLogForEntry( 9573 );
			if ( pQuest != NULL && pQuest->GetMobCount( 1 ) < pQuest->GetQuest()->required_mobcount[1] )
			{
				pQuest->SetMobCount( 1, pQuest->GetMobCount( 1 ) + 1 );
				pQuest->SendUpdateAddKill( 1 );
				pQuest->UpdatePlayerFields();
			}
		}
	}
bool ChatHandler::HandleKillCommand(const char *args, WorldSession *m_session)
{
	UnitPointer target = m_session->GetPlayer()->GetMapMgr()->GetUnit(m_session->GetPlayer()->GetSelection());
	if(target == 0)
	{
		RedSystemMessage(m_session, "A valid selection is required.");
		return true;
	}

	switch(target->GetTypeId())
	{
	case TYPEID_PLAYER:
		sGMLog.writefromsession(m_session, "used kill command on PLAYER %s", TO_PLAYER( target )->GetName() );
		break;

	case TYPEID_UNIT:
		sGMLog.writefromsession(m_session, "used kill command on CREATURE %s", TO_CREATURE( target )->GetCreatureName() ? TO_CREATURE( target )->GetCreatureName()->Name : "unknown");
		break;
	}
	

	// If we're killing a player, send a message indicating a gm killed them.
	if(target->IsPlayer())
	{
		PlayerPointer plr = TO_PLAYER(target);
		m_session->GetPlayer()->DealDamage(plr, plr->GetUInt32Value(UNIT_FIELD_HEALTH),0,0,0);
		//plr->SetUInt32Value(UNIT_FIELD_HEALTH, 0);
		plr->KillPlayer();
		BlueSystemMessageToPlr(plr, "%s killed you with a GM command.", m_session->GetPlayer()->GetName());
	}
	else
	{

		// Cast insta-kill.
		SpellEntry * se = dbcSpell.LookupEntry(5);
		if(se == 0) return false;

		SpellCastTargets targets(target->GetGUID());
		SpellPointer sp(new Spell(m_session->GetPlayer(), se, true, NULLAURA));
		sp->prepare(&targets);

/*		SpellEntry * se = dbcSpell.LookupEntry(20479);
		if(se == 0) return false;
		
		SpellCastTargets targets(target->GetGUID());
		SpellPointer sp(new Spell(target, se, true, NULLAURA));
		sp->prepare(&targets);*/
	}

	return true;
}
	void OnDied(UnitPointer mKiller)
	{
		fulborgskilled++;
		if(mKiller->IsPlayer())
		{
			PlayerPointer mPlayer = TO_PLAYER(mKiller);

			if(fulborgskilled > 8&& mPlayer->GetQuestLogForEntry( 9667 ))
			{
				_unit->GetMapMgr()->GetInterface()->SpawnCreature(17702, -2419, -12166, 33, 3.45f, true, false, 0, 0)->Despawn(18000000, 0);
				fulborgskilled = 0;
				_unit->SendChatMessage(CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, "Chief, we need your help!");
			}
		}
	}
	void OnDied( UnitPointer pKiller )
	{
		PlayerPointer QuestHolder = NULLPLR;
		if ( pKiller->IsPlayer() )
			QuestHolder = TO_PLAYER( pKiller );
		else if ( pKiller->IsPet() && TO_PET( pKiller )->GetPetOwner() != NULLPLR )
			QuestHolder = TO_PET( pKiller )->GetPetOwner();

		if ( QuestHolder == NULLPLR )
			return;

		// M4ksiu: I don't think the method is correct, but it can stay the way it was until someone gives proper infos
		QuestLogEntry* Quest = QuestHolder->GetQuestLogForEntry( 9670 );
		CreaturePointer RandomCreature = NULLCREATURE;
		if ( Quest == NULL )
		{
			// Creatures from Bloodmyst Isle
			uint32 Id[ 51 ] = { 17681, 17887, 17550, 17323, 17338, 17341, 17333, 17340, 17353, 17320, 17339, 17337, 17715, 17322, 17494, 17654, 17342, 17328, 17331, 17325, 17321, 17330, 17522, 17329, 17524, 17327, 17661, 17352, 17334, 17326, 17324, 17673, 17336, 17346, 17589, 17609, 17608, 17345, 17527, 17344, 17347, 17525, 17713, 17523, 17348, 17606, 17604, 17607, 17610, 17358, 17588 };
			RandomCreature = _unit->GetMapMgr()->GetInterface()->SpawnCreature( Id[ RandomUInt( 50 ) ], _unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ(), _unit->GetOrientation(), true, false, 0, 0 );
			if ( RandomCreature != NULLCREATURE )
			{
				RandomCreature->m_noRespawn = true;
				RandomCreature->Despawn( 60000, 0 );
			};

			return;
		}
		else
		{
			uint32 Id[ 8 ] = { 17681, 17321, 17330, 17522, 17673, 17336, 17346, 17589 };
			RandomCreature = _unit->GetMapMgr()->GetInterface()->SpawnCreature( Id[ RandomUInt( 7 ) ], _unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ(), _unit->GetOrientation(), true, false, 0, 0 );
			if ( RandomCreature != NULLCREATURE )
			{
				RandomCreature->m_noRespawn = true;
				RandomCreature->Despawn( 60000, 0 );
				if ( RandomCreature->GetEntry() == 17681 && Quest->GetMobCount( 0 ) < Quest->GetQuest()->required_mobcount[ 0 ] )
				{
					Quest->SetMobCount( 0, Quest->GetMobCount( 0 ) + 1 );
					Quest->SendUpdateAddKill( 0 );
					Quest->UpdatePlayerFields();
				};
			};
		};
	};
	void OnDied(UnitPointer mKiller)
	{
		if(mKiller->IsPlayer())
		{
			PlayerPointer mPlayer = TO_PLAYER(mKiller);
			if(mPlayer == NULL || mPlayer->GetMapMgr() == NULL || mPlayer->GetMapMgr()->GetInterface() == NULL)
				return;
			CreaturePointer  beka1 = sEAS.SpawnCreature(mPlayer, 1516, -13770.5, -6.79, 42.8, 5.7 , 0);
			beka1->GetAIInterface()->MoveTo(-13727.8, -26.2, 46.15, 4.07);
			beka1->Despawn(10*60*1000, 0);
		}
		else
		{
			PlayerPointer mPlayer = _unit->GetMapMgr()->GetInterface()->GetPlayerNearestCoords(_unit->GetPositionX(), _unit->GetPositionY(), _unit->GetPositionZ());
			if(mPlayer)
			{
				if(mPlayer == NULL || mPlayer->GetMapMgr() == NULL || mPlayer->GetMapMgr()->GetInterface() == NULL)
					return;
				CreaturePointer  beka1 = sEAS.SpawnCreature(mPlayer, 1516, -13770.5, -6.79, 42.8, 5.7 , 0);
				beka1->GetAIInterface()->MoveTo(-13727.8, -26.2, 46.15, 4.07);
				beka1->Despawn(10*60*1000, 0);
			}
		}
	}
void HonorHandler::OnPlayerKilledUnit( PlayerPointer pPlayer, UnitPointer pVictim )
{
	if( pVictim == NULL || pPlayer == NULL || !pVictim->IsPlayer() || !pPlayer->IsPlayer() )
		return;

	if( TO_PLAYER( pVictim )->m_honorless )
		return;

    if( pVictim->IsPlayer() )
	{
		if( pPlayer->m_bg )
		{
			if( TO_PLAYER( pVictim )->m_bgTeam == pPlayer->m_bgTeam )
				return;

			// patch 2.4, players killed >50 times in battlegrounds won't be worth honor for the rest of that bg
			if( TO_PLAYER(pVictim)->m_bgScore.Deaths >= 50 )
				return;
		}
		else
		{
			if( pPlayer->GetTeam() == TO_PLAYER( pVictim )->GetTeam() )
				return;
		}
	}

	// Calculate points
	int32 Points = CalculateHonorPointsForKill(pPlayer, pVictim);

	if( Points > 0 )
	{
		if( pPlayer->m_bg )
		{
			// hackfix for battlegrounds (since the gorups there are disabled, we need to do this manually)
			vector<PlayerPointer  > toadd;
			uint32 t = pPlayer->m_bgTeam;
			toadd.reserve(15);		// shouldnt have more than this
			pPlayer->m_bg->Lock();
			set<PlayerPointer  > * s = &pPlayer->m_bg->m_players[t];

			for(set<PlayerPointer  >::iterator itr = s->begin(); itr != s->end(); ++itr)
			{
				if((*itr) == pPlayer || (*itr)->isInRange(pPlayer,40.0f))
					toadd.push_back(*itr);
			}

			if( toadd.size() > 0 )
			{
				uint32 pts = Points / (uint32)toadd.size();
				for(vector<PlayerPointer  >::iterator vtr = toadd.begin(); vtr != toadd.end(); ++vtr)
				{
					AddHonorPointsToPlayer(*vtr, pts);

					(*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill();
					(*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() );
					(*vtr)->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() );

					(*vtr)->m_killsToday++;
					(*vtr)->m_killsLifetime++;
					pPlayer->m_bg->HookOnHK(*vtr);
					if(pVictim)
					{
						// Send PVP credit
						WorldPacket data(SMSG_PVP_CREDIT, 12);
						uint32 pvppoints = pts * 10;
						data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank());
						(*vtr)->GetSession()->SendPacket(&data);
					}
				}
			}

			pPlayer->m_bg->Unlock();
		}
		else if(pPlayer->GetGroup())
        {
            Group *pGroup = pPlayer->GetGroup();
            PlayerPointer gPlayer = NULLPLR;
            int32 GroupPoints;
			pGroup->Lock();
            GroupPoints = (Points / (pGroup->MemberCount() ? pGroup->MemberCount() : 1));
            GroupMembersSet::iterator gitr;
			for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++)
			{
				for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr)
				{
					gPlayer = (*gitr)->m_loggedInPlayer;
                    
                    if(gPlayer && (gPlayer == pPlayer || gPlayer->isInRange(pPlayer,100.0f))) // visible range
                    {
						gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill();
						gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() );
						gPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() );
                        gPlayer->m_killsToday++;
                        gPlayer->m_killsLifetime++;
						if(gPlayer->m_bg)
							gPlayer->m_bg->HookOnHK(gPlayer);

						sHookInterface.OnHonorableKill(gPlayer, TO_PLAYER(pVictim));
		                AddHonorPointsToPlayer(gPlayer, GroupPoints);
                        if(pVictim)
		                {
			                // Send PVP credit
			                WorldPacket data(SMSG_PVP_CREDIT, 12);
			                uint32 pvppoints = GroupPoints * 10;
			                data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank());
			                gPlayer->GetSession()->SendPacket(&data);
		                }
						//patch by emsy
                        // If we are in Halaa
                        if(pPlayer->GetZoneId() == 3518)
                        {
                            // Add Halaa Battle Token
                            SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 33004 : 33005);
                            gPlayer->CastSpell(gPlayer, pvp_token_spell, true);
                        }
                        // If we are in Hellfire Peninsula
                        if(pPlayer->GetZoneId() == 3483)
                        {
                            // Add Mark of Thrallmar/Honor Hold
                            SpellEntry * pvp_token_spell = dbcSpell.LookupEntry(gPlayer->GetTeam()? 32158 : 32155);
                            gPlayer->CastSpell(gPlayer, pvp_token_spell, true);
                        }
                    }

                }
            }
			pGroup->Unlock();
        
        }
        else
        {
			pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKill();
			pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillClass( pVictim->getClass() );
			pPlayer->GetAchievementInterface()->HandleAchievementCriteriaHonorableKillRace( pVictim->getRace() );
		    pPlayer->m_killsToday++;
		    pPlayer->m_killsLifetime++;
		    AddHonorPointsToPlayer(pPlayer, Points);
    		
			if(pPlayer->m_bg)
				pPlayer->m_bg->HookOnHK(pPlayer);

			sHookInterface.OnHonorableKill(pPlayer, TO_PLAYER(pVictim));
		    if(pVictim)
		    {
			    // Send PVP credit
			    WorldPacket data(SMSG_PVP_CREDIT, 12);
			    uint32 pvppoints = Points * 10;
			    data << pvppoints << pVictim->GetGUID() << uint32(TO_PLAYER(pVictim)->GetPVPRank());
			    pPlayer->GetSession()->SendPacket(&data);
		    }
			//patch by emsy
            // If we are in Halaa
            if(pPlayer->GetZoneId() == 3518)
            {
                // Add Halaa Battle Token
                SpellEntry * halaa_spell = dbcSpell.LookupEntry(pPlayer->GetTeam()? 33004 : 33005);
                pPlayer->CastSpell(pPlayer, halaa_spell, true);
            }
        }
	}
}
uint32 CalculateXpToGive(UnitPointer pVictim, UnitPointer pAttacker)
{
	if(pVictim->IsPlayer())
		return 0;

	if( TO_CREATURE(pVictim)->IsTotem())
		return 0;

	CreatureInfo *victimI;
	victimI = TO_CREATURE(pVictim)->GetCreatureInfo();

	if(victimI)
		if(victimI->Type == CRITTER)
			return 0;
	uint32 VictimLvl = pVictim->getLevel();
	uint32 AttackerLvl = pAttacker->getLevel();

	if( pAttacker->IsPet() && TO_PET(pAttacker)->GetPetOwner() )
	{
		// based on: http://www.wowwiki.com/Talk:Formulas:Mob_XP#Hunter.27s_pet_XP (2008/01/12)
		uint32 ownerLvl = TO_PET( pAttacker )->GetPetOwner()->getLevel();
		VictimLvl += ownerLvl - AttackerLvl;
		AttackerLvl = ownerLvl;
	}
	else if( (int32)VictimLvl - (int32)AttackerLvl > 10 ) //not wowwikilike but more balanced
		return 0;

	// Partha: this screws things up for pets and groups
	// No need for it here - it does this later in Player::GiveXP 
	/*
	uint32 max_level = 70;
	if(pAttacker->IsPlayer())
	max_level = pAttacker->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL);
	else if(pAttacker->IsPet())
	max_level = TO_PET( pAttacker )->GetPetOwner()->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL);

	if(pAttacker->getLevel() >= max_level)
	return 0;
	*/


	/*if(VictimLvl+7>AttackerLvl)
	VictimLvl = AttackerLvl + 7;*/

	float zd = 5;
	float g = 5;

	// get zero diff
	// get grey diff

	if(AttackerLvl >= 70)
	{
		zd = 19;
		g = 15;
	}
	else if(AttackerLvl >= 65)
	{
		zd = 18;
		g = 13;
	}
	else if(AttackerLvl >= 60)
	{
		zd = 17;
		g = 14;
	}
	else if(AttackerLvl >= 55)
	{
		zd = 16;
		g = 12;
	}
	else if(AttackerLvl >= 50)
	{
		zd = 15;
		g = 11;
	}
	else if(AttackerLvl >= 45)
	{
		zd = 14;
		g = 10;
	}
	else if(AttackerLvl >= 40)
	{
		zd = 13;
		g = 9;
	}
	else if(AttackerLvl >= 30)
	{
		zd = 12;
		g = 8;
	}
	else if(AttackerLvl >= 20)
	{
		zd = 11;
		g = 7;
	}
	else if(AttackerLvl >= 16)
	{
		zd = 9;
		g = 6;
	}
	else if(AttackerLvl >= 12)
	{
		zd = 8;
		g = 6;
	}
	else if(AttackerLvl >= 10)
	{
		zd = 7;
		g = 6;
	}
	else if(AttackerLvl >= 8)
	{
		zd = 6;
		g = 5;
	}
	else
	{
		zd = 5;
		g = 5;
	}

	float xp = 0.0f;
	float fVictim = float(VictimLvl);
	float fAttacker = float(AttackerLvl);

	if(VictimLvl == AttackerLvl)
		xp = float( ((fVictim * 5.0f) + 45.0f) );
	else if(VictimLvl > AttackerLvl)
	{
		float j = 1.0f + (0.25f * (fVictim - fAttacker));
		xp = float( ((AttackerLvl * 5.0f) + 45.0f) * j );
	}
	else
	{
		if((AttackerLvl - VictimLvl) < g)
		{
			float j = (1.0f - float((fAttacker - fVictim) / zd));
			xp = (AttackerLvl * 5.0f + 45.0f) * j;
		}
	}

	// multiply by global XP rate
	if(xp == 0.0f)
		return 0;

	xp *= sWorld.getRate(RATE_XP);

	// elite boss multiplier
	if(victimI)
	{
		switch(victimI->Rank)
		{
		case 0: // normal mob
			break;
		case 1: // elite
			xp *= 2.0f;
			break;
		case 2: // rare elite
			xp *= 2.0f;
			break;
		case 3: // world boss
			xp *= 2.5f;
			break;
		default:	// rare or higher
			//			xp *= 7.0f;
			break;
		}
	}
	if( xp < 0 )//probably caused incredible wrong exp
		xp = 0;

	return (uint32)xp;
	/*const float ZD[PLAYER_LEVEL_CAP+1] = {1,5,5,5,5,5,5,5,6,6,7,7,8,8,8,9,9,9,9,9,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,14,14,14,14,14,15,15,15,15,15,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17};
	float temp = 0;
	float tempcap = 0;
	float xp = 0;

	if(VictimLvl >= AttackerLvl)
	{
	temp = ((AttackerLvl * 5) + 45) * (1 + 0.05 * (VictimLvl - AttackerLvl));
	tempcap = ((AttackerLvl * 5) + 45) * 1.2;
	if(temp > tempcap)
	{
	if( tempcap < 0 )
	tempcap = 0;
	else
	tempcap *= sWorld.getRate(RATE_XP);

	xp = tempcap;
	}
	else
	{
	if( temp < 0 )
	temp = 0;
	else
	temp *= sWorld.getRate(RATE_XP);

	xp = temp;
	}
	}
	else
	{
	if(getConColor(AttackerLvl, VictimLvl) == 0)
	{
	return (uint32)0;
	}
	else
	{
	if(AttackerLvl < PLAYER_LEVEL_CAP)
	temp = (((AttackerLvl * 5) + 45) * (1 - (AttackerLvl - VictimLvl)/ZD[AttackerLvl]));
	else
	temp = (((AttackerLvl * 5) + 45) * (1 - (AttackerLvl - VictimLvl)/17));
	if( temp < 0 )
	temp = 0;
	else
	temp *= sWorld.getRate(RATE_XP);

	xp = temp;
	}
	}

	if(victimI)
	{
	switch(victimI->Rank)
	{
	case 0: // normal mob
	break;
	case 1: // elite
	xp *= 1.5f;
	break;
	case 2: // rare elite
	xp *= 3.0f;
	break;
	case 3: // world boss
	xp *= 10.0f;
	break;
	default:	// rare or higher
	xp *= 7.0f;
	break;
	}
	}

	return (uint32)(xp);*/
}
uint32 CalculateDamage( UnitPointer pAttacker, UnitPointer pVictim, uint32 weapon_damage_type, SpellEntry* ability ) // spellid is used only for 2-3 spells, that have AP bonus
{
	//TODO: Some awesome formula to determine how much damage to deal
	//consider this is melee damage
	// weapon_damage_type: 0 = melee, 1 = offhand(dualwield), 2 = ranged

	// Attack Power increases your base damage-per-second (DPS) by 1 for every 14 attack power.
	// (c) wowwiki

	//type of this UNIT_FIELD_ATTACK_POWER_MODS is unknown, not even uint32 disabled for now.

	uint32 offset;
	ItemPointer it = NULLITEM;

	if(pAttacker->disarmed && pAttacker->IsPlayer())
	{
		offset=UNIT_FIELD_MINDAMAGE;
		it = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);
	}
	else if( weapon_damage_type == MELEE )
		offset = UNIT_FIELD_MINDAMAGE;
	else if( weapon_damage_type == OFFHAND )
		offset = UNIT_FIELD_MINOFFHANDDAMAGE;
	else  // weapon_damage_type == RANGED
		offset = UNIT_FIELD_MINRANGEDDAMAGE;

	float min_damage = pAttacker->GetFloatValue(offset);
	float max_damage = pAttacker->GetFloatValue(offset+1);
	if(it)
	{
		min_damage -= it->GetProto()->Damage[0].Min;
		max_damage -= it->GetProto()->Damage[0].Max;
	}

	float ap = 0;
	float bonus;
	float wspeed;
	float appbonuspct = 1.0f;
	ItemPointer BonusItem = NULLITEM;
	if( pAttacker->IsPlayer() && weapon_damage_type == MELEE )
	{
		BonusItem = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);
	}
	else if(pAttacker->IsPlayer() && weapon_damage_type == OFFHAND )
	{
		BonusItem = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_OFFHAND);
	}
	else if(pAttacker->IsPlayer() && weapon_damage_type == RANGED )
	{
		BonusItem = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
	}

	if( pAttacker->IsPlayer() && BonusItem )
	{
		appbonuspct = TO_PLAYER(pAttacker)->m_WeaponSubClassDamagePct[ BonusItem->GetProto()->SubClass  ];
	}

	if(offset == UNIT_FIELD_MINRANGEDDAMAGE)
	{
		//starting from base attack power then we apply mods on it
		//ap += pAttacker->GetRAP();
		ap += pVictim->RAPvModifier;

		if(!pVictim->IsPlayer() && TO_CREATURE(pVictim)->GetCreatureName())
		{
			uint32 creatType = TO_CREATURE(pVictim)->GetCreatureName()->Type;
			ap += (float)pAttacker->CreatureRangedAttackPowerMod[creatType];

			if(pAttacker->IsPlayer())
			{
				min_damage = (min_damage + TO_PLAYER(pAttacker)->IncreaseDamageByType[creatType]) * (1 + TO_PLAYER(pAttacker)->IncreaseDamageByTypePCT[creatType]);
				max_damage = (max_damage + TO_PLAYER(pAttacker)->IncreaseDamageByType[creatType]) * (1 + TO_PLAYER(pAttacker)->IncreaseDamageByTypePCT[creatType]);
			}
		}

		if(pAttacker->IsPlayer())
		{
			if(!pAttacker->disarmed)
			{
				ItemPointer it = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
				if(it)
				{
					wspeed = (float)it->GetProto()->Delay;
				}
				else
					wspeed = 2000;
			}
			else
				wspeed = (float)pAttacker->GetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME);
		}
		else
		{
			wspeed = (float)pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME);
		}

		//ranged weapon normalization.
		if(pAttacker->IsPlayer() && ability)
		{
			if(ability->Effect[0] == SPELL_EFFECT_DUMMYMELEE || ability->Effect[1] == SPELL_EFFECT_DUMMYMELEE || ability->Effect[2] == SPELL_EFFECT_DUMMYMELEE)
			{
				wspeed = 2800;
			}
		}

		//Weapon speed constant in feral forms
		if(pAttacker->IsPlayer())
		{
			if(TO_PLAYER(pAttacker)->IsInFeralForm())
			{
				uint8 ss = TO_PLAYER(pAttacker)->GetShapeShift();

				if(ss == FORM_CAT)
					wspeed = 1000.0;
				else if(ss == FORM_DIREBEAR || ss == FORM_BEAR)
					wspeed = 2500.0;
			}
		}

		bonus = (wspeed-pAttacker->GetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME))/14000.0f*ap;
		min_damage += bonus;
		max_damage += bonus;
	}
	else
	{
		//MinD = AP(28AS-(WS/7))-MaxD
		//starting from base attack power then we apply mods on it
		//ap += pAttacker->GetAP();
		ap += pVictim->APvModifier;

		if(!pVictim->IsPlayer() && TO_CREATURE(pVictim)->GetCreatureName())
		{
			uint32 creatType = TO_CREATURE(pVictim)->GetCreatureName()->Type;
			ap += (float)pAttacker->CreatureAttackPowerMod[creatType];

			if(pAttacker->IsPlayer())
			{
				min_damage = (min_damage + TO_PLAYER(pAttacker)->IncreaseDamageByType[creatType]) * (1 + TO_PLAYER(pAttacker)->IncreaseDamageByTypePCT[creatType]);
				max_damage = (max_damage + TO_PLAYER(pAttacker)->IncreaseDamageByType[creatType]) * (1 + TO_PLAYER(pAttacker)->IncreaseDamageByTypePCT[creatType]);
			}
		}

		if(pAttacker->IsPlayer())
		{
			if(!pAttacker->disarmed)
			{
				ItemPointer it = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);

				if(it)
					wspeed = (float)it->GetProto()->Delay;
				else
					wspeed = 2000;
			}
			else
				wspeed = (float)pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME);

			if(ability && ability->SpellGroupType)
			{
				int32 apall = pAttacker->GetAP();
				/* this spell modifier doesn't exist. also need to clear up how the AP is used here
				int32 apb=0;
				SM_FIValue(pAttacker->SM[SMT_ATTACK_POWER_BONUS][1],&apb,ability->SpellGroupType);

				if(apb)
					ap += apall*((float)apb/100);
				else*/
					ap = float(apall);
			}
		}
		else
		{
			wspeed = (float)pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME);
		}

		//Normalized weapon damage checks.
		if(pAttacker->IsPlayer() && ability)
		{
			if(ability->Effect[0] == SPELL_EFFECT_DUMMYMELEE || ability->Effect[1] == SPELL_EFFECT_DUMMYMELEE || ability->Effect[2] == SPELL_EFFECT_DUMMYMELEE)
			{
				it = TO_PLAYER(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);

				if(it)
				{
					if(it->GetProto()->Class == ITEM_CLASS_WEAPON) //weapon
					{
						if(it->GetProto()->InventoryType == INVTYPE_2HWEAPON) wspeed = 3300;
						else if(it->GetProto()->SubClass == 15) wspeed = 1700;
						else wspeed = 2400;
					}
				}
			}
		}

		//Weapon speed constant in feral forms
		if(pAttacker->IsPlayer())
		{
			if(TO_PLAYER(pAttacker)->IsInFeralForm())
			{
				uint8 ss = TO_PLAYER(pAttacker)->GetShapeShift();

				if(ss == FORM_CAT)
					wspeed = 1000.0;
				else if(ss == FORM_DIREBEAR || ss == FORM_BEAR)
					wspeed = 2500.0;
			}
		}

		if (offset == UNIT_FIELD_MINDAMAGE)
			bonus = (wspeed-pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME))/14000.0f*ap;
		else if( offset == UNIT_FIELD_MINOFFHANDDAMAGE )
			bonus = (wspeed-pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME + 1)) / 14000.0f*ap;
		else
			bonus = (wspeed-pAttacker->GetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME))/14000.0f*ap;
		min_damage += bonus;
		max_damage += bonus;
	}

	float diff = fabs(max_damage - min_damage);
	float result = min_damage;

	if(diff >= 1)
		result += float(RandomDouble(diff));

	if(result >= 0)
	{
		return FL2UINT(result * appbonuspct);
	}

	return 0;
}