diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 49 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 15 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 145 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 38 | ||||
| -rw-r--r-- | src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp | 7 | ||||
| -rw-r--r-- | src/server/scripts/World/go_scripts.cpp | 20 | 
6 files changed, 125 insertions, 149 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 186259a5b8d..ccfeb61206f 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -83,13 +83,13 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3  {      for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)      { -        SMART_EVENT eventType = SMART_EVENT((*i).GetEventType()); +        SMART_EVENT eventType = SMART_EVENT(i->GetEventType());          if (eventType == SMART_EVENT_LINK)//special handling              continue; -        if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/) +        if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)          { -            ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type); +            ConditionList conds = sConditionMgr->GetConditionsForSmartEvent(i->entryOrGuid, i->event_id, i->source_type);              ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject());              if (sConditionMgr->IsObjectMeetToConditions(info, conds)) @@ -167,7 +167,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u                  for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)                  {                      if (IsCreature(*itr)) -                        sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0); +                        sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);                      else if (IsPlayer(*itr) && me)                      {                          Unit* templastInvoker = GetLastInvoker(); @@ -2262,8 +2262,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u      if (e.link && e.link != e.event_id)      { -        SmartScriptHolder linked = FindLinkedEvent(e.link); -        if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK) +        SmartScriptHolder& linked = SmartAIMgr::FindLinkedEvent(mEvents, e.link); +        if (linked)              ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);          else              TC_LOG_ERROR("sql.sql", "SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link); @@ -2471,7 +2471,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*                  if (me && me->GetGUID() == (*itr)->GetGUID())                      continue; -                if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist)) +                if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))                      l->push_back(*itr);              } @@ -2490,7 +2490,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*                  if (me && me->GetGUID() == (*itr)->GetGUID())                      continue; -                if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature) +                if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)                      l->push_back(*itr);              } @@ -2509,7 +2509,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*                  if (go && go->GetGUID() == (*itr)->GetGUID())                      continue; -                if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry) +                if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)                      l->push_back(*itr);              } @@ -2528,7 +2528,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*                  if (go && go->GetGUID() == (*itr)->GetGUID())                      continue; -                if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist)) +                if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))                      l->push_back(*itr);              } @@ -2537,32 +2537,28 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*          }          case SMART_TARGET_CREATURE_GUID:          { -            Creature* target = NULL;              if (!scriptTrigger && !baseObject)              {                  TC_LOG_ERROR("sql.sql", "SMART_TARGET_CREATURE_GUID can not be used without invoker");                  break;              } -            target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid); - -            if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)) -                l->push_back(target); +            if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid)) +                if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry) +                    l->push_back(target);              break;          }          case SMART_TARGET_GAMEOBJECT_GUID:          { -            GameObject* target = NULL;              if (!scriptTrigger && !baseObject)              {                  TC_LOG_ERROR("sql.sql", "SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker");                  break;              } -            target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid); - -            if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)) -                l->push_back(target); +            if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid)) +                if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry) +                    l->push_back(target);              break;          }          case SMART_TARGET_PLAYER_RANGE: @@ -2601,26 +2597,21 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*          }          case SMART_TARGET_CLOSEST_CREATURE:          { -            Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead); -            if (target) +            if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))                  l->push_back(target);              break;          }          case SMART_TARGET_CLOSEST_GAMEOBJECT:          { -            GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100)); -            if (target) +            if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))                  l->push_back(target);              break;          }          case SMART_TARGET_CLOSEST_PLAYER:          {              if (me) -            { -                Player* target = me->SelectNearestPlayer((float)e.target.playerDistance.dist); -                if (target) +                if (Player* target = me->SelectNearestPlayer(float(e.target.playerDistance.dist)))                      l->push_back(target); -            }              break;          }          case SMART_TARGET_OWNER_OR_SUMMONER: @@ -2653,7 +2644,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*              if (me)                  if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))                      l->push_back(target); -              break;          }          case SMART_TARGET_CLOSEST_FRIENDLY: @@ -2661,7 +2651,6 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*              if (me)                  if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))                      l->push_back(target); -              break;          }          case SMART_TARGET_POSITION: diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 02bc1a2b487..b59b62c5697 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -257,21 +257,6 @@ class SmartScript                  }              }          } -        SmartScriptHolder FindLinkedEvent(uint32 link) -        { -            if (!mEvents.empty()) -            { -                for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) -                { -                    if (i->event_id == link) -                    { -                        return (*i); -                    } -                } -            } -            SmartScriptHolder s; -            return s; -        }  };  #endif diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 0698e12413f..0b2fdfc6bee 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB()      while (result->NextRow());      TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime)); -  }  SmartWaypointMgr::~SmartWaypointMgr() @@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB()          }          else          { -            CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid))); +            CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)));              if (!creature)              { -                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid))); +                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));                  continue;              }              CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id);              if (!creatureInfo)              { -                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); +                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));                  continue;              }              if (creatureInfo->AIName != "SmartAI")              { -                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid))); +                TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));                  continue;              }          } @@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB()      }      while (result->NextRow()); -    // TO-DO: Find better way -    for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++) +    // Post Loading Validation +    for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i)      { -        for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr) +        for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)          { -            for (auto e : mEventMap[i][itr->first]) +            for (SmartScriptHolder const& e : itr->second)              { -                bool found = false; -                if (e.link && e.link != e.event_id) +                if (e.link)                  { -                    for (auto linked : mEventMap[i][itr->first]) +                    if (!FindLinkedEvent(itr->second, e.link))                      { -                        if (linked.event_id == e.link) -                            if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK) -                                found = true; +                        TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.", +                            e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);                      } +                } -                    if (!found) -                        TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid", -                            e.entryOrGuid, e.GetScriptType(), e.event_id, e.link); +                if (e.GetEventType() == SMART_EVENT_LINK) +                { +                    if (!FindLinkedSourceEvent(itr->second, e.event_id)) +                    { +                        TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.", +                            e.entryOrGuid, e.GetScriptType(), e.event_id); +                    }                  }              }          } @@ -295,8 +297,13 @@ void SmartAIMgr::LoadSmartAIFromDB()  bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)  { +    if (std::abs(e.target.o) > 2 * float(M_PI)) +        TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has abs(`target.o` = %f) > 2*PI (orientation is expressed in radians)", +            e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.target.o); +      if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE)          return true; // AI template has special handling +      switch (e.GetTargetType())      {          case SMART_TARGET_CREATURE_DISTANCE: @@ -375,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)          TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType());          return false;      } +      // in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core      if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1]))      {          TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType());          return false;      } +      if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)      {          TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());          return false;      } +      if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)      {          TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);          return false;      } +      if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)      {          TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);          return false;      } + +    if (e.link && e.link == e.event_id) +    { +        TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); +        return false; +    } +      if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)      {          e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script! @@ -407,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)      }      else      { -        uint32 type = e.event.type; -        switch (type) +        switch (e.GetEventType())          {              case SMART_EVENT_UPDATE:              case SMART_EVENT_UPDATE_IC: @@ -568,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)                  break;              }              case SMART_EVENT_TEXT_OVER: -                //if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group! -                break; -            case SMART_EVENT_LINK: -            { -                if (e.link && e.link == e.event_id) -                { -                    TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id); +                if (!IsTextValid(e, e.event.textOver.textGroupID))                      return false; -                }                  break; -            }              case SMART_EVENT_DUMMY_EFFECT:              {                  if (!IsSpellValid(e, e.event.dummy.spell)) @@ -686,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)                      return false;                  }                  break; +            case SMART_EVENT_LINK:              case SMART_EVENT_GO_STATE_CHANGED:              case SMART_EVENT_GO_EVENT_INFORM:              case SMART_EVENT_TIMED_EVENT_TRIGGERED: @@ -729,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)      switch (e.GetActionType())      {          case SMART_ACTION_TALK: -        { -            if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE) -            { -                if (!IsTextValid(e, e.action.talk.textGroupID)) -                    return false; -            } +        case SMART_ACTION_SIMPLE_TALK: +            if (!IsTextValid(e, e.action.talk.textGroupID)) +                return false;              break; -        }          case SMART_ACTION_SET_FACTION:              if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID))              { @@ -816,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)              if (!IsSpellValid(e, e.action.cast.spell))                  return false; -            SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell); +            SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);              for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)              {                  if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2)) @@ -979,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)              if (!NotNULL(e, e.action.item.count))                  return false; -            CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry); +            CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry);              for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr)                  TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)", -                e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second); +                    e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);              break;          }          case SMART_ACTION_TELEPORT: @@ -1183,7 +1189,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)          case SMART_ACTION_SET_NPC_FLAG:          case SMART_ACTION_ADD_NPC_FLAG:          case SMART_ACTION_REMOVE_NPC_FLAG: -        case SMART_ACTION_SIMPLE_TALK:          case SMART_ACTION_CROSS_CAST:          case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:          case SMART_ACTION_RANDOM_MOVE: @@ -1214,49 +1219,45 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)      return true;  } -bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused +bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)  { -    bool error = false; +    if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE) +        return true; +      uint32 entry = 0; -    if (e.entryOrGuid >= 0) +    if (e.GetEventType() == SMART_EVENT_TEXT_OVER)      { -        if (e.GetEventType() == SMART_EVENT_TEXT_OVER) -        { -            entry = e.event.textOver.creatureEntry; -            id = e.event.textOver.textGroupID; -        } -        else -        { -            switch (e.GetTargetType()) -            { -                case SMART_TARGET_CREATURE_DISTANCE: -                case SMART_TARGET_CREATURE_RANGE: -                case SMART_TARGET_CLOSEST_CREATURE: -                    return true; // ignore -                default: -                    entry = uint32(e.entryOrGuid); -                    break; -            } -        } +        entry = e.event.textOver.creatureEntry;      }      else      { -        entry = uint32(abs(e.entryOrGuid)); -        CreatureData const* data = sObjectMgr->GetCreatureData(entry); -        if (!data) +        switch (e.GetTargetType())          { -            TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); -            return false; +            case SMART_TARGET_CREATURE_DISTANCE: +            case SMART_TARGET_CREATURE_RANGE: +            case SMART_TARGET_CLOSEST_CREATURE: +                return true; // ignore +            default: +                if (e.entryOrGuid < 0) +                { +                    entry = uint32(std::abs(e.entryOrGuid)); +                    CreatureData const* data = sObjectMgr->GetCreatureData(entry); +                    if (!data) +                    { +                        TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); +                        return false; +                    } +                    else +                        entry = data->id; +                } +                else +                    entry = uint32(e.entryOrGuid); +                break;          } -        else -            entry = data->id;      }      if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id))) -        error = true; - -    if (error)      {          TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);          return false; @@ -1318,7 +1319,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k      return KillCreditSpellStore.equal_range(killCredit);  } -CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const +CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const  {      return CreateItemSpellStore.equal_range(itemId);  } diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index bdd1dfc6ae0..a567a4be35e 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -1355,6 +1355,8 @@ struct SmartScriptHolder      bool active;      bool runOnce;      bool enableTimed; + +    operator bool() const { return entryOrGuid != 0; }  };  typedef std::unordered_map<uint32, WayPoint*> WPPath; @@ -1477,6 +1479,30 @@ class SmartAIMgr              }          } +        static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) +        { +            SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), +                [eventId](SmartScriptHolder& source) { return source.link == eventId; }); + +            if (itr != list.end()) +                return *itr; + +            static SmartScriptHolder SmartScriptHolderDummy; +            return SmartScriptHolderDummy; +        } + +        static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link) +        { +            SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), +                [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); + +            if (itr != list.end()) +                return *itr; + +            static SmartScriptHolder SmartScriptHolderDummy; +            return SmartScriptHolderDummy; +        } +      private:          //event stores          SmartAIEventMap mEventMap[SMART_SCRIPT_TYPE_MAX]; @@ -1484,16 +1510,6 @@ class SmartAIMgr          bool IsEventValid(SmartScriptHolder& e);          bool IsTargetValid(SmartScriptHolder const& e); -        /*inline bool IsTargetValid(SmartScriptHolder e, int32 target) -        { -            if (target < SMART_TARGET_NONE || target >= SMART_TARGET_END) -            { -                TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Target type %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), target); -                return false; -            } -            return true; -        }*/ -          bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max)          {              if (max < min) @@ -1623,7 +1639,7 @@ class SmartAIMgr          CacheSpellContainerBounds GetSummonCreatureSpellContainerBounds(uint32 creatureEntry) const;          CacheSpellContainerBounds GetSummonGameObjectSpellContainerBounds(uint32 gameObjectEntry) const;          CacheSpellContainerBounds GetKillCreditSpellContainerBounds(uint32 killCredit) const; -        CacheSpellContainerBounds GetCreditItemSpellContainerBounds(uint32 itemId) const; +        CacheSpellContainerBounds GetCreateItemSpellContainerBounds(uint32 itemId) const;          CacheSpellContainer SummonCreatureSpellStore;          CacheSpellContainer SummonGameObjectSpellStore; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index dbe8c8b0329..2e859a7a56f 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -99,7 +99,12 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)      if (is_air_ok)          i_nextMoveTime.Reset(0);      else -        i_nextMoveTime.Reset(urand(500, 10000)); +    { +        if (roll_chance_i(50)) +            i_nextMoveTime.Reset(urand(5000, 10000)); +        else +            i_nextMoveTime.Reset(urand(50, 400)); +    }      creature->AddUnitState(UNIT_STATE_ROAMING_MOVE); diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp index 65cb2c2abce..752ea2feb1c 100644 --- a/src/server/scripts/World/go_scripts.cpp +++ b/src/server/scripts/World/go_scripts.cpp @@ -24,7 +24,6 @@ go_ethereum_stasis  go_sacred_fire_of_life  go_shrine_of_the_birds  go_southfury_moonstone -go_field_repair_bot_74A  go_orb_of_command  go_resonite_cask  go_tablet_of_madness @@ -94,24 +93,6 @@ public:  };  /*###### -## go_field_repair_bot_74A -######*/ - -class go_field_repair_bot_74A : public GameObjectScript -{ -public: -    go_field_repair_bot_74A() : GameObjectScript("go_field_repair_bot_74A") { } - -    bool OnGossipHello(Player* player, GameObject* /*go*/) override -    { -        if (player->HasSkill(SKILL_ENGINEERING) && player->GetBaseSkillValue(SKILL_ENGINEERING) >= 300 && !player->HasSpell(22704)) -            player->CastSpell(player, 22864, false); - -        return true; -    } -}; - -/*######  ## go_gilded_brazier (Paladin First Trail quest (9678))  ######*/ @@ -1213,7 +1194,6 @@ void AddSC_go_scripts()  {      new go_cat_figurine();      new go_barov_journal(); -    new go_field_repair_bot_74A();      new go_gilded_brazier();      new go_orb_of_command();      new go_shrine_of_the_birds();  | 
