Core/AI: Add some checks to catch if the AI changes mid-update for players.
Port From (https://github.com/TrinityCore/TrinityCore/commit/1015f307041b25b47a9bb4bc76ac4ed78c49d735)
This commit is contained in:
@@ -55,7 +55,6 @@ namespace Game.Entities
|
|||||||
bool m_AlreadySearchedAssistance;
|
bool m_AlreadySearchedAssistance;
|
||||||
bool m_cannotReachTarget;
|
bool m_cannotReachTarget;
|
||||||
uint m_cannotReachTimer;
|
uint m_cannotReachTimer;
|
||||||
bool m_AI_locked;
|
|
||||||
|
|
||||||
SpellSchoolMask m_meleeDamageSchoolMask;
|
SpellSchoolMask m_meleeDamageSchoolMask;
|
||||||
public uint m_originalEntry;
|
public uint m_originalEntry;
|
||||||
|
|||||||
@@ -574,9 +574,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do not allow the AI to be changed during update
|
// do not allow the AI to be changed during update
|
||||||
m_AI_locked = true;
|
AIUpdateTick(diff);
|
||||||
base.AIUpdateTick(diff);
|
|
||||||
m_AI_locked = false;
|
|
||||||
|
|
||||||
if (!IsAlive())
|
if (!IsAlive())
|
||||||
break;
|
break;
|
||||||
@@ -729,25 +727,12 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool DestoryAI()
|
bool DestoryAI()
|
||||||
{
|
{
|
||||||
if (m_AI_locked)
|
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Scripts, "DestroyAI: failed to destroy, locked.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAI(null);
|
SetAI(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool InitializeAI(CreatureAI ai = null)
|
public bool InitializeAI(CreatureAI ai = null)
|
||||||
{
|
{
|
||||||
// make sure nothing can change the AI during AI update
|
|
||||||
if (m_AI_locked)
|
|
||||||
{
|
|
||||||
Log.outDebug(LogFilter.Scripts, "InitializeAI: failed to init, locked.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeMovementAI();
|
InitializeMovementAI();
|
||||||
|
|
||||||
SetAI(ai != null ? ai : AISelector.SelectAI(this));
|
SetAI(ai != null ? ai : AISelector.SelectAI(this));
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ namespace Game.Entities
|
|||||||
//AI
|
//AI
|
||||||
protected UnitAI i_AI;
|
protected UnitAI i_AI;
|
||||||
protected UnitAI i_disabledAI;
|
protected UnitAI i_disabledAI;
|
||||||
|
bool m_aiLocked;
|
||||||
|
|
||||||
//Movement
|
//Movement
|
||||||
protected float[] m_speed_rate = new float[(int)UnitMoveType.Max];
|
protected float[] m_speed_rate = new float[(int)UnitMoveType.Max];
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ namespace Game.Entities
|
|||||||
Cypher.Assert(newAI != null);
|
Cypher.Assert(newAI != null);
|
||||||
i_AI = newAI;
|
i_AI = newAI;
|
||||||
newAI.OnCharmed(true);
|
newAI.OnCharmed(true);
|
||||||
AIUpdateTick(0, true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1168,27 +1168,28 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public virtual UnitAI GetAI() { return i_AI; }
|
public virtual UnitAI GetAI() { return i_AI; }
|
||||||
|
|
||||||
public void AIUpdateTick(uint diff, bool force = false)
|
public void AIUpdateTick(uint diff)
|
||||||
{
|
{
|
||||||
if (diff == 0) // some places call with diff = 0, which does nothing (for now), see PR #22296
|
|
||||||
return;
|
|
||||||
|
|
||||||
UnitAI ai = GetAI();
|
UnitAI ai = GetAI();
|
||||||
if (ai != null)
|
if (ai != null)
|
||||||
|
{
|
||||||
|
m_aiLocked = true;
|
||||||
ai.UpdateAI(diff);
|
ai.UpdateAI(diff);
|
||||||
|
m_aiLocked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAI(UnitAI newAI)
|
public void SetAI(UnitAI newAI)
|
||||||
{
|
{
|
||||||
if (i_AI != null)
|
Cypher.Assert(!m_aiLocked, "Attempt to replace AI during AI update tick");
|
||||||
AIUpdateTick(0, true); // old AI gets a final tick if enabled
|
|
||||||
|
|
||||||
i_AI = newAI;
|
i_AI = newAI;
|
||||||
AIUpdateTick(0, true); // new AI gets its initial tick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScheduleAIChange()
|
public void ScheduleAIChange()
|
||||||
{
|
{
|
||||||
|
Cypher.Assert(!m_aiLocked, "Attempt to schedule AI change during AI update tick");
|
||||||
|
|
||||||
bool charmed = IsCharmed();
|
bool charmed = IsCharmed();
|
||||||
// if charm is applied, we can't have disabled AI already, and vice versa
|
// if charm is applied, we can't have disabled AI already, and vice versa
|
||||||
if (charmed)
|
if (charmed)
|
||||||
@@ -1204,9 +1205,9 @@ namespace Game.Entities
|
|||||||
|
|
||||||
void RestoreDisabledAI()
|
void RestoreDisabledAI()
|
||||||
{
|
{
|
||||||
|
Cypher.Assert(!m_aiLocked, "Attempt to restore AI during UpdateAI tick");
|
||||||
Cypher.Assert(IsPlayer() || i_disabledAI != null, "Attempt to restore disabled AI on creature without disabled AI");
|
Cypher.Assert(IsPlayer() || i_disabledAI != null, "Attempt to restore disabled AI on creature without disabled AI");
|
||||||
i_AI = i_disabledAI;
|
i_AI = i_disabledAI;
|
||||||
AIUpdateTick(0, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsPossessing()
|
public bool IsPossessing()
|
||||||
|
|||||||
Reference in New Issue
Block a user