Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 100 additions & 54 deletions src/source/MUHelper/MuHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,17 +262,15 @@ namespace MUHelper

int CMuHelper::ComputeDistanceFromTarget(CHARACTER* pTarget)
{
POINT posA, posB;
const POINT posHero = { Hero->PositionX, Hero->PositionY };

posA = { Hero->PositionX, Hero->PositionY };
posB = { pTarget->PositionX, pTarget->PositionY };
int iPrevDistance = ComputeDistanceBetween(posA, posB);
const POINT posCurrent = { pTarget->PositionX, pTarget->PositionY };
const POINT posNext = { pTarget->TargetX, pTarget->TargetY };

posA = { Hero->PositionX, Hero->PositionY };
posB = { pTarget->TargetX, pTarget->TargetX };
int iNextDistance = ComputeDistanceBetween(posA, posB);

return std::min<int>(iPrevDistance, iNextDistance);
return std::min(
ComputeDistanceBetween(posHero, posCurrent),
ComputeDistanceBetween(posHero, posNext)
);
}

int CMuHelper::ComputeDistanceBetween(POINT posA, POINT posB)
Expand Down Expand Up @@ -731,7 +729,7 @@ namespace MUHelper
m_iCurrentSkill = SelectAttackSkill();
if (m_iCurrentSkill > AT_SKILL_UNDEFINED)
{
SimulateAttack(m_iCurrentSkill);
return SimulateAttack(m_iCurrentSkill);
}

return 1;
Expand Down Expand Up @@ -854,66 +852,100 @@ namespace MUHelper
g_MovementSkill.m_iSkill = iSkill;
g_MovementSkill.m_bMagic = true;

float fSkillDistance = gSkillManager.GetSkillDistance(iSkill, Hero);
const float fSkillDistance = gSkillManager.GetSkillDistance(iSkill, Hero);
const bool bSelfPositionSkill = IsSelfPositionSkill(iSkill);

if (bTargetRequired)
{
if (iTarget == -1)
if (bSelfPositionSkill)
{
return 0;
}
TargetX = Hero->PositionX;
TargetY = Hero->PositionY;

SelectedCharacter = FindCharacterIndex(iTarget);
if (SelectedCharacter == MAX_CHARACTERS_CLIENT)
{
DeleteTarget(iTarget);
return 0;
}
g_MovementSkill.m_iTarget = -1;

CHARACTER* pTarget = &CharactersClient[SelectedCharacter];
if (pTarget->Dead > 0)
{
DeleteTarget(iTarget);
return 0;
// Check if current target is still valid (exists and alive)
if (iTarget != -1)
{
const int iCharIndex = FindCharacterIndex(iTarget);
if (iCharIndex != MAX_CHARACTERS_CLIENT)
{
CHARACTER* pCurrentTarget = &CharactersClient[iCharIndex];
if (pCurrentTarget->Dead > 0 || !IsMonster(pCurrentTarget))
{
DeleteTarget(iTarget);
return 0;
}
}
else
{
DeleteTarget(iTarget);
return 0;
}
}
Comment thread
eduardosmaniotto marked this conversation as resolved.
}
else
{
if (iTarget == -1)
{
return 0;
}

g_MovementSkill.m_iTarget = SelectedCharacter;
const int iCharIndex = FindCharacterIndex(iTarget);
if (iCharIndex == MAX_CHARACTERS_CLIENT)
{
DeleteTarget(iTarget);
return 0;
}

TargetX = (int)(pTarget->Object.Position[0] / TERRAIN_SCALE);
TargetY = (int)(pTarget->Object.Position[1] / TERRAIN_SCALE);
SelectedCharacter = iCharIndex;

PATH_t tempPath;
bool bHasPath = PathFinding2(Hero->PositionX, Hero->PositionY, TargetX, TargetY, &tempPath, m_iHuntingDistance + fSkillDistance);
bool bTargetNear = CheckTile(Hero, &Hero->Object, fSkillDistance);
bool bNoWall = CheckWall(Hero->PositionX, Hero->PositionY, TargetX, TargetY);
CHARACTER* pTarget = &CharactersClient[iCharIndex];
if (pTarget->Dead > 0)
{
DeleteTarget(iTarget);
return 0;
}

// target not reachable, ignore it
if (!bHasPath)
{
DeleteTarget(iTarget);
return 0;
}
g_MovementSkill.m_iTarget = iCharIndex;

// target is not near or the path is obstructed by a wall, move closer
if (!bTargetNear || !bNoWall)
{
Hero->Path.Lock.lock();
TargetX = (int)(pTarget->Object.Position[0] / TERRAIN_SCALE);
TargetY = (int)(pTarget->Object.Position[1] / TERRAIN_SCALE);

// Limit movement to 2 steps at a time
int pathNum = std::min<int>(tempPath.PathNum, 2);
for (int i = 0; i < pathNum; i++)
PATH_t tempPath;
bool bHasPath = PathFinding2(Hero->PositionX, Hero->PositionY, TargetX, TargetY, &tempPath, m_iHuntingDistance + fSkillDistance);

// Target not reachable, ignore it
if (!bHasPath)
{
Hero->Path.PathX[i] = tempPath.PathX[i];
Hero->Path.PathY[i] = tempPath.PathY[i];
DeleteTarget(iTarget);
return 0;
}
Hero->Path.PathNum = pathNum;
Hero->Path.CurrentPath = 0;
Hero->Path.CurrentPathFloat = 0;

Hero->Path.Lock.unlock();
bool bTargetNear = CheckTile(Hero, &Hero->Object, fSkillDistance);
bool bNoWall = CheckWall(Hero->PositionX, Hero->PositionY, TargetX, TargetY);

SendMove(Hero, &Hero->Object);
return 0;
// Target is not near or the path is obstructed by a wall, move closer
if (!bTargetNear || !bNoWall)
{
Hero->Path.Lock.lock();

// Limit movement to 2 steps at a time
int pathNum = std::min<int>(tempPath.PathNum, 2);
for (int i = 0; i < pathNum; i++)
{
Hero->Path.PathX[i] = tempPath.PathX[i];
Hero->Path.PathY[i] = tempPath.PathY[i];
}
Hero->Path.PathNum = pathNum;
Hero->Path.CurrentPath = 0;
Hero->Path.CurrentPathFloat = 0;

Hero->Path.Lock.unlock();

SendMove(Hero, &Hero->Object);
return 0;
}
}
}
else
Expand All @@ -923,7 +955,7 @@ namespace MUHelper
}

int iSkillResult = ExecuteSkill(Hero, iSkill, fSkillDistance);
if (iSkillResult == -1)
if (iSkillResult == -1 && iTarget != -1)
{
DeleteTarget(iTarget);
}
Expand Down Expand Up @@ -999,6 +1031,20 @@ namespace MUHelper
return AT_SKILL_UNDEFINED;
}

// Matches AttackWizard() behavior in ZzzInterface.cpp for these skill IDs.
bool CMuHelper::IsSelfPositionSkill(ActionSkillType iSkill)
{
return (
iSkill == AT_SKILL_NOVA_BEGIN ||
iSkill == AT_SKILL_NOVA ||
iSkill == AT_SKILL_HELL_FIRE ||
iSkill == AT_SKILL_HELL_FIRE_STR ||
iSkill == AT_SKILL_INFERNO ||
iSkill == AT_SKILL_INFERNO_STR ||
iSkill == AT_SKILL_INFERNO_STR_MG
);
}

ActionSkillType CMuHelper::GetDrainLifeSkill()
{
std::vector<ActionSkillType> aiDrainLifeSkills =
Expand Down
1 change: 1 addition & 0 deletions src/source/MUHelper/MuHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ namespace MUHelper
ActionSkillType GetHealingSkill();
ActionSkillType GetDrainLifeSkill();
bool HasAssignedBuffSkill();
bool IsSelfPositionSkill(ActionSkillType iSkill);

private:
ConfigData m_config;
Expand Down
Loading