diff options
Diffstat (limited to 'src')
35 files changed, 737 insertions, 1266 deletions
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 6f614994489..f05ce5bded9 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -982,7 +982,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) if (!idS) return 0; - uint32 id = (uint32)atol(idS); + uint32 id = atoul(idS); switch (type) { @@ -995,13 +995,10 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) if (!talentEntry) return 0; - int32 rank = param1_str ? (uint32)atol(param1_str) : 0; + uint32 rank = param1_str ? atol(param1_str) : 0u; if (rank >= MAX_TALENT_RANK) return 0; - if (rank < 0) - rank = 0; - return talentEntry->RankID[rank]; } case SPELL_LINK_ENCHANT: @@ -1009,7 +1006,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text) return id; case SPELL_LINK_GLYPH: { - uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0; + uint32 glyph_prop_id = param1_str ? atoul(param1_str) : 0; GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id); if (!glyphPropEntry) @@ -1082,7 +1079,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text) } case SPELL_LINK_CREATURE: { - uint32 lowguid = (uint32)atol(idS); + uint32 lowguid = atoul(idS); if (CreatureData const* data = sObjectMgr->GetCreatureData(lowguid)) return ObjectGuid(HIGHGUID_UNIT, data->id, lowguid); @@ -1091,7 +1088,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text) } case SPELL_LINK_GAMEOBJECT: { - uint32 lowguid = (uint32)atol(idS); + uint32 lowguid = atoul(idS); if (GameObjectData const* data = sObjectMgr->GetGOData(lowguid)) return ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, lowguid); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 094a8345395..f7fa719a610 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -29,6 +29,79 @@ #include "SpellMgr.h" #include "Spell.h" +char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] = +{ + "None", + "Creature Loot", + "Disenchant Loot", + "Fishing Loot", + "GameObject Loot", + "Item Loot", + "Mail Loot", + "Milling Loot", + "Pickpocketing Loot", + "Prospecting Loot", + "Reference Loot", + "Skinning Loot", + "Spell Loot", + "Spell Impl. Target", + "Gossip Menu", + "Gossip Menu Option", + "Creature Vehicle", + "Spell Expl. Target", + "Spell Click Event", + "Quest Accept", + "Quest Show Mark", + "Vehicle Spell", + "SmartScript", + "Npc Vendor", + "Spell Proc", + "Phase Def" +}; + +ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] = +{ + { "None", false, false, false }, + { "Aura", true, true, true }, + { "Item Stored", true, true, true }, + { "Item Equipped", true, false, false }, + { "Zone", true, false, false }, + { "Reputation", true, true, false }, + { "Team", true, false, false }, + { "Skill", true, true, false }, + { "Quest Rewarded", true, false, false }, + { "Quest Taken", true, false, false }, + { "Drunken", true, false, false }, + { "WorldState", true, true, false }, + { "Active Event", true, false, false }, + { "Instance Info", true, true, true }, + { "Quest None", true, false, false }, + { "Class", true, false, false }, + { "Race", true, false, false }, + { "Achievement", true, false, false }, + { "Title", true, false, false }, + { "SpawnMask", true, false, false }, + { "Gender", true, false, false }, + { "Unit State", true, false, false }, + { "Map", true, false, false }, + { "Area", true, false, false }, + { "CreatureType", true, false, false }, + { "Spell Known", true, false, false }, + { "PhaseMask", true, false, false }, + { "Level", true, true, false }, + { "Quest Completed", true, false, false }, + { "Near Creature", true, true, false }, + { "Near GameObject", true, true, false }, + { "Object Entry or Guid", true, true, true }, + { "Object TypeMask", true, false, false }, + { "Relation", true, true, false }, + { "Reaction", true, true, false }, + { "Distance", true, true, true }, + { "Alive", false, false, false }, + { "Health Value", true, true, false }, + { "Health Pct", true, true, false } +}; + // Checks if object meets the condition // Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI) bool Condition::Meets(ConditionSourceInfo& sourceInfo) @@ -38,7 +111,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) // object not present, return false if (!object) { - TC_LOG_DEBUG("condition", "Condition object not found for condition (Entry: %u Type: %u Group: %u)", SourceEntry, SourceType, SourceGroup); + TC_LOG_DEBUG("condition", "Condition object not found for %s", ToString().c_str()); return false; } bool condMeets = false; @@ -535,6 +608,34 @@ uint32 Condition::GetMaxAvailableConditionTargets() } } +std::string Condition::ToString(bool ext /*= false*/) const +{ + std::ostringstream ss; + ss << "[Condition "; + ss << "SourceType: " << SourceType; + if (SourceType < CONDITION_SOURCE_TYPE_MAX) + ss << " (" << ConditionMgr::StaticSourceTypeData[SourceType] << ")"; + else + ss << " (Unknown)"; + if (ConditionMgr::CanHaveSourceGroupSet(SourceType)) + ss << ", SourceGroup: " << SourceGroup; + ss << ", SourceEntry: " << SourceEntry; + if (ConditionMgr::CanHaveSourceIdSet(SourceType)) + ss << ", SourceId: " << SourceId; + + if (ext) + { + ss << ", ConditionType: " << ConditionType; + if (ConditionType < CONDITION_MAX) + ss << " (" << ConditionMgr::StaticConditionTypeData[ConditionType].Name << ")"; + else + ss << " (Unknown)"; + } + + ss << "]"; + return ss.str(); +} + ConditionMgr::ConditionMgr() { } ConditionMgr::~ConditionMgr() @@ -597,7 +698,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, std::map<uint32, bool> ElseGroupStore; for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i) { - TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1); + TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", (*i)->ToString().c_str(), (*i)->ConditionValue1); if ((*i)->isLoaded()) { //! Find ElseGroup in ElseGroupStore @@ -618,8 +719,8 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, } else { - TC_LOG_DEBUG("condition", "IsPlayerMeetToConditionList: Reference template -%u not found", - (*i)->ReferenceId);//checked at loading, should never happen + TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s Reference template -%u not found", + (*i)->ToString().c_str(), (*i)->ReferenceId); // checked at loading, should never happen } } @@ -658,7 +759,7 @@ bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, Con return IsObjectMeetToConditionList(sourceInfo, conditions); } -bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const +bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) { return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE || @@ -681,7 +782,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR); } -bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const +bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) { return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT); } @@ -715,7 +816,7 @@ ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, u if (i != (*itr).second.end()) { cond = (*i).second; - TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId); + TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId); } } return cond; @@ -747,7 +848,7 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32 if (i != (*itr).second.end()) { cond = (*i).second; - TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d event_id %u", entryOrGuid, eventId); + TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid %d eventId %u", entryOrGuid, eventId); } } return cond; @@ -895,26 +996,26 @@ void ConditionMgr::LoadConditions(bool isReload) //Grouping is only allowed for some types (loot templates, gossip menus, gossip items) if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType)) { - TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceGroup = %u!", cond->ToString().c_str(), cond->SourceGroup); delete cond; continue; } if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType)) { - TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId); + TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceId = %u!", cond->ToString().c_str(), cond->SourceId); delete cond; continue; } if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL) { - TC_LOG_ERROR("sql.sql", "Condition type %u entry %i can't have ErrorType (%u), set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorType); + TC_LOG_ERROR("sql.sql", "%s can't have ErrorType (%u), set to 0!", cond->ToString().c_str(), cond->ErrorType); cond->ErrorType = 0; } if (cond->ErrorTextId && !cond->ErrorType) { - TC_LOG_ERROR("sql.sql", "Condition type %u entry %i has any ErrorType, ErrorTextId (%u) is set, set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorTextId); + TC_LOG_ERROR("sql.sql", "%s has any ErrorType, ErrorTextId (%u) is set, set to 0!", cond->ToString().c_str(), cond->ErrorTextId); cond->ErrorTextId = 0; } @@ -1005,7 +1106,7 @@ void ConditionMgr::LoadConditions(bool isReload) if (!valid) { - TC_LOG_ERROR("sql.sql", "Not handled grouped condition, SourceGroup %u", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s Not handled grouped condition.", cond->ToString().c_str()); delete cond; } else @@ -1038,21 +1139,20 @@ void ConditionMgr::LoadConditions(bool isReload) while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); - } bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot) { if (!loot) { - TC_LOG_ERROR("sql.sql", "ConditionMgr: LootTemplate %u not found", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s LootTemplate %u not found.", cond->ToString().c_str(), cond->SourceGroup); return false; } if (loot->addConditionItem(cond)) return true; - TC_LOG_ERROR("sql.sql", "ConditionMgr: Item %u not found in LootTemplate %u", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s Item %u not found in LootTemplate %u.", cond->ToString().c_str(), cond->SourceEntry, cond->SourceGroup); return false; } @@ -1072,7 +1172,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond) } } - TC_LOG_ERROR("sql.sql", "addToGossipMenus: GossipMenu %u not found", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s GossipMenu %u not found.", cond->ToString().c_str(), cond->SourceGroup); return false; } @@ -1091,7 +1191,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond) } } - TC_LOG_ERROR("sql.sql", "addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->SourceGroup, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s GossipMenuId %u Item %u not found.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry); return false; } @@ -1116,12 +1216,12 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) continue; // build new shared mask with found effect - uint32 sharedMask = (1<<i); + uint32 sharedMask = (1 << i); ConditionList* cmp = spellInfo->Effects[i].ImplicitTargetConditions; for (uint8 effIndex = i+1; effIndex < MAX_SPELL_EFFECTS; ++effIndex) { if (spellInfo->Effects[effIndex].ImplicitTargetConditions == cmp) - sharedMask |= 1<<effIndex; + sharedMask |= 1 << effIndex; } sharedMasks.push_back(sharedMask); } @@ -1148,8 +1248,8 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) // we have overlapping masks in db if (conditionEffMask != *itr) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - " - "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - " + "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString().c_str(), cond->SourceGroup); return false; } } @@ -1182,7 +1282,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->SourceType)); + TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str()); return false; } @@ -1192,7 +1292,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Creature.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1200,7 +1300,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1209,7 +1309,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Disenchant.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1217,7 +1317,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1226,7 +1326,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Fishing.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1234,7 +1334,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1243,7 +1343,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Gameobject.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1251,7 +1351,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1260,7 +1360,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Item.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1268,7 +1368,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1277,7 +1377,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Mail.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1285,7 +1385,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1294,7 +1394,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Milling.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1302,7 +1402,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1311,7 +1411,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Pickpocketing.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1319,7 +1419,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1328,7 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Prospecting.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1336,7 +1436,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1345,7 +1445,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Reference.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1353,7 +1453,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1362,7 +1462,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Skinning.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1370,7 +1470,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1379,7 +1479,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!LootTemplates_Spell.HaveLootFor(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->ToString().c_str()); return false; } @@ -1387,7 +1487,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!pItemProto && !loot->isReference(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1397,13 +1497,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry); if (!spellInfo) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, SourceEntry does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set, ignoring.", cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup (spell effectMask) set, ignoring.", cond->ToString().c_str()); return false; } @@ -1411,7 +1511,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (!((1<<i) & cond->SourceGroup)) + if (!((1 << i) & cond->SourceGroup)) continue; switch (spellInfo->Effects[i].TargetA.GetSelectionCategory()) @@ -1435,7 +1535,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) } TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i)); - cond->SourceGroup &= ~(1<<i); + cond->SourceGroup &= ~(1 << i); } // all effects were removed, no need to add the condition at all if (!cond->SourceGroup) @@ -1446,7 +1546,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1457,48 +1557,42 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry); if (!spellProto) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; } case CONDITION_SOURCE_TYPE_QUEST_ACCEPT: - if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry)) - { - TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->SourceEntry); - return false; - } - break; case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK: if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry specifies non-existing quest, skipped.", cond->ToString().c_str()); return false; } break; case CONDITION_SOURCE_TYPE_VEHICLE_SPELL: if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } if (!sSpellMgr->GetSpellInfo(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT: if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } if (!sSpellMgr->GetSpellInfo(cond->SourceEntry)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1506,13 +1600,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) { if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup)) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str()); return false; } ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry); if (!itemTemplate) { - TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str()); return false; } break; @@ -1537,13 +1631,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX) { - TC_LOG_ERROR("sql.sql", "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->ConditionType), cond->SourceEntry); + TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str()); return false; } if (cond->ConditionTarget >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup); + TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->ToString(true).c_str()); return false; } @@ -1553,17 +1647,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Aura condition has non existing spell (Id: %d), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 > EFFECT_2) { - TC_LOG_ERROR("sql.sql", "Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing effect index (%u) (must be 0..2), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Aura condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ITEM: @@ -1571,13 +1663,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1); if (!proto) { - TC_LOG_ERROR("sql.sql", "Item condition has non existing item (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (!cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "Item condition has 0 set for item count in value2 (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s Zero item count in ConditionValue2, skipped.", cond->ToString(true).c_str()); return false; } break; @@ -1587,14 +1679,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1); if (!proto) { - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has non existing item (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ZONEID: @@ -1602,20 +1689,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1); if (!areaEntry) { - TC_LOG_ERROR("sql.sql", "ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s Area (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (areaEntry->zone != 0) { - TC_LOG_ERROR("sql.sql", "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s requires to be in area (%u) which is a subzone but zone expected, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_REPUTATION_RANK: @@ -1623,25 +1705,18 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1); if (!factionEntry) { - TC_LOG_ERROR("sql.sql", "Reputation condition has non existing faction (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing faction (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Reputation condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TEAM: { if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE) { - TC_LOG_ERROR("sql.sql", "Team condition specifies unknown team (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s specifies unknown team (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Team condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Team condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_SKILL: @@ -1649,17 +1724,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1); if (!pSkill) { - TC_LOG_ERROR("sql.sql", "Skill condition specifies non-existing skill (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s specifies non-existing skill (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue()) { - TC_LOG_ERROR("sql.sql", "Skill condition specifies skill (%u) with invalid value (%u), skipped", cond->ConditionValue1, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s specifies skill (%u) with invalid value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1, cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Skill condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_QUESTREWARDED: @@ -1669,30 +1742,19 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Quest condition (Type: %u) points to non-existing quest (%u) for Source Entry %u. SourceGroup: %u, SourceTypeOrReferenceId: %u", - cond->ConditionType, cond->ConditionValue1, cond->SourceEntry, cond->SourceGroup, cond->SourceType); + TC_LOG_ERROR("sql.sql", "%s points to non-existing quest (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2 > 1) - TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ACTIVE_EVENT: { GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap(); - if (cond->ConditionValue1 >=events.size() || !events[cond->ConditionValue1].isValid()) + if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid()) { - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has non existing event id (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing event id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_ACHIEVEMENT: @@ -1700,56 +1762,36 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1); if (!achievement) { - TC_LOG_ERROR("sql.sql", "Achivement condition has non existing achivement id (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing achivement id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_CLASS: { if (!(cond->ConditionValue1 & CLASSMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Class condition has non existing classmask (%u), skipped", cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE); + TC_LOG_ERROR("sql.sql", "%s has non existing classmask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Class condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Class condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_RACE: { if (!(cond->ConditionValue1 & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Race condition has non existing racemask (%u), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE); + TC_LOG_ERROR("sql.sql", "%s has non existing racemask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Race condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Race condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_GENDER: { if (!Player::IsValidGender(uint8(cond->ConditionValue1))) { - TC_LOG_ERROR("sql.sql", "Gender condition has invalid gender (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid gender (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_MAPID: @@ -1757,77 +1799,54 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1); if (!me) { - TC_LOG_ERROR("sql.sql", "Map condition has non existing map (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing map (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Map condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Map condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_SPELL: { if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "Spell condition has non existing spell (Id: %d), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value2 (%u)!", cond->ConditionValue1, cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value3 (%u)!", cond->ConditionValue1, cond->ConditionValue3); break; } case CONDITION_LEVEL: { if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "Level condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Level condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_DRUNKENSTATE: { if (cond->ConditionValue1 > DRUNKEN_SMASHED) { - TC_LOG_ERROR("sql.sql", "DrunkState condition has invalid state (%u), skipped", cond->ConditionValue1); - return false; - } - if (cond->ConditionValue2) - { - TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value2 (%u)!", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid state (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_NEAR_CREATURE: { if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "NearCreature condition has non existing creature template entry (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "NearCreature condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_NEAR_GAMEOBJECT: { if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "NearGameObject condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString().c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_OBJECT_ENTRY_GUID: @@ -1837,7 +1856,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_UNIT: if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) @@ -1846,13 +1865,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match creature entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2); return false; } } else { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature guid (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has non existing creature guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } } @@ -1860,7 +1879,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_GAMEOBJECT: if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2)) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) @@ -1869,13 +1888,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue2 && goData->id != cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match gameobject entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match gameobject entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2); return false; } } else { - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject guid (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has non existing gameobject guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } } @@ -1883,12 +1902,12 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) case TYPEID_PLAYER: case TYPEID_CORPSE: if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value2 (%u)!", cond->ConditionValue2); + LogUselessConditionValue(cond, 2, cond->ConditionValue2); if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value3 (%u)!", cond->ConditionValue3); + LogUselessConditionValue(cond, 3, cond->ConditionValue3); break; default: - TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has wrong typeid set (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has wrong typeid set (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -1897,51 +1916,45 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!cond->ConditionValue1 || (cond->ConditionValue1 & ~(TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE))) { - TC_LOG_ERROR("sql.sql", "TypeMask condition has invalid typemask set (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid typemask set (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_RELATION_TO: { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 >= RELATION_MAX) { - TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(RelationType) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "RelationTo condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_REACTION_TO: { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (!cond->ConditionValue2) { - TC_LOG_ERROR("sql.sql", "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(rankMask) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } break; @@ -1950,78 +1963,55 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets()) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue1 == cond->ConditionTarget) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue3 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ComparisionType (%u), skipped", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3); return false; } break; } - case CONDITION_ALIVE: - { - if (cond->ConditionValue1) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value1 (%u)!", cond->ConditionValue1); - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value3 (%u)!", cond->ConditionValue3); - break; - } case CONDITION_HP_VAL: { if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "HpVal condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "HpVal condition has useless data in value3 (%u)!", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has useless data in value3 (%u)!", cond->ToString(true).c_str(), cond->ConditionValue3); break; } case CONDITION_HP_PCT: { if (cond->ConditionValue1 > 100) { - TC_LOG_ERROR("sql.sql", "HpPct condition has too big percent value (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has too big percent value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } if (cond->ConditionValue2 >= COMP_TYPE_MAX) { - TC_LOG_ERROR("sql.sql", "HpPct condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2); return false; } if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "HpPct condition has useless data in value3 (%u)!", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "%s has useless data in value3 (%u)!", cond->ToString().c_str(), cond->ConditionValue3); break; } - case CONDITION_AREAID: - case CONDITION_INSTANCE_INFO: - break; case CONDITION_WORLD_STATE: { if (!sWorld->getWorldState(cond->ConditionValue1)) { - TC_LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing world state in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3); - break; - } - case CONDITION_PHASEMASK: - { - if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value2 (%u)!", cond->ConditionValue2); - if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TITLE: @@ -2029,7 +2019,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1); if (!titleEntry) { - TC_LOG_ERROR("sql.sql", "Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing title in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2038,7 +2028,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (cond->ConditionValue1 > SPAWNMASK_RAID_ALL) { - TC_LOG_ERROR("sql.sql", "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing SpawnMask in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2047,7 +2037,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!(cond->ConditionValue1 & UNIT_STATE_ALL_STATE_SUPPORTED)) { - TC_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing UnitState in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; @@ -2056,17 +2046,35 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (!cond->ConditionValue1 || cond->ConditionValue1 > CREATURE_TYPE_GAS_CLOUD) { - TC_LOG_ERROR("sql.sql", "CreatureType condition has non existing CreatureType in value1 (%u), skipped", cond->ConditionValue1); + TC_LOG_ERROR("sql.sql", "%s has non existing CreatureType in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); return false; } break; } + case CONDITION_INSTANCE_INFO: + case CONDITION_AREAID: + case CONDITION_PHASEMASK: + case CONDITION_ALIVE: + break; default: break; } + + if (cond->ConditionValue1 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue1) + LogUselessConditionValue(cond, 1, cond->ConditionValue1); + if (cond->ConditionValue2 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue2) + LogUselessConditionValue(cond, 2, cond->ConditionValue2); + if (cond->ConditionValue3 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue3) + LogUselessConditionValue(cond, 3, cond->ConditionValue3); + return true; } +void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32 value) +{ + TC_LOG_ERROR("sql.sql", "%s has useless data in ConditionValue%u (%u)!", cond->ToString(true).c_str(), index, value); +} + void ConditionMgr::Clean() { for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr) diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 24e44c662ba..621da355b7b 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -210,6 +210,8 @@ struct Condition uint32 GetSearcherTypeMaskForCondition(); bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; } uint32 GetMaxAvailableConditionTargets(); + + std::string ToString(bool ext = false) const; /// For logging purpose }; typedef std::list<Condition*> ConditionList; @@ -228,7 +230,6 @@ class ConditionMgr ~ConditionMgr(); public: - static ConditionMgr* instance() { static ConditionMgr instance; @@ -243,14 +244,24 @@ class ConditionMgr bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions); bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions); bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); - bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const; - bool CanHaveSourceIdSet(ConditionSourceType sourceType) const; + static bool CanHaveSourceGroupSet(ConditionSourceType sourceType); + static bool CanHaveSourceIdSet(ConditionSourceType sourceType); ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry); ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType); ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId); + struct ConditionTypeInfo + { + char const* Name; + bool HasConditionValue1; + bool HasConditionValue2; + bool HasConditionValue3; + }; + static char const* StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX]; + static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX]; + private: bool isSourceTypeValid(Condition* cond); bool addToLootTemplate(Condition* cond, LootTemplate* loot); @@ -259,6 +270,8 @@ class ConditionMgr bool addToSpellImplicitTargetConditions(Condition* cond); bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); + static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value); + void Clean(); // free up resources std::list<Condition*> AllocatedMemoryStore; // some garbage collection :) diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 4ffddde021c..6702815870f 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -607,7 +607,7 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin for (uint32 index = 0; index < count; ++index) { - m_uint32Values[startOffset + index] = atol(tokens[index]); + m_uint32Values[startOffset + index] = atoul(tokens[index]); _changesMask.SetBit(startOffset + index); } } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 048b2f8e9bb..04e6cb000f8 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -203,7 +203,7 @@ void PlayerTaxi::LoadTaxiMask(std::string const &data) for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index) { // load and set bits only for existing taxi nodes - m_taximask[index] = sTaxiNodesMask[index] & uint32(atol(*iter)); + m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter); } } @@ -229,7 +229,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint3 for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter) { - uint32 node = uint32(atol(*iter)); + uint32 node = atoul(*iter); AddTaxiDestination(node); } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 9a4b7a347c8..beac32b0145 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13852,7 +13852,7 @@ void CharmInfo::LoadPetActionBar(const std::string& data) // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion ActiveStates type = ActiveStates(atol(*iter)); ++iter; - uint32 action = uint32(atol(*iter)); + uint32 action = atoul(*iter); PetActionBar[index].SetActionAndType(action, type); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9e31e901189..8dc117b3362 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -556,17 +556,17 @@ void ObjectMgr::LoadCreatureTemplateAddons() creatureAddon.auras.resize(tokens.size()); for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) { - SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr))); + SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr)); if (!AdditionalSpellInfo) { - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr)); continue; } if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)) - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr)); - creatureAddon.auras[i++] = uint32(atol(*itr)); + creatureAddon.auras[i++] = atoul(*itr); } if (creatureAddon.mount) @@ -1004,17 +1004,17 @@ void ObjectMgr::LoadCreatureAddons() creatureAddon.auras.resize(tokens.size()); for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr) { - SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr))); + SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr)); if (!AdditionalSpellInfo) { - TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has wrong spell %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr)); continue; } if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE)) - TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr))); + TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr)); - creatureAddon.auras[i++] = uint32(atol(*itr)); + creatureAddon.auras[i++] = atoul(*itr); } if (creatureAddon.mount) @@ -5673,35 +5673,32 @@ void ObjectMgr::LoadAreaTriggerScripts() uint32 oldMSTime = getMSTime(); _areaTriggerScriptStore.clear(); // need for reload case - QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts"); + QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts"); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty."); return; } - uint32 count = 0; - do { - ++count; - Field* fields = result->Fetch(); - uint32 Trigger_ID = fields[0].GetUInt32(); - const char *scriptName = fields[1].GetCString(); + uint32 triggerId = fields[0].GetUInt32(); + char const* scriptName = fields[1].GetCString(); - AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); + AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(triggerId); if (!atEntry) { - TC_LOG_ERROR("sql.sql", "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.", Trigger_ID); + TC_LOG_ERROR("sql.sql", "AreaTrigger (ID: %u) does not exist in `AreaTrigger.dbc`.", triggerId); continue; } - _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName); - } while (result->NextRow()); + _areaTriggerScriptStore[triggerId] = GetScriptId(scriptName); + } + while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u areatrigger scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " areatrigger scripts in %u ms", _areaTriggerScriptStore.size(), GetMSTimeDiffToNow(oldMSTime)); } uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 team) @@ -8544,31 +8541,32 @@ void ObjectMgr::LoadScriptNames() { uint32 oldMSTime = getMSTime(); - _scriptNamesStore.push_back(""); + _scriptNamesStore.emplace_back(""); + QueryResult result = WorldDatabase.Query( - "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 " - "UNION " - "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' " - "UNION " - "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''"); + "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 " + "UNION " + "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''"); if (!result) { @@ -8576,20 +8574,23 @@ void ObjectMgr::LoadScriptNames() return; } - uint32 count = 1; - do { - _scriptNamesStore.push_back((*result)[0].GetString()); - ++count; + _scriptNamesStore.emplace_back((*result)[0].GetCString()); } while (result->NextRow()); std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end()); - TC_LOG_INFO("server.loading", ">> Loaded %d Script Names in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); + +#ifdef SCRIPTS + for (size_t i = 1; i < _scriptNamesStore.size(); ++i) + UnusedScriptNames.push_back(_scriptNamesStore[i]); +#endif + + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " ScriptNames in %u ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime)); } -uint32 ObjectMgr::GetScriptId(const char *name) +uint32 ObjectMgr::GetScriptId(char const* name) { // use binary search to find the script name in the sorted vector // assume "" is the first element diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 62303143202..7504f03868e 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -1253,9 +1253,8 @@ class ObjectMgr bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const; void LoadScriptNames(); - ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; } - const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; } - uint32 GetScriptId(const char *name); + char const* GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; } + uint32 GetScriptId(char const* name); SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const { diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 18cd5d5bd06..7e218b601e0 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -2004,7 +2004,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } for (uint32 index = 0; index < ktcount; ++index) - knownTitles[index] = atol(tokens[index]); + knownTitles[index] = atoul(tokens[index]); for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it) { diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 88ee153423f..77d3d3ffe0b 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -128,7 +128,7 @@ void InstanceScript::LoadObjectData(ObjectData const* creatureData, ObjectData c if (gameObjectData) LoadObjectData(gameObjectData, _gameObjectInfo); - TC_LOG_ERROR("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size()); + TC_LOG_DEBUG("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size()); } void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objectInfo) diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index be0bf1aa067..d1ebcba118d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -34,6 +34,12 @@ #include "WorldPacket.h" #include "WorldSession.h" +// namespace +// { + UnusedScriptContainer UnusedScripts; + UnusedScriptNamesContainer UnusedScriptNames; +// } + // This is the global static registry of scripts. template<class TScript> class ScriptRegistry @@ -89,6 +95,12 @@ class ScriptRegistry { ScriptPointerList[id] = script; sScriptMgr->IncrementScriptCount(); + + #ifdef SCRIPTS + UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName()); + if (itr != UnusedScriptNames.end() && *itr == script->GetName()) + UnusedScriptNames.erase(itr); + #endif } else { @@ -106,8 +118,7 @@ class ScriptRegistry // Avoid calling "delete script;" because we are currently in the script constructor // In a valid scenario this will not happen because every script has a name assigned in the database - // If that happens, it's acceptable to just leak a few bytes - + UnusedScripts.push_back(script); return; } } @@ -189,6 +200,15 @@ void ScriptMgr::Initialize() FillSpellSummary(); AddScripts(); +#ifdef SCRIPTS + for (std::string const& scriptName : UnusedScriptNames) + { + TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, but no core script found!", scriptName.c_str()); + } +#endif + + UnloadUnusedScripts(); + TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime)); } @@ -229,10 +249,19 @@ void ScriptMgr::Unload() #undef SCR_CLEAR + UnloadUnusedScripts(); + delete[] SpellSummary; delete[] UnitAI::AISpellInfo; } +void ScriptMgr::UnloadUnusedScripts() +{ + for (size_t i = 0; i < UnusedScripts.size(); ++i) + delete UnusedScripts[i]; + UnusedScripts.clear(); +} + void ScriptMgr::LoadDatabase() { sScriptSystemMgr->LoadScriptWaypoints(); diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index f6e76763f95..6a4e2f9910a 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -873,6 +873,15 @@ class GroupScript : public ScriptObject // Placed here due to ScriptRegistry::AddScript dependency. #define sScriptMgr ScriptMgr::instance() +// namespace +// { + typedef std::vector<ScriptObject*> UnusedScriptContainer; + typedef std::list<std::string> UnusedScriptNamesContainer; + + extern UnusedScriptContainer UnusedScripts; + extern UnusedScriptNamesContainer UnusedScriptNames; +// } + // Manages registration, loading, and execution of scripts. class ScriptMgr { @@ -901,6 +910,7 @@ class ScriptMgr public: /* Unloading */ void Unload(); + void UnloadUnusedScripts(); public: /* SpellScriptLoader */ diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 69297d32105..609617f0478 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -284,11 +284,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { - if (!AntiDOS.EvaluateOpcode(*packet, currentTime)) - { - KickPlayer(); - } - else if (packet->GetOpcode() >= NUM_MSG_TYPES) + if (packet->GetOpcode() >= NUM_MSG_TYPES) { TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerInfo().c_str()); @@ -320,7 +316,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); } } - else if (_player->IsInWorld()) + else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime)) { sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle.handler)(*packet); @@ -332,7 +328,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); - else + else if (AntiDOS.EvaluateOpcode(*packet, currentTime)) { // not expected _player or must checked in packet handler sScriptMgr->OnPacketReceive(this, *packet); @@ -345,7 +341,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); - else + else if(AntiDOS.EvaluateOpcode(*packet, currentTime)) { sScriptMgr->OnPacketReceive(this, *packet); (this->*opHandle.handler)(*packet); @@ -365,9 +361,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; - sScriptMgr->OnPacketReceive(this, *packet); - (this->*opHandle.handler)(*packet); - LogUnprocessedTail(packet); + if (AntiDOS.EvaluateOpcode(*packet, currentTime)) + { + sScriptMgr->OnPacketReceive(this, *packet); + (this->*opHandle.handler)(*packet); + LogUnprocessedTail(packet); + } break; case STATUS_NEVER: TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() @@ -1262,8 +1261,11 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co case POLICY_LOG: return true; case POLICY_KICK: + { TC_LOG_INFO("network", "AntiDOS: Player kicked!"); + Session->KickPlayer(); return false; + } case POLICY_BAN: { BanMode bm = (BanMode)sWorld->getIntConfig(CONFIG_PACKET_SPOOF_BANMODE); @@ -1277,7 +1279,7 @@ bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) co } sWorld->BanAccount(bm, nameOrIp, duration, "DOS (Packet Flooding/Spoofing", "Server: AutoDOS"); TC_LOG_INFO("network", "AntiDOS: Player automatically banned for %u seconds.", duration); - + Session->KickPlayer(); return false; } default: // invalid policy diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 584331ad393..136f8aab22c 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -527,10 +527,10 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (!changenth(line, 2, chraccount)) // characters.account update ROLLBACK(DUMP_FILE_BROKEN); - race = uint8(atol(getnth(line, 4).c_str())); - playerClass = uint8(atol(getnth(line, 5).c_str())); - gender = uint8(atol(getnth(line, 6).c_str())); - level = uint8(atol(getnth(line, 7).c_str())); + race = uint8(atoul(getnth(line, 4).c_str())); + playerClass = uint8(atoul(getnth(line, 5).c_str())); + gender = uint8(atoul(getnth(line, 6).c_str())); + level = uint8(atoul(getnth(line, 7).c_str())); if (name.empty()) { // check if the original name already exists diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index d3d012e70d5..2eebc9cae10 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -488,7 +488,7 @@ public: static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler* handler, char const* args) { - uint32 msg = atol((char*)args); + uint32 msg = atoul(args); handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetSession()->GetPlayer(), msg); return true; } @@ -507,7 +507,7 @@ public: static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler* handler, char const* args) { - QuestFailedReason msg = static_cast<QuestFailedReason>(atol((char*)args)); + QuestFailedReason msg = static_cast<QuestFailedReason>(atoul(args)); handler->GetSession()->GetPlayer()->SendCanTakeQuestResponse(msg); return true; } diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index f3ddc6f0137..c0bf2a6bb84 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -118,7 +118,7 @@ public: if (!id) return false; - uint32 objectId = atol(id); + uint32 objectId = atoul(id); if (!objectId) return false; @@ -238,7 +238,7 @@ public: if (!id) return false; - uint32 objectId = atol(id); + uint32 objectId = atoul(id); if (objectId) result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index a558d977b85..06967c69888 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -269,7 +269,7 @@ public: const char* onlineState = ""; // Parse the guid to uint32... - ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args))); + ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args))); // ... and try to extract a player out of it. if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp index 0f21200c22d..b57629a577e 100644 --- a/src/server/scripts/Commands/cs_list.cpp +++ b/src/server/scripts/Commands/cs_list.cpp @@ -65,7 +65,7 @@ public: if (!id) return false; - uint32 creatureId = atol(id); + uint32 creatureId = atoul(id); if (!creatureId) { handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId); @@ -82,7 +82,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; @@ -133,11 +133,11 @@ public: if (!*args) return false; - char* id = handler->extractKeyFromLink((char*)args, "Hitem"); + char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); if (!id) return false; - uint32 itemId = atol(id); + uint32 itemId = atoul(id); if (!itemId) { handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); @@ -154,7 +154,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; @@ -354,7 +354,7 @@ public: if (!id) return false; - uint32 gameObjectId = atol(id); + uint32 gameObjectId = atoul(id); if (!gameObjectId) { handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId); @@ -371,7 +371,7 @@ public: } char* countStr = strtok(NULL, " "); - uint32 count = countStr ? atol(countStr) : 10; + uint32 count = countStr ? atoul(countStr) : 10; if (count == 0) return false; @@ -476,7 +476,7 @@ public: if (!*args) return false; - ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args))); + ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args))); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) { diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index a853a02bb11..2f2891b42ab 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1134,7 +1134,7 @@ public: char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); if (!id) return false; - itemId = uint32(atol(id)); + itemId = atoul(id); } char const* ccount = strtok(NULL, " "); @@ -1216,7 +1216,7 @@ public: if (!id) return false; - uint32 itemSetId = atol(id); + uint32 itemSetId = atoul(id); // prevent generation all items with itemset field value '0' if (itemSetId == 0) @@ -1357,7 +1357,7 @@ public: return false; } - int32 level = uint32(atol(levelStr)); + int32 level = atol(levelStr); Player* target = handler->getSelectedPlayer(); if (!target) @@ -1379,7 +1379,7 @@ public: // If our target does not yet have the skill they are trying to add to them, the chosen level also becomes // the max level of the new profession. - uint16 max = maxPureSkill ? atol (maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); + uint16 max = maxPureSkill ? atoul(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level); if (level <= 0 || level > max || max <= 0) return false; @@ -1419,7 +1419,7 @@ public: PreparedStatement* stmt = NULL; // To make sure we get a target, we convert our guid to an omniversal... - ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atol((char*)args))); + ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args))); // ... and make sure we get a target, somehow. if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) @@ -1780,7 +1780,7 @@ public: uint32 totalmail = uint32(fields[1].GetUInt64()); // ... we have to convert it from Char to int. We can use totalmail as it is - rmailint = atol(readmail.c_str()); + rmailint = atoul(readmail.c_str()); // Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given if (totalmail >= 1) diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 987c12debb7..1434493e948 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -326,15 +326,15 @@ public: char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 uint32 maxcount = 0; if (fmaxcount) - maxcount = atol(fmaxcount); + maxcount = atoul(fmaxcount); char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0 uint32 incrtime = 0; if (fincrtime) - incrtime = atol(fincrtime); + incrtime = atoul(fincrtime); char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 - uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; + uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0; Creature* vendor = handler->getSelectedCreature(); if (!vendor) { @@ -564,7 +564,7 @@ public: handler->SetSentErrorMessage(true); return false; } - uint32 itemId = atol(pitem); + uint32 itemId = atoul(pitem); if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId)) { @@ -1321,7 +1321,7 @@ public: return false; } - ObjectGuid receiver_guid(HIGHGUID_PLAYER, uint32(atol(receiver_str))); + ObjectGuid receiver_guid(HIGHGUID_PLAYER, uint32(atoul(receiver_str))); // check online security Player* receiver = ObjectAccessor::FindPlayer(receiver_guid); diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp index fb486128049..9f7098b9134 100644 --- a/src/server/scripts/Commands/cs_quest.cpp +++ b/src/server/scripts/Commands/cs_quest.cpp @@ -67,7 +67,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -112,7 +112,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -165,7 +165,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); @@ -269,7 +269,7 @@ public: if (!cId) return false; - uint32 entry = atol(cId); + uint32 entry = atoul(cId); Quest const* quest = sObjectMgr->GetQuestTemplate(entry); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp index 58f38ec4267..860cc609c7b 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp @@ -225,7 +225,7 @@ class boss_ragnaros : public CreatureScript events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, urand(10000, 14000)); break; case EVENT_MAGMA_BLAST: - if (me->IsWithinMeleeRange(me->GetVictim())) + if (!me->IsWithinMeleeRange(me->GetVictim())) { DoCastVictim(SPELL_MAGMA_BLAST); if (!_hasYelledMagmaBurst) diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index 992b20d2580..a0ff40c8a3c 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -66,12 +66,32 @@ enum Spells SPELL_FEAR = 31970, }; +enum Events +{ + EVENT_DRAIN_NORDRASSIL = 1, + EVENT_HAND_OF_DEATH, // Raid wiper + EVENT_UNLEASH_SOUL_CHARGE, + EVENT_FINGER_OF_DEATH, + EVENT_GRIP_OF_THE_LEGION, + EVENT_FEAR, + EVENT_AIR_BURST, + EVENT_DOOMFIRE, + EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage + EVENT_SUMMON_WHISP +}; + enum Summons { - CREATURE_DOOMFIRE = 18095, - CREATURE_DOOMFIRE_SPIRIT = 18104, - CREATURE_ANCIENT_WISP = 17946, - CREATURE_CHANNEL_TARGET = 22418, + NPC_DOOMFIRE = 18095, + NPC_DOOMFIRE_SPIRIT = 18104, + NPC_ANCIENT_WISP = 17946, + NPC_CHANNEL_TARGET = 22418 +}; + +enum Actions +{ + ACTION_ENRAGE, + ACTION_CHANNEL_WORLD_TREE }; Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f}; @@ -249,409 +269,288 @@ class boss_archimonde : public CreatureScript public: boss_archimonde() : CreatureScript("boss_archimonde") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_archimondeAI>(creature); - } - - struct boss_archimondeAI : public hyjal_trashAI + struct boss_archimondeAI : public BossAI { - boss_archimondeAI(Creature* creature) : hyjal_trashAI(creature) + boss_archimondeAI(Creature* creature) : BossAI(creature, DATA_ARCHIMONDE) { Initialize(); - instance = creature->GetInstanceScript(); } void Initialize() { DoomfireSpiritGUID.Clear(); - damageTaken = 0; WorldTreeGUID.Clear(); - DrainNordrassilTimer = 0; - FearTimer = 42000; - AirBurstTimer = 30000; - GripOfTheLegionTimer = urand(5000, 25000); - DoomfireTimer = 20000; - SoulChargeTimer = urand(2000, 30000); SoulChargeCount = 0; - MeleeRangeCheckTimer = 15000; - HandOfDeathTimer = 2000; - WispCount = 0; // When ~30 wisps are summoned, Archimonde dies - EnrageTimer = 600000; // 10 minutes - CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage - SummonWispTimer = 0; + WispCount = 0; // When ~30 wisps are summoned, Archimonde dies + _unleashSpell = 0; + _chargeSpell = 0; Enraged = false; - BelowTenPercent = false; HasProtected = false; - IsChanneling = false; } - InstanceScript* instance; - - ObjectGuid DoomfireSpiritGUID; - ObjectGuid WorldTreeGUID; - - uint32 DrainNordrassilTimer; - uint32 FearTimer; - uint32 AirBurstTimer; - uint32 GripOfTheLegionTimer; - uint32 DoomfireTimer; - uint32 SoulChargeTimer; - uint8 SoulChargeCount; - uint32 MeleeRangeCheckTimer; - uint32 HandOfDeathTimer; - uint32 SummonWispTimer; - uint8 WispCount; - uint32 EnrageTimer; - uint32 CheckDistanceTimer; - - bool Enraged; - bool BelowTenPercent; - bool HasProtected; - bool IsChanneling; - void Reset() override { - instance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED); - Initialize(); + _Reset(); + me->RemoveAllAuras(); // Reset Soul Charge auras. + if (!me->isMoving()) + DoAction(ACTION_CHANNEL_WORLD_TREE); } void EnterCombat(Unit* /*who*/) override { - me->InterruptSpell(CURRENT_CHANNELED_SPELL); Talk(SAY_AGGRO); - DoZoneInCombat(); - - instance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS); - } - - void KilledUnit(Unit* victim) override - { - Talk(SAY_SLAY); - - if (victim && victim->GetTypeId() == TYPEID_PLAYER) - GainSoulCharge(victim->ToPlayer()); + _EnterCombat(); + events.ScheduleEvent(EVENT_FEAR, 42000); + events.ScheduleEvent(EVENT_AIR_BURST, 30000); + events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000)); + events.ScheduleEvent(EVENT_DOOMFIRE, 20000); + events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000)); + events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 15000); + events.ScheduleEvent(EVENT_HAND_OF_DEATH, 600000); + events.ScheduleEvent(EVENT_DISTANCE_CHECK, 30000); } - void GainSoulCharge(Player* victim) + void ExecuteEvent(uint32 eventId) override { - switch (victim->getClass()) + switch (eventId) { - case CLASS_PRIEST: - case CLASS_PALADIN: - case CLASS_WARLOCK: - victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true); + case EVENT_DRAIN_NORDRASSIL: + if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID)) + Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); + events.ScheduleEvent(EVENT_DRAIN_NORDRASSIL, 1000); break; - case CLASS_MAGE: - case CLASS_ROGUE: - case CLASS_WARRIOR: - victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true); + case EVENT_HAND_OF_DEATH: + DoCastAOE(SPELL_HAND_OF_DEATH); + events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000); break; - case CLASS_DRUID: - case CLASS_SHAMAN: - case CLASS_HUNTER: - victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true); + case EVENT_UNLEASH_SOUL_CHARGE: + _chargeSpell = 0; + _unleashSpell = 0; + me->InterruptNonMeleeSpells(false); + switch (urand(0, 2)) + { + case 0: + _chargeSpell = SPELL_SOUL_CHARGE_RED; + _unleashSpell = SPELL_UNLEASH_SOUL_RED; + break; + case 1: + _chargeSpell = SPELL_SOUL_CHARGE_YELLOW; + _unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; + break; + case 2: + _chargeSpell = SPELL_SOUL_CHARGE_GREEN; + _unleashSpell = SPELL_UNLEASH_SOUL_GREEN; + break; + } + + if (me->HasAura(_chargeSpell)) + { + me->RemoveAuraFromStack(_chargeSpell); + DoCastVictim(_unleashSpell); + SoulChargeCount--; + events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000)); + } + break; + case EVENT_FINGER_OF_DEATH: + if (!SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f)) // Checks if there are no targets in melee range + { + DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); + events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 1000); + } + else + events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 5000); + break; + case EVENT_GRIP_OF_THE_LEGION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_GRIP_OF_THE_LEGION); + events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000)); + break; + case EVENT_AIR_BURST: + Talk(SAY_AIR_BURST); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_AIR_BURST); //not on tank + events.ScheduleEvent(EVENT_AIR_BURST, urand(25000, 40000)); + break; + case EVENT_FEAR: + DoCastAOE(SPELL_FEAR); + events.ScheduleEvent(EVENT_FEAR, 42000); + break; + case EVENT_DOOMFIRE: + Talk(SAY_DOOMFIRE); + if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1)) + SummonDoomfire(temp); + else + SummonDoomfire(me->GetVictim()); + events.ScheduleEvent(EVENT_DOOMFIRE, 20000); + break; + case EVENT_DISTANCE_CHECK: + if (Creature* channelTrigger = ObjectAccessor::GetCreature(*me, WorldTreeGUID)) + if (me->IsWithinDistInMap(channelTrigger, 75.0f)) + DoAction(ACTION_ENRAGE); + events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000); + break; + case EVENT_SUMMON_WHISP: + DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + ++WispCount; + if (WispCount >= 30) + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500); + break; + default: break; } - - SoulChargeTimer = urand(2000, 30000); - ++SoulChargeCount; - } - - void JustDied(Unit* killer) override - { - hyjal_trashAI::JustDied(killer); - Talk(SAY_DEATH); - - instance->SetData(DATA_ARCHIMONDEEVENT, DONE); } - bool CanUseFingerOfDeath() + void DamageTaken(Unit* /*attacker*/, uint32 &damage) override { - // First we check if our current victim is in melee range or not. - Unit* victim = me->GetVictim(); - if (victim && me->IsWithinDistInMap(victim, me->GetAttackDistance(victim))) - return false; - - ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList(); - if (threatlist.empty()) - return false; - - std::list<Unit*> targets; - ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); - for (; itr != threatlist.end(); ++itr) + if (me->HealthBelowPctDamaged(10, damage)) { - Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()); - if (unit && unit->IsAlive()) - targets.push_back(unit); - } + if (!Enraged) + DoAction(ACTION_ENRAGE); - if (targets.empty()) - return false; + if (!HasProtected) + { + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MoveIdle(); - targets.sort(Trinity::ObjectDistanceOrderPred(me)); - Unit* target = targets.front(); - if (target) - { - if (!me->IsWithinDistInMap(target, me->GetAttackDistance(target))) - return true; // Cast Finger of Death - else // This target is closest, he is our new tank - me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim())); + // All members of raid must get this buff + DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true); + HasProtected = true; + events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500); + } } - - return false; } - void JustSummoned(Creature* summoned) override + void KilledUnit(Unit* victim) override { - if (summoned->GetEntry() == CREATURE_ANCIENT_WISP) - summoned->AI()->AttackStart(me); - else - { - summoned->setFaction(me->getFaction()); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - - if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT) - { - DoomfireSpiritGUID = summoned->GetGUID(); - } + Talk(SAY_SLAY); - if (summoned->GetEntry() == CREATURE_DOOMFIRE) + if (victim->GetTypeId() == TYPEID_PLAYER) { - summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false); - summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID()); - - if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID)) + switch (victim->getClass()) { - summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f); - DoomfireSpiritGUID.Clear(); + case CLASS_PRIEST: + case CLASS_PALADIN: + case CLASS_WARLOCK: + victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true); + break; + case CLASS_MAGE: + case CLASS_ROGUE: + case CLASS_WARRIOR: + victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true); + break; + case CLASS_DRUID: + case CLASS_SHAMAN: + case CLASS_HUNTER: + victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true); + break; } + + events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000)); + ++SoulChargeCount; } } - //this is code doing close to what the summoning spell would do (spell 31903) - void SummonDoomfire(Unit* target) + void JustReachedHome() override { - me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, - target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, - TEMPSUMMON_TIMED_DESPAWN, 27000); - - me->SummonCreature(CREATURE_DOOMFIRE, - target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0, - TEMPSUMMON_TIMED_DESPAWN, 27000); + DoAction(ACTION_CHANNEL_WORLD_TREE); } - void UnleashSoulCharge() + void JustDied(Unit* /*killer*/) override { - me->InterruptNonMeleeSpells(false); - - bool HasCast = false; - uint32 chargeSpell = 0; - uint32 unleashSpell = 0; + Talk(SAY_DEATH); + _JustDied(); + // @todo: remove this when instance script gets updated, kept for compatibility only + instance->SetData(DATA_ARCHIMONDE, DONE); + } - switch (urand(0, 2)) + void JustSummoned(Creature* summoned) override + { + switch (summoned->GetEntry()) { - case 0: - chargeSpell = SPELL_SOUL_CHARGE_RED; - unleashSpell = SPELL_UNLEASH_SOUL_RED; + case NPC_ANCIENT_WISP: + summoned->AI()->AttackStart(me); break; - case 1: - chargeSpell = SPELL_SOUL_CHARGE_YELLOW; - unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; + case NPC_DOOMFIRE_SPIRIT: + DoomfireSpiritGUID = summoned->GetGUID(); break; - case 2: - chargeSpell = SPELL_SOUL_CHARGE_GREEN; - unleashSpell = SPELL_UNLEASH_SOUL_GREEN; - break; - } + case NPC_DOOMFIRE: + summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false); + summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID()); - if (me->HasAura(chargeSpell)) - { - me->RemoveAuraFromStack(chargeSpell); - DoCastVictim(unleashSpell); - HasCast = true; - SoulChargeCount--; + if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID)) + { + summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f); + DoomfireSpiritGUID.Clear(); + } + break; + default: + break; } - - if (HasCast) - SoulChargeTimer = urand(2000, 30000); } - void UpdateAI(uint32 diff) override + void DoAction(int32 actionId) override { - if (!me->IsInCombat()) + switch (actionId) { - // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. - if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35))) - { - me->SetVisible(false); - me->setFaction(35); - } - else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35))) - { - me->setFaction(1720); - me->SetVisible(true); - } - - if (DrainNordrassilTimer <= diff) - { - if (!IsChanneling) + case ACTION_ENRAGE: + me->GetMotionMaster()->Clear(false); + me->GetMotionMaster()->MoveIdle(); + Enraged = true; + Talk(SAY_ENRAGE); + break; + case ACTION_CHANNEL_WORLD_TREE: + if (Creature* temp = me->SummonCreature(NPC_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000)) { - Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000); - - if (temp) - WorldTreeGUID = temp->GetGUID(); + WorldTreeGUID = temp->GetGUID(); if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID)) { Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Nordrassil->SetDisplayId(11686); DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); - IsChanneling = true; } + events.ScheduleEvent(EVENT_DRAIN_NORDRASSIL, 1000); } - - if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID)) - { - Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true); - DrainNordrassilTimer = 1000; - } - } else DrainNordrassilTimer -= diff; + break; + default: + break; } + } - if (!UpdateVictim()) + //this is code doing close to what the summoning spell would do (spell 31903) + void SummonDoomfire(Unit* target) + { + if (!target) return; - if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged) - BelowTenPercent = true; - - if (!Enraged) - { - if (EnrageTimer <= diff) - { - if (HealthAbovePct(10)) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - Enraged = true; - Talk(SAY_ENRAGE); - } - } else EnrageTimer -= diff; - - if (CheckDistanceTimer <= diff) - { - // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature - Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000); - if (Check) - { - Check->SetVisible(false); - - if (me->IsWithinDistInMap(Check, 75)) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - Enraged = true; - Talk(SAY_ENRAGE); - } - } - CheckDistanceTimer = 5000; - } else CheckDistanceTimer -= diff; - } - - if (BelowTenPercent) - { - if (!HasProtected) - { - me->GetMotionMaster()->Clear(false); - me->GetMotionMaster()->MoveIdle(); - - //all members of raid must get this buff - DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true); - HasProtected = true; - Enraged = true; - } - - if (SummonWispTimer <= diff) - { - DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - SummonWispTimer = 1500; - ++WispCount; - } else SummonWispTimer -= diff; - - if (WispCount >= 30) - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - - if (Enraged) - { - if (HandOfDeathTimer <= diff) - { - DoCastVictim(SPELL_HAND_OF_DEATH); - HandOfDeathTimer = 2000; - } else HandOfDeathTimer -= diff; - return; // Don't do anything after this point. - } - - if (SoulChargeCount) - { - if (SoulChargeTimer <= diff) - UnleashSoulCharge(); - else SoulChargeTimer -= diff; - } - - if (GripOfTheLegionTimer <= diff) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); - GripOfTheLegionTimer = urand(5000, 25000); - } else GripOfTheLegionTimer -= diff; - - if (AirBurstTimer <= diff) - { - Talk(SAY_AIR_BURST); - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank - AirBurstTimer = urand(25000, 40000); - } else AirBurstTimer -= diff; - - if (FearTimer <= diff) - { - DoCastVictim(SPELL_FEAR); - FearTimer = 42000; - } else FearTimer -= diff; - - if (DoomfireTimer <= diff) - { - Talk(SAY_DOOMFIRE); - Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!temp) - temp = me->GetVictim(); - - //replace with spell cast 31903 once implicitTarget 73 implemented - SummonDoomfire(temp); - - //supposedly three doomfire can be up at the same time - DoomfireTimer = 20000; - } else DoomfireTimer -= diff; - - if (MeleeRangeCheckTimer <= diff) - { - if (CanUseFingerOfDeath()) - { - DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); - MeleeRangeCheckTimer = 1000; - } - - MeleeRangeCheckTimer = 5000; - } else MeleeRangeCheckTimer -= diff; + me->SummonCreature(NPC_DOOMFIRE_SPIRIT, + target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, + TEMPSUMMON_TIMED_DESPAWN, 27000); - DoMeleeAttackIfReady(); + me->SummonCreature(NPC_DOOMFIRE, + target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0, + TEMPSUMMON_TIMED_DESPAWN, 27000); } - void WaypointReached(uint32 /*waypointId*/) override { } + + private: + ObjectGuid DoomfireSpiritGUID; + ObjectGuid WorldTreeGUID; + uint8 SoulChargeCount; + uint8 WispCount; + uint32 _chargeSpell; + uint32 _unleashSpell; + bool Enraged; + bool HasProtected; }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_archimondeAI>(creature); + } }; void AddSC_boss_archimonde() diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index 1d4a728b08b..fa8edf2c498 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -104,14 +104,32 @@ public: { switch (creature->GetEntry()) { - case RAGE_WINTERCHILL: RageWinterchill = creature->GetGUID(); break; - case ANETHERON: Anetheron = creature->GetGUID(); break; - case KAZROGAL: Kazrogal = creature->GetGUID(); break; - case AZGALOR: Azgalor = creature->GetGUID(); break; - case ARCHIMONDE: Archimonde = creature->GetGUID(); break; - case JAINA: JainaProudmoore = creature->GetGUID(); break; - case THRALL: Thrall = creature->GetGUID(); break; - case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break; + case RAGE_WINTERCHILL: + RageWinterchill = creature->GetGUID(); + break; + case ANETHERON: + Anetheron = creature->GetGUID(); + break; + case KAZROGAL: + Kazrogal = creature->GetGUID(); + break; + case AZGALOR: + Azgalor = creature->GetGUID(); + break; + case ARCHIMONDE: + Archimonde = creature->GetGUID(); + if (GetData(DATA_AZGALOREVENT) != DONE) + creature->SetVisible(false); + break; + case JAINA: + JainaProudmoore = creature->GetGUID(); + break; + case THRALL: + Thrall = creature->GetGUID(); + break; + case TYRANDE: + TyrandeWhisperwind = creature->GetGUID(); + break; } } @@ -150,6 +168,9 @@ public: m_auiEncounter[3] = data; if (data == DONE) { + if (Creature* archimonde = instance->GetCreature(Archimonde)) + archimonde->SetVisible(true); + if (ArchiYell) break; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp index b84d24d66d3..794496382c2 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp @@ -292,6 +292,7 @@ public: break; } player->CLOSE_GOSSIP_MENU(); + ai->SetDespawnAtFar(false); creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); return true; } diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp index 9f5e7bdf29d..d254cbe08fb 100644 --- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp +++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp @@ -19,12 +19,11 @@ /* ScriptData SDName: Dustwallow_Marsh SD%Complete: 95 -SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle +SDComment: Quest support: 558, 11126, 11142, 11174, Vendor Nat Pagle SDCategory: Dustwallow Marsh EndScriptData */ /* ContentData -npc_risen_husk_spirit npc_lady_jaina_proudmoore npc_nat_pagle npc_private_hendel @@ -40,99 +39,6 @@ EndContentData */ #include "WorldSession.h" /*###### -## npc_risen_husk_spirit -######*/ - -enum HauntingWitchHill -{ - // Quest - QUEST_WHATS_HAUNTING_WITCH_HILL = 11180, - - // General spells - SPELL_SUMMON_RESTLESS_APPARITION = 42511, - SPELL_WITCH_HILL_INFORMATION_CREDIT = 42512, - - // Risen Husk specific - SPELL_CONSUME_FLESH = 37933, - NPC_RISEN_HUSK = 23555, - - // Risen Spirit specific - SPELL_INTANGIBLE_PRESENCE = 43127, - NPC_RISEN_SPIRIT = 23554, - - // Events - EVENT_CONSUME_FLESH = 1, - EVENT_INTANGIBLE_PRESENCE = 2, -}; - -class npc_risen_husk_spirit : public CreatureScript -{ - public: - npc_risen_husk_spirit() : CreatureScript("npc_risen_husk_spirit") { } - - struct npc_risen_husk_spiritAI : public ScriptedAI - { - npc_risen_husk_spiritAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - events.Reset(); - if (me->GetEntry() == NPC_RISEN_HUSK) - events.ScheduleEvent(EVENT_CONSUME_FLESH, 5000); - else if (me->GetEntry() == NPC_RISEN_SPIRIT) - events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 5000); - } - - void JustDied(Unit* killer) override - { - if (killer->GetTypeId() == TYPEID_PLAYER) - { - if (killer->ToPlayer()->GetQuestStatus(QUEST_WHATS_HAUNTING_WITCH_HILL) == QUEST_STATUS_INCOMPLETE) - { - DoCast(me, SPELL_SUMMON_RESTLESS_APPARITION, true); - DoCast(killer, SPELL_WITCH_HILL_INFORMATION_CREDIT, true); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CONSUME_FLESH: - DoCastVictim(SPELL_CONSUME_FLESH); - events.ScheduleEvent(EVENT_CONSUME_FLESH, 15000); - break; - case EVENT_INTANGIBLE_PRESENCE: - DoCastVictim(SPELL_INTANGIBLE_PRESENCE); - events.ScheduleEvent(EVENT_INTANGIBLE_PRESENCE, 15000); - break; - default: - break; - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_risen_husk_spiritAI(creature); - } -}; - -/*###### ## npc_lady_jaina_proudmoore ######*/ @@ -369,131 +275,6 @@ public: }; -/*###### -## npc_stinky -######*/ - -enum Stinky -{ - QUEST_STINKYS_ESCAPE_H = 1270, - QUEST_STINKYS_ESCAPE_A = 1222, - SAY_QUEST_ACCEPTED = 0, - SAY_STAY_1 = 1, - SAY_STAY_2 = 2, - SAY_STAY_3 = 3, - SAY_STAY_4 = 4, - SAY_STAY_5 = 5, - SAY_STAY_6 = 6, - SAY_QUEST_COMPLETE = 7, - SAY_ATTACKED_1 = 8, - EMOTE_DISAPPEAR = 9 -}; - -class npc_stinky : public CreatureScript -{ -public: - npc_stinky() : CreatureScript("npc_stinky") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_stinkyAI(creature); - } - - bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_STINKYS_ESCAPE_H || quest->GetQuestId() == QUEST_STINKYS_ESCAPE_A) - { - if (npc_stinkyAI* pEscortAI = CAST_AI(npc_stinky::npc_stinkyAI, creature->AI())) - { - creature->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE); - creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_QUEST_ACCEPTED); - pEscortAI->Start(false, false, player->GetGUID()); - } - } - return true; - } - - struct npc_stinkyAI : public npc_escortAI - { - npc_stinkyAI(Creature* creature) : npc_escortAI(creature) { } - - void WaypointReached(uint32 waypointId) override - { - Player* player = GetPlayerForEscort(); - if (!player) - return; - - switch (waypointId) - { - case 7: - Talk(SAY_STAY_1, player); - break; - case 11: - Talk(SAY_STAY_2, player); - break; - case 25: - Talk(SAY_STAY_3, player); - break; - case 26: - Talk(SAY_STAY_4, player); - break; - case 27: - Talk(SAY_STAY_5, player); - break; - case 28: - Talk(SAY_STAY_6, player); - me->SetStandState(UNIT_STAND_STATE_KNEEL); - break; - case 29: - me->SetStandState(UNIT_STAND_STATE_STAND); - break; - case 37: - Talk(SAY_QUEST_COMPLETE, player); - me->SetSpeed(MOVE_RUN, 1.2f, true); - me->SetWalk(false); - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) - player->GroupEventHappens(QUEST_STINKYS_ESCAPE_H, me); - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) - player->GroupEventHappens(QUEST_STINKYS_ESCAPE_A, me); - break; - case 39: - Talk(EMOTE_DISAPPEAR); - break; - } - } - - void EnterCombat(Unit* who) override - { - Talk(SAY_ATTACKED_1, who); - } - - void Reset() override { } - - void JustDied(Unit* /*killer*/) override - { - Player* player = GetPlayerForEscort(); - if (player && HasEscortState(STATE_ESCORT_ESCORTING)) - { - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_H)) - player->FailQuest(QUEST_STINKYS_ESCAPE_H); - - if (player->GetQuestStatus(QUEST_STINKYS_ESCAPE_A)) - player->FailQuest(QUEST_STINKYS_ESCAPE_A); - } - } - - void UpdateAI(uint32 uiDiff) override - { - npc_escortAI::UpdateAI(uiDiff); - - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); - } - }; -}; enum SpellScripts { @@ -634,46 +415,13 @@ class spell_energize_aoe : public SpellScriptLoader } }; -/*###### -## go_blackhoof_cage -######*/ - -enum PrisonersOfTheGrimTotems -{ - NPC_THERAMORE_PRISONER = 23720, - SAY_FREE = 0, -}; - -class go_blackhoof_cage : public GameObjectScript -{ -public: - go_blackhoof_cage() : GameObjectScript("go_blackhoof_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - go->UseDoorOrButton(); - if (Creature* prisoner = go->FindNearestCreature(NPC_THERAMORE_PRISONER, 1.0f)) - { - if (player) - player->KilledMonsterCredit(NPC_THERAMORE_PRISONER); - - prisoner->AI()->Talk(SAY_FREE); // We also emote cry here (handled in creature_text.emote) - prisoner->DespawnOrUnsummon(6000); - } - return true; - } -}; - void AddSC_dustwallow_marsh() { - new npc_risen_husk_spirit(); new npc_lady_jaina_proudmoore(); new npc_nat_pagle(); new npc_private_hendel(); new npc_zelfrax(); - new npc_stinky(); new spell_ooze_zap(); new spell_ooze_zap_channel_end(); new spell_energize_aoe(); - new go_blackhoof_cage(); } diff --git a/src/server/scripts/Northrend/zone_icecrown.cpp b/src/server/scripts/Northrend/zone_icecrown.cpp index 7436ac8400f..2b317453992 100644 --- a/src/server/scripts/Northrend/zone_icecrown.cpp +++ b/src/server/scripts/Northrend/zone_icecrown.cpp @@ -210,52 +210,6 @@ public: }; /*###### -## npc_vereth_the_cunning -######*/ - -enum VerethTheCunning -{ - NPC_GEIST_RETURN_BUNNY_KC = 31049, - NPC_LITHE_STALKER = 30894, - SPELL_SUBDUED_LITHE_STALKER = 58151, -}; - -class npc_vereth_the_cunning : public CreatureScript -{ -public: - npc_vereth_the_cunning() : CreatureScript("npc_vereth_the_cunning") { } - - struct npc_vereth_the_cunningAI : public ScriptedAI - { - npc_vereth_the_cunningAI(Creature* creature) : ScriptedAI(creature) { } - - void MoveInLineOfSight(Unit* who) override - - { - ScriptedAI::MoveInLineOfSight(who); - - if (who->GetEntry() == NPC_LITHE_STALKER && me->IsWithinDistInMap(who, 10.0f)) - { - if (Unit* owner = who->GetCharmer()) - { - if (who->HasAura(SPELL_SUBDUED_LITHE_STALKER)) - { - owner->ToPlayer()->KilledMonsterCredit(NPC_GEIST_RETURN_BUNNY_KC); - who->ToCreature()->DisappearAndDie(); - - } - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_vereth_the_cunningAI(creature); - } -}; - -/*###### * npc_tournament_training_dummy ######*/ enum TournamentDummy @@ -881,207 +835,12 @@ class npc_frostbrood_skytalon : public CreatureScript } }; -/*###### -## The Flesh Giant Champion - Id: 13235 -######*/ -enum FleshGiant -{ - QUEST_FLESH_GIANT_CHAMPION = 13235, - - NPC_MORBIDUS = 30698, - NPC_LICH_KING = 31301, - NPC_OLAKIN = 31428, - NPC_DHAKAR = 31306, - - FACTION_HOSTILE = 14, - FACTION_BASIC = 2102, - - EVENT_INTRO = 1, - EVENT_LK_SAY_1 = 2, - EVENT_LK_SAY_2 = 3, - EVENT_LK_SAY_3 = 4, - EVENT_LK_SAY_4 = 5, - EVENT_LK_SAY_5 = 6, - EVENT_OUTRO = 7, - EVENT_START = 8, - - SPELL_SIMPLE_TELEPORT = 64195, - - SAY_DHAKAR_START = 0, - SAY_LK_1 = 0, - SAY_LK_2 = 1, - SAY_LK_3 = 2, - SAY_LK_4 = 3, - SAY_LK_5 = 4, - SAY_OLAKIN_PAY = 0 -}; - -class npc_margrave_dhakar : public CreatureScript -{ - public: - npc_margrave_dhakar() : CreatureScript("npc_margrave_dhakar") { } - - struct npc_margrave_dhakarAI : public ScriptedAI - { - npc_margrave_dhakarAI(Creature* creature) : ScriptedAI(creature) , _summons(me) { } - - void Reset() override - { - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); - - _events.Reset(); - _summons.DespawnAll(); - } - - void sGossipSelect(Player* player, uint32 sender, uint32 action) override - { - if (player->GetQuestStatus(QUEST_FLESH_GIANT_CHAMPION) == QUEST_STATUS_INCOMPLETE && !player->IsInCombat()) - { - if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) - { - _events.ScheduleEvent(EVENT_INTRO, 1000); - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } - } - } - - void UpdateAI(uint32 diff) override - { - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_INTRO: - { - Talk(SAY_DHAKAR_START); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY2H); - - if (Creature* morbidus = me->FindNearestCreature(NPC_MORBIDUS, 50.0f, true)) - { - if (Creature* lichKing = me->SummonCreature(NPC_LICH_KING, morbidus->GetPositionX() + 10.0f, morbidus->GetPositionY(), morbidus->GetPositionZ())) - { - _lichKingGuid = lichKing->GetGUID(); - lichKing->SetFacingTo(morbidus->GetOrientation()); - lichKing->CastSpell(lichKing, SPELL_SIMPLE_TELEPORT, true); - } - } - - _events.ScheduleEvent(EVENT_LK_SAY_1, 5000); - break; - } - case EVENT_LK_SAY_1: - { - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->AI()->Talk(SAY_LK_1); - _events.ScheduleEvent(EVENT_LK_SAY_2, 5000); - break; - } - case EVENT_LK_SAY_2: - { - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->AI()->Talk(SAY_LK_2); - _events.ScheduleEvent(EVENT_LK_SAY_3, 5000); - break; - } - case EVENT_LK_SAY_3: - { - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->AI()->Talk(SAY_LK_3); - _events.ScheduleEvent(EVENT_LK_SAY_4, 5000); - break; - } - case EVENT_LK_SAY_4: - { - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->AI()->Talk(SAY_LK_4); - _events.ScheduleEvent(EVENT_OUTRO, 12000); - break; - } - case EVENT_LK_SAY_5: - { - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->AI()->Talk(SAY_LK_5); - _events.ScheduleEvent(EVENT_OUTRO, 8000); - break; - } - case EVENT_OUTRO: - { - if (Creature* olakin = me->FindNearestCreature(NPC_OLAKIN, 50.0f, true)) - olakin->AI()->Talk(SAY_OLAKIN_PAY); - - if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _lichKingGuid)) - lichKing->DespawnOrUnsummon(0); - - _events.ScheduleEvent(EVENT_START, 5000); - break; - } - case EVENT_START: - { - if (Creature* morbidus = me->FindNearestCreature(NPC_MORBIDUS, 50.0f, true)) - { - morbidus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_DISABLE_MOVE); - morbidus->setFaction(FACTION_HOSTILE); - } - - break; - } - } - } - - DoMeleeAttackIfReady(); - } - - private: - EventMap _events; - SummonList _summons; - ObjectGuid _lichKingGuid; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_margrave_dhakarAI(creature); - } -}; - -class npc_morbidus : public CreatureScript -{ - public: - npc_morbidus() : CreatureScript("npc_morbidus") { } - - struct npc_morbidusAI : public ScriptedAI - { - npc_morbidusAI(Creature* creature) : ScriptedAI(creature) { } - - void Reset() override - { - if (Creature* dhakar = me->FindNearestCreature(NPC_DHAKAR, 50.0f, true)) - dhakar->AI()->Reset(); - - // this will prevent the event to start without morbidus being alive - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - me->SetReactState(REACT_PASSIVE); - me->setFaction(FACTION_BASIC); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_morbidusAI(creature); - } -}; - void AddSC_icecrown() { new npc_squire_david; new npc_argent_valiant; new npc_guardian_pavilion; - new npc_vereth_the_cunning; new npc_tournament_training_dummy; new npc_blessed_banner(); new npc_frostbrood_skytalon(); - new npc_margrave_dhakar(); - new npc_morbidus(); } diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp index 53fbf8f0cf7..1f55abf8a11 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp @@ -21,8 +21,14 @@ DoorData const doorData[] = { - { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END + { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; + +ObjectData const gameObjectData[] = +{ + { GO_TALON_KING_COFFER, DATA_TALON_KING_COFFER }, + { 0, 0 } // END }; class instance_sethekk_halls : public InstanceMapScript @@ -37,6 +43,7 @@ class instance_sethekk_halls : public InstanceMapScript SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadDoorData(doorData); + LoadObjectData(nullptr, gameObjectData); } void OnCreatureCreate(Creature* creature) override @@ -50,16 +57,27 @@ class instance_sethekk_halls : public InstanceMapScript } } - void OnGameObjectCreate(GameObject* go) override + bool SetBossState(uint32 type, EncounterState state) override { - if (go->GetEntry() == GO_IKISS_DOOR) - AddDoor(go, true); - } + if (!InstanceScript::SetBossState(type, state)) + return false; - void OnGameObjectRemove(GameObject* go) override - { - if (go->GetEntry() == GO_IKISS_DOOR) - AddDoor(go, false); + switch (type) + { + case DATA_TALON_KING_IKISS: + if (state == DONE) + { + /// @workaround: GO_FLAG_INTERACT_COND remains on the gob, but it is not handled correctly in this case + /// gameobject should have GO_DYNFLAG_LO_ACTIVATE too, which makes gobs interactable with GO_FLAG_INTERACT_COND + /// so just removed GO_FLAG_INTERACT_COND + if (GameObject* coffer = GetGameObject(DATA_TALON_KING_COFFER)) + coffer->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE); + } + break; + default: + break; + } + return true; } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h index 4b6bfab46cb..8cf01fb4635 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h @@ -28,7 +28,10 @@ enum DataTypes // Encounter States/Boss GUIDs DATA_DARKWEAVER_SYTH = 0, DATA_TALON_KING_IKISS = 1, - DATA_ANZU = 2 + DATA_ANZU = 2, + + // Additional Data + DATA_TALON_KING_COFFER = 3 }; enum CreatureIds @@ -39,7 +42,8 @@ enum CreatureIds enum GameObjectIds { - GO_IKISS_DOOR = 177203 + GO_IKISS_DOOR = 177203, + GO_TALON_KING_COFFER = 187372 }; template<class AI> diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp index f0884e83baa..794d3a490f6 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp @@ -31,21 +31,25 @@ class go_main_chambers_access_panel : public GameObjectScript return false; if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO && (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE || instance->GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL)) - { instance->SetBossState(DATA_HYDROMANCER_THESPIA, SPECIAL); - go->SetGoState(GO_STATE_ACTIVE); - } if (go->GetEntry() == GO_ACCESS_PANEL_MEK && (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE || instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL)) - { instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, SPECIAL); - go->SetGoState(GO_STATE_ACTIVE); - } + + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + go->SetGoState(GO_STATE_ACTIVE); return true; } }; +ObjectData const gameObjectData[] = +{ + { GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDRO }, + { GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEK }, + { 0, 0 } // END +}; + class instance_steam_vault : public InstanceMapScript { public: @@ -57,6 +61,7 @@ class instance_steam_vault : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(EncounterCount); + LoadObjectData(nullptr, gameObjectData); DistillerState = 0; } @@ -89,6 +94,8 @@ class instance_steam_vault : public InstanceMapScript default: break; } + + InstanceScript::OnGameObjectCreate(go); } ObjectGuid GetGuidData(uint32 type) const override @@ -128,6 +135,9 @@ class instance_steam_vault : public InstanceMapScript switch (type) { case DATA_HYDROMANCER_THESPIA: + if (state == DONE) + if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_HYDRO)) + panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (state == SPECIAL) { if (GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL) @@ -137,6 +147,9 @@ class instance_steam_vault : public InstanceMapScript } break; case DATA_MEKGINEER_STEAMRIGGER: + if (state == DONE) + if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_MEK)) + panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); if (state == SPECIAL) { if (GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL) diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h index 58f71b047ef..d18d0406dea 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h +++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h @@ -28,7 +28,11 @@ enum DataTypes DATA_HYDROMANCER_THESPIA = 0, DATA_MEKGINEER_STEAMRIGGER = 1, DATA_WARLORD_KALITHRESH = 2, - DATA_DISTILLER = 3 + DATA_DISTILLER = 3, + + // Additional Data + DATA_ACCESS_PANEL_HYDRO = 4, + DATA_ACCESS_PANEL_MEK = 5 }; enum CreatureIds diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index 22968d70ff1..6717bec109f 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -69,7 +69,7 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader bool Load() override { - return GetCaster()->GetTypeId() == TYPEID_PLAYER; + return GetOwner()->GetTypeId() == TYPEID_PLAYER; } bool Validate(SpellInfo const* /*spellInfo*/) override @@ -81,16 +81,16 @@ class spell_hun_aspect_of_the_beast : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Player* caster = GetCaster()->ToPlayer()) - if (Pet* pet = caster->GetPet()) - pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET); + Player* player = GetTarget()->ToPlayer(); + if (Pet* pet = player->GetPet()) + pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET); } void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - if (Player* caster = GetCaster()->ToPlayer()) - if (caster->GetPet()) - caster->CastSpell(caster, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); + Player* player = GetTarget()->ToPlayer(); + if (player->GetPet()) + player->CastSpell(player, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); } void Register() override diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index e35f7c9b70e..28680c9d1ce 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -40,8 +40,6 @@ go_dragonflayer_cage go_tadpole_cage go_amberpine_outhouse go_hive_pod -go_gjalerbron_cage -go_large_gjalerbron_cage go_veil_skith_cage EndContentData */ @@ -1111,69 +1109,6 @@ class go_massive_seaforium_charge : public GameObjectScript }; /*###### -## go_gjalerbron_cage -######*/ - -enum OfKeysAndCages -{ - QUEST_ALLIANCE_OF_KEYS_AND_CAGES = 11231, - QUEST_HORDE_OF_KEYS_AND_CAGES = 11265, - NPC_GJALERBRON_PRISONER = 24035, - SAY_FREE = 0, -}; - -class go_gjalerbron_cage : public GameObjectScript -{ - public: - go_gjalerbron_cage() : GameObjectScript("go_gjalerbron_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - go->UseDoorOrButton(); - if ((player->GetTeamId() == TEAM_ALLIANCE && player->GetQuestStatus(QUEST_ALLIANCE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE) || - (player->GetTeamId() == TEAM_HORDE && player->GetQuestStatus(QUEST_HORDE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE)) - { - if (Creature* prisoner = go->FindNearestCreature(NPC_GJALERBRON_PRISONER, 5.0f)) - { - player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER); - - prisoner->AI()->Talk(SAY_FREE); - prisoner->DespawnOrUnsummon(6000); - } - } - return true; - } -}; - -/*######## -## go_large_gjalerbron_cage -#####*/ - -class go_large_gjalerbron_cage : public GameObjectScript -{ - public: - go_large_gjalerbron_cage() : GameObjectScript("go_large_gjalerbron_cage") { } - - bool OnGossipHello(Player* player, GameObject* go) override - { - go->UseDoorOrButton(); - if ((player->GetTeamId() == TEAM_ALLIANCE && player->GetQuestStatus(QUEST_ALLIANCE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE) || - (player->GetTeamId() == TEAM_HORDE && player->GetQuestStatus(QUEST_HORDE_OF_KEYS_AND_CAGES) == QUEST_STATUS_INCOMPLETE)) - { - std::list<Creature*> prisonerList; - GetCreatureListWithEntryInGrid(prisonerList, go, NPC_GJALERBRON_PRISONER, INTERACTION_DISTANCE); - for (std::list<Creature*>::const_iterator itr = prisonerList.begin(); itr != prisonerList.end(); ++itr) - { - player->KilledMonsterCredit(NPC_GJALERBRON_PRISONER, (*itr)->GetGUID()); - (*itr)->DespawnOrUnsummon(6000); - (*itr)->AI()->Talk(SAY_FREE); - } - } - return false; - } -}; - -/*######## #### go_veil_skith_cage #####*/ @@ -1293,8 +1228,6 @@ void AddSC_go_scripts() new go_amberpine_outhouse(); new go_hive_pod(); new go_massive_seaforium_charge(); - new go_gjalerbron_cage(); - new go_large_gjalerbron_cage(); new go_veil_skith_cage(); new go_frostblade_shrine(); new go_midsummer_bonfire(); diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h index 27e6cb63514..8ffb138379a 100644 --- a/src/server/shared/Common.h +++ b/src/server/shared/Common.h @@ -79,6 +79,9 @@ inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; } +inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); } +inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 10); } + #define STRINGIZE(a) #a enum TimeConstants diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h index dbe2b8ec902..a62fe973dfa 100644 --- a/src/server/shared/Networking/SocketMgr.h +++ b/src/server/shared/Networking/SocketMgr.h @@ -46,7 +46,16 @@ public: return false; } - _acceptor = new AsyncAcceptor(service, bindIp, port); + try + { + _acceptor = new AsyncAcceptor(service, bindIp, port); + } + catch (boost::system::system_error const& err) + { + TC_LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork (%s:%u): %s", bindIp.c_str(), port, err.what()); + return false; + } + _threads = CreateThreads(); ASSERT(_threads); |