Skip to content
Permalink
Browse files

Core/SmartAI: Various fixes and extensions for smart scripts: (#18673)

- Possible crashes fixed
- Memory leak fixed
- Implemented checking of vehicle conditions
- Extended eventphasemask to 12 bits (sql required to change DB field type)
- SMART_EVENT_GOSSIP_HELLO - added possibility to detect for gameobject reportUse call
- Renamed action SMART_ACTION_SET_FLY to SMART_ACTION_SET_DISABLE_GRAVITY (to reflect actual functionality)
- Added targetsLimit to action SMART_ACTION_CAST and SMART_ACTION_INVOKER_CAST to limit max amount of targets (selected randomly)
- Action SMART_ACTION_TALK corrected to always work as intended
- Properly call GroupEventHappens in action SMART_ACTION_CALL_GROUPEVENTHAPPENS if invoker was charmed or owned by the player
- Properly utilize followAngle in action SMART_ACTION_FOLLOW (db orientation should be in degrees), but keep backward compatibility
- Added action SMART_ACTION_SET_CAN_FLY (119) 0/1
- Added action SMART_ACTION_REMOVE_AURAS_BY_TYPE (120) AuraType, can be used to exit vehicle for example
- Added action SMART_ACTION_SET_SIGHT_DIST (121) sightDist
- Added action SMART_ACTION_FLEE (122) fleeTime
- Added action SMART_ACTION_ADD_THREAT (123) +threat, -threat
- Added action SMART_ACTION_LOAD_EQUIPMENT (124) equipmentId
- Added action SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT (125) minId, maxId
- Added action SMART_ACTION_REMOVE_ALL_GAMEOBJECTS (126), removes all owned gameobjects
- Added action SMART_ACTION_STOP_MOTION (127), stopMoving, movementExpired
- Extended target SMART_TARGET_HOSTILE_SECOND_AGGRO with following parameters maxdist, playerOnly, powerType + 1
- Extended target SMART_TARGET_HOSTILE_LAST_AGGRO with following parameters maxdist, playerOnly, powerType + 1
- Extended target SMART_TARGET_HOSTILE_RANDOM with following parameters maxdist, playerOnly, powerType + 1
- Extended target SMART_TARGET_HOSTILE_RANDOM_NOT_TOP with following parameters maxdist, playerOnly, powerType + 1
- Extended target SMART_TARGET_THREAT_LIST with maxdist
- Extended target SMART_TARGET_OWNER_OR_SUMMONER to be able to get charmer/owner of current owner
- Added new target SMART_TARGET_FARTHEST with maxDist, playerOnly, isInLos restrictions
- Added SpellHit hook to GameObjectAI and extended SmartGameObjectAI to call SMART_EVENT_SPELLHIT when gameobject is hit by spell
- Call GameObjectAI Reset hook on gameobject respawn (for ex. to reset one time events in smart scripts)
- Fixed some logic errors in code
- SmartAI Escorts properly despawn escortee if no players are in range
- Disable Evading while charming creature with SmartAI
- Don't call SMART_EVENT_RESPAWN for dead units before they actually respawn
- Don't call SMART_EVENT_RESPAWN for not spawned gameobjects
- Properly call SMART_EVENT_RESPAWN for gameobject respawn
- Allow action SMART_ACTION_SET_IN_COMBAT_WITH_ZONE to utilize targetlist
- Allow action SMART_ACTION_CALL_FOR_HELP to utilize targetList
- Allow action SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL to utilize targetList
- Allow action SMART_ACTION_SET_VISIBILITY to utilize targetList
- Allow action SMART_ACTION_SET_ACTIVE to utilize targetList
- Allow action SMART_ACTION_ATTACK_START to select random attack target instead of first on the list
- Allow gameobjects to summon gameobjects with action SMART_ACTION_SUMMON_GO
- Properly store action invokers for action SMART_ACTION_WP_START, if no player invokers are found, distance despawn check won't be used
- Allow action SMART_ACTION_WP_RESUME to compensate for the state the unit actually is in (eg. combat)
- Allow action SMART_ACTION_MOVE_TO_POS to select random of the avaiable targets, not only the first one.
- Allow action SMART_ACTION_MOVE_TO_POS to utilize x, y, z parameters as an offset to calculated coordinates
- Action SMART_ACTION_RESPAWN_TARGET should never modify respawntime of already spawned gameobjects, use dedicated function
- Properly delete ontime events created by SMART_ACTION_CREATE_TIMED_EVENT
- If action could not be started because conditions were not satisfied, do not recalculate the waittime to action repeattime, use smaller value to recheck more frequently
- Allow target SMART_TARGET_CLOSEST_PLAYER to be used by gameobjects
- Allow target SMART_TARGET_OWNER_OR_SUMMONER to be used by gameobjects
- Fixed SMART_EVENT_COUNTER_SET to be only called for the id that was incremented
- Changed the way counters work
- Protect PhaseInc from surpassing maximum phase
- Added loading checks for missing NON_REPEATABLE flag if no repeatmin, repeatmax is set
- Added spell validation for SMART_ACTION_CROSS_CAST
  • Loading branch information
xinef1 authored and Shauren committed Feb 17, 2017
1 parent 9d74252 commit b0ae5fadd19fd172ec5154cde4f4fd14aa20ff88
@@ -302,24 +302,27 @@ void VehicleAI::LoadConditions()

void VehicleAI::CheckConditions(uint32 diff)
{
if (m_ConditionsTimer < diff)
if (!m_HasConditions)
return;

if (m_ConditionsTimer <= diff)
{
if (m_HasConditions)
if (Vehicle* vehicleKit = me->GetVehicleKit())
{
if (Vehicle* vehicleKit = me->GetVehicleKit())
for (SeatMap::iterator itr = vehicleKit->Seats.begin(); itr != vehicleKit->Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*me, itr->second.Passenger.Guid))
for (SeatMap::iterator itr = vehicleKit->Seats.begin(); itr != vehicleKit->Seats.end(); ++itr)
if (Unit* passenger = ObjectAccessor::GetUnit(*me, itr->second.Passenger.Guid))
{
if (Player* player = passenger->ToPlayer())
{
if (Player* player = passenger->ToPlayer())
if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry(), player, me))
{
if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry(), player, me))
{
player->ExitVehicle();
return; // check other pessanger in next tick
}
player->ExitVehicle();
return; // check other pessanger in next tick
}
}
}
}

m_ConditionsTimer = VEHICLE_CONDITION_CHECK_TIME;
}
else
@@ -47,7 +47,7 @@ class TC_GAME_API GameObjectAI

static int Permissible(GameObject const* go);

virtual bool GossipHello(Player* /*player*/) { return false; }
virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; }
virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { return false; }
virtual bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) { return false; }
virtual bool QuestAccept(Player* /*player*/, Quest const* /*quest*/) { return false; }
@@ -61,6 +61,7 @@ class TC_GAME_API GameObjectAI
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) { }
virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { }
virtual void EventInform(uint32 /*eventId*/) { }
virtual void SpellHit(Unit* /*unit*/, const SpellInfo* /*spellInfo*/) { }
};

class TC_GAME_API NullGameObjectAI : public GameObjectAI
@@ -348,3 +348,40 @@ bool NonTankTargetSelector::operator()(Unit const* target) const

return target != _source->GetVictim();
}

bool PowerUsersSelector::operator()(Unit const* target) const
{
if (!_me || !target)
return false;

if (target->getPowerType() != _power)
return false;

if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
return false;

if (_dist > 0.0f && !_me->IsWithinCombatRange(target, _dist))
return false;

if (_dist < 0.0f && _me->IsWithinCombatRange(target, -_dist))
return false;

return true;
}

bool FarthestTargetSelector::operator()(Unit const* target) const
{
if (!_me || !target)
return false;

if (_playerOnly && target->GetTypeId() != TYPEID_PLAYER)
return false;

if (_dist > 0.0f && !_me->IsWithinCombatRange(target, _dist))
return false;

if (_inLos && !_me->IsWithinLOSInMap(target))
return false;

return true;
}
@@ -115,6 +115,33 @@ struct TC_GAME_API NonTankTargetSelector : public std::unary_function<Unit*, boo
bool _playerOnly;
};

// Simple selector for units using mana
struct TC_GAME_API PowerUsersSelector
{
public:
PowerUsersSelector(Unit const* unit, Powers power, float dist, bool playerOnly) : _me(unit), _power(power), _dist(dist), _playerOnly(playerOnly) { }
bool operator()(Unit const* target) const;

private:
Unit const* _me;
Powers const _power;
float const _dist;
bool const _playerOnly;
};

struct TC_GAME_API FarthestTargetSelector
{
public:
FarthestTargetSelector(Unit const* unit, float dist, bool playerOnly, bool inLos) : _me(unit), _dist(dist), _playerOnly(playerOnly), _inLos(inLos) {}
bool operator()(Unit const* target) const;

private:
const Unit* _me;
float _dist;
bool _playerOnly;
bool _inLos;
};

class TC_GAME_API UnitAI
{
protected:

0 comments on commit b0ae5fa

Please sign in to comment.
You can’t perform that action at this time.