All pastes #1088697 Raw Edit

6405_Blink_Patch

public text v1 · immutable
#1088697 ·published 2008-07-31 18:25 UTC
rendered paste body
Index: src/game/Spell.cpp
===================================================================
--- src/game/Spell.cpp	(revision 6405)
+++ src/game/Spell.cpp	(working copy)
@@ -3821,18 +3821,50 @@
             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 = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->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;
+				
+				// orientation coordinates
+				float ox = m_caster->GetPositionX();
+				float oy = m_caster->GetPositionY();
+				float oz = m_caster->GetPositionZ();
+				
+				// destination coordinates
+				float fx = ox + dis * cos(m_caster->GetOrientation());
+                float fy = oy + dis * sin(m_caster->GetOrientation());
+				
+				// possible destination z coordinate
+				float fz_ground = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx, fy, MAX_HEIGHT, true);
+				float fz_floor = MapManager::Instance().GetBaseMap(m_caster->GetMapId())->GetHeight(fx, fy, m_caster->GetPositionZ(), true);
+				
+				// absolute diferente between orientation z and possible destination z
+				float ground_dif = fabs(fz_ground - oz);
+				float floor_dif = fabs(fz_floor - oz);
+				
+				// control caster to not climb/drop when destination z > +-8; or we don't have a valid destination z value
+				if (ground_dif > 8.0 && floor_dif > 8.0) return SPELL_FAILED_TRY_AGAIN;
+				
+				// begin -- chech if we hit something in the way
+				bool hit_ground = false, hit_floor = false;
+				float fx2, fy2, fz2;
+				hit_ground = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(m_caster->GetMapId(), ox, oy, oz + ground_dif + 0.75, fx, fy, fz_ground + 0.75, fx2, fy2, fz2, -0.75);
+				hit_floor = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(m_caster->GetMapId(), ox, oy, oz + floor_dif + 0.75, fx, fy, fz_floor + 0.75, fx2, fy2, fz2, -0.75);
+ 
+				if (ground_dif <= 8.0 && floor_dif <= 8.0) // both possible destination z are valid.
+				{
+					if (hit_ground == true && hit_floor == true) return SPELL_FAILED_TRY_AGAIN; // we hit something in the way of both possible destination z
+				}
+				else
+				{
+					if (ground_dif <= 8.0) // only fz_ground destination z is valid.
+					{
+						if (hit_ground == true) return SPELL_FAILED_TRY_AGAIN; // we hit something in the way of destination z
+					}
+					else // only fz_floor destination z is valid.
+					{
+						if (hit_floor == true) return SPELL_FAILED_TRY_AGAIN; // we hit something in the way of destination z
+					}
+				}
+				// end -- chech if we hit something in the way
 
-                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())
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp	(revision 6405)
+++ src/game/SpellEffects.cpp	(working copy)
@@ -5222,21 +5222,53 @@
         uint32 mapid = m_caster->GetMapId();
         float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
 
-        // before caster
-        float fx,fy,fz;
-        unitTarget->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis);
-        float ox,oy,oz;
-        unitTarget->GetPosition(ox,oy,oz);
+		// orientation coordinates
+		float ox = unitTarget->GetPositionX();
+		float oy = unitTarget->GetPositionY();
+		float oz = unitTarget->GetPositionZ();
+		
+		// destination coordinates
+		float fx = ox + dis * cos(unitTarget->GetOrientation());
+        float fy = oy + dis * sin(unitTarget->GetOrientation());
+		
+		// possible z destination coordinate
+		float fz_ground = MapManager::Instance().GetBaseMap(unitTarget->GetMapId())->GetHeight(fx, fy, MAX_HEIGHT, true);
+		float fz_floor = MapManager::Instance().GetBaseMap(unitTarget->GetMapId())->GetHeight(fx, fy, unitTarget->GetPositionZ(), true);
+		
+		// absolute diferente between orientation z and destination z
+		float ground_dif = fabs(fz_ground - oz);
+		float floor_dif = fabs(fz_floor - oz);
+		
+		// chech if we hit something in the way
+		float fz, fx2, fy2, fz2;
+		bool hit_ground = false, hit_floor = false;
+		hit_ground = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unitTarget->GetMapId(), ox, oy, oz + ground_dif + 0.75, fx, fy, fz_ground + 0.75, fx2, fy2, fz2, -0.75);
+		hit_floor = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(unitTarget->GetMapId(), ox, oy, oz + floor_dif + 0.75, fx, fy, fz_floor + 0.75, fx2, fy2, fz2, -0.75);
+		
+		// begin -- choose the best destination z to go
+		if (ground_dif <= 8.0 && floor_dif <= 8.0)
+		{
+			if (fz_ground >= fz_floor)
+			{
+				if (hit_ground == false) fz = fz_ground;
+				else if (hit_floor == false) fz = fz_floor;
+			}
+			else
+			{
+				if (hit_floor == false) fz = fz_floor;
+				else if (hit_ground == false) fz = fz_ground;
+			}
+		}
+		else
+		{
+			if (ground_dif <= 8.0) fz = fz_ground;
+			else fz = fz_floor;
+		}
+		// end -- choose the best destination z to go
+ 
+		// a little increment
+		fz += 0.06;
 
-        float fx2,fy2,fz2;                                  // getObjectHitPos overwrite last args in any result case
-        if(VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(mapid, ox,oy,oz+0.5, fx,fy,oz+0.5,fx2,fy2,fz2, -0.5))
-        {
-            fx = fx2;
-            fy = fy2;
-            fz = fz2;
-            unitTarget->UpdateGroundPositionZ(fx,fy,fz);
-        }
-
         if(unitTarget->GetTypeId() == TYPEID_PLAYER)
             ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, unitTarget->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0));
         else