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]; }
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; }
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 }
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; }
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; }