diff options
Diffstat (limited to 'src')
53 files changed, 326 insertions, 210 deletions
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 137f88e819b..ca6d4a8209f 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -120,7 +120,7 @@ BattleGround::~BattleGround() this->RemoveFromBGFreeSlotQueue(); } -void BattleGround::Update(time_t diff) +void BattleGround::Update(uint32 diff) { if(!GetPlayersSize() && !GetRemovedPlayersSize() && !GetReviveQueueSize()) //BG is empty diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 6f7c8334996..ba3bcce1750 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -264,7 +264,7 @@ class BattleGround BattleGround(); /*BattleGround(const BattleGround& bg);*/ virtual ~BattleGround(); - virtual void Update(time_t diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version + virtual void Update(uint32 diff); // must be implemented in BG subclass of BG specific update code, but must in begginning call parent version virtual bool SetupBattleGround() // must be implemented in BG subclass { return true; diff --git a/src/game/BattleGroundAA.cpp b/src/game/BattleGroundAA.cpp index 8737088894a..63ae9f7c59a 100644 --- a/src/game/BattleGroundAA.cpp +++ b/src/game/BattleGroundAA.cpp @@ -32,7 +32,7 @@ BattleGroundAA::~BattleGroundAA() } -void BattleGroundAA::Update(time_t diff) +void BattleGroundAA::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundAA.h b/src/game/BattleGroundAA.h index edddc110600..955b74fd2f0 100644 --- a/src/game/BattleGroundAA.h +++ b/src/game/BattleGroundAA.h @@ -37,7 +37,7 @@ class BattleGroundAA : public BattleGround public: BattleGroundAA(); ~BattleGroundAA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundAB.cpp b/src/game/BattleGroundAB.cpp index 00e1090d8d5..6388cacd698 100644 --- a/src/game/BattleGroundAB.cpp +++ b/src/game/BattleGroundAB.cpp @@ -52,7 +52,7 @@ BattleGroundAB::~BattleGroundAB() { } -void BattleGroundAB::Update(time_t diff) +void BattleGroundAB::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundAB.h b/src/game/BattleGroundAB.h index 464108d63c9..fca7986bc24 100644 --- a/src/game/BattleGroundAB.h +++ b/src/game/BattleGroundAB.h @@ -238,7 +238,7 @@ class BattleGroundAB : public BattleGround BattleGroundAB(); ~BattleGroundAB(); - void Update(time_t diff); + void Update(uint32 diff); void AddPlayer(Player *plr); void RemovePlayer(Player *plr,uint64 guid); void HandleAreaTrigger(Player *Source, uint32 Trigger); diff --git a/src/game/BattleGroundAV.cpp b/src/game/BattleGroundAV.cpp index 6b892a0fa5d..bffe9d0e4ad 100644 --- a/src/game/BattleGroundAV.cpp +++ b/src/game/BattleGroundAV.cpp @@ -294,7 +294,7 @@ Creature* BattleGroundAV::AddAVCreature(uint16 cinfoid, uint16 type ) return creature; } -void BattleGroundAV::Update(time_t diff) +void BattleGroundAV::Update(uint32 diff) { BattleGround::Update(diff); if (GetStatus() == STATUS_WAIT_JOIN && GetPlayersSize()) diff --git a/src/game/BattleGroundAV.h b/src/game/BattleGroundAV.h index e80ad47d869..f9343ddfcbc 100644 --- a/src/game/BattleGroundAV.h +++ b/src/game/BattleGroundAV.h @@ -1500,7 +1500,7 @@ class BattleGroundAV : public BattleGround public: BattleGroundAV(); ~BattleGroundAV(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundBE.cpp b/src/game/BattleGroundBE.cpp index 6f4ac89c64e..604ca339680 100644 --- a/src/game/BattleGroundBE.cpp +++ b/src/game/BattleGroundBE.cpp @@ -37,7 +37,7 @@ BattleGroundBE::~BattleGroundBE() } -void BattleGroundBE::Update(time_t diff) +void BattleGroundBE::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundBE.h b/src/game/BattleGroundBE.h index a16464dd31b..6abf33eb8f2 100644 --- a/src/game/BattleGroundBE.h +++ b/src/game/BattleGroundBE.h @@ -57,7 +57,7 @@ class BattleGroundBE : public BattleGround public: BattleGroundBE(); ~BattleGroundBE(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundDS.cpp b/src/game/BattleGroundDS.cpp index 276c0c84c41..825a52967b6 100644 --- a/src/game/BattleGroundDS.cpp +++ b/src/game/BattleGroundDS.cpp @@ -30,7 +30,7 @@ BattleGroundDS::~BattleGroundDS() } -void BattleGroundDS::Update(time_t diff) +void BattleGroundDS::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundDS.h b/src/game/BattleGroundDS.h index afcb8f09225..7f9de8ca7de 100644 --- a/src/game/BattleGroundDS.h +++ b/src/game/BattleGroundDS.h @@ -35,7 +35,7 @@ class BattleGroundDS : public BattleGround public: BattleGroundDS(); ~BattleGroundDS(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index 1af6aaabf8b..9872a49125a 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -51,7 +51,7 @@ BattleGroundEY::~BattleGroundEY() { } -void BattleGroundEY::Update(time_t diff) +void BattleGroundEY::Update(uint32 diff) { BattleGround::Update(diff); // after bg start we get there (once) diff --git a/src/game/BattleGroundEY.h b/src/game/BattleGroundEY.h index 0152a889f30..f512112ba53 100644 --- a/src/game/BattleGroundEY.h +++ b/src/game/BattleGroundEY.h @@ -300,7 +300,7 @@ class BattleGroundEY : public BattleGround public: BattleGroundEY(); ~BattleGroundEY(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 75d3c2755ce..1065eecfa29 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -1097,7 +1097,7 @@ BattleGroundMgr::~BattleGroundMgr() } // used to update running battlegrounds, and delete finished ones -void BattleGroundMgr::Update(time_t diff) +void BattleGroundMgr::Update(uint32 diff) { BattleGroundSet::iterator itr, next; for(itr = m_BattleGrounds.begin(); itr != m_BattleGrounds.end(); itr = next) diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index 6a973f4f732..bab20ae7b5d 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -175,7 +175,7 @@ class BattleGroundMgr /* Construction */ BattleGroundMgr(); ~BattleGroundMgr(); - void Update(time_t diff); + void Update(uint32 diff); /* Packet Building */ void BuildPlayerJoinedBattleGroundPacket(WorldPacket *data, Player *plr); diff --git a/src/game/BattleGroundNA.cpp b/src/game/BattleGroundNA.cpp index f06910af986..1079c510b24 100644 --- a/src/game/BattleGroundNA.cpp +++ b/src/game/BattleGroundNA.cpp @@ -37,7 +37,7 @@ BattleGroundNA::~BattleGroundNA() } -void BattleGroundNA::Update(time_t diff) +void BattleGroundNA::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundNA.h b/src/game/BattleGroundNA.h index 45dc9efec31..f31555d65f9 100644 --- a/src/game/BattleGroundNA.h +++ b/src/game/BattleGroundNA.h @@ -58,7 +58,7 @@ class BattleGroundNA : public BattleGround public: BattleGroundNA(); ~BattleGroundNA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundRL.cpp b/src/game/BattleGroundRL.cpp index 193578e88b0..6585a164211 100644 --- a/src/game/BattleGroundRL.cpp +++ b/src/game/BattleGroundRL.cpp @@ -37,7 +37,7 @@ BattleGroundRL::~BattleGroundRL() } -void BattleGroundRL::Update(time_t diff) +void BattleGroundRL::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundRL.h b/src/game/BattleGroundRL.h index d3f58264833..567b677769e 100644 --- a/src/game/BattleGroundRL.h +++ b/src/game/BattleGroundRL.h @@ -54,7 +54,7 @@ class BattleGroundRL : public BattleGround public: BattleGroundRL(); ~BattleGroundRL(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundRV.cpp b/src/game/BattleGroundRV.cpp index 20c7d11f876..a66f0ce30e2 100644 --- a/src/game/BattleGroundRV.cpp +++ b/src/game/BattleGroundRV.cpp @@ -30,7 +30,7 @@ BattleGroundRV::~BattleGroundRV() } -void BattleGroundRV::Update(time_t diff) +void BattleGroundRV::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundRV.h b/src/game/BattleGroundRV.h index 9f515e35b93..2d2ad12c941 100644 --- a/src/game/BattleGroundRV.h +++ b/src/game/BattleGroundRV.h @@ -35,7 +35,7 @@ class BattleGroundRV : public BattleGround public: BattleGroundRV(); ~BattleGroundRV(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundSA.cpp b/src/game/BattleGroundSA.cpp index d7bc422ca0e..20a69297609 100644 --- a/src/game/BattleGroundSA.cpp +++ b/src/game/BattleGroundSA.cpp @@ -29,7 +29,7 @@ BattleGroundSA::~BattleGroundSA() } -void BattleGroundSA::Update(time_t diff) +void BattleGroundSA::Update(uint32 diff) { BattleGround::Update(diff); } diff --git a/src/game/BattleGroundSA.h b/src/game/BattleGroundSA.h index 6727c7a1f96..331a41455fd 100644 --- a/src/game/BattleGroundSA.h +++ b/src/game/BattleGroundSA.h @@ -35,7 +35,7 @@ class BattleGroundSA : public BattleGround public: BattleGroundSA(); ~BattleGroundSA(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/BattleGroundWS.cpp b/src/game/BattleGroundWS.cpp index 755089473e8..51ec6595b93 100644 --- a/src/game/BattleGroundWS.cpp +++ b/src/game/BattleGroundWS.cpp @@ -58,7 +58,7 @@ BattleGroundWS::~BattleGroundWS() { } -void BattleGroundWS::Update(time_t diff) +void BattleGroundWS::Update(uint32 diff) { BattleGround::Update(diff); diff --git a/src/game/BattleGroundWS.h b/src/game/BattleGroundWS.h index 17b59d98343..426fb2ebcb1 100644 --- a/src/game/BattleGroundWS.h +++ b/src/game/BattleGroundWS.h @@ -136,7 +136,7 @@ class BattleGroundWS : public BattleGround /* Construction */ BattleGroundWS(); ~BattleGroundWS(); - void Update(time_t diff); + void Update(uint32 diff); /* inherited from BattlegroundClass */ virtual void AddPlayer(Player *plr); diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index ce089511586..858c236a6fb 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -291,6 +291,7 @@ ChatCommand * ChatHandler::getCommandTable() { "spell_required", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellRequiredCommand, "", NULL }, { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, + { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL }, { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, { "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 337d34e3b0c..36c196b1b14 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -244,6 +244,7 @@ class ChatHandler bool HandleReloadLootTemplatesReferenceCommand(const char* args); bool HandleReloadLootTemplatesQuestMailCommand(const char* args); bool HandleReloadLootTemplatesSkinningCommand(const char* args); + bool HandleReloadLootTemplatesSpellCommand(const char* args); bool HandleReloadTrinityStringCommand(const char* args); bool HandleReloadNpcGossipCommand(const char* args); bool HandleReloadNpcOptionCommand(const char* args); diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index 5a74550c12a..61fe2fba697 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -717,7 +717,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke if (mask & GROUP_UPDATE_FLAG_AURAS) { - uint64 auramask = player->GetAuraUpdateMask(); + const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { @@ -802,7 +802,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke { if(pet) { - uint64 auramask = pet->GetAuraUpdateMask(); + const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for(uint32 i = 0; i < MAX_AURAS; ++i) { diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index b0cf4695afe..12f251ec025 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -343,6 +343,15 @@ bool ChatHandler::HandleReloadLootTemplatesSkinningCommand(const char*) return true; } +bool ChatHandler::HandleReloadLootTemplatesSpellCommand(const char*) +{ + sLog.outString( "Re-Loading Loot Tables... (`spell_loot_template`)" ); + LoadLootTemplates_Spell(); + LootTemplates_Spell.CheckLootRefs(); + SendGlobalSysMessage("DB table `spell_loot_template` reloaded."); + return true; +} + bool ChatHandler::HandleReloadTrinityStringCommand(const char*) { sLog.outString( "Re-Loading trinity_string Table!" ); diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 90162a213d7..100acfbc7ab 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -25,6 +25,7 @@ #include "World.h" #include "Util.h" #include "SharedDefines.h" +#include "SpellMgr.h" static Rates const qualityToRate[MAX_ITEM_QUALITY] = { RATE_DROP_ITEM_POOR, // ITEM_QUALITY_POOR @@ -36,17 +37,18 @@ static Rates const qualityToRate[MAX_ITEM_QUALITY] = { RATE_DROP_ITEM_ARTIFACT, // ITEM_QUALITY_ARTIFACT }; -LootStore LootTemplates_Creature( "creature_loot_template", "creature entry"); -LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id"); -LootStore LootTemplates_Fishing( "fishing_loot_template", "area id"); -LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry"); -LootStore LootTemplates_Item( "item_loot_template", "item entry"); -LootStore LootTemplates_Milling( "milling_loot_template", "item entry"); -LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid"); -LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry"); -LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id"); -LootStore LootTemplates_Reference( "reference_loot_template", "reference id"); -LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id"); +LootStore LootTemplates_Creature( "creature_loot_template", "creature entry", true); +LootStore LootTemplates_Disenchant( "disenchant_loot_template", "item disenchant id", true); +LootStore LootTemplates_Fishing( "fishing_loot_template", "area id", true); +LootStore LootTemplates_Gameobject( "gameobject_loot_template", "gameobject entry", true); +LootStore LootTemplates_Item( "item_loot_template", "item entry", true); +LootStore LootTemplates_Milling( "milling_loot_template", "item entry (herb)", true); +LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid", true); +LootStore LootTemplates_Prospecting( "prospecting_loot_template", "item entry (ore)", true); +LootStore LootTemplates_QuestMail( "quest_mail_loot_template", "quest id (with mail template)",false); +LootStore LootTemplates_Reference( "reference_loot_template", "reference id", false); +LootStore LootTemplates_Skinning( "skinning_loot_template", "creature skinning id", true); +LootStore LootTemplates_Spell( "spell_loot_template", "spell id (explicitly discovering ability)",false); class LootTemplate::LootGroup // A set of loot definitions for items (refs are not allowed) @@ -56,7 +58,7 @@ class LootTemplate::LootGroup // A set of loot def bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry bool HasQuestDropForPlayer(Player const * player) const; // The same for active quests of the player - void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot + void Process(Loot& loot, bool rate) const; // Rolls an item from the group (if any) and adds the item to the loot float RawTotalChance() const; // Overall chance for the group (without equal chanced items) float TotalChance() const; // Overall chance for the group @@ -67,7 +69,7 @@ class LootTemplate::LootGroup // A set of loot def LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance - LootStoreItem const * Roll() const; // Rolls an item from the group, returns NULL if all miss their chances + LootStoreItem const * Roll(bool rate) const; // Rolls an item from the group, returns NULL if all miss their chances }; //Remove all data and free all memory @@ -231,17 +233,17 @@ void LootStore::ReportNotExistedId(uint32 id) const // Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation) // RATE_DROP_ITEMS is no longer used for all types of entries -bool LootStoreItem::Roll() const +bool LootStoreItem::Roll(bool rate) const { if(chance>=100.f) return true; if(mincountOrRef < 0) // reference case - return roll_chance_f(chance*sWorld.getRate(RATE_DROP_ITEM_REFERENCED)); + return roll_chance_f(chance* (rate ? sWorld.getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f)); ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid); - float qualityModifier = pProto ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + float qualityModifier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; return roll_chance_f(chance*qualityModifier); } @@ -380,7 +382,7 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner) items.reserve(MAX_NR_LOOT_ITEMS); quest_items.reserve(MAX_NR_QUEST_ITEMS); - tab->Process(*this, store); // Processing is done there, callback via Loot::AddItem() + tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem() // Setting access rights fow group-looting case if(!loot_owner) @@ -766,7 +768,7 @@ void LootTemplate::LootGroup::AddEntry(LootStoreItem& item) } // Rolls an item from the group, returns NULL if all miss their chances -LootStoreItem const * LootTemplate::LootGroup::Roll() const +LootStoreItem const * LootTemplate::LootGroup::Roll(bool rate) const { if (!ExplicitlyChanced.empty()) // First explicitly chanced entries are checked { @@ -778,7 +780,8 @@ LootStoreItem const * LootTemplate::LootGroup::Roll() const return &ExplicitlyChanced[i]; ItemPrototype const *pProto = objmgr.GetItemPrototype(ExplicitlyChanced[i].itemid); - Roll -= ExplicitlyChanced[i].chance; + //float qualityMultiplier = pProto && rate ? sWorld.getRate(qualityToRate[pProto->Quality]) : 1.0f; + Roll -= ExplicitlyChanced[i].chance;// * qualityMultiplier; if (Roll < 0) return &ExplicitlyChanced[i]; } @@ -814,9 +817,9 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const } // Rolls an item from the group (if any takes its chance) and adds the item to the loot -void LootTemplate::LootGroup::Process(Loot& loot) const +void LootTemplate::LootGroup::Process(Loot& loot, bool rate) const { - LootStoreItem const * item = Roll(); + LootStoreItem const * item = Roll(rate); if (item != NULL) loot.AddItem(*item); } @@ -901,21 +904,21 @@ void LootTemplate::AddEntry(LootStoreItem& item) } // Rolls for every item in the template and adds the rolled items the the loot -void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) const +void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 groupId) const { if (groupId) // Group reference uses own processing of the group { if (groupId > Groups.size()) return; // Error message already printed at loading stage - Groups[groupId-1].Process(loot); + Groups[groupId-1].Process(loot,rate); return; } // Rolling non-grouped items for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i ) { - if ( !i->Roll() ) + if (!i->Roll(rate)) continue; // Bad luck for the entry if (i->mincountOrRef < 0) // References processing @@ -926,7 +929,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co continue; // Error message already printed at loading stage for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator - Referenced->Process(loot, store, i->group); // Ref processing + Referenced->Process(loot, store, rate, i->group); } else // Plain entries (not a reference, not grouped) loot.AddItem(*i); // Chance is already checked, just add @@ -934,7 +937,7 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, uint8 groupId) co // Now processing groups for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i ) - i->Process(loot); + i->Process(loot,rate); } // True if template includes at least 1 quest drop entry @@ -1145,9 +1148,17 @@ void LoadLootTemplates_Milling() // remove real entries and check existence loot for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) - if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i)) - if(ids_set.count(proto->ItemId)) - ids_set.erase(proto->ItemId); + { + ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i); + if(!proto) + continue; + + if((proto->BagFamily & BAG_FAMILY_MASK_HERBS)==0) + continue; + + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Milling.ReportUnusedIds(ids_set); @@ -1186,9 +1197,17 @@ void LoadLootTemplates_Prospecting() // remove real entries and check existence loot for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) - if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i)) - if(ids_set.count(proto->ItemId)) - ids_set.erase(proto->ItemId); + { + ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i); + if(!proto) + continue; + + if((proto->BagFamily & BAG_FAMILY_MASK_MINING_SUPP)==0) + continue; + + if(ids_set.count(proto->ItemId)) + ids_set.erase(proto->ItemId); + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Prospecting.ReportUnusedIds(ids_set); @@ -1202,8 +1221,17 @@ void LoadLootTemplates_QuestMail() // remove real entries and check existence loot ObjectMgr::QuestMap const& questMap = objmgr.GetQuestTemplates(); for(ObjectMgr::QuestMap::const_iterator itr = questMap.begin(); itr != questMap.end(); ++itr ) + { + if(!itr->second->GetRewMailTemplateId()) + continue; + if(ids_set.count(itr->first)) ids_set.erase(itr->first); + /* disabled reporting: some quest mails not include items + else + LootTemplates_QuestMail.ReportNotExistedId(itr->first); + */ + } // output error for any still listed (not referenced from appropriate table) ids LootTemplates_QuestMail.ReportUnusedIds(ids_set); @@ -1235,6 +1263,37 @@ void LoadLootTemplates_Skinning() LootTemplates_Skinning.ReportUnusedIds(ids_set); } +void LoadLootTemplates_Spell() +{ + LootIdSet ids_set; + LootTemplates_Spell.LoadAndCollectLootIds(ids_set); + + // remove real entries and check existence loot + for(uint32 spell_id = 1; spell_id < sSpellStore.GetNumRows(); ++spell_id) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry (spell_id); + if(!spellInfo) + continue; + + // possible cases + if(!IsExplicitDiscoverySpell (spellInfo)) + continue; + + if(!ids_set.count(spell_id)) + { + // not report about not trainable spells (optionally supported by DB) + // 61756 (Northrend Inscription Research (FAST QA VERSION) for example + if(spellInfo->Attributes & SPELL_ATTR_UNK5) + LootTemplates_Spell.ReportNotExistedId(spell_id); + } + else + ids_set.erase(spell_id); + } + + // output error for any still listed (not referenced from appropriate table) ids + LootTemplates_QuestMail.ReportUnusedIds(ids_set); +} + void LoadLootTemplates_Reference() { LootIdSet ids_set; diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index f9fed651a1c..5205024a46c 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -77,7 +77,7 @@ struct LootStoreItem group(_group), maxcount(_maxcount), conditionId(_conditionId), needs_quest(_chanceOrQuestChance < 0) {} - bool Roll() const; // Checks if the entry takes it's chance (at loot generation) + bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation) bool IsValid(LootStore const& store, uint32 entry) const; // Checks correctness of values }; @@ -129,7 +129,8 @@ typedef std::set<uint32> LootIdSet; class LootStore { public: - explicit LootStore(char const* name, char const* entryName) : m_name(name), m_entryName(entryName) {} + explicit LootStore(char const* name, char const* entryName, bool ratesAllowed) + : m_name(name), m_entryName(entryName), m_ratesAllowed(m_ratesAllowed) {} virtual ~LootStore() { Clear(); } void Verify() const; @@ -147,6 +148,7 @@ class LootStore char const* GetName() const { return m_name; } char const* GetEntryName() const { return m_entryName; } + bool IsRatesAllowed() const { return m_ratesAllowed; } protected: void LoadLootTable(); void Clear(); @@ -154,6 +156,7 @@ class LootStore LootTemplateMap m_LootTemplates; char const* m_name; char const* m_entryName; + bool m_ratesAllowed; }; class LootTemplate @@ -165,7 +168,7 @@ class LootTemplate // Adds an entry to the group (at loading stage) void AddEntry(LootStoreItem& item); // Rolls for every item in the template and adds the rolled items the the loot - void Process(Loot& loot, LootStore const& store, uint8 GroupId = 0) const; + void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const; // True if template includes at least 1 quest drop entry bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const; @@ -303,6 +306,7 @@ extern LootStore LootTemplates_Skinning; extern LootStore LootTemplates_Disenchant; extern LootStore LootTemplates_Prospecting; extern LootStore LootTemplates_QuestMail; +extern LootStore LootTemplates_Spell; void LoadLootTemplates_Creature(); void LoadLootTemplates_Fishing(); @@ -314,6 +318,8 @@ void LoadLootTemplates_Skinning(); void LoadLootTemplates_Disenchant(); void LoadLootTemplates_Prospecting(); void LoadLootTemplates_QuestMail(); + +void LoadLootTemplates_Spell(); void LoadLootTemplates_Reference(); inline void LoadLootTables() @@ -328,6 +334,8 @@ inline void LoadLootTables() LoadLootTemplates_Disenchant(); LoadLootTemplates_Prospecting(); LoadLootTemplates_QuestMail(); + LoadLootTemplates_Spell(); + LoadLootTemplates_Reference(); } diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index e78de5571bc..e9a77d13b7c 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -241,7 +241,7 @@ void MapManager::RemoveBonesFromMap(uint32 mapid, uint64 guid, float x, float y) } void -MapManager::Update(time_t diff) +MapManager::Update(uint32 diff) { i_timer.Update(diff); if( !i_timer.Passed() ) diff --git a/src/game/MapManager.h b/src/game/MapManager.h index ec793b81a38..9bd63e4bb78 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -56,7 +56,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit uint32 GetZoneId(uint32 mapid, float x, float y, float z) const { return Map::GetZoneId(GetAreaFlag(mapid, x, y, z),mapid); } void Initialize(void); - void Update(time_t); + void Update(uint32); void SetGridCleanUpDelay(uint32 t) { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 03165ff51e7..ba74bd3b762 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -4864,7 +4864,7 @@ void ObjectMgr::LoadAreaTriggerScripts() sLog.outString( ">> Loaded %u areatrigger scripts", count ); } -uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid ) +uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team ) { bool found = false; float dist; @@ -4873,7 +4873,7 @@ uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid ) for(uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) { TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); - if(node && node->map_id == mapid) + if(node && node->map_id == mapid && node->MountCreatureID[team == ALLIANCE ? 1 : 0]) { float dist2 = (node->x - x)*(node->x - x)+(node->y - y)*(node->y - y)+(node->z - z)*(node->z - z); if(found) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 18b80eee523..cbf8514fe25 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -435,7 +435,7 @@ class ObjectMgr uint32 GetPlayerAccountIdByGUID(const uint64 &guid) const; uint32 GetPlayerAccountIdByPlayerName(const std::string& name) const; - uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid ); + uint32 GetNearestTaxiNode( float x, float y, float z, uint32 mapid, uint32 team ); void GetTaxiPath( uint32 source, uint32 destination, uint32 &path, uint32 &cost); uint16 GetTaxiMount( uint32 id, uint32 team ); void GetTaxiPathNodes( uint32 path, Path &pathnodes, std::vector<uint32>& mapIds ); diff --git a/src/game/Pet.h b/src/game/Pet.h index d89e14e1d74..113d1e203fa 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -216,7 +216,7 @@ class Pet : public Creature time_t m_resetTalentsTime; uint32 m_usedTalentCount; - uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); } void ResetAuraUpdateMask() { m_auraUpdateMask = 0; } diff --git a/src/game/PetAI.cpp b/src/game/PetAI.cpp index abb62ade7da..1d4fbfba8e2 100644 --- a/src/game/PetAI.cpp +++ b/src/game/PetAI.cpp @@ -146,11 +146,11 @@ void PetAI::UpdateAI(const uint32 diff) else m_updateAlliesTimer -= diff; - if (inCombat && i_pet.getVictim() == NULL) + if (inCombat && !i_pet.getVictim()) _stopAttack(); // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc. - if( i_pet.getVictim() != NULL ) + if( i_pet.getVictim() ) { if( _needToStop() ) { diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index a08c3f1bff8..f7d853c4b29 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -106,7 +106,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) } // only place where pet can be player pet->clearUnitState(UNIT_STAT_FOLLOW); - uint64 selguid = _player->GetSelection(); + const uint64& selguid = _player->GetSelection(); Unit *TargetUnit = ObjectAccessor::GetUnit(*_player, selguid); if(!TargetUnit) return; @@ -118,27 +118,35 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) //if(!pet->IsWithinLOSInMap(TargetUnit)) // return; - if(pet->GetTypeId() != TYPEID_PLAYER) + // This is true if pet has no target or has target but targets differs. + if(pet->getVictim() != TargetUnit) { - if (((Creature*)pet)->AI()) - ((Creature*)pet)->AI()->AttackStart(TargetUnit); + if (pet->getVictim()) + pet->AttackStop(); - //10% chance to play special pet attack talk, else growl - if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10) - pet->SendPetTalk((uint32)PET_TALK_ATTACK); - else + if(pet->GetTypeId() != TYPEID_PLAYER) { - // 90% chance for pet and 100% chance for charmed creature - pet->SendPetAIReaction(guid1); + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(TargetUnit); + + //10% chance to play special pet attack talk, else growl + if(((Creature*)pet)->isPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10) + pet->SendPetTalk((uint32)PET_TALK_ATTACK); + else + { + // 90% chance for pet and 100% chance for charmed creature + pet->SendPetAIReaction(guid1); + } } - } - else // charmed player - { - if(pet->getVictim() && pet->getVictim() != TargetUnit) - pet->AttackStop(); + else // charmed player + { + if(pet->getVictim() && pet->getVictim() != TargetUnit) + pet->AttackStop(); - pet->Attack(TargetUnit,true); - pet->SendPetAIReaction(guid1); + pet->Attack(TargetUnit,true); + pet->SendPetAIReaction(guid1); + } } break; } @@ -178,15 +186,13 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) case ACT_PASSIVE: // 0x0100 case ACT_ENABLED: // 0xC100 spell { - Unit* unit_target; - if(guid2) - unit_target = ObjectAccessor::GetUnit(*_player,guid2); - else - unit_target = NULL; - + Unit* unit_target = NULL; if (((Creature*)pet)->GetGlobalCooldown() > 0) return; + if(guid2) + unit_target = ObjectAccessor::GetUnit(*_player,guid2); + // do not cast unknown spells SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid ); if(!spellInfo) @@ -211,7 +217,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) int16 result = spell->PetCanCast(unit_target); - //auto turn to target unless possessed + //auto turn to target unless possessed if(result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->isPossessed()) { pet->SetInFront(unit_target); @@ -242,12 +248,15 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) if( unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->isPossessed()) { - pet->clearUnitState(UNIT_STAT_FOLLOW); - if(pet->getVictim()) - pet->AttackStop(); - pet->GetMotionMaster()->Clear(); - if (((Creature*)pet)->AI()) - ((Creature*)pet)->AI()->AttackStart(unit_target); + // This is true if pet has no target or has target but targets differs. + if (pet->getVictim() != unit_target) + { + if (pet->getVictim()) + pet->AttackStop(); + pet->GetMotionMaster()->Clear(); + if (((Creature*)pet)->AI()) + ((Creature*)pet)->AI()->AttackStart(unit_target); + } } spell->prepare(&(spell->m_targets)); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c9da16cab17..3a8ebeede4d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -196,7 +196,7 @@ void PlayerTaxi::AppendTaximaskTo( ByteBuffer& data, bool all ) } } -bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values ) +bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values, uint32 team ) { ClearTaxiDestinations(); @@ -224,6 +224,10 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString( const std::string& values ) return false; } + // can't load taxi path without mount set (quest taxi path?) + if(!objmgr.GetTaxiMount(GetTaxiSource(),team)) + return false; + return true; } @@ -14767,7 +14771,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) } // Not finish taxi flight path - if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes)) + if(!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes,GetTeam())) { // problems with taxi path loading TaxiNodesEntry const* nodeEntry = NULL; @@ -20101,3 +20105,23 @@ void Player::InitRunes() for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); } + +void Player::AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store) +{ + Loot loot; + loot.FillLoot (loot_id,store,this); + if(loot.items.empty ()) + return; + LootItem const* lootItem = &loot.items[0]; + + ItemPosCountVec dest; + uint8 msg = CanStoreNewItem (bag,slot,dest,lootItem->itemid,lootItem->count); + if(msg != EQUIP_ERR_OK && slot != NULL_SLOT) + msg = CanStoreNewItem( bag, NULL_SLOT,dest,lootItem->itemid,lootItem->count); + if( msg != EQUIP_ERR_OK && bag != NULL_BAG) + msg = CanStoreNewItem( NULL_BAG, NULL_SLOT,dest,lootItem->itemid,lootItem->count); + if(msg != EQUIP_ERR_OK) + return; + + StoreNewItem (dest,lootItem->itemid,true,lootItem->randomPropertyId); +} diff --git a/src/game/Player.h b/src/game/Player.h index 1cbe373dcd1..d4ef1151b4e 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -940,7 +940,7 @@ class TRINITY_DLL_SPEC PlayerTaxi void AppendTaximaskTo(ByteBuffer& data,bool all); // Destinations - bool LoadTaxiDestinationsFromString(const std::string& values); + bool LoadTaxiDestinationsFromString(const std::string& values, uint32 team); std::string SaveTaxiDestinationsToString(); void ClearTaxiDestinations() { m_TaxiDestinations.clear(); } @@ -1154,6 +1154,8 @@ class TRINITY_DLL_SPEC Player : public Unit Item* EquipItem( uint16 pos, Item *pItem, bool update ); void AutoUnequipOffhandIfNeed(); bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count); + void AutoStoreLootItem(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store); + void AutoStoreLootItem(uint32 loot_id, LootStore const& store) { AutoStoreLootItem(NULL_BAG,NULL_SLOT,loot_id,store); } uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const; @@ -1418,7 +1420,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SetSelection(const uint64 &guid) { m_curSelection = guid; SetUInt64Value(UNIT_FIELD_TARGET, guid); } uint8 GetComboPoints() { return m_comboPoints; } - uint64 GetComboTarget() { return m_comboTarget; } + const uint64& GetComboTarget() const { return m_comboTarget; } void AddComboPoints(Unit* target, int8 count); void ClearComboPoints(); @@ -2178,9 +2180,9 @@ class TRINITY_DLL_SPEC Player : public Unit GroupReference& GetGroupRef() { return m_group; } void SetGroup(Group *group, int8 subgroup = -1); uint8 GetSubGroup() const { return m_group.getSubGroup(); } - uint32 GetGroupUpdateFlag() { return m_groupUpdateMask; } + uint32 GetGroupUpdateFlag() const { return m_groupUpdateMask; } void SetGroupUpdateFlag(uint32 flag) { m_groupUpdateMask |= flag; } - uint64 GetAuraUpdateMask() { return m_auraUpdateMask; } + const uint64& GetAuraUpdateMask() const { return m_auraUpdateMask; } void SetAuraUpdateMask(uint8 slot) { m_auraUpdateMask |= (uint64(1) << slot); } void UnsetAuraUpdateMask(uint8 slot) { m_auraUpdateMask &= ~(uint64(1) << slot); } Player* GetNextRandomRaidMember(float radius); diff --git a/src/game/SkillDiscovery.cpp b/src/game/SkillDiscovery.cpp index edded6302aa..6758f3db9fd 100644 --- a/src/game/SkillDiscovery.cpp +++ b/src/game/SkillDiscovery.cpp @@ -32,14 +32,14 @@ struct SkillDiscoveryEntry { uint32 spellId; // discavered spell - uint32 reqClass; // class limitation + uint32 reqSkillValue; // skill level limitation float chance; // chance SkillDiscoveryEntry() - : spellId(0), reqClass(0), chance(0) {} + : spellId(0), reqSkillValue(0), chance(0) {} - SkillDiscoveryEntry(uint16 _spellId, uint32 req_class, float _chance) - : spellId(_spellId), reqClass(req_class), chance(_chance) {} + SkillDiscoveryEntry(uint16 _spellId, uint32 req_skill_val, float _chance) + : spellId(_spellId), reqSkillValue(req_skill_val), chance(_chance) {} }; typedef std::list<SkillDiscoveryEntry> SkillDiscoveryList; @@ -54,8 +54,8 @@ void LoadSkillDiscoveryTable() uint32 count = 0; - // 0 1 2 3 - QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqClass, chance FROM skill_discovery_template"); + // 0 1 2 3 + QueryResult *result = WorldDatabase.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template"); if (result) { @@ -70,18 +70,13 @@ void LoadSkillDiscoveryTable() uint32 spellId = fields[0].GetUInt32(); int32 reqSkillOrSpell = fields[1].GetInt32(); - uint32 reqClass = fields[2].GetInt32(); + uint32 reqSkillValue = fields[2].GetInt32(); float chance = fields[3].GetFloat(); if( chance <= 0 ) // chance { - ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(chance problem)\n"; - continue; - } - - if(reqClass && (reqClass >= MAX_CLASSES || ((1 << (reqClass-1)) & CLASSMASK_ALL_PLAYABLE)==0)) - { - ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell << " reqClass = " << reqClass << " chance = " << chance << "(class problem)\n"; + ssNonDiscoverableEntries << "spellId = " << spellId << " reqSkillOrSpell = " << reqSkillOrSpell + << " reqSkillValue = " << reqSkillValue << " chance = " << chance << "(chance problem)\n"; continue; } @@ -103,7 +98,7 @@ void LoadSkillDiscoveryTable() continue; } - SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); + SkillDiscoveryStore[reqSkillOrSpell].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) ); } else if( reqSkillOrSpell == 0 ) // skill case { @@ -118,7 +113,7 @@ void LoadSkillDiscoveryTable() for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) { - SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqClass, chance) ); + SkillDiscoveryStore[-int32(_spell_idx->second->skillId)].push_back( SkillDiscoveryEntry(spellId, reqSkillValue, chance) ); } } else @@ -144,53 +139,57 @@ void LoadSkillDiscoveryTable() } } -uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) +uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player) { - // check spell case + // explicit discovery spell chances (always success if case exist) + // in this case we have both skill and spell SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId); + if(tab == SkillDiscoveryStore.end()) + return 0; - if(tab != SkillDiscoveryStore.end()) - { - SpellEntry const* spellInfo = sSpellStore.LookupEntry (spellId); - if(!spellInfo) - return 0; + SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellId); + SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellId); + uint32 skillvalue = lower != upper ? player->GetSkillValue(lower->second->skillId) : 0; - // explicit discovery spell chances (alwasy success if case exist) - if(IsExplicitDiscoverySpell(spellInfo)) - { - float full_chance = 0; - for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) - if(!item_iter->reqClass || player->getClass ()==item_iter->reqClass) - if(!player->HasSpell(item_iter->spellId)) - full_chance += item_iter->chance; + float full_chance = 0; + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + if(item_iter->reqSkillValue <= skillvalue) + if(!player->HasSpell(item_iter->spellId)) + full_chance += item_iter->chance; - float rate = full_chance / 100.0f; - float roll = rand_chance() * rate; // roll now in range 0..full_chance + float rate = full_chance / 100.0f; + float roll = rand_chance() * rate; // roll now in range 0..full_chance - for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) - { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; + for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) + { + if(item_iter->reqSkillValue > skillvalue) + continue; - if(player->HasSpell(item_iter->spellId)) - continue; + if(player->HasSpell(item_iter->spellId)) + continue; - if(item_iter->chance > roll) - return item_iter->spellId; + if(item_iter->chance > roll) + return item_iter->spellId; - roll -= item_iter->chance; - } + roll -= item_iter->chance; + } - return 0; - } + return 0; +} +uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) +{ + uint32 skillvalue = skillId ? player->GetSkillValue(skillId) : 0; + // check spell case + SkillDiscoveryMap::iterator tab = SkillDiscoveryStore.find(spellId); + + if(tab != SkillDiscoveryStore.end()) + { for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; - if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && item_iter->reqSkillValue <= skillvalue && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; } @@ -207,10 +206,8 @@ uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player) { for(SkillDiscoveryList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter) { - if(item_iter->reqClass && player->getClass ()!= item_iter->reqClass) - continue; - if( roll_chance_f(item_iter->chance * sWorld.getRate(RATE_SKILL_DISCOVERY)) + && item_iter->reqSkillValue <= skillvalue && !player->HasSpell(item_iter->spellId) ) return item_iter->spellId; } diff --git a/src/game/SkillDiscovery.h b/src/game/SkillDiscovery.h index bdd126e0cb3..e64fa826940 100644 --- a/src/game/SkillDiscovery.h +++ b/src/game/SkillDiscovery.h @@ -27,4 +27,5 @@ class Player; void LoadSkillDiscoveryTable(); uint32 GetSkillDiscoverySpell(uint32 skillId, uint32 spellId, Player* player); +uint32 GetExplicitDiscoverySpell(uint32 spellId, Player* player); #endif diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 98abee49b16..80d280eb22a 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -315,7 +315,7 @@ enum AuraType SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, SPELL_AURA_269 = 269, SPELL_AURA_270 = 270, - SPELL_AURA_271 = 271, + SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, SPELL_AURA_272 = 272, SPELL_AURA_273 = 273, SPELL_AURA_274 = 274, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 72bf6d91a03..471dbdfec16 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -325,7 +325,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT &Aura::HandleNULL, //269 ignore DR effects? &Aura::HandleNULL, //270 - &Aura::HandleNULL, //271 increase damage done? + &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus &Aura::HandleNULL, //272 reduce spell cast time? &Aura::HandleNULL, //273 &Aura::HandleNULL, //274 proc free shot? @@ -6446,7 +6446,7 @@ void Aura::PeriodicDummyTick() if (!caster) return; // Skip 0 tick - if (m_duration < m_modifier.periodictime) + if (m_duration > m_modifier.periodictime) return; int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target); damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 22aab9d7ebe..27a51ee8b34 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4749,21 +4749,17 @@ void Spell::EffectScriptEffect(uint32 effIndex) // PX-238 Winter Wondervolt TRAP case 26275: { - if (unitTarget->HasAura(26272,0) || - unitTarget->HasAura(26157,0) || - unitTarget->HasAura(26273,0) || - unitTarget->HasAura(26274,0)) - return; + uint32 spells[4] = { 26272, 26157, 26273, 26274 }; - uint32 iTmpSpellId; - switch(urand(0,3)) - { - case 0: iTmpSpellId = 26272; break; - case 1: iTmpSpellId = 26157; break; - case 2: iTmpSpellId = 26273; break; - case 3: iTmpSpellId = 26274; break; - } + // check presence + for(int j = 0; j < 4; ++j) + if(unitTarget->HasAura(spells[j],0)) + return; + + // select spell + uint32 iTmpSpellId = spells[urand(0,3)]; + // cast unitTarget->CastSpell(unitTarget, iTmpSpellId, true); return; } @@ -4807,16 +4803,16 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 spellid; switch(m_spellInfo->Id) { - case 25140: spellid = 32571; break; - case 25143: spellid = 32572; break; - case 25650: spellid = 30140; break; - case 25652: spellid = 30141; break; - case 29128: spellid = 32568; break; - case 29129: spellid = 32569; break; - case 35376: spellid = 25649; break; - case 35727: spellid = 35730; break; - default: - return; + case 25140: spellid = 32571; break; + case 25143: spellid = 32572; break; + case 25650: spellid = 30140; break; + case 25652: spellid = 30141; break; + case 29128: spellid = 32568; break; + case 29129: spellid = 32569; break; + case 35376: spellid = 25649; break; + case 35727: spellid = 35730; break; + default: + return; } unitTarget->CastSpell(unitTarget,spellid,false); @@ -4981,18 +4977,10 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 spellId; switch(rand()%4) { - case 0: - spellId=46740; - break; - case 1: - spellId=46739; - break; - case 2: - spellId=46738; - break; - case 3: - spellId=46736; - break; + case 0: spellId = 46740; break; + case 1: spellId = 46739; break; + case 2: spellId = 46738; break; + case 3: spellId = 46736; break; } unitTarget->CastSpell(unitTarget, spellId, true); break; @@ -5029,11 +5017,11 @@ void Spell::EffectScriptEffect(uint32 effIndex) case 60893: // Northrend Alchemy Research case 61177: // Northrend Inscription Research case 61288: // Minor Inscription Research - case 61756: // Northrend Inscription Research (FAST QA VERSION) + case 61756: // Northrend Inscription Research (FAST QA VERSION) { if(!IsExplicitDiscoverySpell(m_spellInfo)) { - sLog.outError("Wrong explicit discowry spell %u structure, or outdated...",m_spellInfo->Id); + sLog.outError("Wrong explicit discovery spell %u structure, or outdated...",m_spellInfo->Id); return; } @@ -5043,6 +5031,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) // need replace effect 0 item by loot uint32 reagent_id = m_spellInfo->EffectItemType[0]; + if(!player->HasItemCount(reagent_id,1)) return; @@ -5050,7 +5039,11 @@ void Spell::EffectScriptEffect(uint32 effIndex) uint32 count = 1; player->DestroyItemCount (reagent_id,count,true); - if(uint32 discoveredSpell = GetSkillDiscoverySpell(0, m_spellInfo->Id, player)) + // create some random items + player->AutoStoreLootItem(m_spellInfo->Id,LootTemplates_Spell); + + // learn random explicit discovery recipe (if any) + if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player)) player->learnSpell(discoveredSpell); return; } diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp index fa649e20f6e..c3b9dce4c05 100644 --- a/src/game/TaxiHandler.cpp +++ b/src/game/TaxiHandler.cpp @@ -56,7 +56,7 @@ void WorldSession::SendTaxiStatus( uint64 guid ) return; } - uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam()); // not found nearest if(curloc == 0) @@ -103,7 +103,7 @@ void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data ) void WorldSession::SendTaxiMenu( Creature* unit ) { // find current node - uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam()); if ( curloc == 0 ) return; @@ -136,7 +136,7 @@ void WorldSession::SendDoFlight( uint16 MountId, uint32 path, uint32 pathNode ) bool WorldSession::SendLearnNewTaxiNode( Creature* unit ) { // find current node - uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId()); + uint32 curloc = objmgr.GetNearestTaxiNode(unit->GetPositionX(),unit->GetPositionY(),unit->GetPositionZ(),unit->GetMapId(),GetPlayer( )->GetTeam()); if ( curloc == 0 ) return true; // `true` send to avoid WorldSession::SendTaxiMenu call with one more curlock seartch with same false result. diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 070725090cb..ddfd53657c6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5443,7 +5443,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { triggered_spell_id = 57669; target = this; - return true; + break; } // Lock and Load if ( dummySpell->SpellIconID == 3579 ) @@ -7680,6 +7680,12 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 } } + // From caster spells + AuraList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER); + for(AuraList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i) + if( (*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto)) + TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f; + // Distribute Damage over multiple effects, reduce by AoE CastingTime = GetCastingTimeForBonus( spellProto, damagetype, CastingTime ); @@ -10457,6 +10463,7 @@ bool InitTriggerAuraData() isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE]=true; isTriggerAura[SPELL_AURA_PRAYER_OF_MENDING] = true; isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; + isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true; isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true; isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true; @@ -10712,6 +10719,11 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag if (procSpell==NULL || procSpell->Mechanic != auraModifier->m_miscvalue) continue; break; + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: + // Compare casters + if (triggeredByAura->GetCasterGUID() != pTarget->GetGUID()) + continue; + break; default: // nothing do, just charges counter break; diff --git a/src/game/Weather.cpp b/src/game/Weather.cpp index d825b2f4064..11eedab7593 100644 --- a/src/game/Weather.cpp +++ b/src/game/Weather.cpp @@ -42,7 +42,7 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone } /// Launch a weather update -bool Weather::Update(time_t diff) +bool Weather::Update(uint32 diff) { if (m_timer.GetCurrent()>=0) m_timer.Update(diff); diff --git a/src/game/Weather.h b/src/game/Weather.h index 7fc3068ffe7..8d9585b07d3 100644 --- a/src/game/Weather.h +++ b/src/game/Weather.h @@ -62,7 +62,7 @@ class Weather void SetWeather(WeatherType type, float grade); /// For which zone is this weather? uint32 GetZone() { return m_zone; }; - bool Update(time_t diff); + bool Update(uint32 diff); private: WeatherState GetWeatherState() const; uint32 m_zone; diff --git a/src/game/World.cpp b/src/game/World.cpp index b07be31b66a..1607206cf40 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1504,7 +1504,7 @@ void World::RecordTimeDiff(const char *text, ...) } /// Update the World ! -void World::Update(time_t diff) +void World::Update(uint32 diff) { m_updateTime = uint32(diff); if(m_configs[CONFIG_INTERVAL_LOG_UPDATE]) @@ -2908,7 +2908,7 @@ void World::SendServerMessage(uint32 type, const char *text, Player* player) SendGlobalMessage( &data ); } -void World::UpdateSessions( time_t diff ) +void World::UpdateSessions( uint32 diff ) { ///- Add new sessions while(!addSessQueue.empty()) diff --git a/src/game/World.h b/src/game/World.h index 119f4af63e9..c35529b21f8 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -463,9 +463,9 @@ class World static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; } static bool IsStopped() { return m_stopEvent; } - void Update(time_t diff); + void Update(uint32 diff); - void UpdateSessions( time_t diff ); + void UpdateSessions( uint32 diff ); /// Set a server rate (see #Rates) void setRate(Rates rate,float value) { rate_values[rate]=value; } /// Get a server rate (see #Rates) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c9cdb24bc63..31218cdc9f6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7125" + #define REVISION_NR "7136" #endif // __REVISION_NR_H__ |