Skip to content

Commit

Permalink
[core] Adjust draw-in behavior and add additional functionality
Browse files Browse the repository at this point in the history
Co-authored-by: Tiberon <[email protected]>
  • Loading branch information
CriticalXI and TiberonKalkaz committed Dec 15, 2024
1 parent 18b6b24 commit b848181
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 19 deletions.
3 changes: 3 additions & 0 deletions scripts/enum/mob_mod.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,7 @@ xi.mobMod =
SKIP_ALLEGIANCE_CHECK = 80, -- Skip the allegiance check for valid target (allows for example a mob to cast a TARGET_ENEMY spell on itself)
ABILITY_RESPONSE = 81, -- Mob can respond to player ability use with onPlayerAbilityUse()
SPEED_BOOST_MULT = 82, -- Multiplier for the base speed of a mob when the mob's target is out of range (range between 100 and 500, 250 means 2.5x, mechanism is from retail)
DRAW_IN_FRONT = 83, -- Mob will draw in slightly in front of them instead of the center of their hitbox (HNMs such as Tiamat)
DRAW_IN_CUSTOM_RANGE = 84, -- Override the default range of MeleeRange*2 of when players start to get drawn-in
DRAW_IN_BIND = 85, -- Forces mob to draw in the moment you leave melee range (ex. Mimics)
}
14 changes: 12 additions & 2 deletions src/map/ai/controllers/mob_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,19 @@ void CMobController::Move()
if (((currentDistance > closeDistance) || move) && PMob->PAI->CanFollowPath())
{
// TODO: can this be moved to scripts entirely?
if (PMob->getMobMod(MOBMOD_DRAW_IN) > 0)
if (PMob->getMobMod(MOBMOD_DRAW_IN))
{
if (currentDistance >= PMob->GetMeleeRange() * 2 && battleutils::DrawIn(PTarget, PMob, PMob->GetMeleeRange() - 0.2f))
uint8 drawInRange = PMob->getMobMod(MOBMOD_DRAW_IN_CUSTOM_RANGE) > 0 ? PMob->getMobMod(MOBMOD_DRAW_IN_CUSTOM_RANGE) : PMob->GetMeleeRange() * 2;

// Draw in when target is farther than 2x melee range
if (currentDistance > drawInRange && battleutils::DrawIn(PTarget, PMob, PMob->GetMeleeRange() - 0.2f, drawInRange))
{
FaceTarget();
return;
}
// If i'm bound/can't move, draw in the moment they leave my melee range
else if ((PMob->getMobMod(MOBMOD_DRAW_IN_BIND) && PMob->speed == 0 || PMob->getMobMod(MOBMOD_NO_MOVE)) &&
currentDistance > PMob->GetMeleeRange() && battleutils::DrawIn(PTarget, PMob, PMob->GetMeleeRange() - 1.2f, PMob->GetMeleeRange()))
{
FaceTarget();
return;
Expand Down
7 changes: 4 additions & 3 deletions src/map/lua/lua_baseentity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17172,7 +17172,8 @@ void CLuaBaseEntity::drawIn(sol::variadic_args va)
return;
}

auto mobObj = dynamic_cast<CMobEntity*>(m_PBaseEntity);
auto mobObj = dynamic_cast<CMobEntity*>(m_PBaseEntity);
uint8 drawInRange = mobObj->GetMeleeRange() * 2;

if (va.size() == 0)
{
Expand All @@ -17182,7 +17183,7 @@ void CLuaBaseEntity::drawIn(sol::variadic_args va)
{
return;
}
battleutils::DrawIn(defaultTarget, mobObj, mobObj->GetMeleeRange() - 0.2f);
battleutils::DrawIn(defaultTarget, mobObj, mobObj->GetMeleeRange() - 0.2f, drawInRange);
return;
}

Expand All @@ -17204,7 +17205,7 @@ void CLuaBaseEntity::drawIn(sol::variadic_args va)

if (PTarget)
{
battleutils::DrawIn(PTarget, mobObj, mobObj->GetMeleeRange() - 0.2f);
battleutils::DrawIn(PTarget, mobObj, mobObj->GetMeleeRange() - 0.2f, drawInRange);
}

return;
Expand Down
3 changes: 3 additions & 0 deletions src/map/mob_modifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ enum MOBMODIFIER : int
MOBMOD_SKIP_ALLEGIANCE_CHECK = 80, // Skip the allegiance check for valid target (allows for example a mob to cast a TARGET_ENEMY spell on itself)
MOBMOD_ABILITY_RESPONSE = 81, // Mob can respond to player ability use with onPlayerAbilityUse()
MOBMOD_SPEED_BOOST_MULT = 82, // Multiplier for the base speed of a mob when the mob's target is out of range (range between 100 and 25500, 250 means 2.5x, mechanism is from retail)
MOBMOD_DRAW_IN_FRONT = 83, // Mob will draw in slightly in front of them instead of the center of their hitbox (HNMs such as Tiamat)
MOBMOD_DRAW_IN_CUSTOM_RANGE = 84, // Override the default range of MeleeRange*2 of when players start to get drawn-in
MOBMOD_DRAW_IN_BIND = 85, // Forces mob to draw in the moment you leave melee range (ex. Mimics)
};

#endif
37 changes: 24 additions & 13 deletions src/map/utils/battleutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5595,8 +5595,14 @@ namespace battleutils
}
}

bool DrawIn(CBattleEntity* PTarget, CMobEntity* PMob, float offset)
bool DrawIn(CBattleEntity* PTarget, CMobEntity* PMob, float offset, uint8 drawInRange)
{
// Check if time to draw in again, if not then exit
if (std::chrono::time_point_cast<std::chrono::seconds>(server_clock::now()).time_since_epoch().count() - PMob->GetLocalVar("DrawInTime") < 2)
{
return false;
}

position_t& pos = PMob->loc.p;
position_t nearEntity = nearPosition(pos, offset, (float)0);

Expand All @@ -5622,19 +5628,13 @@ namespace battleutils
// Move the target a little higher, just in case
nearEntity.y -= 1.0f;

bool success = false;
float drawInDistance = (float)(PMob->getMobMod(MOBMOD_DRAW_IN) > 1 ? PMob->getMobMod(MOBMOD_DRAW_IN) : PMob->GetMeleeRange() * 2);
bool success = false;

if (std::chrono::time_point_cast<std::chrono::seconds>(server_clock::now()).time_since_epoch().count() - PMob->GetLocalVar("DrawInTime") < 2)
{
return false;
}

std::function<void(CBattleEntity*)> drawInFunc = [PMob, drawInDistance, &nearEntity, &success](CBattleEntity* PMember)
std::function<void(CBattleEntity*)> drawInFunc = [PMob, drawInRange, &nearEntity, &success](CBattleEntity* PMember)
{
float pDistance = distance(PMob->loc.p, PMember->loc.p);

if (PMob->loc.zone == PMember->loc.zone && pDistance > drawInDistance && PMember->status != STATUS_TYPE::CUTSCENE_ONLY)
if (PMob->loc.zone == PMember->loc.zone && pDistance > drawInRange && PMember->status != STATUS_TYPE::CUTSCENE_ONLY)
{
// don't draw in dead players for now!
// see tractor
Expand All @@ -5645,9 +5645,20 @@ namespace battleutils
else
{
// draw in!
PMember->loc.p.x = nearEntity.x;
PMember->loc.p.y = nearEntity.y;
PMember->loc.p.z = nearEntity.z;
// Certain families (such as Wyrms) draw in in front of where they are looking
if (PMob->getMobMod(MOBMOD_DRAW_IN_FRONT))
{
PMember->loc.p.x = nearEntity.x;
PMember->loc.p.y = nearEntity.y;
PMember->loc.p.z = nearEntity.z;
}
// Default behavior is to draw in to middle of hit box.
else
{
PMember->loc.p.x = PMob->loc.p.x;
PMember->loc.p.y = nearEntity.y;
PMember->loc.p.z = PMob->loc.p.z;
}

if (PMember->objtype == TYPE_PC)
{
Expand Down
2 changes: 1 addition & 1 deletion src/map/utils/battleutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ namespace battleutils
WEATHER GetWeather(CBattleEntity* PEntity, bool ignoreScholar);
WEATHER GetWeather(CBattleEntity* PEntity, bool ignoreScholar, uint16 zoneWeather);
bool WeatherMatchesElement(WEATHER weather, uint8 element);
bool DrawIn(CBattleEntity* PEntity, CMobEntity* PMob, float offset);
bool DrawIn(CBattleEntity* PEntity, CMobEntity* PMob, float offset, uint8 drawInRange);
void DoWildCardToEntity(CCharEntity* PCaster, CCharEntity* PTarget, uint8 roll);
bool DoRandomDealToEntity(CCharEntity* PChar, CBattleEntity* PTarget);

Expand Down

0 comments on commit b848181

Please sign in to comment.