void DoAction(const int32 actionId) { switch (actionId) { case ACTION_OUTRO: { Position pos; if (Creature* pIck = GetIck()) { // TODO: tele on Ick then run some distance. pIck->GetNearPosition(pos, 5.0f, 3.14f); me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0.0f); } me->SetVisible(true); Creature* pJainaOrSylvanas = me->GetCreature(*me, pInstance->GetData64(DATA_JAINA_SYLVANAS_1)); if (pJainaOrSylvanas) { Position pos; me->GetNearPosition(pos, 5.0f, 0); pJainaOrSylvanas->NearTeleportTo( pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetAngle(me->GetPositionX(), me->GetPositionY())); } else { if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE) pJainaOrSylvanas = me->SummonCreature( NPC_SYLVANAS_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN); else pJainaOrSylvanas = me->SummonCreature(NPC_JAINA_PART1, *me, TEMPSUMMON_MANUAL_DESPAWN); } if (pJainaOrSylvanas) { pJainaOrSylvanas->SetOrientation( pJainaOrSylvanas->GetAngle(me->GetPositionX(), me->GetPositionY())); me->SetOrientation( me->GetAngle(pJainaOrSylvanas->GetPositionX(), pJainaOrSylvanas->GetPositionY())); uiNpcOutroDialog = pJainaOrSylvanas->GetGUID(); } phase = PHASE_OUTRO; events.Reset(); events.ScheduleEvent(EVENT_OUTRO_1, 1000); break; } } }
// basic detection void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode) { uint32 key = player->GetGUIDLow(); if (opcode != MSG_MOVE_HEARTBEAT || m_Players[key].GetLastOpcode() != MSG_MOVE_HEARTBEAT) return; // in this case we don't care if they are "legal" flags, they are handled in another parts of the Anticheat Manager. if (player->IsInWater() || player->IsFlying() || player->IsFalling()) return; Position playerPos; float deltaZ = fabs(playerPos.GetPositionZ() - movementInfo.pos.GetPositionZ()); float deltaXY = movementInfo.pos.GetExactDist2d(&playerPos); float angle = Position::NormalizeOrientation(tan(deltaZ/deltaXY)); if (angle > CLIMB_ANGLE) { Report(player, WALLCLIMB_HACK); } }
bool Position::IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const { // rotate the WorldObject position instead of rotating the whole cube, that way we can make a simplified // is-in-cube check and we have to calculate only one point instead of 4 // 2PI = 360*, keep in mind that ingame orientation is counter-clockwise double rotation = 2 * M_PI - center.GetOrientation(); double sinVal = std::sin(rotation); double cosVal = std::cos(rotation); float BoxDistX = GetPositionX() - center.GetPositionX(); float BoxDistY = GetPositionY() - center.GetPositionY(); float rotX = float(center.GetPositionX() + BoxDistX * cosVal - BoxDistY*sinVal); float rotY = float(center.GetPositionY() + BoxDistY * cosVal + BoxDistX*sinVal); // box edges are parallel to coordiante axis, so we can treat every dimension independently :D float dz = GetPositionZ() - center.GetPositionZ(); float dx = rotX - center.GetPositionX(); float dy = rotY - center.GetPositionY(); if ((std::fabs(dx) > xradius) || (std::fabs(dy) > yradius) || (std::fabs(dz) > zradius)) return false; return true; }
void Vehicle::Relocate(Position pos) { sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Relocate %u", _me->GetEntry()); std::set<Unit*> vehiclePlayers; for (int8 i = 0; i < 8; i++) vehiclePlayers.insert(GetPassenger(i)); // passengers should be removed or they will have movement stuck RemoveAllPassengers(); for (std::set<Unit*>::const_iterator itr = vehiclePlayers.begin(); itr != vehiclePlayers.end(); ++itr) { if (Unit* plr = (*itr)) { // relocate/setposition doesn't work for player plr->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); //plr->TeleportTo(pPlayer->GetMapId(), triggerPos.GetPositionX(), triggerPos.GetPositionY(), triggerPos.GetPositionZ(), triggerPos.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT); } } _me->UpdatePosition(pos, true); // problems, and impossible to do delayed enter //pPlayer->EnterVehicle(veh); }
void Position::RelocateOffset(const Position & offset) { m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + float(M_PI))); m_positionY = GetPositionY() + (offset.GetPositionY() * std::cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation())); m_positionZ = GetPositionZ() + offset.GetPositionZ(); SetOrientation(GetOrientation() + offset.GetOrientation()); }
// basic detection void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode) { if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & CLIMB_HACK_DETECTION) == 0) return; uint32 key = player->GetGUIDLow(); if (opcode != MSG_MOVE_HEARTBEAT || m_Players[key].GetLastOpcode() != MSG_MOVE_HEARTBEAT) return; // in this case we don't care if they are "legal" flags, they are handled in another parts of the Anticheat Manager. if (player->IsInWater() || player->IsFlying() || player->IsFalling()) return; Position playerPos; Position pos = player->GetPosition(); float deltaZ = fabs(playerPos.GetPositionZ() - movementInfo.pos.GetPositionZ()); float deltaXY = movementInfo.pos.GetExactDist2d(&playerPos); float angle = Position::NormalizeOrientation(tan(deltaZ/deltaXY)); if (angle > CLIMB_ANGLE) { TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Climb-Hack detected player GUID (low) %u", player->GetGUIDLow()); BuildReport(player,CLIMB_HACK_REPORT); } }
bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* caster, SpellInfo const* spell, Position const& pos) { SetMap(caster->GetMap()); Relocate(pos); if (!IsPositionValid()) { TC_LOG_ERROR("misc", "AreaTrigger (spell %u) not created. Invalid coordinates (X: %f Y: %f)", spell->Id, GetPositionX(), GetPositionY()); return false; } WorldObject::_Create(guidlow, HIGHGUID_AREATRIGGER, caster->GetPhaseMask()); SetEntry(triggerEntry); SetDuration(spell->GetDuration()); SetObjectScale(1); SetUInt32Value(AREATRIGGER_SPELLID, spell->Id); SetUInt32Value(AREATRIGGER_SPELLVISUALID, spell->SpellVisual[0]); SetUInt32Value(AREATRIGGER_DURATION, spell->GetDuration()); SetFloatValue(AREATRIGGER_FINAL_POS + 0, pos.GetPositionX()); SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY()); SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ()); for (auto phase : caster->GetPhases()) SetInPhase(phase, false, true); if (!GetMap()->AddToMap(this)) return false; return true; }
TempSummon* SummonKrikThik(uint32 creatureId) { float angle = frand(0, 2*M_PI); float x = CenterPos.GetPositionX() + (RADIUS_CIRCLE * std::cos(angle)); float y = CenterPos.GetPositionY() + (RADIUS_CIRCLE * std::sin(angle)); return me->SummonCreature(creatureId, x, y, CenterPos.GetPositionZ()); }
void UpdateAI(const uint32 diff) { if (!UpdateVictim() || me->HasUnitState(UNIT_STAT_CASTING)) return; if ((me->HealthBelowPct(69) && Phase == 0) || (me->HealthBelowPct(34) && Phase == 1)) { Phase++; // Switch Position with a random Shadow of Obsidius and empty Threat list Creature* target = ShadowOfObsidiusList[urand(0,RAID_MODE(1,2))]; Position telePos; me->GetPosition(&telePos); // Switch Positions me->NearTeleportTo(target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0); target->NearTeleportTo(telePos.GetPositionX(),telePos.GetPositionY(),telePos.GetPositionZ(),0); // Resetts Aggro me->getThreatManager().resetAllAggro(); me->MonsterYell("Your kind has no place in the master's world.", LANG_UNIVERSAL, NULL); return; } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_THUNDERCLAP: DoCastAOE(SPELL_THUNDERCLAP); events.ScheduleEvent(EVENT_THUNDERCLAP, 7000); break; case EVENT_TWILIGHT_CORRUPTION: if(Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true)) DoCast(pTarget,SPELL_TWILIGHT_CORRUPTION); events.ScheduleEvent(EVENT_TWILIGHT_CORRUPTION, 10000); break; case EVENT_STONE_BLOW: DoCastVictim(SPELL_STONE_BLOW); events.ScheduleEvent(EVENT_STONE_BLOW, 13000); break; default: break; } } DoMeleeAttackIfReady(); }
void PeriodicTick(constAuraEffectPtr aurEff) { if (!GetCaster()) return; count++; Position pos; GetCaster()->GetNearPosition(pos, 4.0f * count, 0.0f); GetCaster()->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_FLAME_BREATH_1, true); }
void Position::GetPositionOffsetTo(const Position & endPos, Position & retOffset) const { float dx = endPos.GetPositionX() - GetPositionX(); float dy = endPos.GetPositionY() - GetPositionY(); retOffset.m_positionX = dx * std::cos(GetOrientation()) + dy * std::sin(GetOrientation()); retOffset.m_positionY = dy * std::cos(GetOrientation()) - dx * std::sin(GetOrientation()); retOffset.m_positionZ = endPos.GetPositionZ() - GetPositionZ(); retOffset.SetOrientation(endPos.GetOrientation() - GetOrientation()); }
/// @todo this should be handled in map, maybe add a summon function in map // There is no other way afaik... void SpawnGameObject(uint32 entry, Position const& pos) { GameObject* go = new GameObject(); if (!go->Create(instance->GenerateLowGuid<HighGuid::GameObject>(), entry, instance, PHASEMASK_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0, 0, 0, 0, 120, GO_STATE_READY)) { delete go; return; } instance->AddToMap(go); }
void HandleDummy(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); if (Unit* target = GetHitUnit()) { Position pos; target->GetFirstCollisionPosition(pos, 5.0f, M_PI); GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true); GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH); GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation()); } }
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 sender, uint32 action) { player->PlayerTalkClass->ClearMenus(); player->CLOSE_GOSSIP_MENU(); if (action >= 4) return false; Position loc = blackrock_depths_locs[action]; if (!player->isInCombat()) player->NearTeleportTo(loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), false); return true; }
/// @todo this should be handled in map, maybe add a summon function in map // There is no other way afaik... void SpawnGameObject(uint32 entry, Position& pos) { GameObject* go = new GameObject; if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, instance, PHASEMASK_NORMAL, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), 0, 0, 0, 0, 120, GO_STATE_READY)) { delete go; return; } instance->AddToMap(go); }
void HandleDummy(SpellEffIndex effIndex) { int32 damage = GetEffectValue(); Spell* baseSpell = GetSpell(); Position pos; Unit* caster = GetCaster(); if (Unit* target = GetHitUnit()) { GetSummonPosition(effIndex, pos, 0.0f, 0); if (!target->HasAuraType(SPELL_AURA_DEFLECT_SPELLS)) // Deterrence target->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), damage, true); } }
void AreaTrigger::UpdateCircularMovementPosition(uint32 /*diff*/) { if (_circularMovementInfo->StartDelay > GetElapsedTimeForMovement()) return; _circularMovementInfo->ElapsedTimeForMovement = GetElapsedTimeForMovement() - _circularMovementInfo->StartDelay; Position pos = CalculateCircularMovementPosition(); GetMap()->AreaTriggerRelocation(this, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); #ifdef TRINITY_DEBUG DebugVisualizePosition(); #endif }
void PeriodicTick(AuraEffect const* aurEff) { if (!GetCaster()) return; count++; if (count > 11) { GetCaster()->RemoveAura(SPELL_COLDFLAME); return; } Position pos; GetCaster()->GetNearPosition(pos, 3.0f * (count / 2), 0.0f); GetCaster()->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_COLDFLAME_DMG, true); }
void Vehicle::Relocate(Position pos) { std::set<Unit*> vehiclePlayers; for(int8 i = 0; i < 8; i++) vehiclePlayers.insert(GetPassenger(i)); // passengers should be removed or they will have movement stuck RemoveAllPassengers(); for(std::set<Unit*>::const_iterator itr = vehiclePlayers.begin(); itr != vehiclePlayers.end(); ++itr) { if(Unit* plr = (*itr)) plr->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); } _me->SetPosition(pos, true); }
void UpdateAI(uint32 diff) { if (!UpdateVictim()) return; if (_phase == PHASE_GLOB && summons.empty()) { DoResetThreat(); me->NearTeleportTo(ViscidusCoord.GetPositionX(), ViscidusCoord.GetPositionY(), ViscidusCoord.GetPositionZ(), ViscidusCoord.GetOrientation()); _hitcounter = 0; _phase = PHASE_FROST; InitSpells(); me->SetVisible(true); } events.Update(diff); while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_POISONBOLT_VOLLEY: DoCast(me, SPELL_POISONBOLT_VOLLEY); events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000)); break; case EVENT_POISON_SHOCK: DoCast(me, SPELL_POISON_SHOCK); events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000)); break; case EVENT_RESET_PHASE: _hitcounter = 0; _phase = PHASE_FROST; break; default: break; } } if (_phase != PHASE_GLOB) DoMeleeAttackIfReady(); }
void FleeingMovementGenerator<T>::SetTargetLocation(T* owner) { if (!owner || !owner->IsAlive()) return; if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || owner->IsMovementPreventedByCasting()) { MovementGenerator::AddFlag(MOVEMENTGENERATOR_FLAG_INTERRUPTED); owner->StopMoving(); _path = nullptr; return; } Position destination = owner->GetPosition(); GetPoint(owner, destination); // Add LOS check for target point if (!owner->IsWithinLOS(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ())) { _timer.Reset(200); return; } if (!_path) { _path = std::make_unique<PathGenerator>(owner); _path->SetPathLengthLimit(30.0f); } bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); if (!result || (_path->GetPathType() & PATHFIND_NOPATH)) { _timer.Reset(100); return; } owner->AddUnitState(UNIT_STATE_FLEEING_MOVE); Movement::MoveSplineInit init(owner); init.MovebyPath(_path->GetPath()); init.SetWalk(false); int32 traveltime = init.Launch(); _timer.Reset(traveltime + urand(800, 1500)); }
void HandleTriggerSpell(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); PreventHitEffect(EFFECT_0); PreventHitEffect(EFFECT_1); std::list<Creature*> unitList; Unit* target = NULL; caster->GetCreaturesWithEntryInRange(unitList, 30.0f, NPC_BLUE_RACER); if (!unitList.empty()) for (std::list<Creature*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr) if (caster->HasInLine((*itr), 1.0f) && (*itr)->GetGUID() != caster->GetGUID()) { target = (*itr); break; } if (!target) { unitList.clear(); caster->GetCreaturesWithEntryInRange(unitList, 30.0f, NPC_RED_RACER); if (!unitList.empty()) for (std::list<Creature*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr) if (caster->HasInLine((*itr), 1.0f) && (*itr)->GetGUID() != caster->GetGUID()) { target = (*itr); break; } } if (target) { caster->CastSpell(target, SPELL_RACER_CHARGE_TO_OBJECT, true); caster->CastSpell(target, SPELL_RACER_SLAM_HIT, true); } else { Position pos; float x = caster->GetPositionX()+30*cos(caster->GetOrientation()); float y = caster->GetPositionY()+30*sin(caster->GetOrientation()); pos.Relocate(x, y, caster->GetMap()->GetHeight(x, y, MAX_HEIGHT)+0.5f); //caster->GetFirstCollisionPosition(pos, 30.0f, caster->GetOrientation()); caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_RACER_CHARGE_TO_OBJECT, true); } }
void MovementInform(uint32 type, uint32 id) { if (type == POINT_MOTION_TYPE) { switch (id) { case 8: m_pPointData = GetMoveData(); if (m_pPointData) { me->SetSpeed(MOVE_FLIGHT, 1.0f); me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); } break; case 9: me->GetMotionMaster()->MoveChase(me->getVictim()); m_uiBellowingRoarTimer = 1000; break; case 10: me->SetFlying(true); me->GetMotionMaster()->MovePoint(11, Phase2Location.GetPositionX(), Phase2Location.GetPositionY(), Phase2Location.GetPositionZ() + 25); me->SetSpeed(MOVE_FLIGHT, 1.0f); DoScriptText(SAY_PHASE_2_TRANS, me); if (instance) instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase); m_uiWhelpTimer = 5000; m_uiLairGuardTimer = 15000; break; case 11: if (m_pPointData) me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ); me->GetMotionMaster()->Clear(false); me->GetMotionMaster()->MoveIdle(); break; default: m_bIsMoving = false; break; } } }
void FillPath(Position const& pos, Movement::PointsArray& path) { G3D::Vector3 point; point.x = pos.GetPositionX(); point.y = pos.GetPositionY(); point.z = pos.GetPositionZ(); point.x -= 1.0f; path.push_back(point); point.x += 1.0f; path.push_back(point); point.z += 25.0f; path.push_back(point); path.push_back(point); }
void MovementInform(uint32 uiType, uint32 uiId) { if (uiType != POINT_MOTION_TYPE) return; switch (uiId) { case 0: me->GetMotionMaster()->MovePoint(1, HomeLocation.GetPositionX(), HomeLocation.GetPositionY(), HomeLocation.GetPositionZ()); me->SetHomePosition(HomeLocation); break; case 1: me->RemoveFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); break; } }
void HandlePull(SpellEffIndex effIndex) { PreventHitDefaultEffect(effIndex); Unit* target = GetHitUnit(); if (!target) return; Position pos; if (target->GetDistance(GetCaster()) < 5.0f) { float o = frand(0, 2*M_PI); pos.Relocate(GetCaster()->GetPositionX() + 4.0f*cos(o), GetCaster()->GetPositionY() + 4.0f*sin(o), GetCaster()->GetPositionZ()+frand(10.0f, 15.0f)); } else pos.Relocate(GetCaster()->GetPositionX(), GetCaster()->GetPositionY(), GetCaster()->GetPositionZ()+1.0f); float speedXY = float(GetSpellInfo()->Effects[effIndex].MiscValue) * 0.1f; float speedZ = target->GetDistance(pos) / speedXY * 0.5f * Movement::gravity; target->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ); }
void SpellHit(Unit * caster, const SpellEntry * spell) { if (spell->Id == SPELL_SUMMON_BLIZZARD) { uint64 AranGUID = 0; if (instance) AranGUID = instance->GetData64(DATA_SHADE_OF_ARAN); me->CastSpell(me, SPELL_CIRCULAR_BLIZZARD, false, 0, 0, AranGUID); ChangeBlizzardWaypointsOrder(urand(0, 7)); pos.m_positionX = blizzardWaypoints[0][0]; pos.m_positionY = blizzardWaypoints[1][0]; pos.m_positionZ = me->GetPositionZ(); DoTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); currentWaypoint = 0; waypointTimer = 0; move = true; } }
void Vehicle::Relocate (Position pos) { sLog->outDebug(LOG_FILTER_VEHICLES, "Vehicle::Relocate %u", me->GetEntry()); std::set<Unit*> vehiclePlayers; for (int8 i = 0; i < 8; i++) vehiclePlayers.insert(GetPassenger(i)); // passengers should be removed or they will have movement stuck RemoveAllPassengers(); for (std::set<Unit*>::const_iterator itr = vehiclePlayers.begin(); itr != vehiclePlayers.end(); ++itr) { if (Unit* player = (*itr)) { // relocate/setposition doesn't work for player player->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()); } } me->UpdatePosition(pos, true); }
void UpdateAI(const uint32 diff) { if (!pInstance) return; if (pInstance) if (pInstance->GetBossState(DATA_GUNSHIP_EVENT) != IN_PROGRESS) return; if (IsPortalMage) return; if (me->isAlive() && IsCasting && !me->HasUnitState(UNIT_STATE_CASTING)) me->CastSpell(me, SPELL_BEHIND_ZERO, false); if (!MovementDone) { Transport * pTransport = GetTransportByGUID(me, pInstance->GetData64(DATA_GUNSHIP_TRANSPORT_SECOND)); if (!pTransport) return; Position correctPosition; if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE) correctPosition = HordeIceMageCastPosition; else correctPosition = AllyIceMageCastPosition; float x = correctPosition.GetPositionX(); float y = correctPosition.GetPositionY(); float z = correctPosition.GetPositionZ(); me->GetMotionMaster()->MovePoint(MOVE_ICE_MAGE, Transport::getX(x, y, pTransport), Transport::getY(x, y, pTransport), Transport::getZ(z, pTransport)); MovementDone = true; } }
void MotionMaster::MoveFall(uint32 id/*=0*/) { // use larger distance for vmap height search than in most other cases float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseMask(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);; // try to find ground Z if (tz <= INVALID_HEIGHT) tz = _owner->GetMap()->GetHeight(_owner->GetPhaseMask(), _owner->GetPositionX(), _owner->GetPositionY(), MAX_HEIGHT, true, MAX_FALL_DISTANCE); if (tz <= INVALID_HEIGHT) { TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).", _owner->GetMap()->GetId(), _owner->GetPositionX(), _owner->GetPositionX(), _owner->GetPositionZ()); return; } // Abort too if the ground is very near if (fabs(_owner->GetPositionZ() - tz) < 0.1f) return; if (_owner->GetTypeId() == TYPEID_PLAYER) { _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING); _owner->m_movementInfo.SetFallTime(0); } Position pos = _owner->GetPosition(); pos.m_positionZ = tz; _owner->GetFirstCollisionPosition(pos, fabs(_owner->GetPositionZ() - tz), 0); tz = pos.GetPositionZ(); Movement::MoveSplineInit init(_owner); init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz); init.SetFall(); init.Launch(); Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED); }