diff --git a/src/game/ArenaTeam.cpp b/src/game/ArenaTeam.cpp index f777b0ee8b..00e0f08822 100644 --- a/src/game/ArenaTeam.cpp +++ b/src/game/ArenaTeam.cpp @@ -145,7 +145,7 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid) // hide promote/remove buttons if(CaptainGuid != PlayerGuid) pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1); - sLog.outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", pl->GetName(), pl->GetGUID(), GetType(), GetId()); + sLog.outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", pl->GetName(), pl->GetGUIDLow(), GetType(), GetId()); } return true; } @@ -254,7 +254,7 @@ void ArenaTeam::SetCaptain(const uint64& guid) if(newcaptain) { newcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 0); - sLog.outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUID(), newcaptain->GetName(), newcaptain->GetGUID(), GetId(), GetType()); + sLog.outArena("Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldcaptain->GetName(), oldcaptain->GetGUIDLow(), newcaptain->GetName(), newcaptain->GetGUID(), GetId(), GetType()); } } @@ -280,7 +280,7 @@ void ArenaTeam::DelMember(uint64 guid) { player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + i, 0); } - sLog.outArena("Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), guid, GetType(), GetId()); + sLog.outArena("Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); } CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u' AND guid = '%u'", GetId(), GUID_LOPART(guid)); } @@ -299,7 +299,7 @@ void ArenaTeam::Disband(WorldSession *session) } if(Player *player = session->GetPlayer()) - sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUID(), GetType(), GetId()); + sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id); diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index ba9cc5d7a2..1722fd9602 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -713,7 +713,6 @@ ChatCommand * ChatHandler::getCommandTable() { "freeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFreezeCommand, "", NULL }, { "unfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnFreezeCommand, "", NULL }, { "listfreeze", SEC_ADMINISTRATOR, false, &ChatHandler::HandleListFreezeCommand, "", NULL }, - { "flusharenapoints", SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, { "possess", SEC_ADMINISTRATOR, false, &ChatHandler::HandlePossessCommand, "", NULL }, { "unpossess", SEC_ADMINISTRATOR, false, &ChatHandler::HandleUnPossessCommand, "", NULL }, diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index bc0e3b8f80..06338bbe23 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -122,6 +122,9 @@ bool ChatHandler::HandleAHBotOptionsCommand(const char* args) } else if (strncmp(opt,"maxitems",l) == 0) { + PSendSysMessage("ahbotoptions mintime has been deprecated"); + return false; + /* char * param1 = strtok(NULL, " "); if ((!ahMapIdStr) || (!param1)) { @@ -129,6 +132,7 @@ bool ChatHandler::HandleAHBotOptionsCommand(const char* args) return false; } AuctionHouseBotCommands(2, ahMapID, NULL, param1); + */ } else if (strncmp(opt,"mintime",l) == 0) { diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 49327ed359..e861635281 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1036,7 +1036,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) SpellMissInfo missInfo = DoSpellHitOnUnit(spellHitTarget, mask); if(missInfo != SPELL_MISS_NONE) { - m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo); + if(missInfo != SPELL_MISS_MISS) + m_caster->SendSpellMiss(unit, m_spellInfo->Id, missInfo); m_damage = 0; spellHitTarget = NULL; } @@ -1186,10 +1187,17 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask) if( !m_caster->IsFriendlyTo(unit) ) { + // reset damage to 0 if target has Invisibility or Vanish aura (_only_ vanish, not stealth) and isn't visible for caster + // I do not think this is a correct way to fix it. Sanctuary effect should make all delayed spells invalid // for delayed spells ignore not visible explicit target - if(m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() && !unit->isVisibleForOrDetect(m_caster,false)) + if(m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() + && (unit->HasAuraType(SPELL_AURA_MOD_INVISIBILITY) + || unit->HasAuraTypeWithFamilyFlags(SPELL_AURA_MOD_STEALTH, SPELLFAMILY_ROGUE, SPELLFAMILYFLAG_ROGUE_VANISH)) + && !unit->isVisibleForOrDetect(m_caster, true)) { - return SPELL_MISS_EVADE; + // that was causing CombatLog errors + // return SPELL_MISS_EVADE; + return SPELL_MISS_MISS; // miss = do not send anything here } unit->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_HITBYSPELL); @@ -2547,18 +2555,29 @@ void Spell::cancel() void Spell::cast(bool skipCheck) { - SetExecutedCurrently(true); - // update pointers base at GUIDs to prevent access to non-existed already object UpdatePointers(); - // cancel at lost main target unit - if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) + if(m_targets.getUnitTarget()) { - cancel(); - SetExecutedCurrently(false); - return; + // three check: prepare, cast (m_casttime > 0), hit (delayed) + if(m_casttime && m_targets.getUnitTarget()->isAlive() && !m_caster->canSeeOrDetect(m_targets.getUnitTarget(), true)) + { + cancel(); + return; + } } + else + { + // cancel at lost main target unit + if(m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) + { + cancel(); + return; + } + } + + SetExecutedCurrently(true); if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster) m_caster->SetInFront(m_targets.getUnitTarget()); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 82efd2e54a..14ad660df6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -513,6 +513,17 @@ void Unit::UpdateInterruptMask() m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags; } +bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const +{ + if(!HasAuraType(auraType)) return false; + AuraEffectList const &auras = GetAurasByType(auraType); + for(AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if(SpellEntry const *iterSpellProto = (*itr)->GetSpellProto()) + if(iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags[0] & familyFlags) + return true; + return false; +} + /* Called by DealDamage for auras that have a chance to be dispelled on damage taken. */ void Unit::RemoveSpellbyDamageTaken(uint32 damage, uint32 spell) { diff --git a/src/game/Unit.h b/src/game/Unit.h index ea99f8a242..82e4df55a9 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1243,6 +1243,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject void ClearInCombat(); uint32 GetCombatTimer() const { return m_CombatTimer; } + bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } diff --git a/src/game/Wintergrasp.cpp b/src/game/Wintergrasp.cpp index 782ec4ab53..2d76559a1c 100644 --- a/src/game/Wintergrasp.cpp +++ b/src/game/Wintergrasp.cpp @@ -49,6 +49,9 @@ void LoadTeamPair(TeamPairMap &pairMap, const TeamPair *pair) } } +#define REMOVE_RANK_AURAS(p) (p)->RemoveAura(SPELL_RECRUIT);\ + (p)->RemoveAura(SPELL_CORPORAL);(p)->RemoveAura(SPELL_LIEUTENANT) + typedef std::list AreaPOIList; bool OPvPWintergrasp::SetupOutdoorPvP() @@ -342,8 +345,12 @@ void OPvPWintergrasp::HandlePlayerEnterZone(Player * plr, uint32 zone) void OPvPWintergrasp::HandlePlayerLeaveZone(Player * plr, uint32 zone) { - if(!plr->GetSession()->PlayerLogout() && plr->m_Vehicle) // dismiss in change zone case - plr->m_Vehicle->Dismiss(); + if(!plr->GetSession()->PlayerLogout()) + { + if(plr->m_Vehicle) // dismiss in change zone case + plr->m_Vehicle->Dismiss(); + REMOVE_RANK_AURAS(plr); + } plr->RemoveAura(SPELL_TENACITY); OutdoorPvP::HandlePlayerLeaveZone(plr, zone); UpdateTenacityStack(); @@ -495,9 +502,7 @@ void OPvPWintergrasp::StartBattle() { for(PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) { - (*itr)->RemoveAura(SPELL_RECRUIT); - (*itr)->RemoveAura(SPELL_CORPORAL); - (*itr)->RemoveAura(SPELL_LIEUTENANT); + REMOVE_RANK_AURAS(*itr); (*itr)->CastSpell(*itr, SPELL_RECRUIT, true); } } @@ -514,9 +519,7 @@ void OPvPWintergrasp::EndBattle() for(PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) { - (*itr)->RemoveAura(SPELL_RECRUIT); - (*itr)->RemoveAura(SPELL_CORPORAL); - (*itr)->RemoveAura(SPELL_LIEUTENANT); + REMOVE_RANK_AURAS(*itr); } } } diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h new file mode 100644 index 0000000000..8e8aa8bfba --- /dev/null +++ b/src/shared/Database/DBCStructure.h @@ -0,0 +1,904 @@ +/* + * Copyright (C) 2005-2008 MaNGOS + * + * Copyright (C) 2008 Trinity + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DBCSTRUCTURE_H +#define DBCSTRUCTURE_H + +#include "DBCEnums.h" +#include "Platform/Define.h" + +#include +#include +#include + +// Structures using to access raw DBC data and required packing to portability + +// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform +#if defined( __GNUC__ ) +#pragma pack(1) +#else +#pragma pack(push,1) +#endif + +struct AreaTableEntry +{ + uint32 ID; // 0 + uint32 mapid; // 1 + uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area + uint32 exploreFlag; // 3, main index + uint32 flags; // 4, unknown value but 312 for all cities + // 5-9 unused + int32 area_level; // 10 + char* area_name[16]; // 11-26 + // 27, string flags, unused + uint32 team; // 28 +}; + +struct AreaTriggerEntry +{ + uint32 id; // 0 + uint32 mapid; // 1 + float x; // 2 + float y; // 3 + float z; // 4 + float radius; // 5 + float box_x; // 6 extent x edge + float box_y; // 7 extent y edge + float box_z; // 8 extent z edge + float box_orientation; // 9 extent rotation by about z axis +}; + +struct AuctionHouseEntry +{ + uint32 houseId; // 0 index + uint32 faction; // 1 id of faction.dbc for player factions associated with city + uint32 depositPercent; // 2 1/3 from real + uint32 cutPercent; // 3 + //char* name[16]; // 4-19 + // 20 string flag, unused +}; + +struct BankBagSlotPricesEntry +{ + uint32 ID; + uint32 price; +}; + +struct BattlemasterListEntry +{ + uint32 id; // 0 + uint32 mapid[3]; // 1-3 mapid + // 4-8 unused + uint32 type; // 9 (3 - BG, 4 - arena) + uint32 minlvl; // 10 + uint32 maxlvl; // 11 + uint32 maxplayersperteam; // 12 + // 13-14 unused + char* name[16]; // 15-30 + // 31 string flag, unused + // 32 unused +}; + +#define MAX_OUTFIT_ITEMS 12 +// #define MAX_OUTFIT_ITEMS 24 // 12->24 in 3.0.x + +struct CharStartOutfitEntry +{ + //uint32 Id; // 0 + uint32 RaceClassGender; // 1 (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender) + int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-13 + //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 14-25 not required at server side + //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 26-37 not required at server side + //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids) + //uint32 Unknown2; // 39 + //uint32 Unknown3; // 40 +}; + +struct CharTitlesEntry +{ + uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() + //uint32 unk1; // 1 flags? + //char* name[16]; // 2-17, unused + // 18 string flag, unused + //char* name2[16]; // 19-34, unused + // 35 string flag, unused + uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<