diff options
Diffstat (limited to 'src')
30 files changed, 387 insertions, 226 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 1a26e241c5e..01fb936b847 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -46,7 +46,7 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c) // spawn in run mode me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); - mRun = true; + mRun = false; me->GetPosition(&mLastOOCPos); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 15423c7aff2..ce357393515 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -282,6 +282,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) case SMART_TARGET_HOSTILE_RANDOM: case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP: case SMART_TARGET_ACTION_INVOKER: + case SMART_TARGET_INVOKER_PARTY: case SMART_TARGET_POSITION: case SMART_TARGET_NONE: case SMART_TARGET_ACTION_INVOKER_VEHICLE: diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index d64b2a9913d..5e529768c04 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -202,6 +202,9 @@ void BattlegroundAB::StartingEventOpenDoors() } DoorOpen(BG_AB_OBJECT_GATE_A); DoorOpen(BG_AB_OBJECT_GATE_H); + + // Achievement: Let's Get This Done + StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, AB_EVENT_START_BATTLE); } void BattlegroundAB::AddPlayer(Player* player) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 38c8f4a21d4..c86076f0250 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -181,6 +181,8 @@ enum BG_AB_Objectives #define BG_AB_NotABBGWeekendReputationTicks 200 #define BG_AB_ABBGWeekendReputationTicks 150 +#define AB_EVENT_START_BATTLE 9158 // Achievement: Let's Get This Done + // x, y, z, o const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = { {1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 01f62bfcf35..f2e8c2bf0af 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -420,6 +420,9 @@ void BattlegroundAV::StartingEventOpenDoors() DoorOpen(BG_AV_OBJECT_DOOR_H); DoorOpen(BG_AV_OBJECT_DOOR_A); + + // Achievement: The Alterac Blitz + StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, AV_EVENT_START_BATTLE); } void BattlegroundAV::AddPlayer(Player* player) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index e2902f8fd2d..82e231c63fa 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -50,6 +50,8 @@ class Battleground; #define BG_AV_KILL_SURVIVING_CAPTAIN 2 #define BG_AV_REP_SURVIVING_CAPTAIN 125 +#define AV_EVENT_START_BATTLE 9166 // Achievement: The Alterac Blitz + enum BG_AV_Sounds { //TODO: get out if there comes a sound when neutral team captures mine diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 4595a061e1a..1e7f79b8391 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -120,6 +120,9 @@ void BattlegroundEY::StartingEventOpenDoors() uint8 buff = urand(0, 2); SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + buff + i * 3, RESPAWN_IMMEDIATELY); } + + // Achievement: Flurry + StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EY_EVENT_START_BATTLE); } void BattlegroundEY::AddPoints(uint32 Team, uint32 Points) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 5f89e0d7021..baa9ca30cff 100755 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -220,6 +220,8 @@ enum EYBattlegroundObjectTypes #define BG_EY_NotEYWeekendHonorTicks 330 #define BG_EY_EYWeekendHonorTicks 200 +#define EY_EVENT_START_BATTLE 13180 // Achievement: Flurry + enum BG_EY_Score { BG_EY_WARNING_NEAR_VICTORY_SCORE = 1400, diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 0bcd1a7864b..49b5d4cba65 100755 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -63,7 +63,7 @@ bool Condition::Meets(Player* player, Unit* invoker) case CONDITION_REPUTATION_RANK: { if (FactionEntry const* faction = sFactionStore.LookupEntry(mConditionValue1)) - condMeets = uint32(player->GetReputationMgr().GetRank(faction)) == mConditionValue2; + condMeets = (mConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction))); break; } case CONDITION_ACHIEVEMENT: diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 0f146598a6e..ac7343e8f23 100755 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -483,7 +483,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player) void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDungeons, const std::string& comment) { if (!player || !player->GetSession() || selectedDungeons.empty()) - return; + return; Group* grp = player->GetGroup(); uint64 guid = player->GetGUID(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index bed3c0cb1a7..ce80d7a7af3 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -296,15 +296,24 @@ Item* TradeData::GetItem(TradeSlots slot) const return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : NULL; } -bool TradeData::HasItem(uint64 item_guid) const +bool TradeData::HasItem(uint64 itemGuid) const { for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) - if (m_items[i] == item_guid) + if (m_items[i] == itemGuid) return true; return false; } +TradeSlots const TradeData::GetTradeSlotForItem(uint64 itemGuid) +{ + for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (m_items[i] == itemGuid) + return TradeSlots(i); + + return TRADE_SLOT_INVALID; +} + Item* TradeData::GetSpellCastItem() const { return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : NULL; @@ -12805,6 +12814,14 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) return; } + //! If trading + if (TradeData* tradeData = GetTradeData()) + { + //! If current item is in trade window (only possible with packet spoofing - silent return) + if (tradeData->GetTradeSlotForItem(pSrcItem->GetGUID()) != TRADE_SLOT_INVALID) + return; + } + sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "STORAGE: SplitItem bag = %u, slot = %u, item = %u, count = %u", dstbag, dstslot, pSrcItem->GetEntry(), count); Item* pNewItem = pSrcItem->CloneItem(count, this); if (!pNewItem) @@ -12833,7 +12850,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) pSrcItem->SetState(ITEM_CHANGED, this); StoreItem(dest, pNewItem, true); } - else if (IsBankPos (dst)) + else if (IsBankPos(dst)) { // change item amount before check (for unique max count check) pSrcItem->SetCount(pSrcItem->GetCount() - count); @@ -12853,7 +12870,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) pSrcItem->SetState(ITEM_CHANGED, this); BankItem(dest, pNewItem, true); } - else if (IsEquipmentPos (dst)) + else if (IsEquipmentPos(dst)) { // change item amount before check (for unique max count check), provide space for splitted items pSrcItem->SetCount(pSrcItem->GetCount() - count); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7a455590506..fccd380bd29 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -686,7 +686,8 @@ enum TradeSlots { TRADE_SLOT_COUNT = 7, TRADE_SLOT_TRADED_COUNT = 6, - TRADE_SLOT_NONTRADED = 6 + TRADE_SLOT_NONTRADED = 6, + TRADE_SLOT_INVALID = -1, }; enum TransferAbortReason @@ -1001,7 +1002,8 @@ class TradeData TradeData* GetTraderData() const; Item* GetItem(TradeSlots slot) const; - bool HasItem(uint64 item_guid) const; + bool HasItem(uint64 itemGuid) const; + TradeSlots const GetTradeSlotForItem(uint64 itemGuid); void SetItem(TradeSlots slot, Item* item); uint32 GetSpell() const { return m_spell; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 63aa7771063..6bab63acf1b 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2114,12 +2114,12 @@ void Unit::SendMeleeAttackStart(Unit* victim) void Unit::SendMeleeAttackStop(Unit* victim) { - WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size + WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); data.append(GetPackGUID()); data.append(victim ? victim->GetPackGUID() : 0); // can be 0x00... data << uint32(0); // can be 0x1 SendMessageToSet(&data, true); - sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTART"); + sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTOP"); if (victim) sLog->outDetail("%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUIDLow()); @@ -7068,6 +7068,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere return false; basepoints0 = CalculatePctN(int32(damage), triggerAmount); triggered_spell_id = 58879; + // Cast on spirit wolf + CastCustomSpell(this, triggered_spell_id, &basepoints0, NULL, NULL, true, NULL, triggeredByAura); break; } // Shaman T8 Elemental 4P Bonus @@ -15847,6 +15849,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au case CHARM_TYPE_VEHICLE: SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); charmer->ToPlayer()->SetClientControl(this, 1); + charmer->ToPlayer()->SetMover(this); charmer->ToPlayer()->SetViewpoint(this, true); charmer->ToPlayer()->VehicleSpellInitialize(); break; @@ -15855,6 +15858,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); charmer->ToPlayer()->SetClientControl(this, 1); + charmer->ToPlayer()->SetMover(this); charmer->ToPlayer()->SetViewpoint(this, true); charmer->ToPlayer()->PossessSpellInitialize(); break; diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index b3531d585c3..7e4bebaab95 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -359,7 +359,6 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) { if (!_me->SetCharmedBy(unit, CHARM_TYPE_VEHICLE)) ASSERT(false); - unit->ToPlayer()->SetMover(this->GetBase()); } if (_me->IsInWorld()) @@ -411,10 +410,7 @@ void Vehicle::RemovePassenger(Unit* unit) unit->ClearUnitState(UNIT_STAT_ONVEHICLE); if (_me->GetTypeId() == TYPEID_UNIT && unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL) - { _me->RemoveCharmedBy(unit); - unit->ToPlayer()->SetMover(unit->ToPlayer()); - } if (_me->IsInWorld()) { diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 19bc1ab7dea..b31b632e963 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -203,7 +203,9 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, // skip non-existed member if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name)) { - CharacterDatabase.PQuery("DELETE FROM group_member WHERE memberGuid=%u", guidLow); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER); + stmt->setUInt32(0, guidLow); + CharacterDatabase.Execute(stmt); return; } diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index c17f5096748..8975a2d7d7b 100755 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -307,7 +307,7 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed) init.SetVelocity(speed); init.SetAnimation(Movement::ToGround); init.Launch(); - Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); + Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed) @@ -322,7 +322,7 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed) init.SetVelocity(speed); init.SetAnimation(Movement::ToFly); init.Launch(); - Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); + Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ) @@ -365,7 +365,10 @@ void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float spee init.SetParabolic(max_height,0); init.SetVelocity(speedXY); init.Launch(); - Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); + if (i_owner->GetTypeId() == TYPEID_PLAYER) + Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); + else + Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE); } void MotionMaster::MoveFall(uint32 id/*=0*/) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index bded2fd512c..b03e13f91f4 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -211,6 +211,19 @@ void ChaseMovementGenerator<T>::Reset(T &owner) Initialize(owner); } +template<class T> +void ChaseMovementGenerator<T>::MovementInform(T & /*unit*/) +{ +} + +template<> +void ChaseMovementGenerator<Creature>::MovementInform(Creature &unit) +{ + // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle + if (unit.AI()) + unit.AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); +} + //-----------------------------------------------// template<> bool FollowMovementGenerator<Creature>::EnableWalking() const @@ -300,6 +313,7 @@ template void ChaseMovementGenerator<Player>::Finalize(Player &); template void ChaseMovementGenerator<Creature>::Finalize(Creature &); template void ChaseMovementGenerator<Player>::Reset(Player &); template void ChaseMovementGenerator<Creature>::Reset(Creature &); +template void ChaseMovementGenerator<Player>::MovementInform(Player &unit); template void FollowMovementGenerator<Player>::Finalize(Player &); template void FollowMovementGenerator<Creature>::Finalize(Creature &); diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h index 785d12ba6d2..982f7fc875c 100755 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h @@ -76,7 +76,7 @@ class ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T, ChaseMo void Initialize(T &); void Finalize(T &); void Reset(T &); - void MovementInform(T &){} + void MovementInform(T &); static void _clearUnitStateMove(T &u) { u.ClearUnitState(UNIT_STAT_CHASE_MOVE); } static void _addUnitStateMove(T &u) { u.AddUnitState(UNIT_STAT_CHASE_MOVE); } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index ea858eaba84..ce8628af1ca 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -84,6 +84,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature) // Inform script MovementInform(creature); + creature.UpdateWaypointID(i_currentNode); Stop(i_path->at(i_currentNode)->delay); } @@ -94,13 +95,11 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) if (Stopped()) return true; - const WaypointData *node = i_path->at(i_currentNode); - if (m_isArrivalDone) { if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint { - creature.SetHomePosition(node->x, node->y, node->z, creature.GetOrientation()); + creature.SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature.GetOrientation()); creature.GetMotionMaster()->Initialize(); return false; } @@ -108,6 +107,8 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature) i_currentNode = (i_currentNode+1) % i_path->size(); } + const WaypointData *node = i_path->at(i_currentNode); + m_isArrivalDone = false; creature.AddUnitState(UNIT_STAT_ROAMING_MOVE); diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp index aaafb09115d..59eefb9fa77 100755 --- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp @@ -101,14 +101,14 @@ void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auction //this void causes on client to display: "Your auction sold" void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction) { - WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (7*4)); - data << auction->Id; - data << auction->bid; - data << (uint32) 0; //unk - data << (uint32) 0; //unk - data << (uint32) 0; //unk - data << auction->item_template; - data << (uint32) 0; //unk + WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (8*4)); + data << uint32(auction->Id); + data << uint32(auction->bid); + data << uint32(0); //unk + data << uint64(0); //unk (bidder guid?) + data << uint32(auction->item_template); + data << uint32(0); //unk + data << float(0); //unk (time?) SendPacket(&data); } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 535253f4e13..7c09a2f32c6 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3096,17 +3096,9 @@ void AuraEffect::HandleModPossess(AuraApplication const* aurApp, uint8 mode, boo } if (apply) - { - if (target->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp)) - caster->ToPlayer()->SetMover(target); - } + target->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp); else - { target->RemoveCharmedBy(caster); - caster->ToPlayer()->SetMover(caster); - if (target->GetTypeId() == TYPEID_PLAYER) - target->ToPlayer()->SetMover(target); - } } // only one spell has this aura @@ -3134,13 +3126,11 @@ void AuraEffect::HandleModPossessPet(AuraApplication const* aurApp, uint8 mode, if (caster->ToPlayer()->GetPet() != pet) return; - if (pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp)) - caster->ToPlayer()->SetMover(pet); + pet->SetCharmedBy(caster, CHARM_TYPE_POSSESS, aurApp); } else { pet->RemoveCharmedBy(caster); - caster->ToPlayer()->SetMover(caster); if (!pet->IsWithinDistInMap(caster, pet->GetMap()->GetVisibilityRange())) pet->Remove(PET_SAVE_NOT_IN_SLOT, true); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 5577422919f..b32e346757f 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1963,6 +1963,13 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo)) return false; + // TODO: + // - do checks using conditions table for eventInfo->GetActor() and eventInfo->GetActionTarget() + // - add DoCheckProc() AuraScript hook + // to allow additional requirements for procs + // this is needed because this is the last moment in which you can prevent aura charge drop on proc + // and possibly a way to prevent default checks (if there're going to be any) + // Check if current equipment meets aura requirements // do that only for passive spells // TODO: this needs to be unified for all kinds of auras @@ -2023,11 +2030,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo) { - // TODO: script hooks here (allowing prevention of selected effects) + // TODO: OnProc hook here for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (aurApp->HasEffect(i)) + // TODO: OnEffectProc hook here (allowing prevention of selected effects) GetEffect(i)->HandleProc(aurApp, eventInfo); - // TODO: script hooks here + // TODO: AfterEffectProc hook here + + // TODO: AfterProc hook here // Remove aura if we've used last charge to proc if (IsUsingCharges() && !GetCharges()) diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 8c9cde37c15..de743eb2991 100755 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -186,6 +186,9 @@ class Aura bool CanStackWith(Aura const* existingAura) const; // Proc system + // this subsystem is not yet in use - the core of it is functional, but still some research has to be done + // and some dependant problems fixed before it can replace old proc system (for example cooldown handling) + // currently proc system functionality is implemented in Unit::ProcDamageAndSpell bool IsProcOnCooldown() const; void AddProcCooldown(uint32 msec); bool IsUsingCharges() const { return m_isUsingCharges; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 1b6a6c6fdcf..57932ef56c6 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -130,7 +130,7 @@ public: { uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); if (tguid > 0) - WorldDatabase.PQuery("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); + WorldDatabase.PExecute("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO()); return true; } @@ -679,7 +679,7 @@ public: if (target->GetTransport()) if (target->GetGUIDTransport()) - WorldDatabase.PQuery("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport()); + WorldDatabase.PExecute("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport()); target->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 4d8ce4ef4ed..35b590fe404 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -404,113 +404,116 @@ public: if (!*args) return false; - uint32 entry = (uint32) atoi((char*)args); - QueryResult result = WorldDatabase.PQuery("SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = %u", entry); - if (!result) - { - handler->PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry); - handler->SetSentErrorMessage(true); - return false; - } - - CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); - if (!cInfo) - { - handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry); - handler->SetSentErrorMessage(true); - return false; - } + Tokens entries(std::string(args), ' '); - sLog->outString("Reloading creature template entry %u", entry); - - Field* fields = result->Fetch(); - - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString(); - const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString(); - const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString(); - const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32(); - - for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + for (Tokens::const_iterator itr = entries.begin(); itr != entries.end(); ++itr) { - const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32(); + uint32 entry = uint32(atoi(*itr)); + QueryResult result = WorldDatabase.PQuery("SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = %u", entry); + if (!result) + { + handler->PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry); + continue; + } + + CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry); + if (!cInfo) + { + handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry); + continue; + } + + sLog->outString("Reloading creature template entry %u", entry); + + Field* fields = result->Fetch(); + + const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString(); + const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString(); + const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString(); + const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32(); + + for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + { + const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32(); + } + + const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString(); + const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[67].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[68].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[69].GetFloat(); + const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[70].GetBool(); + const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[71].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[72].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[73].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[74].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[75].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[76].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->movementId = fields[77].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[78].GetBool(); + const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[79].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[81].GetUInt32(); + const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[82].GetCString()); + + sObjectMgr->CheckCreatureTemplate(cInfo); } - const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString(); - const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[67].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[68].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[69].GetFloat(); - const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[70].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[71].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[72].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[73].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[74].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[75].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[76].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->movementId = fields[77].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[78].GetBool(); - const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[79].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[81].GetUInt32(); - const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[82].GetCString()); - - sObjectMgr->CheckCreatureTemplate(cInfo); - handler->SendGlobalGMSysMessage("Creature template reloaded."); return true; } diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp index d444160b8f2..a0d6f04f44c 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp @@ -67,6 +67,7 @@ class boss_bronjahm : public CreatureScript { boss_bronjahmAI(Creature* creature) : BossAI(creature, DATA_BRONJAHM) { + DoCast(me, SPELL_SOULSTORM_CHANNEL, true); } void InitializeAI() @@ -82,14 +83,17 @@ class boss_bronjahm : public CreatureScript events.Reset(); events.SetPhase(PHASE_1); events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000); - events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000)); + events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000)); events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1); - me->CastSpell(me, SPELL_SOULSTORM_CHANNEL, true); - instance->SetBossState(DATA_BRONJAHM, NOT_STARTED); } + void JustReachedHome() + { + DoCast(me, SPELL_SOULSTORM_CHANNEL, true); + } + void EnterCombat(Unit* /*who*/) { DoScriptText(SAY_AGGRO, me); @@ -118,7 +122,7 @@ class boss_bronjahm : public CreatureScript events.SetPhase(PHASE_2); DoCast(me, SPELL_TELEPORT); events.ScheduleEvent(EVENT_FEAR, urand(12000, 16000), 0, PHASE_2); - events.ScheduleEvent(EVENT_SOULSTORM, 700, 0, PHASE_2); + events.ScheduleEvent(EVENT_SOULSTORM, 100, 0, PHASE_2); } } @@ -147,7 +151,7 @@ class boss_bronjahm : public CreatureScript { case EVENT_MAGIC_BANE: DoCastVictim(SPELL_MAGIC_S_BANE); - events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000)); + events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000)); break; case EVENT_SHADOW_BOLT: if (!me->IsWithinMeleeRange(me->getVictim())) diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp index 8180a686e0e..fb39019fb84 100644 --- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp @@ -306,6 +306,7 @@ class boss_devourer_of_souls : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) { me->SetOrientation(me->GetAngle(target)); + me->SendMovementFlagUpdate(); DoCast(me, SPELL_WAILING_SOULS_BEAM); } @@ -332,6 +333,7 @@ class boss_devourer_of_souls : public CreatureScript case EVENT_WAILING_SOULS_TICK: beamAngle += beamAngleDiff; me->SetOrientation(beamAngle); + me->SendMovementFlagUpdate(); me->StopMoving(); DoCast(me, SPELL_WAILING_SOULS); diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp index ea84502c16d..1ab95c53500 100644 --- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp +++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp @@ -18,7 +18,7 @@ /* ScriptData SDName: Boss_Ingvar_The_Plunderer SD%Complete: 95 -SDComment: Some Problems with Annhylde Movement, Blizzlike Timers +SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer) SDCategory: Udgarde Keep EndScriptData */ @@ -45,16 +45,32 @@ enum Creatures MOB_INGVAR_UNDEAD = 23980, }; +enum Events +{ + EVENT_CLEAVE = 1, + EVENT_SMASH, + EVENT_STAGGERING_ROAR, + EVENT_ENRAGE, + + EVENT_DARK_SMASH, + EVENT_DREADFUL_ROAR, + EVENT_WOE_STRIKE, + EVENT_SHADOW_AXE +}; + +enum Phases +{ + PHASE_HUMAN = 1, + PHASE_UNDEAD, +}; + enum Spells { //Ingvar Spells human form SPELL_CLEAVE = 42724, SPELL_SMASH = 42669, - H_SPELL_SMASH = 59706, SPELL_STAGGERING_ROAR = 42708, - H_SPELL_STAGGERING_ROAR = 59708, SPELL_ENRAGE = 42705, - H_SPELL_ENRAGE = 59707, SPELL_INGVAR_FEIGN_DEATH = 42795, SPELL_SUMMON_BANSHEE = 42912, @@ -63,9 +79,7 @@ enum Spells //Ingvar Spells undead form SPELL_DARK_SMASH = 42723, SPELL_DREADFUL_ROAR = 42729, - H_SPELL_DREADFUL_ROAR = 59734, SPELL_WOE_STRIKE = 42730, - H_SPELL_WOE_STRIKE = 59735, ENTRY_THROW_TARGET = 23996, SPELL_SHADOW_AXE_SUMMON = 42749 @@ -83,9 +97,9 @@ public: struct boss_ingvar_the_plundererAI : public ScriptedAI { - boss_ingvar_the_plundererAI(Creature* c) : ScriptedAI(c) + boss_ingvar_the_plundererAI(Creature* creature) : ScriptedAI(creature) { - instance = c->GetInstanceScript(); + instance = creature->GetInstanceScript(); } InstanceScript* instance; @@ -93,10 +107,6 @@ public: bool bIsUndead; bool bEventInProgress; - uint32 uiCleaveTimer; - uint32 uiSmashTimer; - uint32 uiEnrageTimer; - uint32 uiRoarTimer; uint32 uiSpawnResTimer; void Reset() @@ -110,10 +120,18 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); me->SetStandState(UNIT_STAND_STATE_STAND); - uiCleaveTimer = 2000; - uiSmashTimer = 5000; - uiEnrageTimer = 10000; - uiRoarTimer = 15000; + events.Reset(); + events.SetPhase(PHASE_HUMAN); + + events.ScheduleEvent(EVENT_CLEAVE, urand(6,12)*IN_MILLISECONDS, 0, PHASE_HUMAN); + events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN); + events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN); + events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN); + + events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); uiSpawnResTimer = 3000; @@ -138,6 +156,7 @@ public: bEventInProgress = true; bIsUndead = true; + events.SetPhase(PHASE_UNDEAD); DoScriptText(YELL_DEAD_1, me); } @@ -208,70 +227,60 @@ public: return; } - if (uiCleaveTimer <= diff) - { - if (!me->HasUnitState(UNIT_STAT_CASTING)) - { - if (bIsUndead) - DoCast(me->getVictim(), SPELL_WOE_STRIKE); - else - DoCast(me->getVictim(), SPELL_CLEAVE); - uiCleaveTimer = rand()%5000 + 2000; - } - } else uiCleaveTimer -= diff; + events.Update(diff); - if (uiSmashTimer <= diff) - { - if (!me->HasUnitState(UNIT_STAT_CASTING)) - { - if (bIsUndead) - DoCast(me->getVictim(), SPELL_DARK_SMASH); - else - DoCast(me->getVictim(), SPELL_SMASH); - uiSmashTimer = 10000; - } - } else uiSmashTimer -= diff; + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; - if (!bIsUndead) - { - if (uiEnrageTimer <= diff) - { - DoCast(me, SPELL_ENRAGE); - uiEnrageTimer = 10000; - } else uiEnrageTimer -= diff; - } else // In Undead form used to summon weapon + while (uint32 eventId = events.ExecuteEvent()) { - if (uiEnrageTimer <= diff) + switch (eventId) { - if (!me->HasUnitState(UNIT_STAT_CASTING)) - { - // Spawn target for Axe - Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1); - if (target) + // PHASE ONE + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + events.ScheduleEvent(EVENT_CLEAVE, urand(6,12)*IN_MILLISECONDS, 0, PHASE_HUMAN); + break; + case EVENT_STAGGERING_ROAR: + DoCast(me, SPELL_STAGGERING_ROAR); + events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN); + break; + case EVENT_ENRAGE: + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN); + break; + case EVENT_SMASH: + DoCastVictim(SPELL_SMASH); + events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN); + break; + // PHASE TWO + case EVENT_DARK_SMASH: + DoCastVictim(SPELL_DARK_SMASH); + events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + break; + case EVENT_DREADFUL_ROAR: + DoCast(me, SPELL_DREADFUL_ROAR); + events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + break; + case EVENT_WOE_STRIKE: + DoCastVictim(SPELL_WOE_STRIKE); + events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD); + break; + case EVENT_SHADOW_AXE: + if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1)) { me->SummonCreature(ENTRY_THROW_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2000); - DoCast(me, SPELL_SHADOW_AXE_SUMMON); } - uiEnrageTimer = 30000; - } - } else uiEnrageTimer -= diff; - } - - if (uiRoarTimer <= diff) - { - if (!me->HasUnitState(UNIT_STAT_CASTING)) - { - if (bIsUndead) - DoCast(me, SPELL_DREADFUL_ROAR); - else - DoCast(me, SPELL_STAGGERING_ROAR); - uiRoarTimer = 10000; + events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD); + break; } - } else uiRoarTimer -= diff; + } DoMeleeAttackIfReady(); } + private: + EventMap events; }; }; diff --git a/src/server/scripts/Northrend/dalaran.cpp b/src/server/scripts/Northrend/dalaran.cpp index 57007a93fa7..cd3cbf29d0d 100644 --- a/src/server/scripts/Northrend/dalaran.cpp +++ b/src/server/scripts/Northrend/dalaran.cpp @@ -32,7 +32,12 @@ Script Data End */ enum Spells { SPELL_TRESPASSER_A = 54028, - SPELL_TRESPASSER_H = 54029 + SPELL_TRESPASSER_H = 54029, + + SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, + SPELL_SUNREAVER_DISGUISE_MALE = 70974, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, + SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, }; enum NPCs // All outdoor guards are within 35.0f of these NPCs @@ -71,8 +76,10 @@ public: Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself(); - // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass - if (!player || player->isGameMaster() || player->IsBeingTeleported() || player->HasAura(70973) || player->HasAura(70971)) + if (!player || player->isGameMaster() || player->IsBeingTeleported() || + // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass + player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) || + player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE)) return; switch (me->GetEntry()) diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 3fb2c4f3319..2b31a50510d 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1481,6 +1481,82 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader } }; +enum DalaranDisguiseSpells +{ + SPELL_SUNREAVER_DISGUISE_TRIGGER = 69672, + SPELL_SUNREAVER_DISGUISE_FEMALE = 70973, + SPELL_SUNREAVER_DISGUISE_MALE = 70974, + + SPELL_SILVER_COVENANT_DISGUISE_TRIGGER = 69673, + SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971, + SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972, +}; + +class spell_gen_dalaran_disguise : public SpellScriptLoader +{ + public: + spell_gen_dalaran_disguise(const char* name) : SpellScriptLoader(name) {} + + class spell_gen_dalaran_disguise_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_dalaran_disguise_SpellScript); + bool Validate(SpellInfo const* spellEntry) + { + switch (spellEntry->Id) + { + case SPELL_SUNREAVER_DISGUISE_TRIGGER: + if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_FEMALE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_MALE)) + return false; + break; + case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER: + if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_FEMALE)) + return false; + if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_MALE)) + return false; + break; + } + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + + if (Player* player = GetHitPlayer()) + { + uint8 gender = player->getGender(); + + uint32 spellId = GetSpellInfo()->Id; + + switch (spellId) + { + case SPELL_SUNREAVER_DISGUISE_TRIGGER: + spellId = gender ? SPELL_SUNREAVER_DISGUISE_FEMALE : SPELL_SUNREAVER_DISGUISE_MALE; + break; + case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER: + spellId = gender ? SPELL_SILVER_COVENANT_DISGUISE_FEMALE : SPELL_SILVER_COVENANT_DISGUISE_MALE; + break; + default: + break; + } + + GetCaster()->CastSpell(player, spellId, true); + } + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_gen_dalaran_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_dalaran_disguise_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1514,4 +1590,6 @@ void AddSC_generic_spell_scripts() new spell_gen_oracle_wolvar_reputation(); new spell_gen_damage_reduction_aura(); new spell_gen_luck_of_the_draw(); + new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise"); + new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise"); } |