Beispiel #1
0
float TerrainMgr::GetLandHeight(float x, float y)
{
	if(!AreCoordinatesValid(x, y))
		return 0.0f;

	// Convert the co-ordinates to cells.
	uint32 CellX = ConvertGlobalXCoordinate(x);
	uint32 CellY = ConvertGlobalYCoordinate(y);

	if(!CellInformationLoaded(CellX, CellY) && !LoadCellInformation(CellX, CellY))
		return 0.0f;

	// Convert the co-ordinates to cell's internal
	// system.
	float IntX = ConvertInternalXCoordinate(x, CellX);
	float IntY = ConvertInternalYCoordinate(y, CellY);

	// Calculate x index.
	float TempFloat = IntX * (MAP_RESOLUTION / CellsPerTile / _cellSize);
	uint32 XOffset = FL2UINT(TempFloat);
	if((TempFloat - (XOffset * _cellSize)) >= 0.5f)
		++XOffset;

	// Calculate y index.
	TempFloat = IntY * (MAP_RESOLUTION / CellsPerTile / _cellSize);
	uint32 YOffset = FL2UINT(TempFloat);
	if((TempFloat - (YOffset * _cellSize)) >= 0.5f)
		++YOffset;

	// Return our cached information.
	return GetCellInformation(CellX, CellY)->Z[XOffset][YOffset];
}
Beispiel #2
0
bool ChatHandler::HandleRangeCheckCommand( const char *args , WorldSession *m_session )
{
	WorldPacket data;
	uint64 guid = m_session->GetPlayer()->GetSelection();
	m_session->SystemMessage( "=== RANGE CHECK ===" );
	if (guid == 0)
	{
		m_session->SystemMessage("No selection imo.");
		return true;
	}

	Unit* unit = m_session->GetPlayer()->GetMapMgr()->GetUnit( guid );
	if(!unit)
	{
		m_session->SystemMessage("Invalid selection imo.");
		return true;
	}
	float DistSq = unit->GetDistanceSq( TO_OBJECT(m_session->GetPlayer()) );
	m_session->SystemMessage( "GetDistanceSq  :   %u" , FL2UINT( DistSq ) );
	LocationVector locvec( m_session->GetPlayer()->GetPositionX() , m_session->GetPlayer()->GetPositionY() , m_session->GetPlayer()->GetPositionZ() );
	float DistReal = unit->CalcDistance( locvec );
	m_session->SystemMessage( "CalcDistance   :   %u" , FL2UINT( DistReal ) );
	float Dist2DSq = unit->GetDistance2dSq( TO_OBJECT(m_session->GetPlayer()) );
	m_session->SystemMessage( "GetDistance2dSq:   %u" , FL2UINT( Dist2DSq ) );
	return true;
}
ProcCondHandlerRes ProcHandler::FlametongueTotemAndFlametongueWeapon(ProcCondSharedDataStruct *shareddata)
{
	if(!shareddata->owner->IsPlayer())
		return PROCCOND_BREAK_EXECUTION;

	if (shareddata->spellId == 25555 ||
		shareddata->spellId == 16389 ||
		shareddata->spellId == 10523 ||
		shareddata->spellId == 8248 ||
		shareddata->spellId == 8253)
	{
		shareddata->spellId = 16368;	// Flametongue Totem proc
	}
	else
	{
		shareddata->spellId = 29469;	// Flametongue Weapon proc
	}

	Item * mh = TO_PLAYER(shareddata->owner)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);
	if(mh != NULL)
	{
		float mhs = float(mh->GetProto()->Delay);
		shareddata->dmg_overwrite = FL2UINT(mhs * 0.001f * (shareddata->spe->EffectBasePoints[0] + 1) / 88);

		return PROCCOND_CONTINUE_EXECUTION;
	}
	else
		return PROCCOND_BREAK_EXECUTION;
}
Beispiel #4
0
bool TerrainMgr::WriteNewHeightToPos(float x, float y, float new_z)
{
	if(!AreCoordinatesValid(x, y))
		return false;

	// Convert the co-ordinates to cells.
	uint32 CellX = ConvertGlobalXCoordinate(x);
	uint32 CellY = ConvertGlobalYCoordinate(y);

	if(!CellInformationLoaded(CellX, CellY) && !LoadCellInformation(CellX, CellY))
		return false;

	// Convert the co-ordinates to cell's internal
	// system.
	float IntX = ConvertInternalXCoordinate(x, CellX);
	float IntY = ConvertInternalYCoordinate(y, CellY);

	// Calculate x index.
	float TempFloat = IntX * (MAP_RESOLUTION / CellsPerTile / _cellSize);
	uint32 XOffset = FL2UINT(TempFloat);
	if((TempFloat - (XOffset * _cellSize)) >= 0.5f)
		++XOffset;

	// Calculate y index.
	TempFloat = IntY * (MAP_RESOLUTION / CellsPerTile / _cellSize);
	uint32 YOffset = FL2UINT(TempFloat);
	if((TempFloat - (YOffset * _cellSize)) >= 0.5f)
		++YOffset;

	if( CellX > 511 )
		CellX = 511;
	if( CellY > 511 )
		CellY = 511;
	if( XOffset > 31 )
		XOffset = 31;
	if( YOffset > 31 )
		YOffset = 31;

	// Return our cached information.
	CellInformation[CellX][CellY]->Z[XOffset][YOffset] = new_z;
	return true;
}
void Player::ModStanding( uint32 Faction, int32 Value )
{
	FactionDBC * f = dbcFaction.LookupEntry( Faction );
	if ( f == NULL || f->RepListId < 0 )
		return;
	ReputationMap::iterator itr = m_reputation.find( Faction );

	if ( pctReputationMod > 0 )
	{
		float d = float( float( pctReputationMod ) / 100.0f );
		Value += FL2UINT( float( float( Value ) * d ) );
	}

	if ( itr == m_reputation.end() )
	{
		if ( !AddNewFaction( f, Value, false ) )
			return;
	}
	else
	{
		// Increment it.
		if ( RankChanged( itr->second->standing, Value ) )
		{
			itr->second->standing += Value;
			UpdateInrangeSetsBasedOnReputation();
		}
		else
		{
			itr->second->standing += Value;
		}
		
		OnModStanding( f, itr->second );
   }

#ifdef OPTIMIZED_PLAYER_SAVING
	save_Reputation();
#endif
}
Beispiel #6
0
void AuctionHouse::RemoveAuction(Auction * auct)
{
	Log.Debug("AuctionHouse", "%u: Removing auction %u, reason %u.", dbc->id, auct->Id, auct->DeletedReason);

	char subject[100];
	char body[200];
	switch(auct->DeletedReason)
	{
	case AUCTION_REMOVE_EXPIRED:
		{
			// ItemEntry:0:3
			snprintf(subject, 100, "%u:0:3", (unsigned int)auct->pItem->GetEntry());

			// Auction expired, resend item, no money to owner.
			sMailSystem.SendAutomatedMessage(AUCTION, dbc->id, auct->Owner, subject, "", 0, 0, auct->pItem->GetGUID(), 62);
		}break;

	case AUCTION_REMOVE_WON:
		{
			// ItemEntry:0:1
			snprintf(subject, 100, "%u:0:1", (unsigned int)auct->pItem->GetEntry());

			// <owner player guid>:bid:buyout
			snprintf(body, 200, "%X:%u:%u", (unsigned int)auct->Owner, (unsigned int)auct->HighestBid, (unsigned int)auct->BuyoutPrice);

			// Auction won by highest bidder. He gets the item.
			sMailSystem.SendAutomatedMessage(AUCTION, dbc->id, auct->HighestBidder, subject, body, 0, 0, auct->pItem->GetGUID(), 62);

			// Send a mail to the owner with his cut of the price.
			uint32 auction_cut = FL2UINT(float(cut_percent * float(auct->HighestBid)));
			int32 amount = auct->HighestBid - auction_cut + auct->DepositAmount;
			if(amount < 0)
				amount = 0;

			// ItemEntry:0:2
			snprintf(subject, 100, "%u:0:2", (unsigned int)auct->pItem->GetEntry());

			// <hex player guid>:bid:0:deposit:cut
			if(auct->HighestBid == auct->BuyoutPrice)	   // Buyout
				snprintf(body, 200, "%X:%u:%u:%u:%u", (unsigned int)auct->HighestBidder, (unsigned int)auct->HighestBid, (unsigned int)auct->BuyoutPrice, (unsigned int)auct->DepositAmount, (unsigned int)auction_cut);
			else
				snprintf(body, 200, "%X:%u:0:%u:%u", (unsigned int)auct->HighestBidder, (unsigned int)auct->HighestBid, (unsigned int)auct->DepositAmount, (unsigned int)auction_cut);

			// send message away.
			sMailSystem.SendAutomatedMessage(AUCTION, dbc->id, auct->Owner, subject, body, amount, 0, 0, 62);

			// If it's not a buyout (otherwise the players has been already notified)
			if(auct->HighestBid < auct->BuyoutPrice || auct->BuyoutPrice == 0)
			{
				this->SendAuctionBuyOutNotificationPacket(auct);
			}
		}break;
	case AUCTION_REMOVE_CANCELLED:
		{
			snprintf(subject, 100, "%u:0:5", (unsigned int)auct->pItem->GetEntry());
			uint32 cut = uint32(float(cut_percent * auct->HighestBid));
			Player * plr = objmgr.GetPlayer(auct->Owner);
			if(cut && plr && plr->GetUInt32Value(PLAYER_FIELD_COINAGE) >= cut)
				plr->ModUnsigned32Value(PLAYER_FIELD_COINAGE, -((int32)cut));

			sMailSystem.SendAutomatedMessage(AUCTION, GetID(), auct->Owner, subject, "", 0, 0, auct->pItem->GetGUID(), 62);

			// return bidders money
			if(auct->HighestBidder)
			{
				sMailSystem.SendAutomatedMessage(AUCTION, GetID(), auct->HighestBidder, subject, "", auct->HighestBid, 0, 0, 62);
			}

		}break;
	}

	// Remove the auction from the hashmap.
	auctionLock.AcquireWriteLock();
	itemLock.AcquireWriteLock();

	auctions.erase(auct->Id);
	auctionedItems.erase(auct->pItem->GetGUID());

	auctionLock.ReleaseWriteLock();
	itemLock.ReleaseWriteLock();

	// Destroy the item from memory (it still remains in the db)
	auct->pItem->DeleteMe();

	// Finally destroy the auction instance.
	auct->DeleteFromDB();
	delete auct;
}
Beispiel #7
0
uint32 CalculateDamage( Unit* pAttacker, Unit* pVictim, uint32 weapon_damage_type, uint64 spellgroup, 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;
    Item *it = NULL;

    if(pAttacker->disarmed && pAttacker->IsPlayer())
    {
        offset=UNIT_FIELD_MINDAMAGE;
        it = static_cast< 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;

    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() && ((Creature*)pVictim)->GetCreatureInfo())
        {
            uint32 creatType = ((Creature*)pVictim)->GetCreatureInfo()->Type;
            ap += (float)pAttacker->CreatureRangedAttackPowerMod[creatType];

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

        if(pAttacker->IsPlayer())
        {
            if(!pAttacker->disarmed)
            {
                Item *it = static_cast< 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(static_cast< Player* >(pAttacker)->IsInFeralForm())
            {
                uint8 ss = static_cast< 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() && ((Creature*)pVictim)->GetCreatureInfo())
        {
            uint32 creatType = ((Creature*)pVictim)->GetCreatureInfo()->Type;
            ap += (float)pAttacker->CreatureAttackPowerMod[creatType];

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

        if(pAttacker->IsPlayer())
        {
            if(!pAttacker->disarmed)
            {
                Item *it = static_cast< 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(spellgroup)
            {
                int32 apall = pAttacker->GetAP();
                int32 apb=0;
                SM_FIValue(pAttacker->SM_PAPBonus,&apb,spellgroup);

                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 = static_cast< Player* >(pAttacker)->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_MAINHAND);

                if(it)
                {
                    if(it->GetProto()->Class == 2) //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(static_cast< Player* >(pAttacker)->IsInFeralForm())
            {
                uint8 ss = static_cast< 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
            bonus = (wspeed-pAttacker->GetUInt32Value(UNIT_FIELD_BASEATTACKTIME_01))/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)
    {
        if( pAttacker->IsPlayer() && ((Player*)pAttacker)->m_outStealthDamageBonusTimer )
        {
            if( (uint32)UNIXTIME >= ((Player*)pAttacker)->m_outStealthDamageBonusTimer )
                ((Player*)pAttacker)->m_outStealthDamageBonusTimer = 0;
            else
                result *= ((float(((Player*)pAttacker)->m_outStealthDamageBonusPct) / 100.0f) + 1.0f);
        }

        return FL2UINT(result);
    }

    return 0;
}
void Player::ModStanding(uint32 Faction, int32 Value)
{
	ReputationMap::iterator itr = m_reputation.find(Faction);
	FactionDBC * dbc = dbcFaction.LookupEntry(Faction);
	if(dbc == 0) return;

	if(itr == m_reputation.end())
	{
		// New faction!
		FactionReputation * rep = new FactionReputation;
		rep->flag = 0;
		rep->standing = Value;
		rep->baseStanding = 0;
		m_reputation[dbc->ID] = rep;
		if(dbc->RepListId >= 0)
			reputationByListId[dbc->RepListId] = rep;
	}
	else
	{
		// Bonus
		if(pctReputationMod > 0)
		{
			float d = float(float(pctReputationMod) / 100.0f);
			Value += FL2UINT( float( float(Value) * d ) );
		}

		// Increment it.
		if(RankChanged(itr->second->standing, Value))
		{
			itr->second->standing += Value;
			UpdateInrangeSetsBasedOnReputation();
		}
		else
		{
			itr->second->standing += Value;
		}

		// Set visible if invisible.
		if(!Visible(itr->second->flag))
		{
			SetFlagVisible(itr->second->flag);
			if(IsInWorld())
				m_session->OutPacket(SMSG_SET_FACTION_VISIBLE, 4, &dbc->RepListId);
		}

		// Set at war if we're beyond hostile.
		if(GetReputationRankFromStanding(itr->second->standing) <= STANDING_HOSTILE && !AtWar(itr->second->flag))
			SetFlagAtWar(itr->second->flag);

		if(IsInWorld() && Visible(itr->second->flag))
		{
			WorldPacket data(SMSG_SET_FACTION_STANDING, 12);
			data << uint32(0) << uint8(0) << uint32(1) << dbc->RepListId << itr->second->CalcStanding();
			m_session->SendPacket(&data);
		}
   }

#ifdef OPTIMIZED_PLAYER_SAVING
	save_Reputation();
#endif
}
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;
}