mirror of
https://github.com/mangosfour/server.git
synced 2025-12-29 16:37:04 +00:00
Mant more cmangos Cata commits applied
Commit:
This commit is contained in:
parent
6db0ba8ae9
commit
8cac2f42db
51 changed files with 964 additions and 270 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue