From 34f0792f75cbb82f118961a27183d5aedfcc4e0d Mon Sep 17 00:00:00 2001 From: Rat Date: Tue, 22 Nov 2011 16:50:00 +0100 Subject: fixed startup crash while loading instance_encounters --- src/server/game/Instances/InstanceScript.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index f0e21f7f709..f9525a2af1e 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -432,7 +432,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi if ((*itr)->creditType == type && (*itr)->creditEntry == creditEntry) { completedEncounters |= 1 << (*itr)->dbcEntry->encounterIndex; - sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName[0]); + sLog->outDebug(LOG_FILTER_TSCR, "Instance %s (instanceId %u) completed encounter %s", instance->GetMapName(), instance->GetInstanceId(), (*itr)->dbcEntry->encounterName); if (uint32 dungeonId = (*itr)->lastEncounterDungeon) { Map::PlayerList const& players = instance->GetPlayers(); -- cgit v1.2.3 From ac81411db461184a9d20cb43b44eca414df5e81e Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 30 Mar 2012 02:43:17 +0200 Subject: Core/Protocol: - 5 new opcodes - Some spell research and fixed MSG_CHANNEL_START - Fixed SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT for 4.2.2, and removed SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE (which does not exist) --- src/server/game/Instances/InstanceScript.cpp | 21 ++++++++++++--------- src/server/game/Instances/InstanceScript.h | 13 +++++++++++-- src/server/game/Server/Protocol/Opcodes.cpp | 14 +++++++------- src/server/game/Server/Protocol/Opcodes.h | 14 +++++++------- src/server/game/Spells/Spell.cpp | 22 ++++++++++++++++++++-- src/server/game/Spells/Spell.h | 2 +- 6 files changed, 58 insertions(+), 28 deletions(-) (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index d0a96e3b62e..2a0f62d8de2 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -397,22 +397,25 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 switch (type) { - case ENCOUNTER_FRAME_ADD: - case ENCOUNTER_FRAME_REMOVE: - case 2: + case ENCOUNTER_FRAME_ENGAGE: + case ENCOUNTER_FRAME_DISENGAGE: + case ENCOUNTER_FRAME_UPDATE_PRIORITY: + if (!unit) + return; data.append(unit->GetPackGUID()); data << uint8(param1); break; - case 3: - case 4: - case 6: + case ENCOUNTER_FRAME_ADD_TIMER: + case ENCOUNTER_FRAME_ENABLE_OBJECTIVE: + case ENCOUNTER_FRAME_DISABLE_OBJECTIVE: + case ENCOUNTER_FRAME_COMBAT_RES_LIMIT: data << uint8(param1); - data << uint8(param2); break; - case 5: + case ENCOUNTER_FRAME_UPDATE_OBJECTIVE: data << uint8(param1); + data << uint8(param2); break; - case 7: + case ENCOUNTER_FRAME_UNK7: default: break; } diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 69f11c203c1..469948d8e2d 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -42,8 +42,17 @@ typedef std::set MinionSet; enum EncounterFrameType { - ENCOUNTER_FRAME_ADD = 0, - ENCOUNTER_FRAME_REMOVE = 1, + ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT = 0, + ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT = 1, + ENCOUNTER_FRAME_ENGAGE = 2, + ENCOUNTER_FRAME_DISENGAGE = 3, + ENCOUNTER_FRAME_UPDATE_PRIORITY = 4, + ENCOUNTER_FRAME_ADD_TIMER = 5, + ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 6, + ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 7, + ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 8, + ENCOUNTER_FRAME_UNK7 = 9, // Seems to have something to do with sorting the encounter units + ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT = 10, }; enum EncounterState diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 8e53d6230c4..541fd054e89 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -91,7 +91,7 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_AISTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(CMSG_DISABLE_PVP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_ADVANCE_SPAWN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_BEGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_PROOF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_RECODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -235,7 +235,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem ); DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_OK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJ_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameObjectUseOpcode ); //DEFINE_OPCODE_HANDLER(CMSG_DESTROY_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -372,7 +372,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode ); //DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); + DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(MSG_CHANNEL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(CMSG_CANCEL_CHANNELLING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling ); DEFINE_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -384,8 +384,8 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_ATTACKSTOP, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode ); DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -591,7 +591,7 @@ void InitOpcodes() DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_GETTICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode ); //DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_GETTICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(MSG_CORPSE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode ); DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_DELETETICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode ); @@ -1020,7 +1020,7 @@ void InitOpcodes() //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_ENTER_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_EXIT_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); //DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_INSTANCE_COMMAND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(CMSG_BOT_DETECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); DEFINE_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_PLAYER_LOGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 65fa2a5a950..0f6dcb48677 100755 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -558,10 +558,10 @@ enum Opcodes SMSG_ATTACKERSTATEUPDATE = 0x0E6A, SMSG_ATTACKSTART = 0xCA4A, SMSG_ATTACKSTOP = 0xCED7, - SMSG_ATTACKSWING_BADFACING = 0x00, - SMSG_ATTACKSWING_CANT_ATTACK = 0x00, - SMSG_ATTACKSWING_DEADTARGET = 0x00, - SMSG_ATTACKSWING_NOTINRANGE = 0x00, + SMSG_ATTACKSWING_BADFACING = 0x18E2, + SMSG_ATTACKSWING_CANT_ATTACK = 0x00, // 0x1CEA or 0x4CFE + SMSG_ATTACKSWING_DEADTARGET = 0x00, // 0x1CEA or 0x4CFE + SMSG_ATTACKSWING_NOTINRANGE = 0xCC62, SMSG_AUCTION_BIDDER_LIST_RESULT = 0x88E3, SMSG_AUCTION_BIDDER_NOTIFICATION = 0xC85B, SMSG_AUCTION_COMMAND_RESULT = 0xCCCE, @@ -625,7 +625,7 @@ enum Opcodes SMSG_CHAT_WRONG_FACTION = 0x0E66, SMSG_CHECK_FOR_BOTS = 0x00, SMSG_CLEAR_COOLDOWN = 0x986F, - SMSG_CLEAR_TARGET = 0x00, + SMSG_CLEAR_TARGET = 0xDA7A, SMSG_CLIENT_CONTROL_UPDATE = 0x08CB, SMSG_CLIENTCACHE_VERSION = 0x88F2, SMSG_COMBAT_LOG_MULTIPLE = 0x5C56, @@ -671,7 +671,7 @@ enum Opcodes SMSG_EMOTE = 0x0C67, SMSG_ENABLE_BARBER_SHOP = 0x9C7A, SMSG_ENCHANTMENTLOG = 0x48E2, - SMSG_ENVIRONMENTALDAMAGELOG = 0x00, + SMSG_ENVIRONMENTALDAMAGELOG = 0x5A6B, SMSG_EQUIPMENT_SET_LIST = 0x18DF, SMSG_EQUIPMENT_SET_SAVED = 0x00, SMSG_EQUIPMENT_SET_USE_RESULT = 0x00, @@ -1057,7 +1057,7 @@ enum Opcodes SMSG_UPDATE_COMBO_POINTS = 0x9AF6, SMSG_UPDATE_CURRENCY = 0x00, SMSG_UPDATE_CURRENCY_WEEK_LIMIT = 0x00, - SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x00, + SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x8C4A, SMSG_UPDATE_INSTANCE_OWNERSHIP = 0xCA73, SMSG_UPDATE_ITEM_ENCHANTMENTS = 0xCA43, SMSG_UPDATE_LAST_INSTANCE = 0x58FE, diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8d98e4c2777..531a944bada 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3858,7 +3858,7 @@ void Spell::SendSpellStart() data << uint32(0); } - if (castFlags & CAST_FLAG_UNKNOWN_31) + if (castFlags & CAST_FLAG_HEAL_PREDICTION) { data << uint32(0); data << uint8(0); // unkByte @@ -4175,7 +4175,25 @@ void Spell::SendChannelStart(uint32 duration) data.append(m_caster->GetPackGUID()); data << uint32(m_spellInfo->Id); data << uint32(duration); - + data << uint8(0); // immunity (castflag & 0x04000000) + /* + if (immunity) + { + data << uint32(); // CastSchoolImmunities + data << uint32(); // CastImmunities + } + */ + data << uint8(0); // healPrediction (castflag & 0x40000000) + /* + if (healPrediction) + { + data.appendPackGUID(channelTarget); // target packguid + data << uint32(); // spellid + data << uint8(0); // unk3 + if (unk3 == 2) + data.append(); // unk packed guid (unused ?) + } + */ m_caster->SendMessageToSet(&data, true); m_timer = duration; diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index dd377d66feb..ca069046677 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -68,7 +68,7 @@ enum SpellCastFlags CAST_FLAG_UNKNOWN_28 = 0x08000000, CAST_FLAG_UNKNOWN_29 = 0x10000000, CAST_FLAG_UNKNOWN_30 = 0x20000000, - CAST_FLAG_UNKNOWN_31 = 0x40000000, + CAST_FLAG_HEAL_PREDICTION = 0x40000000, CAST_FLAG_UNKNOWN_32 = 0x80000000, }; -- cgit v1.2.3 From fc673fce920fca74652576276dee3df991c117bf Mon Sep 17 00:00:00 2001 From: kaelima Date: Fri, 30 Mar 2012 15:13:54 +0200 Subject: Core/Protocol: Missing changes from ac81411db461184a9d20cb43b44eca414df5e81e --- src/server/game/Instances/InstanceScript.cpp | 4 +++- .../IcecrownCitadel/boss_blood_prince_council.cpp | 18 +++++++++--------- .../IcecrownCitadel/boss_valithria_dreamwalker.cpp | 10 +++++----- 3 files changed, 17 insertions(+), 15 deletions(-) (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 2a0f62d8de2..90a669b8615 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -408,7 +408,7 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 case ENCOUNTER_FRAME_ADD_TIMER: case ENCOUNTER_FRAME_ENABLE_OBJECTIVE: case ENCOUNTER_FRAME_DISABLE_OBJECTIVE: - case ENCOUNTER_FRAME_COMBAT_RES_LIMIT: + case ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT: data << uint8(param1); break; case ENCOUNTER_FRAME_UPDATE_OBJECTIVE: @@ -416,6 +416,8 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 data << uint8(param2); break; case ENCOUNTER_FRAME_UNK7: + case ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT: + case ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT: default: break; } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp index 70b07c61e79..22717279c5a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp @@ -210,19 +210,19 @@ class boss_blood_council_controller : public CreatureScript if (Creature* keleseth = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_KELESETH_GUID))) { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, keleseth); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, keleseth); DoZoneInCombat(keleseth); } if (Creature* taldaram = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_TALDARAM_GUID))) { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, taldaram); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, taldaram); DoZoneInCombat(taldaram); } if (Creature* valanar = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_PRINCE_VALANAR_GUID))) { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, valanar); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, valanar); DoZoneInCombat(valanar); } @@ -412,12 +412,12 @@ class boss_prince_keleseth_icc : public CreatureScript summons.DespawnAll(); Talk(SAY_KELESETH_DEATH); - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } void JustReachedHome() { - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); me->SetHealth(_spawnHealth); _isEmpowered = false; if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) @@ -636,12 +636,12 @@ class boss_prince_taldaram_icc : public CreatureScript summons.DespawnAll(); Talk(EMOTE_TALDARAM_DEATH); - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } void JustReachedHome() { - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); me->SetHealth(_spawnHealth); _isEmpowered = false; if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) @@ -859,12 +859,12 @@ class boss_prince_valanar_icc : public CreatureScript summons.DespawnAll(); Talk(SAY_VALANAR_DEATH); - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); } void JustReachedHome() { - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); me->SetHealth(me->GetMaxHealth()); _isEmpowered = false; if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BLOOD_PRINCES_CONTROL))) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index e0993178890..2298e9fe65f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -232,7 +232,7 @@ class ValithriaDespawner : public BasicEvent { case NPC_VALITHRIA_DREAMWALKER: if (InstanceScript* instance = creature->GetInstanceScript()) - instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, creature); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature); break; case NPC_BLAZING_SKELETON: case NPC_SUPPRESSER: @@ -304,7 +304,7 @@ class boss_valithria_dreamwalker : public CreatureScript me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true); // Glyph of Dispel Magic - not a percent heal by effect, its cast with custom basepoints me->ApplySpellImmune(0, IMMUNITY_ID, 56131, true); - _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); _missedPortals = 0; _under25PercentTalkDone = false; _over75PercentTalkDone = false; @@ -322,7 +322,7 @@ class boss_valithria_dreamwalker : public CreatureScript return; DoCast(me, SPELL_COPY_DAMAGE); - _instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, me); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); _events.ScheduleEvent(EVENT_INTRO_TALK, 15000); _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000)); if (IsHeroic()) @@ -336,7 +336,7 @@ class boss_valithria_dreamwalker : public CreatureScript { _done = true; Talk(SAY_VALITHRIA_SUCCESS); - _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); me->RemoveAurasDueToSpell(SPELL_CORRUPTION_VALITHRIA); DoCast(me, SPELL_ACHIEVEMENT_CHECK); DoCastAOE(SPELL_DREAMWALKERS_RAGE); @@ -371,7 +371,7 @@ class boss_valithria_dreamwalker : public CreatureScript { _justDied = true; Talk(SAY_VALITHRIA_DEATH); - _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER))) trigger->AI()->DoAction(ACTION_DEATH); } -- cgit v1.2.3 From 61dce1a02e0092f4ad57dbe05ec74d6dd89df14a Mon Sep 17 00:00:00 2001 From: Naios Date: Wed, 26 Sep 2012 17:46:00 +0200 Subject: Core/PhaseMgr: Implemented Phase Definitions, Terrainswap and multiphasing * fixes cataclysm aura effect SPELL_AURA_PHASE without phasemasks defined in miscValueA * implements CONDITION_SOURCE_TYPE_PHASE_DEFINITION Thanks to: - Cyberbrest: For the hard research work about multiphasing. - Venugh: He helped me with a lot of strange compile Errors. - Shauren: For the 4.3.4 phaseshift packet. - Booksize: He showed me how terrainswap works Signed-off-by: Naios --- .../2012_09_26_00_world_phase_definitions_434.sql | 66 ++++ src/server/game/Conditions/ConditionMgr.cpp | 48 ++- src/server/game/Conditions/ConditionMgr.h | 6 +- src/server/game/DataStores/DBCStructure.h | 4 +- src/server/game/Entities/Player/Player.cpp | 74 ++-- src/server/game/Entities/Player/Player.h | 9 +- src/server/game/Globals/ObjectMgr.cpp | 97 +++++- src/server/game/Globals/ObjectMgr.h | 11 + src/server/game/Handlers/MiscHandler.cpp | 47 ++- src/server/game/Instances/InstanceScript.cpp | 11 + src/server/game/Instances/InstanceScript.h | 3 + src/server/game/Maps/PhaseMgr.cpp | 371 +++++++++++++++++++++ src/server/game/Maps/PhaseMgr.h | 173 ++++++++++ src/server/game/Miscellaneous/Language.h | 10 +- src/server/game/Server/Protocol/Opcodes.cpp | 2 +- src/server/game/Server/WorldSession.h | 2 +- src/server/game/Spells/Auras/SpellAuraEffects.cpp | 26 +- src/server/game/World/World.cpp | 14 + src/server/game/World/World.h | 2 + src/server/scripts/Commands/cs_debug.cpp | 29 +- src/server/scripts/Commands/cs_gobject.cpp | 4 +- src/server/scripts/Commands/cs_modify.cpp | 17 +- src/server/scripts/Commands/cs_npc.cpp | 4 +- src/server/scripts/Commands/cs_reload.cpp | 10 + src/server/scripts/Commands/cs_wp.cpp | 16 +- 25 files changed, 973 insertions(+), 83 deletions(-) create mode 100644 sql/updates/world/2012_09_26_00_world_phase_definitions_434.sql mode change 100755 => 100644 src/server/game/Entities/Player/Player.h create mode 100644 src/server/game/Maps/PhaseMgr.cpp create mode 100644 src/server/game/Maps/PhaseMgr.h (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/sql/updates/world/2012_09_26_00_world_phase_definitions_434.sql b/sql/updates/world/2012_09_26_00_world_phase_definitions_434.sql new file mode 100644 index 00000000000..b8e97278eb5 --- /dev/null +++ b/sql/updates/world/2012_09_26_00_world_phase_definitions_434.sql @@ -0,0 +1,66 @@ +DROP TABLE IF EXISTS `phase_definitions`; +CREATE TABLE `phase_definitions` ( + `zoneId` mediumint(7) unsigned NOT NULL DEFAULT '0', + `entry` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `phasemask` bigint(20) unsigned NOT NULL DEFAULT '0', + `phaseId` tinyint(3) unsigned NOT NULL DEFAULT '0', + `terrainswapmap` smallint(5) unsigned NOT NULL DEFAULT '0', + `flags` tinyint(3) unsigned DEFAULT '0', + `comment` text, + PRIMARY KEY (`zoneId`, `entry`) +) +AUTO_INCREMENT=1 +ENGINE=MyISAM +COLLATE='utf8_general_ci'; + +INSERT INTO `phase_definitions` (`zoneId`, `entry`, `phasemask`, `phaseId`, `terrainswapmap`, `flags`, `comment`) VALUES +(1519, 1, 129, 0, 0, 0, 'Stormwind: [A] Heros Call: Vashj''ir'), +(1519, 2, 257, 0, 0, 0, 'Stormwind: [A] Heros Call: Hyjal'), +(1519, 3, 513, 0, 0, 0, 'Stormwind: [A] Heros Call: Deepholm'), +(1519, 4, 1025, 0, 0, 0, 'Stormwind: [A] Heros Call: Uldum'), +(1519, 5, 2049, 0, 0, 0, 'Stormwind: [A] Heros Call: Twilight Highlands'), +(1637, 1, 129, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Vashj''ir'), +(1637, 2, 257, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Hyjal'), +(1637, 3, 513, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Deepholm'), +(1637, 4, 1025, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Uldum'), +(1637, 5, 2049, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Twilight Highlands'), +(616 , 1, 0 , 165, 719, 0, 'Mount Hyjal: Default Terrainswap'); + +DROP TABLE IF EXISTS `spell_phase`; +CREATE TABLE `spell_phase` ( + `id` mediumint(7) unsigned NOT NULL DEFAULT '0', + `phasemask` bigint(20) unsigned NOT NULL DEFAULT '1', + `terrainswapmap` smallint(5) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) +AUTO_INCREMENT=1 +ENGINE=MyISAM +COLLATE='utf8_general_ci'; + +DELETE FROM `trinity_string` WHERE `entry` BETWEEN 176 AND 182; +INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES +(176, '|cff0099FFPhaseMgr: Report for player: %s, zoneId: %u, level: %u, team: %u, phaseupdateflag: %u|r'), +(177, '|cff663399PhaseMgr: There are no definitions defined for zoneId %u.|r'), +(178, '|cff0066FFPhaseMgr: Success (entry: %u) - added %s %u to the players phase.|r'), +(179, '|cffFF0000PhaseMgr: Condition for phase %u (entry: %u, zoneId: %u) failed.|r'), +(180, '|cffFF0000PhaseMgr: Condition for phase %u (entry: %u, zoneId: %u) has last phasemask flag. Skipped other definitions.|r'), +(181, '|cff6699FFPhaseMgr: The player gets phasemask %u through definitions, %u through phasing auras, and phase %u through custom phase.|r'), +(182, '|cff0099FFPhaseMgr: The player has phasemask %u (real: %u).|r'); + +DELETE FROM `command` WHERE `name` IN('debug phase', 'debug send setphaseshift'); +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('debug phase', 1, 'Syntax: .debug phase\r\n\r\nSends a phase debug report of a player to you.'); + +/* +Conditions (SourceGroup -> ZoneId, SourceEntry -> Entry) + +If you visit the Gm Island as a alliance race you are automatically phased into phase 2. + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=23 AND `SourceGroup`=876 AND `SourceEntry`=1; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(23, 876, 1, 0, 0, 6, 0, 469, 0, 0, 0, 0, '', 'Phase Definitions Example: Phase is only visible for Alliance Members'); + +DELETE FROM `phase_definitions` WHERE `zoneId`=876 AND `entry`=1; +INSERT INTO `phase_definitions` (`zoneId`, `entry`, `phasemask`, `phaseId`, `terrainswapmap`, `flags`, `comment`) VALUES +(876, 1, 2, 0, 0, 0, '[Example] Gm Island'); +*/ diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 917c4cd7f90..406fb7cb753 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -611,7 +611,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL || sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET || sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || - sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT); + sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || + sourceType == CONDITION_SOURCE_TYPE_PHASE_DEFINITION); } bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const @@ -687,6 +688,23 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32 return cond; } +ConditionList ConditionMgr::GetConditionsForPhaseDefinition(uint32 zone, uint32 entry) +{ + ConditionList cond; + PhaseDefinitionConditionContainer::const_iterator itr = PhaseDefinitionsConditionStore.find(zone); + if (itr != PhaseDefinitionsConditionStore.end()) + { + ConditionTypeContainer::const_iterator i = (*itr).second.find(entry); + if (i != (*itr).second.end()) + { + cond = (*i).second; + sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForPhaseDefinition: found conditions for zone %u entry %u spell %u", zone, entry); + } + } + + return cond; +} + void ConditionMgr::LoadConditions(bool isReload) { uint32 oldMSTime = getMSTime(); @@ -898,6 +916,13 @@ void ConditionMgr::LoadConditions(bool isReload) ++count; continue; } + case CONDITION_SOURCE_TYPE_PHASE_DEFINITION: + { + PhaseDefinitionsConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond); + valid = true; + ++count; + continue; + } default: break; } @@ -1389,6 +1414,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) return false; } break; + case CONDITION_SOURCE_TYPE_PHASE_DEFINITION: + if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType)) + { + sLog->outError(LOG_FILTER_SQL, "Condition source type `CONDITION_SOURCE_TYPE_PHASE_DEFINITION` does not support condition type %u, ignoring.", cond->ConditionType); + return false; + } + break; case CONDITION_SOURCE_TYPE_GOSSIP_MENU: case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: @@ -1399,6 +1431,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) return true; } + bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX) @@ -1940,6 +1973,19 @@ void ConditionMgr::Clean() SpellClickEventConditionStore.clear(); + for (PhaseDefinitionConditionContainer::iterator itr = PhaseDefinitionsConditionStore.begin(); itr != PhaseDefinitionsConditionStore.end(); ++itr) + { + for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it) + { + for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i) + delete *i; + it->second.clear(); + } + itr->second.clear(); + } + + PhaseDefinitionsConditionStore.clear(); + // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;) for (std::list::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr) delete *itr; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 57af0562dcd..fe7f6a18af8 100755 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -124,7 +124,8 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20, CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21, CONDITION_SOURCE_TYPE_SMART_EVENT = 22, - CONDITION_SOURCE_TYPE_MAX = 23 //MAX + CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 23, + CONDITION_SOURCE_TYPE_MAX = 24 //MAX }; enum ComparisionType @@ -211,6 +212,7 @@ typedef std::map ConditionTypeContainer; typedef std::map ConditionContainer; typedef std::map CreatureSpellConditionContainer; typedef std::map, ConditionTypeContainer> SmartEventConditionContainer; +typedef std::map PhaseDefinitionConditionContainer; typedef std::map ConditionReferenceContainer;//only used for references @@ -237,6 +239,7 @@ class ConditionMgr ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType); ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId); + ConditionList GetConditionsForPhaseDefinition(uint32 zone, uint32 entry); private: bool isSourceTypeValid(Condition* cond); @@ -254,6 +257,7 @@ class ConditionMgr CreatureSpellConditionContainer VehicleSpellConditionStore; CreatureSpellConditionContainer SpellClickEventConditionStore; SmartEventConditionContainer SmartEventConditionStore; + PhaseDefinitionConditionContainer PhaseDefinitionsConditionStore; }; template bool CompareValues(ComparisionType type, T val1, T val2) diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 308b9fa1a60..a1a0931dc5a 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1408,8 +1408,8 @@ struct LockEntry struct PhaseEntry { uint32 ID; // 0 - char* Name; // 1 - uint32 phaseShift; // 2 + char* Name; // 1 + uint32 flag; // 2 }; struct MailTemplateEntry diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9a0b21194cd..0582a879d5f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -649,7 +649,7 @@ void KillRewarder::Reward() #ifdef _MSC_VER #pragma warning(disable:4355) #endif -Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this) +Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this), phaseMgr(this) { #ifdef _MSC_VER #pragma warning(default:4355) @@ -2938,18 +2938,6 @@ void Player::SetGameMaster(bool on) } else { - // restore phase - uint32 newPhase = 0; - AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE); - if (!phases.empty()) - for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - newPhase |= (*itr)->GetMiscValue(); - - if (!newPhase) - newPhase = PHASEMASK_NORMAL; - - SetPhaseMask(newPhase, false); - m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; setFactionForRace(getRace()); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); @@ -2970,6 +2958,9 @@ void Player::SetGameMaster(bool on) getHostileRefManager().setOnlineOfflineState(true); m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER); + + phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); + phaseMgr.Update(); } UpdateObjectVisibility(); @@ -3202,6 +3193,11 @@ void Player::GiveLevel(uint8 level) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); + PhaseUpdateData phaseUdateData; + phaseUdateData.AddConditionType(CONDITION_LEVEL); + + phaseMgr.NotifyConditionChanged(phaseUdateData); + // Refer-A-Friend if (GetSession()->GetRecruiterId()) if (level < sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) @@ -7628,6 +7624,8 @@ void Player::UpdateArea(uint32 newArea) // so apply them accordingly m_areaUpdateId = newArea; + phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); + AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); UpdatePvPState(true); @@ -7644,10 +7642,14 @@ void Player::UpdateArea(uint32 newArea) } else RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY); + + phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); } void Player::UpdateZone(uint32 newZone, uint32 newArea) { + phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE); + if (m_zoneUpdateId != newZone) { sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); @@ -7757,6 +7759,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) UpdateLocalChannels(newZone); UpdateZoneDependentAuras(newZone); + + phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE); } //If players are too far away from the duel flag... they lose the duel @@ -15010,6 +15014,11 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) CastSpell(this, itr->second->spellId, true); } + PhaseUpdateData phaseUdateData; + phaseUdateData.AddQuestUpdate(quest_id); + + phaseMgr.NotifyConditionChanged(phaseUdateData); + UpdateForQuestWorldObjects(); } @@ -15178,6 +15187,11 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, m_RewardedQuests.insert(quest_id); m_RewardedQuestsSave[quest_id] = true; + PhaseUpdateData phaseUdateData; + phaseUdateData.AddQuestUpdate(quest_id); + + phaseMgr.NotifyConditionChanged(phaseUdateData); + // StoreNewItem, mail reward, etc. save data directly to the database // to prevent exploitable data desynchronisation we save the quest status to the database too // (to prevent rewarding this quest another time while rewards were already given out) @@ -15767,6 +15781,11 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status) m_QuestStatusSave[quest_id] = true; } + PhaseUpdateData phaseUdateData; + phaseUdateData.AddQuestUpdate(quest_id); + + phaseMgr.NotifyConditionChanged(phaseUdateData); + UpdateForQuestWorldObjects(); } @@ -15777,6 +15796,11 @@ void Player::RemoveActiveQuest(uint32 quest_id) { m_QuestStatus.erase(itr); m_QuestStatusSave[quest_id] = false; + + PhaseUpdateData phaseUdateData; + phaseUdateData.AddQuestUpdate(quest_id); + + phaseMgr.NotifyConditionChanged(phaseUdateData); return; } } @@ -15788,6 +15812,11 @@ void Player::RemoveRewardedQuest(uint32 quest_id) { m_RewardedQuests.erase(rewItr); m_RewardedQuestsSave[quest_id] = false; + + PhaseUpdateData phaseUdateData; + phaseUdateData.AddQuestUpdate(quest_id); + + phaseMgr.NotifyConditionChanged(phaseUdateData); } } @@ -24420,25 +24449,6 @@ void Player::_LoadSkills(PreparedQueryResult result) } } -uint32 Player::GetPhaseMaskForSpawn() const -{ - uint32 phase = PHASEMASK_NORMAL; - if (!isGameMaster()) - phase = GetPhaseMask(); - else - { - AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE); - if (!phases.empty()) - phase = phases.front()->GetMiscValue(); - } - - // some aura phases include 1 normal map in addition to phase itself - if (uint32 n_phase = phase & ~PHASEMASK_NORMAL) - return n_phase; - - return PHASEMASK_NORMAL; -} - InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const { ItemTemplate const* pProto = pItem->GetTemplate(); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h old mode 100755 new mode 100644 index 4d91ac42879..f1f58231bef --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -37,6 +37,9 @@ #include "Unit.h" #include "Util.h" // for Tokens typedef #include "WorldSession.h" +#include "PhaseMgr.h" + +// for template #include "SpellMgr.h" #include @@ -54,6 +57,7 @@ class PlayerMenu; class PlayerSocial; class SpellCastTargets; class UpdateMask; +class PhaseMgr; typedef std::deque PlayerMails; @@ -1342,7 +1346,8 @@ class Player : public Unit, public GridObject Pet* GetPet() const; Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime); void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); - uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn + + PhaseMgr& GetPhaseMgr() { return phaseMgr; } void Say(const std::string& text, const uint32 language); void Yell(const std::string& text, const uint32 language); @@ -3083,6 +3088,8 @@ class Player : public Unit, public GridObject uint32 _pendingBindTimer; uint32 _activeCheats; + + PhaseMgr phaseMgr; }; void AddItemsSetItem(Player*player, Item* item); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 3945d3b76fe..dd2afa44a07 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -8652,7 +8652,7 @@ void ObjectMgr::LoadFactionChangeTitles() } uint32 count = 0; - + do { Field* fields = result->Fetch(); @@ -8666,7 +8666,7 @@ void ObjectMgr::LoadFactionChangeTitles() sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", horde); else FactionChange_Titles[alliance] = horde; - + ++count; } while (result->NextRow()); @@ -8674,6 +8674,99 @@ void ObjectMgr::LoadFactionChangeTitles() sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadPhaseDefinitions() +{ + _PhaseDefinitionStore.clear(); + + uint32 oldMSTime = getMSTime(); + + // 0 1 2 3 4 5 + QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags FROM `phase_definitions` ORDER BY `entry` ASC"); + + if (!result) + { + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 phasing definitions. DB table `phase_definitions` is empty."); + return; + } + + uint32 count = 0; + + do + { + Field *fields = result->Fetch(); + + PhaseDefinition PhaseDefinition; + + PhaseDefinition.zoneId = fields[0].GetUInt32(); + PhaseDefinition.entry = fields[1].GetUInt32(); + PhaseDefinition.phasemask = fields[2].GetUInt32(); + PhaseDefinition.phaseId = fields[3].GetUInt32(); + PhaseDefinition.terrainswapmap = fields[4].GetUInt32(); + PhaseDefinition.flags = fields[5].GetUInt32(); + + // Checks + if ((PhaseDefinition.flags & PHASE_FLAG_OVERWRITE_EXISTING) && (PhaseDefinition.flags & PHASE_FLAG_NEGATE_PHASE)) + { + sLog->outError(LOG_FILTER_SQL, "Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", PhaseDefinition.zoneId, PhaseDefinition.entry); + PhaseDefinition.flags &= ~PHASE_FLAG_NEGATE_PHASE; + } + + _PhaseDefinitionStore[PhaseDefinition.zoneId].push_back(PhaseDefinition); + + ++count; + } + while (result->NextRow()); + + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); +} + +void ObjectMgr::LoadSpellPhaseInfo() +{ + _SpellPhaseStore.clear(); + + uint32 oldMSTime = getMSTime(); + + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`"); + + if (!result) + { + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty."); + return; + } + + uint32 count = 0; + do + { + Field *fields = result->Fetch(); + + SpellPhaseInfo spellPhaseInfo; + spellPhaseInfo.spellId = fields[0].GetUInt32(); + + SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellPhaseInfo.spellId); + if (!spell) + { + sLog->outError(LOG_FILTER_SQL, "Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo.spellId); + continue; + } + + if (!spell->HasAura(SPELL_AURA_PHASE)) + { + sLog->outError(LOG_FILTER_SQL, "Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE, useless value.", spellPhaseInfo.spellId); + continue; + } + + spellPhaseInfo.phasemask = fields[1].GetUInt32(); + spellPhaseInfo.terrainswapmap = fields[2].GetUInt32(); + + _SpellPhaseStore[spellPhaseInfo.spellId] = spellPhaseInfo; + + ++count; + } + while (result->NextRow()); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell dbc infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); +} + GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) { GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 61094d60c55..496d5ae224f 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -42,8 +42,10 @@ #include #include "ConditionMgr.h" #include +#include "PhaseMgr.h" class Item; +class PhaseMgr; // 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__) @@ -906,6 +908,12 @@ class ObjectMgr void LoadTrainerSpell(); void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel); + void LoadPhaseDefinitions(); + void LoadSpellPhaseInfo(); + + PhaseDefinitionStore const* GetPhaseDefinitionStore() { return &_PhaseDefinitionStore; } + SpellPhaseStore const* GetSpellPhaseStore() { return &_SpellPhaseStore; } + std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint8 level); uint32 GetXPForLevel(uint8 level) const; @@ -1222,6 +1230,9 @@ class ObjectMgr PageTextContainer _pageTextStore; InstanceTemplateContainer _instanceTemplateStore; + PhaseDefinitionStore _PhaseDefinitionStore; + SpellPhaseStore _SpellPhaseStore; + private: void LoadScripts(ScriptsType type); void CheckScripts(ScriptsType type, std::set& ids); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2acc8ffcf7b..1947baa43b6 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1753,10 +1753,51 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/) SendAccountDataTimes(GLOBAL_CACHE_MASK); } -void WorldSession::SendSetPhaseShift(uint32 PhaseShift) +void WorldSession::SendSetPhaseShift(std::set const& phaseIds, std::set const& terrainswaps) { - WorldPacket data(SMSG_SET_PHASE_SHIFT, 4); - data << uint32(PhaseShift); + ObjectGuid guid = _player->GetGUID(); + + WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2); + data.WriteBit(guid[2]); + data.WriteBit(guid[3]); + data.WriteBit(guid[1]); + data.WriteBit(guid[6]); + data.WriteBit(guid[4]); + data.WriteBit(guid[5]); + data.WriteBit(guid[0]); + data.WriteBit(guid[7]); + + data.WriteByteSeq(guid[7]); + data.WriteByteSeq(guid[4]); + + data << uint32(0); + //for (uint8 i = 0; i < worldMapAreaCount; ++i) + // data << uint16(0); // WorldMapArea.dbc id (controls map display) + + data.WriteByteSeq(guid[1]); + + data << uint32(0); // flags (not phasemask) + + data.WriteByteSeq(guid[2]); + data.WriteByteSeq(guid[6]); + + data << uint32(0); // Inactive terrain swaps + //for (uint8 i = 0; i < inactiveSwapsCount; ++i) + // data << uint16(0); + + data << uint32(phaseIds.size()) * 2; // Phase.dbc ids + for (std::set::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr) + data << uint16(*itr); + + data.WriteByteSeq(guid[3]); + data.WriteByteSeq(guid[0]); + + data << uint32(terrainswaps.size()) * 2; // Active terrain swaps + for (std::set::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr) + data << uint16(*itr); + + data.WriteByteSeq(guid[5]); + SendPacket(&data); } diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index d967ece9cf2..f14dc3c8b14 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -450,3 +450,14 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi } } } + +void InstanceScript::UpdatePhasing() +{ + PhaseUpdateData phaseUdateData; + phaseUdateData.AddConditionType(CONDITION_INSTANCE_DATA); + + Map::PlayerList const& players = instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (Player* player = itr->getSource()) + player->GetPhaseMgr().NotifyConditionChanged(phaseUdateData); +} diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index ab37c1ab5e9..291ba3be52f 100755 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -217,6 +217,9 @@ class InstanceScript : public ZoneScript virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} + // ReCheck PhaseTemplate related conditions + void UpdatePhasing(); + protected: void SetBossNumber(uint32 number) { bosses.resize(number); } void LoadDoorData(DoorData const* data); diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp new file mode 100644 index 00000000000..63bdff2d094 --- /dev/null +++ b/src/server/game/Maps/PhaseMgr.cpp @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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, see . + */ + +#include "PhaseMgr.h" +#include "Chat.h" + +////////////////////////////////////////////////////////////////// +// Updating + +PhaseMgr::PhaseMgr(Player* _player) : player(_player), phaseData(_player), _UpdateFlags(0) +{ + _PhaseDefinitionStore = sObjectMgr->GetPhaseDefinitionStore(); + _SpellPhaseStore = sObjectMgr->GetSpellPhaseStore(); +} + +void PhaseMgr::Update() +{ + if (IsUpdateInProgress()) + return; + + if (_UpdateFlags & PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED) + phaseData.SendPhaseshiftToPlayer(); + + if (_UpdateFlags & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED) + phaseData.SendPhaseMaskToPlayer(); + + _UpdateFlags = 0; +} + +void PhaseMgr::RemoveUpdateFlag(PhaseUpdateFlag updateFlag) +{ + _UpdateFlags &= ~updateFlag; + + if (updateFlag == PHASE_UPDATE_FLAG_ZONE_UPDATE) + { + // Update zone changes + if (phaseData.HasActiveDefinitions()) + { + phaseData.ResetDefinitions(); + _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); + } + + if (_PhaseDefinitionStore->find(player->GetZoneId()) != _PhaseDefinitionStore->end()) + Recalculate(); + } + + Update(); +} + +///////////////////////////////////////////////////////////////// +// Notifier + +void PhaseMgr::NotifyConditionChanged(PhaseUpdateData const& updateData) +{ + if (NeedsPhaseUpdateWithData(updateData)) + { + Recalculate(); + Update(); + } +} + +////////////////////////////////////////////////////////////////// +// Phasing Definitions + +void PhaseMgr::Recalculate() +{ + if (phaseData.HasActiveDefinitions()) + { + phaseData.ResetDefinitions(); + _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); + } + + PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); + if (itr != _PhaseDefinitionStore->end()) + for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) + if (CheckDefinition(&(*phase))) + { + phaseData.AddPhaseDefinition(&(*phase)); + + if (phase->phasemask) + _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; + + if (phase->phaseId || phase->terrainswapmap) + _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; + + if (phase->IsLastDefinition()) + break; + } +} + +inline bool PhaseMgr::CheckDefinition(PhaseDefinition const* phaseDefinition) +{ + return sConditionMgr->IsObjectMeetToConditions(player, sConditionMgr->GetConditionsForPhaseDefinition(phaseDefinition->zoneId, phaseDefinition->entry)); +} + +bool PhaseMgr::NeedsPhaseUpdateWithData(PhaseUpdateData const updateData) const +{ + PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); + if (itr != _PhaseDefinitionStore->end()) + { + for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) + { + ConditionList conditionList = sConditionMgr->GetConditionsForPhaseDefinition(phase->zoneId, phase->entry); + for (ConditionList::const_iterator condition = conditionList.begin(); condition != conditionList.end(); ++condition) + if (updateData.IsConditionRelated(*condition)) + return true; + } + } + return false; +} + +////////////////////////////////////////////////////////////////// +// Auras + +void PhaseMgr::RegisterPhasingAuraEffect(AuraEffect const* auraEffect) +{ + PhaseInfo phaseInfo; + + if (auraEffect->GetMiscValue()) + { + _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; + phaseInfo.phasemask = auraEffect->GetMiscValue(); + } + else + { + SpellPhaseStore::const_iterator itr = _SpellPhaseStore->find(auraEffect->GetId()); + if (itr != _SpellPhaseStore->end()) + { + if (itr->second.phasemask) + { + _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; + phaseInfo.phasemask = itr->second.phasemask; + } + + if (itr->second.terrainswapmap) + phaseInfo.terrainswapmap = itr->second.terrainswapmap; + } + } + + phaseInfo.phaseId = auraEffect->GetMiscValueB(); + + if (phaseInfo.NeedsClientSideUpdate()) + _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; + + phaseData.AddAuraInfo(auraEffect->GetId(), phaseInfo); + + Update(); +} + +void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect) +{ + _UpdateFlags |= phaseData.RemoveAuraInfo(auraEffect->GetId()); + + Update(); +} + +////////////////////////////////////////////////////////////////// +// Commands + +void PhaseMgr::SendDebugReportToPlayer(Player* const debugger) +{ + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags); + + PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); + if (itr == _PhaseDefinitionStore->end()) + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId()); + else + { + for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) + { + if (CheckDefinition(&(*phase))) + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask); + else + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId); + + if (phase->IsLastDefinition()) + { + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId); + break; + } + } + } + + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask); + + ChatHandler(debugger).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask()); +} + +void PhaseMgr::SetCustomPhase(uint32 const phaseMask) +{ + phaseData._CustomPhasemask = phaseMask; + + _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; + + Update(); +} + +////////////////////////////////////////////////////////////////// +// Phase Data + +uint32 PhaseData::GetCurrentPhasemask() const +{ + if (player->isGameMaster()) + return PHASEMASK_ANYWHERE; + + if (_CustomPhasemask) + return _CustomPhasemask; + + return GetPhaseMaskForSpawn(); +} + +inline uint32 PhaseData::GetPhaseMaskForSpawn() const +{ + uint32 const phase = (_PhasemaskThroughDefinitions | _PhasemaskThroughAuras); + return (phase ? phase : PHASEMASK_NORMAL); +} + +void PhaseData::SendPhaseMaskToPlayer() +{ + // Server side update + uint32 const phasemask = GetCurrentPhasemask(); + if (player->GetPhaseMask() == phasemask) + return; + + player->SetPhaseMask(phasemask, false); + + if (player->IsVisible()) + player->UpdateObjectVisibility(); +} + +void PhaseData::SendPhaseshiftToPlayer() +{ + // Client side update + std::set phaseIds; + std::set terrainswaps; + + for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) + { + if (itr->second.terrainswapmap) + terrainswaps.insert(itr->second.terrainswapmap); + + if (itr->second.phaseId) + phaseIds.insert(itr->second.phaseId); + } + + // Phase Definitions + for (std::list::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr) + { + if ((*itr)->phaseId) + phaseIds.insert((*itr)->phaseId); + + if ((*itr)->terrainswapmap) + terrainswaps.insert((*itr)->terrainswapmap); + } + + player->GetSession()->SendSetPhaseShift(phaseIds, terrainswaps); +} + +void PhaseData::AddPhaseDefinition(PhaseDefinition const* phaseDefinition) +{ + if (phaseDefinition->IsOverwritingExistingPhases()) + { + activePhaseDefinitions.clear(); + _PhasemaskThroughDefinitions = phaseDefinition->phasemask; + } + else + { + if (phaseDefinition->IsNegatingPhasemask()) + _PhasemaskThroughDefinitions &= ~phaseDefinition->phasemask; + else + _PhasemaskThroughDefinitions |= phaseDefinition->phasemask; + } + + activePhaseDefinitions.push_back(phaseDefinition); +} + +void PhaseData::AddAuraInfo(uint32 const spellId, PhaseInfo phaseInfo) +{ + if (phaseInfo.phasemask) + _PhasemaskThroughAuras |= phaseInfo.phasemask; + + spellPhaseInfo[spellId] = phaseInfo; +} + +uint32 PhaseData::RemoveAuraInfo(uint32 const spellId) +{ + PhaseInfoContainer::const_iterator rAura = spellPhaseInfo.find(spellId); + if (rAura != spellPhaseInfo.end()) + { + uint32 updateflag = 0; + + if (rAura->second.NeedsClientSideUpdate()) + updateflag |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; + + if (rAura->second.NeedsServerSideUpdate()) + { + _PhasemaskThroughAuras = 0; + + updateflag |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; + + spellPhaseInfo.erase(rAura); + + for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) + _PhasemaskThroughAuras |= itr->second.phasemask; + } + + return updateflag; + } + else + return 0; +} + +////////////////////////////////////////////////////////////////// +// Phase Update Data + +void PhaseUpdateData::AddQuestUpdate(uint32 const questId) +{ + AddConditionType(CONDITION_QUESTREWARDED); + AddConditionType(CONDITION_QUESTTAKEN); + AddConditionType(CONDITION_QUEST_COMPLETE); + AddConditionType(CONDITION_QUEST_NONE); + + _questId = questId; +} + +bool PhaseUpdateData::IsConditionRelated(Condition const* condition) const +{ + switch (condition->ConditionType) + { + case CONDITION_QUESTREWARDED: + case CONDITION_QUESTTAKEN: + case CONDITION_QUEST_COMPLETE: + case CONDITION_QUEST_NONE: + return condition->ConditionValue1 == _questId && ((1 << condition->ConditionType) & _conditionTypeFlags); + default: + return (1 << condition->ConditionType) & _conditionTypeFlags; + } +} + +bool PhaseMgr::IsConditionTypeSupported(ConditionTypes const conditionType) +{ + switch (conditionType) + { + case CONDITION_QUESTREWARDED: + case CONDITION_QUESTTAKEN: + case CONDITION_QUEST_COMPLETE: + case CONDITION_QUEST_NONE: + case CONDITION_TEAM: + case CONDITION_CLASS: + case CONDITION_RACE: + case CONDITION_INSTANCE_DATA: + case CONDITION_LEVEL: + return true; + default: + return false; + } +} diff --git a/src/server/game/Maps/PhaseMgr.h b/src/server/game/Maps/PhaseMgr.h new file mode 100644 index 00000000000..accb0cd3ea8 --- /dev/null +++ b/src/server/game/Maps/PhaseMgr.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2008-2012 TrinityCore + * + * 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, see . + */ + +#ifndef TRINITY_PHASEMGR_H +#define TRINITY_PHASEMGR_H + +#include "SharedDefines.h" +#include "SpellAuras.h" +#include "SpellAuraEffects.h" + +class ObjectMgr; +class Player; + +// Phasing (visibility) +enum PhasingFlags +{ + PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases + PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied) + PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask +}; + +enum PhaseUpdateFlag +{ + PHASE_UPDATE_FLAG_ZONE_UPDATE = 0x01, + PHASE_UPDATE_FLAG_AREA_UPDATE = 0x02, + + // Internal flags + PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED = 0x08, + PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED = 0x10, +}; + +struct PhaseDefinition +{ + uint32 zoneId; + uint32 entry; + uint32 phasemask; + uint32 phaseId; + uint32 terrainswapmap; + uint8 flags; + + bool IsOverwritingExistingPhases() const { return flags & PHASE_FLAG_OVERWRITE_EXISTING; } + bool IsLastDefinition() const { return flags & PHASE_FLAG_NO_MORE_PHASES; } + bool IsNegatingPhasemask() const { return flags & PHASE_FLAG_NEGATE_PHASE; } +}; + +typedef std::list PhaseDefinitionContainer; +typedef UNORDERED_MAP PhaseDefinitionStore; + +struct SpellPhaseInfo +{ + uint32 spellId; + uint32 phasemask; + uint32 terrainswapmap; +}; + +typedef UNORDERED_MAP SpellPhaseStore; + +struct PhaseInfo +{ + PhaseInfo() : phasemask(0), terrainswapmap(0), phaseId(0) {} + + uint32 phasemask; + uint32 terrainswapmap; + uint32 phaseId; + + bool NeedsServerSideUpdate() const { return phasemask; } + bool NeedsClientSideUpdate() const { return terrainswapmap || phaseId; } +}; + +typedef UNORDERED_MAP PhaseInfoContainer; + +struct PhaseData +{ + PhaseData(Player* _player) : player(_player), _PhasemaskThroughDefinitions(0), _PhasemaskThroughAuras(0), _CustomPhasemask(0) {} + + uint32 _PhasemaskThroughDefinitions; + uint32 _PhasemaskThroughAuras; + uint32 _CustomPhasemask; + + uint32 GetCurrentPhasemask() const; + inline uint32 GetPhaseMaskForSpawn() const; + + void ResetDefinitions() { _PhasemaskThroughDefinitions = 0; activePhaseDefinitions.clear(); } + void AddPhaseDefinition(PhaseDefinition const* phaseDefinition); + bool HasActiveDefinitions() const { return !activePhaseDefinitions.empty(); } + + void AddAuraInfo(uint32 const spellId, PhaseInfo phaseInfo); + uint32 RemoveAuraInfo(uint32 const spellId); + + void SendPhaseMaskToPlayer(); + void SendPhaseshiftToPlayer(); + +private: + Player* player; + std::list activePhaseDefinitions; + PhaseInfoContainer spellPhaseInfo; +}; + +struct PhaseUpdateData +{ + void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); } + void AddQuestUpdate(uint32 const questId); + + bool IsConditionRelated(Condition const* condition) const; + +private: + uint32 _conditionTypeFlags; + uint32 _questId; +}; + +class PhaseMgr +{ +public: + PhaseMgr(Player* _player); + ~PhaseMgr() {} + + uint32 GetCurrentPhasemask() { return phaseData.GetCurrentPhasemask(); }; + inline uint32 GetPhaseMaskForSpawn() { return phaseData.GetCurrentPhasemask(); } + + // Phase definitions update handling + void NotifyConditionChanged(PhaseUpdateData const& updateData); + void NotifyStoresReloaded() { Recalculate(); Update(); } + + void Update(); + + // Aura phase effects + void RegisterPhasingAuraEffect(AuraEffect const* auraEffect); + void UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect); + + // Update flags (delayed phasing) + void AddUpdateFlag(PhaseUpdateFlag const updateFlag) { _UpdateFlags |= updateFlag; } + void RemoveUpdateFlag(PhaseUpdateFlag const updateFlag); + + // Needed for modify phase command + void SetCustomPhase(uint32 const phaseMask); + + // Debug + void SendDebugReportToPlayer(Player* const debugger); + + static bool IsConditionTypeSupported(ConditionTypes const conditionType); + +private: + void Recalculate(); + + inline bool CheckDefinition(PhaseDefinition const* phaseDefinition); + + bool NeedsPhaseUpdateWithData(PhaseUpdateData const updateData) const; + + inline bool IsUpdateInProgress() const { return (_UpdateFlags & PHASE_UPDATE_FLAG_ZONE_UPDATE) || (_UpdateFlags & PHASE_UPDATE_FLAG_AREA_UPDATE); } + + PhaseDefinitionStore const* _PhaseDefinitionStore; + SpellPhaseStore const* _SpellPhaseStore; + + Player* player; + PhaseData phaseData; + uint8 _UpdateFlags; +}; + +#endif diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 5893bbd6564..c55c57481f4 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -174,7 +174,15 @@ enum TrinityStrings LANG_YOU_CHANGE_RUNIC_POWER = 173, LANG_YOURS_RUNIC_POWER_CHANGED = 174, LANG_LIQUID_STATUS = 175, - // Room for more level 1 176-199 not used + + LANG_PHASING_REPORT_STATUS = 176, + LANG_PHASING_NO_DEFINITIONS = 177, // Phasing + LANG_PHASING_SUCCESS = 178, + LANG_PHASING_FAILED = 179, + LANG_PHASING_LAST_PHASE = 180, + LANG_PHASING_LIST = 181, + LANG_PHASING_PHASEMASK = 182, + // Room for more level 1 183-199 not used // level 2 chat LANG_NO_SELECTION = 200, diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 5b6af4b2de8..694b2cf2d7f 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1157,7 +1157,7 @@ void OpcodeTable::Initialize() DEFINE_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); DEFINE_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index e6c13557076..5c61385f537 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -253,7 +253,7 @@ class WorldSession void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName); void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val = 0); void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3); - void SendSetPhaseShift(uint32 phaseShift); + void SendSetPhaseShift(std::set const& phaseIds, std::set const& terrainswaps); void SendQueryTimeResponse(); void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 28ddaf05afc..d70c68b9be2 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1808,27 +1808,21 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app Unit* target = aurApp->GetTarget(); - // no-phase is also phase state so same code for apply and remove - uint32 newPhase = 0; - Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE); - if (!phases.empty()) - for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - newPhase |= (*itr)->GetMiscValue(); - if (Player* player = target->ToPlayer()) { - if (!newPhase) - newPhase = PHASEMASK_NORMAL; - - // GM-mode have mask 0xFFFFFFFF - if (player->isGameMaster()) - newPhase = 0xFFFFFFFF; - - player->SetPhaseMask(newPhase, false); - player->GetSession()->SendSetPhaseShift(newPhase); + if (apply) + player->GetPhaseMgr().RegisterPhasingAuraEffect(this); + else + player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this); } else { + uint32 newPhase = 0; + Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE); + if (!phases.empty()) + for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) + newPhase |= (*itr)->GetMiscValue(); + if (!newPhase) { newPhase = PHASEMASK_NORMAL; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 94961b7b930..371668e73d9 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1368,6 +1368,9 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Spell Group Stack Rules..."); sSpellMgr->LoadSpellGroupStackRules(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Spell Phase Dbc Info..."); + sObjectMgr->LoadSpellPhaseInfo(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading NPC Texts..."); sObjectMgr->LoadGossipText(); @@ -1616,6 +1619,9 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions LoadWorldStates(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Phase definitions..."); + sObjectMgr->LoadPhaseDefinitions(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Conditions..."); sConditionMgr->LoadConditions(); @@ -3022,3 +3028,11 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const else return NULL; } + +void World::UpdatePhaseDefinitions() +{ + SessionMap::const_iterator itr; + for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) + if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld()) + itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded(); +} diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 33ec159ec81..e1465f4897d 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -784,6 +784,8 @@ class World uint32 GetCleaningFlags() const { return m_CleaningFlags; } void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; } void ResetEventSeasonalQuests(uint16 event_id); + + void UpdatePhaseDefinitions(); protected: void _UpdateGameTime(); // callback for UpdateRealmCharacters diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 67b4d780942..363258648f6 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -90,6 +90,7 @@ public: { "areatriggers", SEC_ADMINISTRATOR, false, &HandleDebugAreaTriggersCommand, "", NULL }, { "los", SEC_MODERATOR, false, &HandleDebugLoSCommand, "", NULL }, { "moveflags", SEC_ADMINISTRATOR, false, &HandleDebugMoveflagsCommand, "", NULL }, + { "phase", SEC_MODERATOR, false, &HandleDebugPhaseCommand, "", NULL }, { NULL, SEC_PLAYER, false, NULL, "", NULL } }; static ChatCommand commandTable[] = @@ -948,8 +949,21 @@ public: if (!*args) return false; - uint32 PhaseShift = atoi(args); - handler->GetSession()->SendSetPhaseShift(PhaseShift); + char* t = strtok((char*)args, " "); + char* p = strtok(NULL, " "); + + if (!t) + return false; + + std::set terrainswap; + std::set phaseId; + + terrainswap.insert((uint32)atoi(t)); + + if (p) + phaseId.insert((uint32)atoi(p)); + + handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap); return true; } @@ -1330,6 +1344,17 @@ public: handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); return true; } + + static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* args) + { + Unit* unit = handler->getSelectedUnit(); + Player* player = handler->GetSession()->GetPlayer(); + if(unit && unit->GetTypeId() == TYPEID_PLAYER) + player = unit->ToPlayer(); + + player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer()); + return true; + } }; void AddSC_debug_commandscript() diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 6803354d29b..fd24e618ef0 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -149,7 +149,7 @@ public: GameObject* object = new GameObject; uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) + if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; return false; @@ -162,7 +162,7 @@ public: } // fill the gameobject data and save to the db - object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn()); + object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); // this will generate a new guid if the object is in an instance if (!object->LoadGameObjectFromDB(guidLow, map)) diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index c370c70a94a..932a0cbc634 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1277,14 +1277,15 @@ public: uint32 phasemask = (uint32)atoi((char*)args); Unit* target = handler->getSelectedUnit(); - if (!target) - target = handler->GetSession()->GetPlayer(); - - // check online security - else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0)) - return false; - - target->SetPhaseMask(phasemask, true); + if (target) + { + if (target->GetTypeId() == TYPEID_PLAYER) + target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); + else + target->SetPhaseMask(phasemask, true); + } + else + handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); return true; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index e43760191df..30713728cf6 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -151,13 +151,13 @@ public: } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o)) { delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); uint32 db_guid = creature->GetDBTableGUIDLow(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index ce0141290ff..14481884ec8 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -115,6 +115,7 @@ public: { "npc_trainer", SEC_ADMINISTRATOR, true, &HandleReloadNpcTrainerCommand, "", NULL }, { "npc_vendor", SEC_ADMINISTRATOR, true, &HandleReloadNpcVendorCommand, "", NULL }, { "page_text", SEC_ADMINISTRATOR, true, &HandleReloadPageTextsCommand, "", NULL }, + { "phasedefinitions", SEC_ADMINISTRATOR, true, &HandleReloadPhaseDefinitionsCommand, "", NULL }, { "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesPickpocketingCommand, "", NULL}, { "points_of_interest", SEC_ADMINISTRATOR, true, &HandleReloadPointsOfInterestCommand, "", NULL }, { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL }, @@ -1250,6 +1251,15 @@ public: handler->SendGlobalGMSysMessage("Vehicle template accessories reloaded."); return true; } + + static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/) + { + sLog->outInfo(LOG_FILTER_GENERAL, "Reloading phase_definitions table..."); + sObjectMgr->LoadPhaseDefinitions(); + sWorld->UpdatePhaseDefinitions(); + handler->SendGlobalGMSysMessage("Phase Definitions reloaded."); + return true; + } }; void AddSC_reload_commandscript() diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index e3cd185e4a3..05226fb55aa 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -688,7 +688,7 @@ public: } // re-create Creature* wpCreature2 = new Creature; - if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -696,7 +696,7 @@ public: return false; } - wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); //TODO: Should we first use "Create" then use "LoadFromDB"? if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) @@ -912,7 +912,7 @@ public: float o = chr->GetOrientation(); Creature* wpCreature = new Creature; - if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) + if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; @@ -928,7 +928,7 @@ public: WorldDatabase.Execute(stmt); - wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { @@ -976,14 +976,14 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature; - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); @@ -1025,14 +1025,14 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature; - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); -- cgit v1.2.3 From 16d9d1e56db68c40eec023d55e7c61874cdb7bc7 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 12 Nov 2012 14:25:51 +0100 Subject: Core/Achievements: multiple changes - Fix crash when updating criteria with no reference player - Update progress counter to uint64 - Remove hack introduced for achievement 318 (conditions are already checked in additionalConditions) - Add extra parameter miscValue3 (needed for type "LOOT_TYPE" with additionalConditions "ITEM_SUBCLASS") - Correct definition for Additional conditions: 11 (HAS_AURA_TYPE), 17 (SOURCE_AREA_OR_ZONE), 18 (TARGET_AREA_OR_ZONE), 41 (TARGET_ZONE) --- src/server/game/Achievements/AchievementMgr.cpp | 128 ++++++++++++++---------- src/server/game/Achievements/AchievementMgr.h | 42 ++++---- src/server/game/Battlegrounds/Battleground.cpp | 4 +- src/server/game/DataStores/DBCEnums.h | 12 +-- src/server/game/Entities/Player/Player.cpp | 32 +++--- src/server/game/Entities/Player/Player.h | 8 +- src/server/game/Entities/Unit/Unit.cpp | 8 +- src/server/game/Guilds/Guild.cpp | 6 +- src/server/game/Guilds/Guild.h | 2 +- src/server/game/Handlers/ChatHandler.cpp | 2 +- src/server/game/Handlers/LootHandler.cpp | 2 +- src/server/game/Instances/InstanceScript.cpp | 2 +- src/server/game/Spells/Spell.cpp | 4 +- 13 files changed, 143 insertions(+), 109 deletions(-) (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index d6b6c928ebb..e5ab02c897e 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -316,7 +316,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return false; return target->getGender() == gender.gender; case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT: - return sScriptMgr->OnCriteriaCheck(ScriptId, source, target); + return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast(source), const_cast(target)); case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT: return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount; case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM: @@ -452,9 +452,9 @@ void AchievementMgr::RemoveCriteriaProgress(const AchievementCriteriaEntr } template -void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2, bool evenIfCriteriaComplete) +void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete) { - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "ResetAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "ResetAchievementCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2); // disable for gamemasters with GM-mode enabled if (GetOwner()->isGameMaster()) @@ -485,7 +485,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, } template<> -void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint32 /*miscValue1*/, uint32 /*miscValue2*/, bool /*evenIfCriteriaComplete*/) +void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint64 /*miscValue1*/, uint64 /*miscValue2*/, bool /*evenIfCriteriaComplete*/) { // Not needed } @@ -728,7 +728,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, P { Field* fields = criteriaResult->Fetch(); uint32 id = fields[0].GetUInt16(); - uint32 counter = fields[1].GetUInt32(); + uint64 counter = fields[1].GetUInt64(); time_t date = time_t(fields[2].GetUInt32()); AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id); @@ -916,12 +916,13 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievemen // if player is in world he can tell his friends about new achievement else if (GetOwner()->IsInWorld()) { + Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); + CellCoord p = Trinity::ComputeCellCoord(GetOwner()->GetPositionX(), GetOwner()->GetPositionY()); Cell cell(p); cell.SetNoCreate(); - Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID); Trinity::LocalizedPacketDo say_do(say_builder); Trinity::PlayerDistWorker > say_worker(GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do); TypeContainerVisitor >, WorldTypeMapContainer > message(say_worker); @@ -1052,7 +1053,7 @@ void AchievementMgr::CheckAllAchievementCriteria(Player* referencePlayer) { // suppress sending packets for (uint32 i=0; i bool IsGuild() { return true; } * this function will be called whenever the user might have done a criteria relevant action */ template -void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit const* unit /*= NULL*/, Player* referencePlayer /*= NULL*/) +void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit const* unit /*= NULL*/, Player* referencePlayer /*= NULL*/) { - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2); + if (type >= ACHIEVEMENT_CRITERIA_TYPE_TOTAL) + { + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria: Wrong criteria type %u", type); + return; + } + + if (!referencePlayer) + { + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria: Player is NULL! Cant update criteria"); + return; + } // disable for gamemasters with GM-mode enabled if (referencePlayer->isGameMaster()) + { + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria: [Player %s GM mode on] %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD + , referencePlayer->GetName().c_str(), GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3); return; + } + + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "UpdateAchievementCriteria: %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD + , GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3); // Lua_GetGuildLevelEnabled() is checked in achievement UI to display guild tab if (IsGuild() && !sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED)) @@ -1098,7 +1116,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, continue; } - if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, unit, referencePlayer)) + if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, miscValue3, unit, referencePlayer)) continue; // requirements not found in the dbc @@ -1118,7 +1136,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED: case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN: case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS: - case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_DEATH: @@ -1161,6 +1178,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED: case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED: + case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS: case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: @@ -1616,7 +1634,7 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) AchievementCriteriaEntryList const* cList = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementForTestId); if (!cList) return false; - uint32 count = 0; + uint64 count = 0; // For SUMM achievements, we have to count the progress of each criteria of the achievement. // Oddly, the target count is NOT contained in the achievement, but in each individual criteria @@ -1677,14 +1695,14 @@ CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntr } template -void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype) +void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint64 changeValue, Player* referencePlayer, ProgressType ptype) { // Don't allow to cheat - doing timed achievements without timer active TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID); if (entry->timeLimit && timedIter == m_timedAchievements.end()) return; - sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "SetCriteriaProgress(%u, %u) for (%s GUID: %u)", + sLog->outDebug(LOG_FILTER_ACHIEVEMENTSYS, "SetCriteriaProgress(%u, " UI64FMTD ") for (%s GUID: %u)", entry->ID, changeValue, GetLogNameForGuid(GetOwner()->GetGUID()), GUID_LOPART(GetOwner()->GetGUID())); CriteriaProgress* progress = GetCriteriaProgress(entry); @@ -1700,7 +1718,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entr } else { - uint32 newValue = 0; + uint64 newValue = 0; switch (ptype) { case PROGRESS_SET: @@ -1709,7 +1727,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entr case PROGRESS_ACCUMULATE: { // avoid overflow - uint32 max_value = std::numeric_limits::max(); + uint64 max_value = std::numeric_limits::max(); newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value; break; } @@ -1852,8 +1870,8 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achiev _achievementPoints += achievement->points; - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, NULL, referencePlayer); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, 0, NULL, referencePlayer); // reward items and titles if any AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement); @@ -1940,8 +1958,8 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achieve _achievementPoints += achievement->points; - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, NULL, referencePlayer); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, 0, NULL, referencePlayer); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, 0, NULL, referencePlayer); } struct VisibleAchievementPred @@ -2225,7 +2243,7 @@ bool AchievementMgr::HasAchieved(uint32 achievementId) const } template -bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) +bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) { if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL)) { @@ -2256,7 +2274,7 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criter return false; } - if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, unit, referencePlayer)) + if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, unit, referencePlayer)) { sLog->outTrace(LOG_FILTER_ACHIEVEMENTSYS, "CanUpdateCriteria: %s (Id: %u Type %s) Requirements not satisfied", criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type)); @@ -2307,7 +2325,7 @@ bool AchievementMgr::ConditionsSatisfied(AchievementCriteriaEntry const *crit } template -bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const *achievementCriteria, uint64 miscValue1, uint64 miscValue2, Unit const *unit, Player* referencePlayer) const +bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const *achievementCriteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const *unit, Player* referencePlayer) const { switch (AchievementCriteriaTypes(achievementCriteria->type)) { @@ -2468,11 +2486,7 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const *ac return false; break; case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: - if (!miscValue1) - return false; - - // if team check required: must kill by opposition faction - if (achievementCriteria->achievement == 318 && miscValue2 == referencePlayer->GetTeam()) + if (!miscValue1 || !unit || unit->GetTypeId() != TYPEID_PLAYER) return false; break; case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM: @@ -2517,9 +2531,9 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const *ac return false; break; case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: - // miscValue1 = loot_type (note: 0 = LOOT_CORPSE and then it ignored) - // miscValue2 = count of item loot - if (!miscValue1 || !miscValue2 || miscValue1 != achievementCriteria->loot_type.lootType) + // miscValue1 = itemId - miscValue2 = count of item loot + // miscValue3 = loot_type (note: 0 = LOOT_CORPSE and then it ignored) + if (!miscValue1 || !miscValue2 || !miscValue3 || miscValue3 != achievementCriteria->loot_type.lootType) return false; break; case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: @@ -2627,7 +2641,7 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const *ac { if (!miscValue1) return false; - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1); + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1)); if (!proto || proto->Quality < ITEM_QUALITY_EPIC) return false; break; @@ -2690,11 +2704,8 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry return false; break; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY: // 7 - if (!unit) + if (!unit || !referencePlayer->IsHostileTo(unit)) return false; - if (const Player* player = unit->ToPlayer()) - if (player->GetTeam() == referencePlayer->GetTeam()) - return false; break; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA: // 8 if (!referencePlayer->HasAura(reqValue)) @@ -2703,8 +2714,8 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA: // 10 if (!unit || !unit->HasAura(reqValue)) return false; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED: // 11 - if (!unit || !unit->IsMounted()) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA_TYPE: // 11 + if (!unit || !unit->HasAuraType(AuraType(reqValue))) return false; break; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN: // 14 @@ -2723,20 +2734,26 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry return false; break; } - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 20 - if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue) + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE: // 17 + { + uint32 zoneId, areaId; + referencePlayer->GetZoneAndAreaId(zoneId, areaId); + if (zoneId != reqValue && areaId != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: // 32 - if (referencePlayer->GetMapId() != reqValue) + } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE: // 18 + { + if (!unit) return false; - break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE: // 18 - if (referencePlayer->GetZoneId() != reqValue) + uint32 zoneId, areaId; + unit->GetZoneAndAreaId(zoneId, areaId); + if (zoneId != reqValue && areaId != reqValue) return false; break; - case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA: // 17 - if (referencePlayer->GetAreaId() != reqValue) + } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 20 + if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue) return false; break; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE: // 25 @@ -2768,6 +2785,10 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry return false; break; } + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: // 32 + if (referencePlayer->GetMapId() != reqValue) + return false; + break; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: // 38 // miscValue1 is title's bit index if (miscValue1 != reqValue) @@ -2781,6 +2802,9 @@ bool AchievementMgr::AdditionalRequirementsSatisfied(AchievementCriteriaEntry if (!unit || unit->getLevel() != reqValue) return false; break; + case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE: // 41 + if (!unit || unit->GetZoneId() != reqValue) + return false; case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: // 46 if (!unit || unit->GetHealthPct() >= reqValue) return false; @@ -3019,10 +3043,12 @@ char const* AchievementGlobalMgr::GetCriteriaTypeString(AchievementCriteriaTypes return "HONORABLE_KILLS_GUILD"; case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD: return "KILL_CREATURE_TYPE_GUILD"; - default: - return "MISSING_TYPE"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE: + return "GUILD_CHALLENGE_TYPE"; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE: + return "GUILD_CHALLENGE"; } - return ""; + return "MISSING_TYPE"; } template class AchievementMgr; @@ -3177,9 +3203,7 @@ void AchievementGlobalMgr::LoadCompletedAchievements() sLog->outError(LOG_FILTER_ACHIEVEMENTSYS, "Non-existing achievement %u data removed from table `character_achievement`.", achievementId); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEVMENT); - stmt->setUInt16(0, uint16(achievementId)); - CharacterDatabase.Execute(stmt); continue; diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index efb9fcba1b6..aa13dac3649 100755 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -28,11 +28,15 @@ #include "DBCEnums.h" #include "DBCStores.h" -typedef std::list AchievementCriteriaEntryList; -typedef std::list AchievementEntryList; +class Unit; +class Player; +class WorldPacket; -typedef std::map AchievementCriteriaListByAchievement; -typedef std::map AchievementListByReferencedId; +typedef std::vector AchievementCriteriaEntryList; +typedef std::vector AchievementEntryList; + +typedef UNORDERED_MAP AchievementCriteriaListByAchievement; +typedef UNORDERED_MAP AchievementListByReferencedId; struct CriteriaProgress { @@ -66,9 +70,7 @@ enum AchievementCriteriaDataType }; #define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 22 // maximum value in AchievementCriteriaDataType enum -class Player; -class Unit; -class WorldPacket; + struct AchievementCriteriaData { @@ -199,15 +201,15 @@ struct AchievementReward std::string text; }; -typedef std::map AchievementRewards; +typedef UNORDERED_MAP AchievementRewards; struct AchievementRewardLocale { - StringVector subject; - StringVector text; + std::vector subject; + std::vector text; }; -typedef std::map AchievementRewardLocales; +typedef UNORDERED_MAP AchievementRewardLocales; struct CompletedAchievementData { @@ -219,6 +221,13 @@ struct CompletedAchievementData typedef UNORDERED_MAP CriteriaProgressMap; typedef UNORDERED_MAP CompletedAchievementMap; +enum ProgressType +{ + PROGRESS_SET, + PROGRESS_ACCUMULATE, + PROGRESS_HIGHEST +}; + template class AchievementMgr { @@ -230,8 +239,8 @@ class AchievementMgr static void DeleteFromDB(uint32 lowguid); void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(SQLTransaction& trans); - void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit const* unit = NULL, Player* referencePlayer = NULL); + void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit const* unit = NULL, Player* referencePlayer = NULL); void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer); void CheckAllAchievementCriteria(Player* referencePlayer); void SendAllAchievementData(Player* receiver) const; @@ -245,20 +254,19 @@ class AchievementMgr uint32 GetAchievementPoints() const { return _achievementPoints; } private: - enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST }; void SendAchievementEarned(AchievementEntry const* achievement) const; void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const; CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry); - void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, Player* referencePlayer, ProgressType ptype = PROGRESS_SET); + void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint64 changeValue, Player* referencePlayer, ProgressType ptype = PROGRESS_SET); void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry); void CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer); bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement); bool IsCompletedAchievement(AchievementEntry const* entry); - bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer); + bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer); void SendPacket(WorldPacket* data) const; bool ConditionsSatisfied(AchievementCriteriaEntry const *criteria, Player* referencePlayer) const; - bool RequirementsSatisfied(AchievementCriteriaEntry const *criteria, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; + bool RequirementsSatisfied(AchievementCriteriaEntry const *criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const; bool AdditionalRequirementsSatisfied(AchievementCriteriaEntry const* criteria, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const; T* _owner; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 389873f7caf..022ff8fa6ee 100755 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -914,9 +914,9 @@ void Battleground::EndBattleground(uint32 winner) if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam())) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) { - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, NULL, player); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, 0, NULL, player); if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max(winnerArenaTeam->GetRating(), 1), 0, NULL, player); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max(winnerArenaTeam->GetRating(), 1), 0, 0, NULL, player); } } } diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 5217fa0d979..853202df8d0 100755 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -111,15 +111,15 @@ enum AchievementCriteriaAdditionalCondition ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY = 7, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA = 8, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA = 10, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_MOUNTED = 11, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA_TYPE = 11, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN = 14, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS = 15, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK16 = 16, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA = 17, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ZONE = 18, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE = 17, + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE = 18, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 20, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_ARENA_TEAM_SIZE = 24, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ARENA_TYPE = 24, // NYI ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE = 27, @@ -129,12 +129,12 @@ enum AchievementCriteriaAdditionalCondition ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK35 = 35, // related to timed completing-quests achievements + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_COMPLETE_QUEST_NOT_IN_GROUP = 35, // NYI ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE) ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40, - ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, // NYI + ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK55 = 55, ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2356f021d00..9fec81729bb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -598,7 +598,7 @@ void KillRewarder::_RewardGroup() if (member->IsAtGroupRewardDistance(_victim)) { _RewardPlayer(member, isDungeon); - member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim); + member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, 0, _victim); } } } @@ -635,7 +635,7 @@ void KillRewarder::Reward() if (uint32 guildId = victim->GetMap()->GetOwnerGuildId()) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) - guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, victim, _killer); + guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer); } } @@ -7156,7 +7156,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace()); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId()); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, 0, victim); } else { @@ -15910,7 +15910,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid) } StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, guid ? GetMap()->GetCreature(guid) : NULL); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, 0, guid ? GetMap()->GetCreature(guid) : NULL); for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i) { @@ -23212,7 +23212,7 @@ uint32 Player::GetResurrectionSpellId() } // Used in triggers for check "Only to targets that grant experience or honor" req -bool Player::isHonorOrXPTarget(Unit* victim) +bool Player::isHonorOrXPTarget(Unit const *victim) { uint8 v_level = victim->getLevel(); uint8 k_grey = Trinity::XP::GetGrayLevel(getLevel()); @@ -23221,11 +23221,11 @@ bool Player::isHonorOrXPTarget(Unit* victim) if (v_level <= k_grey) return false; - if (victim->GetTypeId() == TYPEID_UNIT) + if (Creature const* const creature = victim->ToCreature()) { - if (victim->ToCreature()->isTotem() || - victim->ToCreature()->isPet() || - victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) + if (creature->isTotem() || + creature->isPet() || + creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL) return false; } return true; @@ -24194,7 +24194,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) SendNewItem(newitem, uint32(item->count), false, false, true); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, item->itemid, item->count, loot->loot_type); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count); } else @@ -24517,22 +24517,24 @@ void Player::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 e m_achievementMgr.RemoveTimedAchievement(type, entry); } -void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/) +void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/) { m_achievementMgr.ResetAchievementCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete); } -void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) +void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit* unit /*= NULL*/) { - m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this); + m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, this); + Guild* guild = sGuildMgr->GetGuildById(GetGuildId()); + if (!guild) + return; // Update only individual achievement criteria here, otherwise we may get multiple updates // from a single boss kill if (sAchievementMgr->IsGroupCriteriaType(type)) return; - if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId())) - guild->UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, this); + guild->UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, this); } void Player::CompletedAchievement(AchievementEntry const* entry) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b1bd61480de..2f044326b96 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2090,7 +2090,7 @@ class Player : public Unit, public GridObject void StoreRaidMapDifficulty() { m_raidMapDifficulty = GetMap()->GetDifficulty(); } bool UpdateSkill(uint32 skill_id, uint32 step); - bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step); + bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step); bool UpdateCraftSkill(uint32 spellid); bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1); @@ -2254,7 +2254,7 @@ class Player : public Unit, public GridObject bool IsAtRecruitAFriendDistance(WorldObject const* pOther) const; void RewardPlayerAndGroupAtKill(Unit* victim, bool isBattleGround); void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource); - bool isHonorOrXPTarget(Unit* victim); + bool isHonorOrXPTarget(Unit const *victim); bool GetsRecruitAFriendBonus(bool forXP); uint8 GetGrantableLevels() { return m_grantableLevels; } @@ -2706,8 +2706,8 @@ class Player : public Unit, public GridObject bool HasAchieved(uint32 achievementId) const; void ResetAchievements(); void CheckAllAchievementCriteria(); - void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); + void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit* unit = NULL); void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); void CompletedAchievement(AchievementEntry const* entry); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index fea9a73386a..7ee40ce9fed 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -672,7 +672,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (Battleground* bg = killer->GetBattleground()) bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage); - killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, victim); + killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, 0, victim); killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage); } @@ -9025,7 +9025,7 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth) // use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria) if (gain) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, 0, victim); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED, addhealth); } @@ -9217,7 +9217,7 @@ void Unit::UnsummonAllTotems() void Unit::SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical) { // we guess size - WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+4+4+1+1)); + WorldPacket data(SMSG_SPELLHEALLOG, 8+8+4+4+4+4+1+1); data.append(victim->GetPackGUID()); data.append(GetPackGUID()); data << uint32(SpellID); @@ -14684,7 +14684,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) // update get killing blow achievements, must be done before setDeathState to be able to require auras on target // and before Spirit of Redemption as it also removes auras if (player) - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, 0, victim); // if talent known but not triggered (check priest class for speedup check) bool spiritOfRedemption = false; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 78cd9fb1da5..1a73974b906 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -3450,7 +3450,7 @@ void Guild::GiveXP(uint32 xp, Player* source) } AddGuildNews(GUILD_NEWS_LEVEL_UP, 0, 0, _level); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, NULL, source); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, 0, NULL, source); } void Guild::SendGuildXP(WorldSession* session /* = NULL */) const @@ -3513,9 +3513,9 @@ bool Guild::HasAchieved(uint32 achievementId) const return m_achievementMgr.HasAchieved(achievementId); } -void Guild::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2, Unit* unit, Player* player) +void Guild::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player) { - m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, unit, player); + m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, player); } void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky) diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index ddb7ab505cc..36d8d56b30c 100755 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -865,7 +865,7 @@ public: void ResetTimes(bool weekly); bool HasAchieved(uint32 achievementId) const; - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1, uint32 miscValue2, Unit* unit, Player* player); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player); protected: uint32 m_id; diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 2a923250ad3..d194d379b5c 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -748,7 +748,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) TypeContainerVisitor >, WorldTypeMapContainer> message(emote_worker); cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)); - GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit); + GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, 0, unit); //Send scripted event call if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI()) diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 5f3e3d58da5..c8d6d749331 100755 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -509,7 +509,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); target->SendNewItem(newitem, uint32(item.count), false, false, true); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); - target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); + target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, item.itemid, item.count, loot->loot_type); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index f14dc3c8b14..af4b33e079c 100755 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -328,7 +328,7 @@ void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* player = i->getSource()) - player->UpdateAchievementCriteria(type, miscValue1, miscValue2, unit); + player->UpdateAchievementCriteria(type, miscValue1, miscValue2, 0, unit); } // Start timed achievement for all players in instance diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 89c698744a3..bb482704bb7 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2569,14 +2569,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA if (Player* player = unit->ToPlayer()) { player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, 0, m_caster); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); } if (Player* player = m_caster->ToPlayer()) { player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id); - player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, 0, unit); } if (m_caster != unit) -- cgit v1.2.3 From c0913f09f4ca6ffd617c00a77e5d5f4d96426e56 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 30 Dec 2012 16:43:30 -0500 Subject: Core/Conditions: Fixed build from previous merge. --- src/server/game/Instances/InstanceScript.cpp | 2 +- src/server/game/Maps/PhaseMgr.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server/game/Instances/InstanceScript.cpp') diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index a183c13d2c7..08515140ee7 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -457,7 +457,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi void InstanceScript::UpdatePhasing() { PhaseUpdateData phaseUdateData; - phaseUdateData.AddConditionType(CONDITION_INSTANCE_DATA); + phaseUdateData.AddConditionType(CONDITION_INSTANCE_INFO); Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp index d43a930c71d..9949ee5bdd4 100644 --- a/src/server/game/Maps/PhaseMgr.cpp +++ b/src/server/game/Maps/PhaseMgr.cpp @@ -365,7 +365,7 @@ bool PhaseMgr::IsConditionTypeSupported(ConditionTypes const conditionType) case CONDITION_TEAM: case CONDITION_CLASS: case CONDITION_RACE: - case CONDITION_INSTANCE_DATA: + case CONDITION_INSTANCE_INFO: case CONDITION_LEVEL: return true; default: -- cgit v1.2.3