Merge branch 'master' of github.com:TrinityCore/TrinityCore

This commit is contained in:
Machiavelli
2011-12-19 11:14:26 +01:00
54 changed files with 2134 additions and 245 deletions
@@ -543,7 +543,6 @@ bool npc_escortAI::GetWaypointPosition(uint32 pointId, float& x, float& y, float
if (waypoints.empty())
return false;
ScriptPointVector::const_iterator itrEnd = waypoints.end();
for (ScriptPointVector::const_iterator itr = waypoints.begin(); itr != waypoints.end(); ++itr)
{
if (itr->uiPointId == pointId)
@@ -1075,7 +1075,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
if (!data || !data->Meets(GetPlayer(), unit))
continue;
break;
}
SetCriteriaProgress(achievementCriteria, 1);
@@ -122,28 +122,29 @@ bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
return true;
}
// Ticket must be assigned to player, who tries to close it.
uint64 guid = m_session->GetPlayer()->GetGUID();
if (ticket->IsAssignedNotTo(guid))
// Ticket should be assigned to the player who tries to close it.
// Console can override though
Player* player = m_session ? m_session->GetPlayer() : NULL;
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->GetId());
return true;
}
sTicketMgr->CloseTicket(ticket->GetId(), guid);
sTicketMgr->CloseTicket(ticket->GetId(), player ? player->GetGUID() : -1);
sTicketMgr->UpdateLastChange();
std::string msg = ticket->FormatMessageString(*this, m_session->GetPlayer()->GetName(), NULL, NULL, NULL);
std::string msg = ticket->FormatMessageString(*this, player ? player->GetName() : "Console", NULL, NULL, NULL);
SendGlobalGMSysMessage(msg.c_str());
// Inform player, who submitted this ticket, that it is closed
if (Player* player = ticket->GetPlayer())
if (Player* submitter = ticket->GetPlayer())
{
if (player->IsInWorld())
if (submitter->IsInWorld())
{
WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
data << uint32(GMTICKET_RESPONSE_TICKET_DELETED);
player->GetSession()->SendPacket(&data);
submitter->GetSession()->SendPacket(&data);
}
}
return true;
+1
View File
@@ -908,6 +908,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetCreateHealth(40*petlevel);
SetCreateMana(28 + 10*petlevel);
}
SetBonusDamage(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FIRE) * 0.5f);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
+10 -17
View File
@@ -1850,7 +1850,7 @@ void Player::setDeathState(DeathState s)
SetUInt32Value(PLAYER_SELF_RES_SPELL, 0);
}
bool Player::BuildEnumData(QueryResult result, WorldPacket* data)
bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
{
// 0 1 2 3 4 5 6 7
// "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
@@ -1894,8 +1894,8 @@ bool Player::BuildEnumData(QueryResult result, WorldPacket* data)
*data << uint8(playerBytes2 & 0xFF); // facial hair
*data << uint8(fields[7].GetUInt8()); // level
*data << uint32(fields[8].GetUInt32()); // zone
*data << uint32(fields[9].GetUInt32()); // map
*data << uint32(fields[8].GetUInt16()); // zone
*data << uint32(fields[9].GetUInt16()); // map
*data << fields[10].GetFloat(); // x
*data << fields[11].GetFloat(); // y
@@ -12863,6 +12863,8 @@ void Player::SwapItem(uint16 src, uint16 dst)
RemoveItem(srcbag, srcslot, true);
StoreItem(dest, pSrcItem, true);
if (IsBankPos(src))
ItemAddedQuestCheck(pSrcItem->GetEntry(), pSrcItem->GetCount());
}
else if (IsBankPos (dst))
{
@@ -12876,6 +12878,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
RemoveItem(srcbag, srcslot, true);
BankItem(dest, pSrcItem, true);
ItemRemovedQuestCheck(pSrcItem->GetEntry(), pSrcItem->GetCount());
}
else if (IsEquipmentPos (dst))
{
@@ -13300,11 +13303,7 @@ void Player::UpdateSoulboundTradeItems()
// also checks for garbage data
for (ItemDurationList::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end();)
{
if (!*itr)
{
m_itemSoulboundTradeable.erase(itr++);
continue;
}
ASSERT(*itr);
if ((*itr)->GetOwnerGUID() != GetGUID())
{
m_itemSoulboundTradeable.erase(itr++);
@@ -13319,16 +13318,10 @@ void Player::UpdateSoulboundTradeItems()
}
}
//TODO: should never allow an item to be added to m_itemSoulboundTradeable twice
void Player::RemoveTradeableItem(Item* item)
{
for (ItemDurationList::iterator itr = m_itemSoulboundTradeable.begin(); itr != m_itemSoulboundTradeable.end(); ++itr)
{
if ((*itr) == item)
{
m_itemSoulboundTradeable.erase(itr);
break;
}
}
m_itemSoulboundTradeable.remove(item);
}
void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
@@ -18903,7 +18896,7 @@ void Player::_SaveSkills(SQLTransaction& trans)
void Player::_SaveSpells(SQLTransaction& trans)
{
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
trans->PAppend("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
+2 -2
View File
@@ -1111,7 +1111,7 @@ class Player : public Unit, public GridObject<Player>
void Update(uint32 time);
static bool BuildEnumData(QueryResult result, WorldPacket* data);
static bool BuildEnumData(PreparedQueryResult result, WorldPacket* data);
void SetInWater(bool apply);
@@ -2500,7 +2500,7 @@ class Player : public Unit, public GridObject<Player>
CreatureDisplayInfoEntry const* mountDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID));
if (!mountDisplayInfo)
return GetCollisionHeight(false);
CreatureModelDataEntry const* mountModelData = sCreatureModelDataStore.LookupEntry(mountDisplayInfo->ModelId);
if (!mountModelData)
return GetCollisionHeight(false);
+4 -9
View File
@@ -1926,12 +1926,7 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext
CombatStart(victim);
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MELEE_ATTACK);
uint32 hitInfo;
if (attType == BASE_ATTACK)
hitInfo = HITINFO_NORMALSWING2;
else if (attType == OFF_ATTACK)
hitInfo = HITINFO_LEFTSWING;
else
if (attType != BASE_ATTACK && attType != OFF_ATTACK)
return; // ignore ranged case
// melee attack spell casted at main hand attack only - no normal melee dmg dealt
@@ -5474,7 +5469,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
case CLASS_DRUID:
RandomSpells.push_back(71484);
RandomSpells.push_back(71485);
RandomSpells.push_back(71486);
RandomSpells.push_back(71492);
break;
case CLASS_HUNTER:
RandomSpells.push_back(71486);
@@ -5520,7 +5515,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
case CLASS_DRUID:
RandomSpells.push_back(71561);
RandomSpells.push_back(71556);
RandomSpells.push_back(71558);
RandomSpells.push_back(71560);
break;
case CLASS_HUNTER:
RandomSpells.push_back(71558);
@@ -6502,7 +6497,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
RemoveAura(57934);
if (!redirectTarget)
break;
redirectTarget->CastSpell(this,59628,true);
CastSpell(this,59628,true);
CastSpell(redirectTarget,57933,true);
break;
}
+2 -2
View File
@@ -3818,11 +3818,11 @@ void ObjectMgr::LoadQuests()
// no changes, quest not dependent from this value but can have problems at client (note some may be 0, we must allow this so no check)
}
//check for proper RequiredSkillId value (skill case)
if (int32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
if (uint32 skill_id = SkillByQuestSort(-int32(qinfo->ZoneOrSort)))
{
if (qinfo->RequiredSkillId != skill_id)
{
sLog->outErrorDb("Quest %u has `ZoneOrSort` = %i but `RequiredSkillId` does not have a corresponding value (%i).",
sLog->outErrorDb("Quest %u has `ZoneOrSort` = %i but `RequiredSkillId` does not have a corresponding value (%d).",
qinfo->GetQuestId(), qinfo->ZoneOrSort, skill_id);
//override, and force proper value here?
}
+8
View File
@@ -30,6 +30,7 @@
#include "MapManager.h"
#include "ObjectMgr.h"
#include "Group.h"
#include "LFGMgr.h"
union u_map_magic
{
@@ -2318,6 +2319,13 @@ bool InstanceMap::AddPlayerToMap(Player* player)
ASSERT(playerBind->save == mapSave);
}
}
if (group && group->isLFGGroup())
if (uint32 dungeonId = sLFGMgr->GetDungeon(group->GetGUID(), true))
if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
if (LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(player->GetGUID()).begin())))
if (dungeon->map == GetId() && dungeon->difficulty == GetDifficulty() && randomDungeon->type == LFG_TYPE_RANDOM)
player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
}
// for normal instances cancel the reset schedule when the
+2 -1
View File
@@ -946,8 +946,9 @@ enum TrinityStrings
LANG_GOINFO_NAME = 5027,
LANG_GOINFO_LOOTID = 5028,
LANG_COMMAND_LOOKUP_MAX_RESULTS = 5029,
// Room for more Trinity strings 5030-9999
LANG_FLEE = 5030,
LANG_NPCINFO_AIINFO = 5031,
// Room for more Trinity strings 5032-9999
// Level requirement notifications
LANG_SAY_REQ = 6604,
@@ -47,11 +47,10 @@ template<>
void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
float X, Y, Z, z, nx, ny, nz, ori, dist;
float X, Y, Z, nx, ny, nz, ori, dist;
creature.GetHomePosition(X, Y, Z, ori);
z = creature.GetPositionZ();
Map const* map = creature.GetBaseMap();
// For 2D/3D system selection
@@ -196,7 +196,7 @@ bool LoginQueryHolder::Initialize()
return res;
}
void WorldSession::HandleCharEnum(QueryResult result)
void WorldSession::HandleCharEnum(PreparedQueryResult result)
{
WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
@@ -232,35 +232,16 @@ void WorldSession::HandleCharEnumOpcode(WorldPacket & /*recv_data*/)
CharacterDatabase.Execute(stmt);
/// get all the data necessary for loading all characters (along with their pets) on the account
_charEnumCallback =
CharacterDatabase.AsyncPQuery(
!sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) ?
// ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
"WHERE characters.account = '%u' ORDER BY characters.guid"
:
// --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7
"SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
"characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
// 15 16 17 18 19 20 21
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.equipmentCache, character_banned.guid, character_declinedname.genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"LEFT JOIN character_banned ON characters.guid = character_banned.guid AND character_banned.active = 1 "
"WHERE characters.account = '%u' ORDER BY characters.guid",
PET_SAVE_AS_CURRENT, GetAccountId()
);
if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM_DECLINED_NAME);
else
stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_ENUM);
stmt->setUInt8(0, PET_SAVE_AS_CURRENT);
stmt->setUInt32(1, GetAccountId());
_charEnumCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
@@ -1102,13 +1083,13 @@ void WorldSession::HandleShowingCloakOpcode(WorldPacket& recv_data)
void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
{
uint64 guid;
std::string newname;
std::string newName;
recv_data >> guid;
recv_data >> newname;
recv_data >> newName;
// prevent character rename to invalid name
if (!normalizePlayerName(newname))
if (!normalizePlayerName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_NO_NAME);
@@ -1116,7 +1097,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
uint8 res = ObjectMgr::CheckPlayerName(newname, true);
uint8 res = ObjectMgr::CheckPlayerName(newName, true);
if (res != CHAR_NAME_SUCCESS)
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
@@ -1126,7 +1107,7 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
}
// check name limitations
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newname))
if (AccountMgr::IsPlayerAccount(GetSecurity()) && sObjectMgr->IsReservedName(newName))
{
WorldPacket data(SMSG_CHAR_RENAME, 1);
data << uint8(CHAR_NAME_RESERVED);
@@ -1134,21 +1115,22 @@ void WorldSession::HandleCharRenameOpcode(WorldPacket& recv_data)
return;
}
std::string escaped_newname = newname;
CharacterDatabase.EscapeString(escaped_newname);
// make sure that the character belongs to the current account, that rename at login is enabled
// Ensure that the character belongs to the current account, that rename at login is enabled
// and that there is no character with the desired new name
_charRenameCallback.SetParam(newname);
_charRenameCallback.SetFutureResult(
CharacterDatabase.AsyncPQuery(
"SELECT guid, name FROM characters WHERE guid = %d AND account = %d AND (at_login & %d) = %d AND NOT EXISTS (SELECT NULL FROM characters WHERE name = '%s')",
GUID_LOPART(guid), GetAccountId(), AT_LOGIN_RENAME, AT_LOGIN_RENAME, escaped_newname.c_str()
)
);
_charRenameCallback.SetParam(newName);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_FREE_NAME);
stmt->setUInt32(0, GUID_LOPART(guid));
stmt->setUInt32(1, GetAccountId());
stmt->setUInt16(2, AT_LOGIN_RENAME);
stmt->setUInt16(3, AT_LOGIN_RENAME);
stmt->setString(4, newName);
_charRenameCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname)
void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName)
{
if (!result)
{
@@ -1158,22 +1140,38 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult result, std:
return;
}
uint32 guidLow = result->Fetch()[0].GetUInt32();
Field* fields = result->Fetch();
uint32 guidLow = fields[0].GetUInt32();
std::string oldName = fields[1].GetString();
uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER);
std::string oldname = result->Fetch()[1].GetString();
CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow);
// Update name and at_login flag in the db
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_NAME);
sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str());
stmt->setString(0, newName);
stmt->setUInt16(1, AT_LOGIN_RENAME);
stmt->setUInt32(2, guidLow);
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1));
CharacterDatabase.Execute(stmt);
// Removed declined name from db
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
stmt->setUInt32(0, guidLow);
CharacterDatabase.Execute(stmt);
sLog->outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str());
WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newName.size()+1));
data << uint8(RESPONSE_SUCCESS);
data << uint64(guid);
data << newname;
data << newName;
SendPacket(&data);
sWorld->UpdateCharacterNameData(guidLow, newname);
sWorld->UpdateCharacterNameData(guidLow, newName);
}
void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recv_data)
@@ -938,6 +938,7 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket)
}
_player->RemoveItem(srcbag, srcslot, true);
_player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount());
_player->BankItem(dest, pItem, true);
}
@@ -965,6 +966,7 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket)
_player->RemoveItem(srcbag, srcslot, true);
_player->StoreItem(dest, pItem, true);
_player->ItemAddedQuestCheck(pItem->GetEntry(), pItem->GetCount());
}
else // moving from inventory to bank
{
@@ -613,22 +613,24 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_ADD_IGNORE");
std::string IgnoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
std::string ignoreName = GetTrinityString(LANG_FRIEND_IGNORE_UNKNOWN);
recv_data >> IgnoreName;
recv_data >> ignoreName;
if (!normalizePlayerName(IgnoreName))
if (!normalizePlayerName(ignoreName))
return;
CharacterDatabase.EscapeString(IgnoreName); // prevent SQL injection - normal name must not be changed by this call
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: %s asked to Ignore: '%s'",
GetPlayer()->GetName(), IgnoreName.c_str());
GetPlayer()->GetName(), ignoreName.c_str());
_addIgnoreCallback = CharacterDatabase.AsyncPQuery("SELECT guid FROM characters WHERE name = '%s'", IgnoreName.c_str());
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUID_BY_NAME);
stmt->setString(0, ignoreName);
_addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleAddIgnoreOpcodeCallBack(QueryResult result)
void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result)
{
if (!GetPlayer())
return;
@@ -618,39 +618,43 @@ void WorldSession::HandleStablePet(WorldPacket & recv_data)
return;
}
_stablePetCallback = CharacterDatabase.AsyncPQuery("SELECT owner, slot, id FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot ",
_player->GetGUIDLow(), PET_SAVE_FIRST_STABLE_SLOT, PET_SAVE_LAST_STABLE_SLOT);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_PET_SLOTS);
stmt->setUInt32(0, _player->GetGUIDLow());
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
_stablePetCallback = CharacterDatabase.AsyncQuery(stmt);
}
void WorldSession::HandleStablePetCallback(QueryResult result)
void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
{
if (!GetPlayer())
return;
uint32 free_slot = 1;
uint8 freeSlot = 1;
if (result)
{
do
{
Field* fields = result->Fetch();
uint32 slot = fields[1].GetUInt32();
uint8 slot = fields[1].GetUInt8();
// slots ordered in query, and if not equal then free
if (slot != free_slot)
if (slot != freeSlot)
break;
// this slot not free, skip
++free_slot;
++freeSlot;
}
while (result->NextRow());
}
WorldPacket data(SMSG_STABLE_RESULT, 1);
if (free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots)
if (freeSlot > 0 && freeSlot <= GetPlayer()->m_stableSlots)
{
_player->RemovePet(_player->GetPet(), PetSaveMode(free_slot));
_player->RemovePet(_player->GetPet(), PetSaveMode(freeSlot));
SendStableResult(STABLE_SUCCESS_STABLE);
}
else
@@ -878,19 +882,18 @@ void WorldSession::HandleRepairItemOpcode(WorldPacket & recv_data)
// reputation discount
float discountMod = _player->GetReputationPriceDiscount(unit);
uint32 TotalCost = 0;
if (itemGUID)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "ITEM: Repair item, itemGUID = %u, npcGUID = %u", GUID_LOPART(itemGUID), GUID_LOPART(npcGUID));
Item* item = _player->GetItemByGuid(itemGUID);
if (item)
TotalCost = _player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
_player->DurabilityRepair(item->GetPos(), true, discountMod, guildBank);
}
else
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "ITEM: Repair all items, npcGUID = %u", GUID_LOPART(npcGUID));
TotalCost = _player->DurabilityRepairAll(true, discountMod, guildBank);
_player->DurabilityRepairAll(true, discountMod, guildBank);
}
}
@@ -311,21 +311,17 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
uint64 ownerguid = 0;
uint32 type;
std::string name = "NO_NAME_FOR_GUID";
uint8 signs = 0;
QueryResult result = CharacterDatabase.PQuery(
"SELECT ownerguid, name, "
" (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs, "
" type "
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
// TODO: Use CHAR_LOAD_PETITION PS
QueryResult result = CharacterDatabase.PQuery("SELECT ownerguid, name, type "
"FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
if (result)
{
Field* fields = result->Fetch();
ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
name = fields[1].GetString();
signs = fields[2].GetUInt8();
type = fields[3].GetUInt32();
type = fields[2].GetUInt32();
}
else
{
+9 -8
View File
@@ -998,12 +998,13 @@ void WorldSession::InitializeQueryCallbackParameters()
void WorldSession::ProcessQueryCallbacks()
{
QueryResult result;
PreparedQueryResult result2;
//! HandleCharEnumOpcode
if (_charEnumCallback.ready())
{
_charEnumCallback.get(result);
HandleCharEnum(result);
_charEnumCallback.get(result2);
HandleCharEnum(result2);
_charEnumCallback.cancel();
}
@@ -1037,16 +1038,16 @@ void WorldSession::ProcessQueryCallbacks()
if (_charRenameCallback.IsReady())
{
std::string param = _charRenameCallback.GetParam();
_charRenameCallback.GetResult(result);
HandleChangePlayerNameOpcodeCallBack(result, param);
_charRenameCallback.GetResult(result2);
HandleChangePlayerNameOpcodeCallBack(result2, param);
_charRenameCallback.FreeResult();
}
//- HandleCharAddIgnoreOpcode
if (_addIgnoreCallback.ready())
{
_addIgnoreCallback.get(result);
HandleAddIgnoreOpcodeCallBack(result);
_addIgnoreCallback.get(result2);
HandleAddIgnoreOpcodeCallBack(result2);
_addIgnoreCallback.cancel();
}
@@ -1062,8 +1063,8 @@ void WorldSession::ProcessQueryCallbacks()
//- HandleStablePet
if (_stablePetCallback.ready())
{
_stablePetCallback.get(result);
HandleStablePetCallback(result);
_stablePetCallback.get(result2);
HandleStablePetCallback(result2);
_stablePetCallback.cancel();
}
+8 -9
View File
@@ -400,7 +400,7 @@ class WorldSession
void HandleCharCreateOpcode(WorldPacket& recvPacket);
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
void HandleCharEnum(QueryResult result);
void HandleCharEnum(PreparedQueryResult result);
void HandlePlayerLogin(LoginQueryHolder * holder);
void HandleCharFactionOrRaceChange(WorldPacket& recv_data);
@@ -472,7 +472,7 @@ class WorldSession
void HandleAddFriendOpcodeCallBack(QueryResult result, std::string friendNote);
void HandleDelFriendOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
void HandleAddIgnoreOpcodeCallBack(QueryResult result);
void HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result);
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
@@ -588,7 +588,7 @@ class WorldSession
void HandleBinderActivateOpcode(WorldPacket& recvPacket);
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
void HandleStablePet(WorldPacket& recvPacket);
void HandleStablePetCallback(QueryResult result);
void HandleStablePetCallback(PreparedQueryResult result);
void HandleUnstablePet(WorldPacket& recvPacket);
void HandleUnstablePetCallback(QueryResult result, uint32 petnumber);
void HandleBuyStableSlot(WorldPacket& recvPacket);
@@ -747,7 +747,7 @@ class WorldSession
void HandleSetActionBarToggles(WorldPacket& recv_data);
void HandleCharRenameOpcode(WorldPacket& recv_data);
void HandleChangePlayerNameOpcodeCallBack(QueryResult result, std::string newname);
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, std::string newName);
void HandleSetPlayerDeclinedNames(WorldPacket& recv_data);
void HandleTotemDestroyed(WorldPacket& recv_data);
@@ -896,11 +896,10 @@ class WorldSession
void InitializeQueryCallbackParameters();
void ProcessQueryCallbacks();
ACE_Future_Set<QueryResult> _nameQueryCallbacks;
QueryResultFuture _charEnumCallback;
QueryResultFuture _addIgnoreCallback;
QueryResultFuture _stablePetCallback;
QueryCallback<QueryResult, std::string> _charRenameCallback;
PreparedQueryResultFuture _charEnumCallback;
PreparedQueryResultFuture _addIgnoreCallback;
PreparedQueryResultFuture _stablePetCallback;
QueryCallback<PreparedQueryResult, std::string> _charRenameCallback;
QueryCallback<QueryResult, std::string> _addFriendCallback;
QueryCallback<QueryResult, uint32> _unstablePetCallback;
QueryCallback<QueryResult, uint32> _stableSwapCallback;
@@ -1518,7 +1518,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
spellId3 = 47180;
break;
}
target->CastSpell(target, spellId, true, NULL, this);
target->CastSpell(target, spellId3, true, NULL, this);
}
// Master Shapeshifter - Cat
if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
@@ -4804,8 +4804,10 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (Aura* newAura = target->AddAura(71564, target))
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
break;
case 59628: // Tricks of the Trade
target->SetReducedThreatPercent(100,caster->GetGUID());
case 59628: // Tricks of the Trade
if (!caster->GetMisdirectionTarget())
break;
target->SetReducedThreatPercent(100,caster->GetMisdirectionTarget()->GetGUID());
break;
}
}
@@ -4958,9 +4960,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
// Tricks of the trade
switch(GetId())
{
case 59628:
case 57934:
case 59628: //Tricks of the trade buff on rogue (6sec duration)
target->SetReducedThreatPercent(0,0);
break;
case 57934: //Tricks of the trade buff on rogue (30sec duration)
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE || !caster->GetMisdirectionTarget())
target->SetReducedThreatPercent(0,0);
else
target->SetReducedThreatPercent(0,caster->GetMisdirectionTarget()->GetGUID());
break;
}
default:
+58 -40
View File
@@ -606,57 +606,67 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
case SPELLFAMILY_ROGUE:
{
// Envenom
if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[1] & 0x8))
if (m_spellInfo->SpellFamilyFlags[1] & 0x00000008)
{
// consume from stack dozes not more that have combo-points
if (uint32 combo = m_caster->ToPlayer()->GetComboPoints())
if (Player* player = m_caster->ToPlayer())
{
// Lookup for Deadly poison (only attacker applied)
if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0, 0, m_caster->GetGUID()))
// consume from stack dozes not more that have combo-points
if (uint32 combo = player->GetComboPoints())
{
// count consumed deadly poison doses at target
bool needConsume = true;
uint32 spellId = aurEff->GetId();
uint32 doses = aurEff->GetBase()->GetStackAmount();
if (doses > combo)
doses = combo;
// Master Poisoner
Unit::AuraEffectList const& auraList = m_caster->ToPlayer()->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
// Lookup for Deadly poison (only attacker applied)
if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, m_caster->GetGUID()))
{
if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
// count consumed deadly poison doses at target
bool needConsume = true;
uint32 spellId = aurEff->GetId();
uint32 doses = aurEff->GetBase()->GetStackAmount();
if (doses > combo)
doses = combo;
// Master Poisoner
Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
{
uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
{
uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
if (chance && roll_chance_i(chance))
needConsume = false;
if (chance && roll_chance_i(chance))
needConsume = false;
break;
break;
}
}
if (needConsume)
for (uint32 i = 0; i < doses; ++i)
unitTarget->RemoveAuraFromStack(spellId);
damage *= doses;
damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
}
if (needConsume)
for (uint32 i = 0; i < doses; ++i)
unitTarget->RemoveAuraFromStack(spellId);
damage *= doses;
damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * doses);
// Eviscerate and Envenom Bonus Damage (item set effect)
if (m_caster->HasAura(37169))
damage += combo * 40;
}
// Eviscerate and Envenom Bonus Damage (item set effect)
if (m_caster->HasAura(37169))
damage += ((Player*)m_caster)->GetComboPoints()*40;
}
}
// Eviscerate
else if ((m_spellInfo->SpellFamilyFlags[0] & 0x00020000) && m_caster->GetTypeId() == TYPEID_PLAYER)
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00020000)
{
if (uint32 combo = ((Player*)m_caster)->GetComboPoints())
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
if (uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));
// Eviscerate and Envenom Bonus Damage (item set effect)
if (m_caster->HasAura(37169))
damage += combo*40;
// Eviscerate and Envenom Bonus Damage (item set effect)
if (m_caster->HasAura(37169))
damage += combo*40;
}
}
}
break;
@@ -6234,9 +6244,13 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
if (!unitTarget)
return;
float x, y, z;
unitTarget->GetContactPoint(m_caster, x, y, z);
m_caster->GetMotionMaster()->MoveCharge(x, y, z);
float angle = unitTarget->GetRelativeAngle(m_caster);
Position pos;
unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetObjectSize(), angle);
m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + unitTarget->GetObjectSize());
}
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
@@ -6257,9 +6271,13 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
if (m_targets.HasDst())
{
float x, y, z;
m_targets.GetDst()->GetPosition(x, y, z);
m_caster->GetMotionMaster()->MoveCharge(x, y, z);
Position pos;
m_targets.GetDst()->GetPosition(&pos);
float angle = m_caster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
float dist = m_caster->GetDistance(pos);
m_caster->GetFirstCollisionPosition(pos, dist, angle);
m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
}
}
+13
View File
@@ -2304,6 +2304,19 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
if (Id == 30708)
return false;
break;
case SPELLFAMILY_ROGUE:
switch (Id)
{
// Envenom must be considered as a positive effect even though it deals damage
case 32645: // Envenom (Rank 1)
case 32684: // Envenom (Rank 2)
case 57992: // Envenom (Rank 3)
case 57993: // Envenom (Rank 4)
return true;
default:
break;
}
break;
default:
break;
}
+4
View File
@@ -3227,6 +3227,10 @@ void SpellMgr::LoadDbcDataCorrections()
// this needs research on modifier applying rules, does not seem to be in Attributes fields
spellInfo->EffectSpellClassMask[0] = flag96(0x00000040, 0x00000000, 0x00000000);
break;
case 63163: // Apply Enchanted Bridle (Argent Tournament)
spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1
spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)
break;
case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
+1 -1
View File
@@ -635,7 +635,7 @@ class World
/// Are we in the middle of a shutdown?
bool IsShuttingDown() const { return m_ShutdownTimer > 0; }
uint32 const GetShutDownTimeLeft() { return m_ShutdownTimer; }
uint32 GetShutDownTimeLeft() const { return m_ShutdownTimer; }
void ShutdownServ(uint32 time, uint32 options, uint8 exitcode);
void ShutdownCancel();
void ShutdownMsg(bool show = false, Player* player = NULL);