From 80493719f22ada2d332a88072927b71e963ba258 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Sun, 19 Sep 2021 16:19:29 -0400 Subject: [PATCH] [Summoning] Make Summon a bit more live like (#1539) Pretty sure the distance should probably be melee range / 2 but ahh yeah. Can't do that. Hopefully 5 units isn't too far. --- zone/mob.cpp | 11 +++++++++-- zone/mob.h | 1 + zone/waypoints.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index 9686ff29f..69bf30531 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2838,10 +2838,17 @@ bool Mob::HateSummon() { if(summon_level == 1) { entity_list.MessageClose(this, true, 500, Chat::Say, "%s says 'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); + auto new_pos = m_Position; + float angle = new_pos.w - target->GetHeading(); + new_pos.w = target->GetHeading(); + + // probably should be like half melee range, but we can't get melee range nicely because reasons :) + new_pos = target->TryMoveAlong(new_pos, 5.0f, angle); + if (target->IsClient()) - target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Position.x, m_Position.y, m_Position.z, target->GetHeading(), 0, SummonPC); + target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), new_pos.x, new_pos.y, new_pos.z, new_pos.w, 0, SummonPC); else - target->GMMove(m_Position.x, m_Position.y, m_Position.z, target->GetHeading()); + target->GMMove(new_pos.x, new_pos.y, new_pos.z, new_pos.w); return true; } else if(summon_level == 2) { diff --git a/zone/mob.h b/zone/mob.h index 2095d38fc..9ccf846c9 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -623,6 +623,7 @@ public: void Teleport(const glm::vec3 &pos); void Teleport(const glm::vec4 &pos); void TryMoveAlong(float distance, float angle, bool send = true); + glm::vec4 TryMoveAlong(const glm::vec4 &start, float distance, float angle); void ProcessForcedMovement(); inline void IncDeltaX(float in) { m_Delta.x += in; } inline void IncDeltaY(float in) { m_Delta.y += in; } diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 76db92dd6..97e9d6091 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -935,6 +935,32 @@ void Mob::TryMoveAlong(float distance, float angle, bool send) Teleport(new_pos); } +// like above, but takes a starting position and returns a new location instead of actually moving +glm::vec4 Mob::TryMoveAlong(const glm::vec4 &start, float distance, float angle) +{ + angle += start.w; + angle = FixHeading(angle); + + glm::vec3 tmp_pos; + glm::vec3 new_pos = start; + new_pos.x += distance * g_Math.FastSin(angle); + new_pos.y += distance * g_Math.FastCos(angle); + new_pos.z += GetZOffset(); + + if (zone->HasMap()) { + auto new_z = zone->zonemap->FindClosestZ(new_pos, nullptr); + if (new_z != BEST_Z_INVALID) + new_pos.z = new_z; + + if (zone->zonemap->LineIntersectsZone(start, new_pos, 0.0f, &tmp_pos)) + new_pos = tmp_pos; + } + + new_pos.z = GetFixedZ(new_pos); + + return {new_pos.x, new_pos.y, new_pos.z, start.w}; +} + int ZoneDatabase::GetHighestGrid(uint32 zoneid) { std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);