From 911f8636c916c9cc87ee6da85895aa3a78dac26f Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Tue, 19 Feb 2019 17:56:35 +0100 Subject: [PATCH] Core/Objects: fixed remaining differences for collision height code and fixed an issue that was causing units getting summoned in the air --- src/server/game/DataStores/DBCStructure.h | 2 +- src/server/game/DataStores/DBCfmt.h | 2 +- src/server/game/Entities/Object/Object.cpp | 11 ++++---- src/server/game/Entities/Unit/Unit.cpp | 11 +++++--- src/server/game/Maps/Map.cpp | 2 +- src/server/game/Spells/Spell.cpp | 30 ++++++++++++++++++++++ src/server/game/Spells/SpellEffects.cpp | 1 - 7 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 89e953aa39..430ee77af9 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -981,7 +981,7 @@ struct CreatureModelDataEntry uint32 Flags; char* ModelPath; //uint32 Unk1; - //float Scale; // Used in calculation of unit collision data + float Scale; // Used in calculation of unit collision data //int32 Unk2 //int32 Unk3 //uint32 Unk4 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 965b58bc1f..fd8f15998e 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -48,7 +48,7 @@ char const CinematicCameraEntryfmt[] = "nsiffff"; char const CinematicSequencesEntryfmt[] = "nxixxxxxxx"; char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxx"; char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx"; -char const CreatureModelDatafmt[] = "nisxxxxxxxxxxxxffxxxxxxxxxxxxxx"; +char const CreatureModelDatafmt[] = "nisxfxxxxxxxxxxffxxxxxxxxxxxxxx"; char const CreatureFamilyfmt[] = "nfifiiiiixsx"; char const CreatureSpellDatafmt[] = "niiiixxxx"; char const CreatureTypefmt[] = "nxx"; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 21d4981c5f..84ebe2451f 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2537,9 +2537,11 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float float halfHeight = GetCollisionHeight() * 0.5f; UpdateAllowedPositionZ(destx, desty, destz); - bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY), + + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(GetPhaseShift(), GetMap(), pos.m_positionX, pos.m_positionY); + bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(terrainMapId, pos.m_positionX, pos.m_positionY, pos.m_positionZ + halfHeight, - destx, desty, destz + halfHeight, + destx, desty, destz, destx, desty, destz, -0.5f); // collision occured @@ -2554,10 +2556,9 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float // check dynamic collision col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + halfHeight, - destx, desty, destz + halfHeight, + destx, desty, destz, destx, desty, destz, -0.5f); - // Collided with a gameobject if (col) { @@ -2773,7 +2774,7 @@ float WorldObject::GetFloorZ() const { if (!IsInWorld()) return m_staticFloorZ; - return std::max(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ())); + return std::max(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ() + GetCollisionHeight())); } float WorldObject::GetMapWaterOrGroundLevel(float x, float y, float z, float* ground/* = nullptr*/) const diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 42e3e335e8..7160069111 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13500,12 +13500,12 @@ void Unit::_ExitVehicle(Position const* exitPosition) if (player) player->SetFallInformation(0, GetPositionZ()); - float height = pos.GetPositionZ(); + float height = pos.GetPositionZ() + vehicle->GetBase()->GetCollisionHeight(); Movement::MoveSplineInit init(this); // Creatures without inhabit type air should begin falling after exiting the vehicle - if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f) + if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + vehicle->GetBase()->GetCollisionHeight(), &height)) init.SetFall(); init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false); @@ -14795,6 +14795,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/ target->SendDirectMessage(&data); } +// Returns collisionheight of the unit. If it is 0, it returns DEFAULT_COLLISION_HEIGHT. float Unit::GetCollisionHeight() const { float scaleMod = GetObjectScale(); // 99% sure about this @@ -14807,7 +14808,8 @@ float Unit::GetCollisionHeight() const { CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId()); CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId); - return scaleMod * (mountModelData->MountHeight + modelData->CollisionHeight * 0.5f); + float const collisionHeight = scaleMod * (mountModelData->MountHeight + modelData->CollisionHeight * modelData->Scale * displayInfo->scale * 0.5f); + return collisionHeight == 0.0f ? DEFAULT_COLLISION_HEIGHT : collisionHeight; } } } @@ -14816,7 +14818,8 @@ float Unit::GetCollisionHeight() const CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.AssertEntry(GetNativeDisplayId()); CreatureModelDataEntry const* modelData = sCreatureModelDataStore.AssertEntry(displayInfo->ModelId); - return scaleMod * modelData->CollisionHeight; + float const collisionHeight = scaleMod * modelData->CollisionHeight * modelData->Scale * displayInfo->scale; + return collisionHeight == 0.0f ? DEFAULT_COLLISION_HEIGHT : collisionHeight; } SpellInfo const* Unit::GetCastSpellInfo(SpellInfo const* spellInfo) const diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 8e0eedf5d3..7e763d5275 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2456,7 +2456,7 @@ float Map::GetStaticHeight(PhaseShift const& phaseShift, float x, float y, float if (GridMap* gmap = m_parentTerrainMap->GetGrid(terrainMapId, x, y)) { float gridHeight = gmap->getHeight(x, y); - if (z > gridHeight) + if (G3D::fuzzyGe(z, gridHeight - GROUND_HEIGHT_TOLERANCE)) mapHeight = gridHeight; } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 4cdffddeee..10831fb594 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -1354,6 +1354,36 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation()); break; } + case TARGET_DEST_CASTER_FRONT_LEAP: + { + Unit* unitCaster = m_caster->ToUnit(); + if (!unitCaster) + break; + + float dist = m_spellInfo->Effects[effIndex].CalcRadius(unitCaster); + float angle = targetType.CalcDirectionAngle(); + + Position pos = dest._position; + + unitCaster->MovePositionToFirstCollision(pos, dist, angle); + // Generate path to that point. + if (!m_preGeneratedPath) + m_preGeneratedPath = std::make_unique(unitCaster); + + m_preGeneratedPath->SetPathLengthLimit(dist); + + // Should we use straightline here ? What do we do when we don't have a full path ? + bool pathResult = m_preGeneratedPath->CalculatePath(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), false, true); + if (pathResult && m_preGeneratedPath->GetPathType() & (PATHFIND_NORMAL | PATHFIND_SHORTCUT)) + { + pos.m_positionX = m_preGeneratedPath->GetActualEndPosition().x; + pos.m_positionY = m_preGeneratedPath->GetActualEndPosition().y; + pos.m_positionZ = m_preGeneratedPath->GetActualEndPosition().z; + } + + dest.Relocate(pos); + break; + } default: { float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 0e0f087426..91621c0fe4 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4297,7 +4297,6 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/) return; Position pos = destTarget->GetPosition(); - pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()), 0.0f); unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster); }