ReputationRank ReputationMgr::ReputationToRank(int32 standing) { int32 limit = Reputation_Cap + 1; for (int i = MAX_REPUTATION_RANK-1; i >= MIN_REPUTATION_RANK; --i) { limit -= PointsInRank[i]; if (standing >= limit) return ReputationRank(i); } return MIN_REPUTATION_RANK; }
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental) { if (SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID)) { bool res = false; for (SimpleFactionsList::const_iterator itr = flist->begin();itr != flist->end();++itr) { if (FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr)) { res = SetOneFactionReputation(factionEntryCalc, standing, incremental); if (res) { FactionStateList::iterator itrstate = m_factions.find(factionEntryCalc->reputationListID); if (itrstate != m_factions.end()) SendState(&itrstate->second); } } } return res; } else { // update for the actual faction first bool res = SetOneFactionReputation(factionEntry, standing, incremental); if (res) { // then some spillover calculation here if it exist if (const RepSpilloverTemplate *repTemplate = sObjectMgr.GetRepSpilloverTemplate(factionEntry->ID)) { for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { if (repTemplate->faction[i]) { if (m_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i])) { // bonuses are already given, so just modify standing by rate int32 spilloverRep = standing * repTemplate->faction_rate[i]; SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); } } } } // now we can send it FactionStateList::iterator itr = m_factions.find(factionEntry->reputationListID); if (itr != m_factions.end()) SendState(&itr->second); } return res; } }
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental) { sScriptMgr->OnPlayerReputationChange(_player, factionEntry->ID, standing, incremental); bool res = false; // if spillover definition exists in DB, override DBC if (const RepSpilloverTemplate* repTemplate = sObjectMgr->GetRepSpilloverTemplate(factionEntry->ID)) { for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { if (repTemplate->faction[i]) { if (_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i])) { // bonuses are already given, so just modify standing by rate int32 spilloverRep = int32(standing * repTemplate->faction_rate[i]); SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); } } } } else { float spillOverRepOut = float(standing); // check for sub-factions that receive spillover SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID); // if has no sub-factions, check for factions with same parent if (!flist && factionEntry->team && factionEntry->spilloverRateOut != 0.0f) { spillOverRepOut *= factionEntry->spilloverRateOut; if (FactionEntry const* parent = sFactionStore.LookupEntry(factionEntry->team)) { FactionStateList::iterator parentState = _factions.find(parent->reputationListID); // some team factions have own reputation standing, in this case do not spill to other sub-factions if (parentState != _factions.end() && (parentState->second.Flags & FACTION_FLAG_SPECIAL)) { SetOneFactionReputation(parent, int32(spillOverRepOut), incremental); } else // spill to "sister" factions { flist = GetFactionTeamList(factionEntry->team); } } } if (flist) { // Spillover to affiliated factions for (SimpleFactionsList::const_iterator itr = flist->begin(); itr != flist->end(); ++itr) { if (FactionEntry const* factionEntryCalc = sFactionStore.LookupEntry(*itr)) { if (factionEntryCalc == factionEntry || GetRank(factionEntryCalc) > ReputationRank(factionEntryCalc->spilloverMaxRankIn)) continue; int32 spilloverRep = int32(spillOverRepOut * factionEntryCalc->spilloverRateIn); if (spilloverRep != 0 || !incremental) res = SetOneFactionReputation(factionEntryCalc, spilloverRep, incremental); } } } } // spillover done, update faction itself FactionStateList::iterator faction = _factions.find(factionEntry->reputationListID); if (faction != _factions.end()) { res = SetOneFactionReputation(factionEntry, standing, incremental); // only this faction gets reported to client, even if it has no own visible standing SendState(&faction->second); } // switch faction ! if(_player->GetTeam() == ALLIANCE) { if((int)_player->GetReputation(HORDE)>=0) { _player->SetTeam(HORDE); _player->GetSession()->SendNotification(_player->GetSession()->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATIONS)); } } else { if((int)_player->GetReputation(ALLIANCE)>=0) { _player->SetTeam(ALLIANCE); _player->GetSession()->SendNotification(_player->GetSession()->GetTrinityString(LANG_ERR_NO_TRANSMOGRIFICATIONS)); } } return res; }
void WorldSession::SendListInventory(ObjectGuid vendorguid) { DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY"); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0); return; } // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); // Stop the npc if moving if (!pCreature->IsStopped()) pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); if (!vItems && !tItems) { WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1)); data << ObjectGuid(vendorguid); data << uint8(0); // count==0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } uint8 customitems = vItems ? vItems->GetItemCount() : 0; uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); uint8 count = 0; WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 7 * 4)); data << ObjectGuid(vendorguid); size_t count_pos = data.wpos(); data << uint8(count); float discountMod = _player->GetReputationPriceDiscount(pCreature); for (int i = 0; i < numitems; ++i) { VendorItem const* crItem = i < customitems ? vItems->GetItem(i) : tItems->GetItem(i - customitems); if (crItem) { uint32 itemId = crItem->item; ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); if (pProto) { if (!_player->isGameMaster()) { // class wrong item skip only for bindable case if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP) continue; // race wrong item skip always if ((pProto->AllowableRace & _player->getRaceMask()) == 0) continue; // when no faction required but rank > 0 will be used faction id from the vendor faction template to compare the rank if (!pProto->RequiredReputationFaction && pProto->RequiredReputationRank > 0 && ReputationRank(pProto->RequiredReputationRank) > _player->GetReputationRank(pCreature->getFactionTemplateEntry()->faction)) continue; } ++count; // reputation discount uint32 price = uint32(floor(pProto->BuyPrice * discountMod)); data << uint32(count); data << uint32(itemId); data << uint32(pProto->DisplayInfoID); data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); } } } if (count == 0) { data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } data.put<uint8>(count_pos, count); SendPacket(&data); }
///////////////////////////////////////////////// /// Get unit to unit reaction /// /// @note Relations API Tier 1 /// /// Client-side counterpart: <tt>CGUnit_C::UnitReaction(const CGUnit_C *this, const CGUnit_C *unit)</tt> ///////////////////////////////////////////////// ReputationRank Unit::GetReactionTo(Unit const* unit) const { // Simple sanity check if (!unit) return REP_NEUTRAL; // Original logic begins if (this == unit) return REP_FRIENDLY; if (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { const Player* thisPlayer = GetControllingPlayer(); if (unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED)) { const Player* unitPlayer = unit->GetControllingPlayer(); if (!thisPlayer || !unitPlayer) return REP_NEUTRAL; // Pre-TBC same player check: not present clientside in this order, but in for optimization (same result achieved through same group check below) if (thisPlayer == unitPlayer) return REP_FRIENDLY; if (unitPlayer->GetUInt32Value(PLAYER_DUEL_TEAM)) { // TODO: Dueling misses duel arbiter and temporary truce during countdown, fix me later... if (thisPlayer->IsInDuelWith(unitPlayer)) return REP_HOSTILE; } // Pre-WotLK group check: always, replaced with faction template check in WotLK if (thisPlayer->IsInGroup(unitPlayer)) return REP_FRIENDLY; // Pre-WotLK FFA check, known limitation: FFA doesn't work with totem elementals both client-side and server-side if (thisPlayer->IsPvPFreeForAll() && unitPlayer->IsPvPFreeForAll()) return REP_HOSTILE; } if (thisPlayer) { if (const FactionTemplateEntry* unitFactionTemplate = unit->GetFactionTemplateEntry()) { if (const ReputationRank* rank = thisPlayer->GetReputationMgr().GetForcedRankIfAny(unitFactionTemplate)) return (*rank); const FactionEntry* unitFactionEntry = sFactionStore.LookupEntry(unitFactionTemplate->faction); // If the faction has reputation ranks available, "at war" and contested PVP flags decide outcome if (unitFactionEntry && unitFactionEntry->HasReputation()) { // Pre-TBC contested check: not present clientside in this order, but in for optimization (same result achieved through faction to unit check below) if (thisPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_CONTESTED_PVP) && unitFactionTemplate->IsContestedGuardFaction()) return REP_HOSTILE; return thisPlayer->GetReputationMgr().IsAtWar(unitFactionEntry) ? REP_HOSTILE : REP_FRIENDLY; } } } } // Default fallback if player-specific checks didn't catch anything: facton to unit ReputationRank reaction = GetFactionReaction(GetFactionTemplateEntry(), unit); // Persuation support if (reaction > REP_HOSTILE && reaction < REP_HONORED && (unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PERSUADED) || GetPersuadedGuid() == unit->GetObjectGuid())) { if (const FactionTemplateEntry* unitFactionTemplate = unit->GetFactionTemplateEntry()) { const FactionEntry* unitFactionEntry = sFactionStore.LookupEntry(unitFactionTemplate->faction); if (unitFactionEntry && unitFactionEntry->HasReputation()) reaction = ReputationRank(int32(reaction) + 1); } } return reaction; }
bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standing, bool incremental) { bool res = false; // if spillover definition exists in DB, override DBC if (const RepSpilloverTemplate *repTemplate = sObjectMgr.GetRepSpilloverTemplate(factionEntry->ID)) { for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { if (repTemplate->faction[i]) { if (m_player->GetReputationRank(repTemplate->faction[i]) <= ReputationRank(repTemplate->faction_rank[i])) { // bonuses are already given, so just modify standing by rate int32 spilloverRep = standing * repTemplate->faction_rate[i]; SetOneFactionReputation(sFactionStore.LookupEntry(repTemplate->faction[i]), spilloverRep, incremental); } } } /*if (factionEntry->ID == 1037 || factionEntry->ID == 1052) res = SetOneFactionReputation(factionEntry, standing, incremental);*/ } else { float spillOverRepOut = standing; // check for sub-factions that receive spillover SimpleFactionsList const* flist = GetFactionTeamList(factionEntry->ID); // if has no sub-factions, check for factions with same parent if (!flist && factionEntry->team && factionEntry->spilloverRateOut != 0.0f) { spillOverRepOut *= factionEntry->spilloverRateOut; if (FactionEntry const *parent = sFactionStore.LookupEntry(factionEntry->team)) { FactionStateList::iterator parentState = m_factions.find(parent->reputationListID); // some team factions have own reputation standing, in this case do not spill to other sub-factions if (parentState != m_factions.end() && (parentState->second.Flags & FACTION_FLAG_TEAM_REPUTATION)) { SetOneFactionReputation(parent, int32(spillOverRepOut), incremental); } else // spill to "sister" factions { flist = GetFactionTeamList(factionEntry->team); } } } if (flist) { // Spillover to affiliated factions for (SimpleFactionsList::const_iterator itr = flist->begin(); itr != flist->end(); ++itr) { if (FactionEntry const *factionEntryCalc = sFactionStore.LookupEntry(*itr)) { if (factionEntryCalc == factionEntry || GetRank(factionEntryCalc) > ReputationRank(factionEntryCalc->spilloverMaxRankIn)) continue; int32 spilloverRep = int32(spillOverRepOut * factionEntryCalc->spilloverRateIn); if (spilloverRep != 0 || !incremental) res = SetOneFactionReputation(factionEntryCalc, spilloverRep, incremental); } } } } // spillover done, update faction itself FactionStateList::iterator faction = m_factions.find(factionEntry->reputationListID); if (faction != m_factions.end()) { res = SetOneFactionReputation(factionEntry, standing, incremental); // only this faction gets reported to client, even if it has no own visible standing SendState(&faction->second); } return res; }
bool TELE::IsAllowedToTeleport(Player * const player) const { if (player->isGameMaster()) { if (m_flag == FLAG_GMLEVEL) return player->GetSession()->GetSecurity() >= m_data0; return true; } switch (m_flag) { case FLAG_TEAM: switch (m_data0) { case TEAM_HORDE: return player->GetTeam() == HORDE; case TEAM_ALLIANCE: return player->GetTeam() == ALLIANCE; case TEAM_ALL: return true; } case FLAG_GUILD: return player->GetGuildId() == m_data0; case FLAG_GMLEVEL: return player->GetSession()->GetSecurity() >= m_data0; case FLAG_ISGM: return player->isGameMaster(); case FLAG_ACCOUNT: return player->GetSession()->GetAccountId() == m_data0; case FLAG_LEVEL: return player->getLevel() >= m_data0; case FLAG_ITEM: return player->HasItemCount(m_data0, m_data1, true); case FLAG_QUEST: if (m_data1 < MAX_QUEST_STATUS) return player->GetQuestStatus(m_data0) == m_data1; return player->GetQuestRewardStatus(m_data0); case FLAG_GENDER: return player->getGender() == m_data0; case FLAG_RACE: return player->getRace() == m_data0; case FLAG_CLASS: return player->getClass() == m_data0; case FLAG_REPUTATION: return player->GetReputationRank(m_data0) >= ReputationRank(m_data1); case FLAG_PLAYER: return player->GetGUID() == m_data0; } sLog->outError(LOG_FILTER_GENERAL, "Invalid flag (category: %u). Important problem...", GetCatID()); return false; }
void WorldSession::SendListInventory(ObjectGuid vendorguid) { DEBUG_LOG("WORLD: Sent SMSG_LIST_INVENTORY"); Creature* pCreature = GetPlayer()->GetNPCIfCanInteractWith(vendorguid, UNIT_NPC_FLAG_VENDOR); if (!pCreature) { DEBUG_LOG("WORLD: SendListInventory - %s not found or you can't interact with him.", vendorguid.GetString().c_str()); _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid(), 0); return; } // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) { GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); } // Stop the npc if moving pCreature->StopMoving(); VendorItemData const* vItems = pCreature->GetVendorItems(); VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); if (!vItems && !tItems) { WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + 1)); data << ObjectGuid(vendorguid); data << uint8(0); // count==0, next will be error code data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } uint8 customitems = vItems ? vItems->GetItemCount() : 0; uint8 numitems = customitems + (tItems ? tItems->GetItemCount() : 0); uint8 count = 0; WorldPacket data(SMSG_LIST_INVENTORY, (8 + 1 + numitems * 7 * 4)); data << ObjectGuid(vendorguid); size_t count_pos = data.wpos(); data << uint8(count); float discountMod = _player->GetReputationPriceDiscount(pCreature); for (int i = 0; i < numitems; ++i) { VendorItem const* crItem = i < customitems ? vItems->GetItem(i) : tItems->GetItem(i - customitems); if (crItem) { uint32 itemId = crItem->item; ItemPrototype const* pProto = ObjectMgr::GetItemPrototype(itemId); if (pProto) { if (!_player->isGameMaster()) { // class wrong item skip only for bindable case if ((pProto->AllowableClass & _player->getClassMask()) == 0 && pProto->Bonding == BIND_WHEN_PICKED_UP) { continue; } // race wrong item skip always if ((pProto->AllowableRace & _player->getRaceMask()) == 0) { continue; } // when no faction required but rank > 0 will be used faction id from the vendor faction template to compare the rank if (!pProto->RequiredReputationFaction && pProto->RequiredReputationRank > 0 && ReputationRank(pProto->RequiredReputationRank) > _player->GetReputationRank(pCreature->getFactionTemplateEntry()->faction)) { continue; } if (crItem->conditionId && !sObjectMgr.IsPlayerMeetToCondition(crItem->conditionId, _player, pCreature->GetMap(), pCreature, CONDITION_FROM_VENDOR)) { continue; } } ++count; uint32 price = 0; // check if the item to sell is a mount switch (itemId) { case 1132: // all regular mounts case 2411: case 2414: case 5655: case 5656: case 5665: case 5668: case 5864: case 5872: case 5873: case 8563: case 8588: case 8591: case 8592: case 8595: case 8629: case 8631: case 8632: case 12325: case 12326: case 12327: case 13321: case 13322: case 13331: case 13332: case 13333: case 15277: case 15290: case 18241: case 18242: case 18243: case 18244: case 18245: case 18246: case 18247: case 18248: // apply discount for regular mount and set price price = uint32(floor(AccountTypes(sWorld.getConfig(CONFIG_UINT32_MOUNT_COST)) * discountMod)); break; case 12302: // all epic mounts case 12303: case 12330: case 12351: case 12353: case 12354: case 13086: case 13326: case 13327: case 13328: case 13329: case 13334: case 13335: case 18766: case 18767: case 18768: case 18772: case 18773: case 18774: case 18776: case 18777: case 18778: case 18785: case 18786: case 18787: case 18788: case 18789: case 18790: case 18791: case 18793: case 18794: case 18795: case 18796: case 18797: case 18798: case 18902: // apply discount for epic mount and set price price = uint32(floor(AccountTypes(sWorld.getConfig(CONFIG_UINT32_EPIC_MOUNT_COST)) * discountMod)); break; default: // any other items price = uint32(floor(pProto->BuyPrice * discountMod)); break; } data << uint32(count); data << uint32(itemId); data << uint32(pProto->DisplayInfoID); data << uint32(crItem->maxcount <= 0 ? 0xFFFFFFFF : pCreature->GetVendorItemCurrentCount(crItem)); data << uint32(price); data << uint32(pProto->MaxDurability); data << uint32(pProto->BuyCount); } } } if (count == 0) { data << uint8(0); // "Vendor has no inventory" SendPacket(&data); return; } data.put<uint8>(count_pos, count); SendPacket(&data); }