Jump to content

[Improvement] Blink


Guest Kaios

Recommended Posts

Hello, i was working on my 1.12.1 server and there was some problem with Blink...(Undermap and other)

What features does the patch add?

You can't go undermap now.

For which repository revision was the patch created?

It's for WoW 1.12.1. but it's should work on 3.3.5

Who has been writing this patch?

przemratajczak

Kaios(me)

First off Go here : http://github.com/przemratajczak/mangos/commit/41205afb84a3795df38f2e3dfa162db0b34208c0

Search "void Spell::EffectLeapForward(SpellEffectIndex eff_idx)" in SpellEffect and replace it by mine.

void Spell::EffectLeapForward(SpellEffectIndex eff_idx)
{
   if(unitTarget->IsTaxiFlying())
       return;

   if( m_spellInfo->rangeIndex == 1)                       //self range
   {
       float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx]));

       // before caster
       float fx, fy, fz;
       unitTarget->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis);
       float ox, oy, oz;
       unitTarget->GetPosition(ox, oy, oz);

       float fx2, fy2, fz2;                                // getObjectHitPos overwrite last args in any result case
       if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unitTarget->GetMapId(), ox,oy,oz+0.5f, fx,fy,oz+0.5f,fx2,fy2,fz2, -0.5f))
       {
           fx = fx2;
           fy = fy2;
           fz = fz2;
       }
       if(!unitTarget->IsInWater())
           fz = m_caster->GetBaseMap()->GetHeight(fx,fy,fz,true);
           else
           fz = m_caster->GetMap()->GetWaterLevel(fx,fy);
           if (fabs(fz-oz) > 4.0f)
           {
               fx = ox;
               fy = oy;
               fz = oz;
           }
       unitTarget->NearTeleportTo(fx, fy, fz, unitTarget->GetOrientation(),unitTarget==m_caster);
   }
}

Link to comment
Share on other sites

  • 3 weeks later...

Blinking through closed doors was fixed a long time ago. Are you saying that's now broken again?

Either way, this patch offered by Kaios ought to be worthwhile just for preventing falling through the "ground". It should also benefit similar effects, like Charge and Shadowstep.

However, with Ambal's map re-engineer patch, mmaps redux, and vmaps v3, I'm still not sure if any patch for those effects will be needed when it all finally comes together. The reasons Blink and the rest are glitched is because of incomplete terrain and object data and poor map handling.

P.S. I think that trying to use the data from mmaps, to determine if a path exists, would also help Blink/Charge/Shadowstep/etc. by ensuring you could not move in a direction blocked to you when moving normally. This would also prevent players from using those effects to cheat, such as "hill climbing" or walking through walls.

Link to comment
Share on other sites

I recall a specific instance, in Uldaman at the map room, where you could Blink through those big, iron doors where that metal statue was locked away. You had to do this because the miniature city, where you placed the staff, was not working and so you couldn't unlock the doors.

Last time I tried this and some other places where you could Blink through, you would only get a "Failed" message. I'm not saying you can't do this at all, but it certainly seems it had been fixed in some places, at least.

It'll probably take years before this whole map system is figured out and completed. :rolleyes:

Link to comment
Share on other sites

If you don't mind you can use this hack code to prevent blinking through door that I wrote for my server. It is not recommended for large server because it fetches SQL for object information. If someone can improve this or have better idea feel free to rewrite it.

* this is only half of the code, the minus(deleting) code shouldn't be removed because it is part of my other code, just take a look on the adding parts *

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 95e6580..85e3867 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4302,24 +4302,43 @@ SpellCastResult Spell::CheckCast(bool strict)
            case SPELL_EFFECT_LEAP:
            case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER:
            {
-                float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
-                float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
-                float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
-                // teleport a bit above terrain level to avoid falling below it
-                float fz = m_caster->GetBaseMap()->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
-                if(fz <= INVALID_HEIGHT)                    // note: this also will prevent use effect in instances without vmaps height enabled
-                    return SPELL_FAILED_TRY_AGAIN;
-
-                float caster_pos_z = m_caster->GetPositionZ();
-                // Control the caster to not climb or drop when +-fz > 8
-                if(!(fz <= caster_pos_z + 8 && fz >= caster_pos_z - 8))
-                    return SPELL_FAILED_TRY_AGAIN;
-
                // not allow use this effect at battleground until battleground start
                if(m_caster->GetTypeId() == TYPEID_PLAYER)
                    if(BattleGround const *bg = ((Player*)m_caster)->GetBattleGround())
                        if(bg->GetStatus() != STATUS_IN_PROGRESS)
                            return SPELL_FAILED_TRY_AGAIN;
+
+                //check door
+                bool findDoor = false;
+                float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+
+                QueryResult *result = WorldDatabase.PQuery("SELECT id, "
+                    "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
+                    "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
+                    m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(),
+                    m_caster->GetMapId(),m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), dis*dis+5);
+
+                if (result)
+                {
+                    do
+                    {
+                        Field *fields = result->Fetch();
+                        uint32 entry = fields[0].GetUInt32();
+
+                        GameObjectInfo const * pDoor = sObjectMgr.GetGameObjectInfo(entry);
+
+                        if(!pDoor)
+                            continue;
+
+                        if ( pDoor->type == GAMEOBJECT_TYPE_DOOR )
+                            findDoor = true;
+
+                    } while (result->NextRow());
+                    delete result;
+                }
+                if ( findDoor )
+                    return SPELL_FAILED_TRY_AGAIN;
+
                break;
            }
            case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF:

Link to comment
Share on other sites

If you don't mind you can use this hack code to prevent blinking through door that I wrote for my server. It is not recommended for large server because it fetches SQL for object information. If someone can improve this or have better idea feel free to rewrite it.

* this is only half of the code, the minus(deleting) code shouldn't be removed because it is part of my other code, just take a look on the adding parts *

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 95e6580..85e3867 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4302,24 +4302,43 @@ SpellCastResult Spell::CheckCast(bool strict)
            case SPELL_EFFECT_LEAP:
            case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER:
            {
-                float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
-                float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
-                float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
-                // teleport a bit above terrain level to avoid falling below it
-                float fz = m_caster->GetBaseMap()->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
-                if(fz <= INVALID_HEIGHT)                    // note: this also will prevent use effect in instances without vmaps height enabled
-                    return SPELL_FAILED_TRY_AGAIN;
-
-                float caster_pos_z = m_caster->GetPositionZ();
-                // Control the caster to not climb or drop when +-fz > 8
-                if(!(fz <= caster_pos_z + 8 && fz >= caster_pos_z - 8))
-                    return SPELL_FAILED_TRY_AGAIN;
-
                // not allow use this effect at battleground until battleground start
                if(m_caster->GetTypeId() == TYPEID_PLAYER)
                    if(BattleGround const *bg = ((Player*)m_caster)->GetBattleGround())
                        if(bg->GetStatus() != STATUS_IN_PROGRESS)
                            return SPELL_FAILED_TRY_AGAIN;
+
+                //check door
+                bool findDoor = false;
+                float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+
+                QueryResult *result = WorldDatabase.PQuery("SELECT id, "
+                    "(POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ "
+                    "FROM gameobject WHERE map='%u' AND (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) <= '%f' ORDER BY order_",
+                    m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(),
+                    m_caster->GetMapId(),m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), dis*dis+5);
+
+                if (result)
+                {
+                    do
+                    {
+                        Field *fields = result->Fetch();
+                        uint32 entry = fields[0].GetUInt32();
+
+                        GameObjectInfo const * pDoor = sObjectMgr.GetGameObjectInfo(entry);
+
+                        if(!pDoor)
+                            continue;
+
+                        if ( pDoor->type == GAMEOBJECT_TYPE_DOOR )
+                            findDoor = true;
+
+                    } while (result->NextRow());
+                    delete result;
+                }
+                if ( findDoor )
+                    return SPELL_FAILED_TRY_AGAIN;
+
                break;
            }
            case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF:

This is usually done by using grid searchers. Just fill the list and check if there are any solid GO intercept with you're blink vector.

Not like thats the real solution, but it sure better then sql query :)

Link to comment
Share on other sites

doing a SQL query each time you cast a spell is cumbersome, you should read data from in memory structure, or better use DBC to get bounding box of the gameobject

I don't know if you didn't read my posting or what, if you know a better way please feel free to rewrite it.

There was a previous version that I use GO info stored in mangos but while in the half way I realized my server was a small server so I just did use database method for time save.

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use