生物AI系统增强

- 文件影响 : src/server/game/Entities/Creature/Creature.cpp (+22/-0 行)
- 修复内容 :
  - 新增 m_AlreadyCalledForHelp 递归保护标志
  - 实现脱离战斗时重置CallForHelp标志
  - 防止AI无限递归调用帮助
  - 提升战斗AI的稳定性

智能脚本系统优化
- 文件影响 : src/server/game/AI/SmartScripts/SmartScript.cpp (+16/-0 行)
- 改进 : 添加SMART_ACTION_CALL_FOR_HELP日志跟踪
This commit is contained in:
尚美 2025-10-16 20:49:04 +08:00
parent 856ebfc39e
commit 13c6e2147b
3 changed files with 34 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
@ -1318,6 +1318,16 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsCreature(target))
{
// 在调用 CallForHelp 之前记录日志 寻找调用帮助时候造成无限递归循环问题
LOG_ERROR("scripts.ai", "CALL_FOR_HELP: Creature {} (entry {}) at map {} pos ({:.2f}, {:.2f}, {:.2f}) calling for help, radius {}",
target->GetGUID().ToString(),
target->ToCreature()->GetEntry(),
target->GetMapId(),
target->GetPositionX(),
target->GetPositionY(),
target->GetPositionZ(),
e.action.callHelp.range);
target->ToCreature()->CallForHelp(float(e.action.callHelp.range));
if (e.action.callHelp.withEmote)
{

View File

@ -272,7 +272,7 @@ bool TemporaryThreatModifierEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_lootRecipientGroup(0),
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckTime(2500),
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadyCalledForHelp(false), // 尚美CUSTOM: 初始化 CallForHelp 递归保护标志
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
@ -906,6 +906,15 @@ void Creature::Update(uint32 diff)
}
}
}
// 尚美CUSTOM: 在脱离战斗时重置 CallForHelp 标志
// 这样下次进入战斗时可以再次调用帮助
if (!IsInCombat())
{
m_AlreadyCalledForHelp = false;
}
// 尚美END CUSTOM
break;
}
default:
@ -2488,6 +2497,17 @@ void Creature::CallForHelp(float radius, Unit* target /*= nullptr*/)
return;
}
// 尚美CUSTOM: 添加递归保护,防止无限循环导致栈溢出
// 当生物调用 CallForHelp 时,范围内的友方生物会通过 AttackStart 进入战斗
// 如果这些生物的 SmartAI 也配置了 SMART_EVENT_AGGRO -> SMART_ACTION_CALL_FOR_HELP
// 就会形成递归调用链,最终导致栈溢出崩溃
if (m_AlreadyCalledForHelp)
{
return;
}
m_AlreadyCalledForHelp = true;
// 尚美END CUSTOM
Acore::CallOfHelpCreatureInRangeDo u_do(this, target, radius);
Acore::CreatureWorker<Acore::CallOfHelpCreatureInRangeDo> worker(this, u_do);
Cell::VisitGridObjects(this, worker, radius);

View File

@ -1,4 +1,4 @@
/*
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
@ -468,6 +468,7 @@ protected:
int8 m_originalEquipmentId; // can be -1
bool m_AlreadyCallAssistance;
bool m_AlreadyCalledForHelp; // 尚美CUSTOM: 添加递归保护标志,防止 CallForHelp 无限递归导致栈溢出,参考 m_AlreadyCallAssistance 的实现模式
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_regenPower;