Mant more cmangos Cata commits applied

Commit:
This commit is contained in:
Charles A Edwards 2016-08-29 15:51:13 +01:00 committed by Antz
parent 6db0ba8ae9
commit 8cac2f42db
51 changed files with 964 additions and 270 deletions

View file

@ -5384,14 +5384,13 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect)
if (summon_prop->Group == SUMMON_PROP_GROUP_PETS && prop_id != 1562)
{
DoSummonPet(effect);
return;
}
// Expected Amount: TODO - there are quite some exceptions (like totems, engineering dragonlings..)
uint32 amount = damage > 0 ? damage : 1;
// basepoints of SUMMON_PROP_GROUP_VEHICLE is often a spellId, set amount to 1
if (summon_prop->Group == SUMMON_PROP_GROUP_VEHICLE)
if (summon_prop->Group == SUMMON_PROP_GROUP_VEHICLE || summon_prop->Group == SUMMON_PROP_GROUP_UNCONTROLLABLE_VEHICLE || summon_prop->Group == SUMMON_PROP_GROUP_CONTROLLABLE)
amount = 1;
// Get casting object
@ -5552,6 +5551,7 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect)
break;
}
case SUMMON_PROP_GROUP_VEHICLE:
case SUMMON_PROP_GROUP_UNCONTROLLABLE_VEHICLE:
{
summonResult = DoSummonVehicle(summonPositions, summon_prop, effect, level);
break;
@ -5750,17 +5750,30 @@ bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntr
if (m_duration > 0)
spawnCreature->SetDuration(m_duration);
CreatureInfo const* cInfo = spawnCreature->GetCreatureInfo();
// spawnCreature->SetName(""); // generated by client
spawnCreature->SetOwnerGuid(m_caster->GetObjectGuid());
spawnCreature->SetPowerType(POWER_MANA);
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, spawnCreature->GetCreatureInfo()->NpcFlags);
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, cInfo->UnitFlags);
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, cInfo->NpcFlags);
spawnCreature->setFaction(m_caster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
spawnCreature->SetCreatorGuid(m_caster->GetObjectGuid());
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
spawnCreature->InitStatsForLevel(level, m_caster);
spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false);
spawnCreature->InitStatsForLevel(level);
if (CharmInfo* charmInfo = spawnCreature->GetCharmInfo())
{
charmInfo->SetPetNumber(pet_number, false);
if (spawnCreature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE))
charmInfo->SetReactState(REACT_PASSIVE);
else if ((cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_NO_MELEE) || petType == PROTECTOR_PET)
charmInfo->SetReactState(REACT_DEFENSIVE);
else
charmInfo->SetReactState(REACT_AGGRESSIVE);
}
m_caster->AddGuardian(spawnCreature);
}
@ -10721,24 +10734,159 @@ void Spell::EffectBlock(SpellEffectEntry const* /*effect*/)
void Spell::EffectLeapForward(SpellEffectEntry const* effect)
{
if (unitTarget->IsTaxiFlying())
return;
float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->rangeIndex));
const float IN_OR_UNDER_LIQUID_RANGE = 0.8f; // range to make player under liquid or on liquid surface from liquid level
if (m_spellInfo->rangeIndex == SPELL_RANGE_IDX_SELF_ONLY)
G3D::Vector3 prevPos, nextPos;
float orientation = unitTarget->GetOrientation();
prevPos.x = unitTarget->GetPositionX();
prevPos.y = unitTarget->GetPositionY();
prevPos.z = unitTarget->GetPositionZ();
float groundZ = prevPos.z;
// falling case
if (!unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), prevPos.x, prevPos.y, groundZ, 3.0f) && unitTarget->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING))
{
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex()));
nextPos.x = prevPos.x + dist * cos(orientation);
nextPos.y = prevPos.y + dist * sin(orientation);
nextPos.z = prevPos.z - 2.0f; // little hack to avoid the impression to go up when teleporting instead of continue to fall. This value may need some tweak
// before caster
float fx, fy, fz;
unitTarget->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis);
float ox, oy, oz;
unitTarget->GetPosition(ox, oy, oz);
//
GridMapLiquidData liquidData;
if (unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData))
{
if (fabs(nextPos.z - liquidData.level) < 10.0f)
nextPos.z = liquidData.level - IN_OR_UNDER_LIQUID_RANGE;
}
else
{
// fix z to ground if near of it
unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, nextPos.z, 10.0f);
}
if (unitTarget->GetMap()->GetHitPosition(ox, oy, oz + 0.5f, fx, fy, fz, unitTarget->GetPhaseMask(), -0.5f))
unitTarget->UpdateAllowedPositionZ(fx, fy, fz);
// check any obstacle and fix coords
unitTarget->GetMap()->GetHitPosition(prevPos.x, prevPos.y, prevPos.z + 0.5f, nextPos.x, nextPos.y, nextPos.z, unitTarget->GetPhaseMask(), -0.5f);
unitTarget->NearTeleportTo(fx, fy, fz, unitTarget->GetOrientation(), unitTarget == m_caster);
// teleport
unitTarget->NearTeleportTo(nextPos.x, nextPos.y, nextPos.z, orientation, unitTarget == m_caster);
//sLog.outString("Falling BLINK!");
return;
}
// fix origin position if player was jumping and near of the ground but not in ground
if (fabs(prevPos.z - groundZ) > 0.5f)
prevPos.z = groundZ;
//check if in liquid
bool isPrevInLiquid = unitTarget->GetMap()->GetTerrain()->IsInWater(prevPos.x, prevPos.y, prevPos.z);
const float step = 2.0f; // step length before next check slope/edge/water
const float maxSlope = 50.0f; // 50(degree) max seem best value for walkable slope
const float MAX_SLOPE_IN_RADIAN = maxSlope / 180.0f * M_PI_F;
float nextZPointEstimation = 1.0f;
float destx = prevPos.x + dist * cos(orientation);
float desty = prevPos.y + dist * sin(orientation);
const uint32 numChecks = ceil(fabs(dist / step));
const float DELTA_X = (destx - prevPos.x) / numChecks;
const float DELTA_Y = (desty - prevPos.y) / numChecks;
for (uint32 i = 1; i < numChecks + 1; ++i)
{
// compute next point average position
nextPos.x = prevPos.x + DELTA_X;
nextPos.y = prevPos.y + DELTA_Y;
nextPos.z = prevPos.z + nextZPointEstimation;
bool isInLiquid = false;
bool isInLiquidTested = false;
bool isOnGround = false;
GridMapLiquidData liquidData;
// try fix height for next position
if (!unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, nextPos.z))
{
// we cant so test if we are on water
if (!unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData))
{
// not in water and cannot get correct height, maybe flying?
//sLog.outString("Can't get height of point %u, point value %s", i, nextPos.toString().c_str());
nextPos = prevPos;
break;
}
else
{
isInLiquid = true;
isInLiquidTested = true;
}
}
else
isOnGround = true; // player is on ground
if (isInLiquid || (!isInLiquidTested && unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData)))
{
if (!isPrevInLiquid && fabs(liquidData.level - prevPos.z) > 2.0f)
{
// on edge of water with difference a bit to high to continue
//sLog.outString("Ground vs liquid edge detected!");
nextPos = prevPos;
break;
}
if ((liquidData.level - IN_OR_UNDER_LIQUID_RANGE) > nextPos.z)
nextPos.z = prevPos.z; // we are under water so next z equal prev z
else
nextPos.z = liquidData.level - IN_OR_UNDER_LIQUID_RANGE; // we are on water surface, so next z equal liquid level
isInLiquid = true;
float ground = nextPos.z;
if (unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, ground))
{
if (nextPos.z < ground)
{
nextPos.z = ground;
isOnGround = true; // player is on ground of the water
}
}
}
//unitTarget->SummonCreature(VISUAL_WAYPOINT, nextPos.x, nextPos.y, nextPos.z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
float hitZ = nextPos.z + 1.5f;
if (unitTarget->GetMap()->GetHitPosition(prevPos.x, prevPos.y, prevPos.z + 1.5f, nextPos.x, nextPos.y, hitZ, unitTarget->GetPhaseMask(), -1.0f))
{
//sLog.outString("Blink collision detected!");
nextPos = prevPos;
break;
}
if (isOnGround)
{
// project vector to get only positive value
float ac = fabs(prevPos.z - nextPos.z);
// compute slope (in radian)
float slope = atan(ac / step);
// check slope value
if (slope > MAX_SLOPE_IN_RADIAN)
{
//sLog.outString("bad slope detected! %4.2f max %4.2f, ac(%4.2f)", slope * 180 / M_PI_F, maxSlope, ac);
nextPos = prevPos;
break;
}
//sLog.outString("slope is ok! %4.2f max %4.2f, ac(%4.2f)", slope * 180 / M_PI_F, maxSlope, ac);
}
//sLog.outString("point %u is ok, coords %s", i, nextPos.toString().c_str());
nextZPointEstimation = (nextPos.z - prevPos.z) / 2.0f;
isPrevInLiquid = isInLiquid;
prevPos = nextPos;
}
unitTarget->NearTeleportTo(nextPos.x, nextPos.y, nextPos.z, orientation, unitTarget == m_caster);
}
void Spell::EffectLeapBack(SpellEffectEntry const* effect)
@ -10922,11 +11070,18 @@ void Spell::EffectPlayerPull(SpellEffectEntry const* effect)
if (!unitTarget)
return;
float dist = unitTarget->GetDistance2d(m_caster);
if (damage && dist > damage)
dist = float(damage);
float x, y, z;
m_caster->GetPosition(x, y, z);
unitTarget->KnockBackFrom(m_caster, -dist, float(effect->EffectMiscValue) / 10);
// move back a bit
x = x - (0.6 * cos(m_caster->GetOrientation() + M_PI_F));
y = y - (0.6 * sin(m_caster->GetOrientation() + M_PI_F));
// Try to normalize Z coord because GetContactPoint do nothing with Z axis
unitTarget->UpdateAllowedPositionZ(x, y, z);
float speed = m_spellInfo->speed ? m_spellInfo->speed : 27.0f;
unitTarget->GetMotionMaster()->MoveJump(x, y, z, speed, 2.5f);
}
void Spell::EffectDispelMechanic(SpellEffectEntry const* effect)