Exemplo n.º 1
0
void MOTransport::Update(uint32 update_diff, uint32 p_time)
{
    UpdateSplineMovement(p_time);

    if (!movespline->Finalized())
        return;

    if (m_WayPoints.size() <= 1)
        return;

    bool anchorage = !m_anchorageTimer.Passed();
    if (anchorage)
        m_anchorageTimer.Update(update_diff);

    m_timer = WorldTimer::getMSTime() % GetPeriod(true);
    while (((m_timer - m_curr->first) % m_pathTime) > ((m_next->first - m_curr->first) % m_pathTime))
    {

        DoEventIfAny(*m_curr,true);
        MoveToNextWayPoint();

        // delay detect
        if (m_next->second.delay > 0)
        {
            m_anchorageTimer.SetInterval(m_next->first - m_next->second.delay);
            m_anchorageTimer.Reset();
        }
        DoEventIfAny(*m_curr,false);

        if (!SetPosition(m_curr->second.loc, m_curr->second.teleport))
        {
            if (m_curr->second.loc.GetMapId() == m_next->second.loc.GetMapId() &&
                !m_curr->second.teleport &&
                m_anchorageTimer.Passed() &&
                !(m_curr->second.loc == m_next->second.loc))
            {
                // FIXME - use MovementGenerator instead this
                DEBUG_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES,"Transport::Update %s start spline movement to %f %f %f",GetObjectGuid().GetString().c_str(), m_next->second.loc.x, m_next->second.loc.y, m_next->second.loc.z);
                Movement::MoveSplineInit<GameObject*> init(*this);
                init.MoveTo((Vector3)m_next->second.loc);
                init.SetVelocity(GetGOInfo()->moTransport.moveSpeed);
                init.Launch();
            }
        }
        m_nextNodeTime = m_curr->first;

        DEBUG_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES, "Transport::Update %s moved to %f %f %f %d %s, next keyframe %u", GetObjectGuid().GetString().c_str(), m_curr->second.loc.x, m_curr->second.loc.y, m_curr->second.loc.z, m_curr->second.loc.GetMapId(), m_curr == m_WayPoints.begin() ? "begin move" : "", m_nextNodeTime);
    }
}
Exemplo n.º 2
0
void Transport::Update( uint32 update_diff, uint32 /*p_time*/)
{
    if (m_WayPoints.size() <= 1)
        return;

    m_timer = WorldTimer::getMSTime() % m_period;
    while (((m_timer - m_curr->first) % m_pathTime) > ((m_next->first - m_curr->first) % m_pathTime))
    {

        DoEventIfAny(*m_curr,true);

        MoveToNextWayPoint();

        DoEventIfAny(*m_curr,false);

        // first check help in case client-server transport coordinates de-synchronization
        if (m_curr->second.mapid != GetMapId() || m_curr->second.teleport)
        {
            TeleportTransport(m_curr->second.mapid, m_curr->second.x, m_curr->second.y, m_curr->second.z);
        }
        else
        {
            Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z);
        }

        /*
        for(PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();)
        {
            PlayerSet::const_iterator it2 = itr;
            ++itr;
            //(*it2)->SetPosition( m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO() );
        }
        */

        m_nextNodeTime = m_curr->first;

        if (m_curr == m_WayPoints.begin())
            DETAIL_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES, " ************ BEGIN ************** %s", GetName());

        DETAIL_FILTER_LOG(LOG_FILTER_TRANSPORT_MOVES, "%s moved to %f %f %f %d", GetName(), m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid);
    }
}
Exemplo n.º 3
0
void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z)
{
    Map const* oldMap = GetMap();
    Relocate(x, y, z);

    // we need to create and save new Map object with 'newMapid' because if not done -> lead to invalid Map object reference...
    // player far teleport would try to create same instance, but we need it NOW for transport...
    RemoveFromWorld();
    ResetMap();
    Map* newMap = sMapMgr->CreateBaseMap(newMapid);
    SetMap(newMap);
    ASSERT(GetMap());
    AddToWorld();

    for (UnitSet::iterator itr = _passengers.begin(); itr != _passengers.end();)
    {
        Unit* passenger = *itr;
        ++itr;

        switch (passenger->GetTypeId())
        {
            case TYPEID_UNIT:
                passenger->ToCreature()->FarTeleportTo(newMap, x, y, z, passenger->GetOrientation());
                break;
            case TYPEID_PLAYER:
                if (passenger->isDead() && !passenger->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
                    passenger->ToPlayer()->ResurrectPlayer(1.0f);
                passenger->ToPlayer()->TeleportTo(newMapid, x, y, z, GetOrientation(), TELE_TO_NOT_LEAVE_TRANSPORT);
                break;
        }
    }

    if (oldMap != newMap)
    {
        UpdateForMap(oldMap);
        UpdateForMap(newMap);
    }

    MoveToNextWayPoint();
}
Exemplo n.º 4
0
bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids)
{
    if (pathid >= sTaxiPathNodesByPath.size())
        return false;

    TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid];

    std::vector<keyFrame> keyFrames;
    int mapChange = 0;
    mapids.clear();
    for (size_t i = 1; i < path.size() - 1; ++i)
    {
        if (mapChange == 0)
        {
            TaxiPathNodeEntry const& node_i = path[i];
            if (node_i.mapid == path[i+1].mapid)
            {
                keyFrame k(node_i);
                keyFrames.push_back(k);
                mapids.insert(k.node->mapid);
            }
            else
            {
                mapChange = 1;
            }
        }
        else
        {
            --mapChange;
        }
    }

    int lastStop = -1;
    int firstStop = -1;

    // first cell is arrived at by teleportation :S
    keyFrames[0].distFromPrev = 0;
    if (keyFrames[0].node->actionFlag == 2)
    {
        lastStop = 0;
    }

    // find the rest of the distances between key points
    for (size_t i = 1; i < keyFrames.size(); ++i)
    {
        if ((keyFrames[i].node->actionFlag == 1) || (keyFrames[i].node->mapid != keyFrames[i-1].node->mapid))
        {
            keyFrames[i].distFromPrev = 0;
        }
        else
        {
            keyFrames[i].distFromPrev =
                sqrt(pow(keyFrames[i].node->x - keyFrames[i - 1].node->x, 2) +
                    pow(keyFrames[i].node->y - keyFrames[i - 1].node->y, 2) +
                    pow(keyFrames[i].node->z - keyFrames[i - 1].node->z, 2));
        }
        if (keyFrames[i].node->actionFlag == 2)
        {
            // remember first stop frame
            if(firstStop == -1)
                firstStop = i;
            lastStop = i;
        }
    }

    float tmpDist = 0;
    for (size_t i = 0; i < keyFrames.size(); ++i)
    {
        int j = (i + lastStop) % keyFrames.size();
        if (keyFrames[j].node->actionFlag == 2)
            tmpDist = 0;
        else
            tmpDist += keyFrames[j].distFromPrev;
        keyFrames[j].distSinceStop = tmpDist;
    }

    for (int i = int(keyFrames.size()) - 1; i >= 0; i--)
    {
        int j = (i + (firstStop+1)) % keyFrames.size();
        tmpDist += keyFrames[(j + 1) % keyFrames.size()].distFromPrev;
        keyFrames[j].distUntilStop = tmpDist;
        if (keyFrames[j].node->actionFlag == 2)
            tmpDist = 0;
    }

    for (size_t i = 0; i < keyFrames.size(); ++i)
    {
        if (keyFrames[i].distSinceStop < (30 * 30 * 0.5f))
            keyFrames[i].tFrom = sqrt(2 * keyFrames[i].distSinceStop);
        else
            keyFrames[i].tFrom = ((keyFrames[i].distSinceStop - (30 * 30 * 0.5f)) / 30) + 30;

        if (keyFrames[i].distUntilStop < (30 * 30 * 0.5f))
            keyFrames[i].tTo = sqrt(2 * keyFrames[i].distUntilStop);
        else
            keyFrames[i].tTo = ((keyFrames[i].distUntilStop - (30 * 30 * 0.5f)) / 30) + 30;

        keyFrames[i].tFrom *= 1000;
        keyFrames[i].tTo *= 1000;
    }

    //    for (int i = 0; i < keyFrames.size(); ++i) {
    //        sLog.outString("%f, %f, %f, %f, %f, %f, %f", keyFrames[i].x, keyFrames[i].y, keyFrames[i].distUntilStop, keyFrames[i].distSinceStop, keyFrames[i].distFromPrev, keyFrames[i].tFrom, keyFrames[i].tTo);
    //    }

    // Now we're completely set up; we can move along the length of each waypoint at 100 ms intervals
    // speed = max(30, t) (remember x = 0.5s^2, and when accelerating, a = 1 unit/s^2
    int t = 0;
    bool teleport = false;
    if (keyFrames[keyFrames.size() - 1].node->mapid != keyFrames[0].node->mapid)
        teleport = true;

    WayPoint pos(keyFrames[0].node->mapid, keyFrames[0].node->x, keyFrames[0].node->y, keyFrames[0].node->z, teleport,
        keyFrames[0].node->arrivalEventID, keyFrames[0].node->departureEventID);
    m_WayPoints[0] = pos;
    t += keyFrames[0].node->delay * 1000;

    uint32 cM = keyFrames[0].node->mapid;
    for (size_t i = 0; i < keyFrames.size() - 1; ++i)
    {
        float d = 0;
        float tFrom = keyFrames[i].tFrom;
        float tTo = keyFrames[i].tTo;

        // keep the generation of all these points; we use only a few now, but may need the others later
        if (((d < keyFrames[i + 1].distFromPrev) && (tTo > 0)))
        {
            while ((d < keyFrames[i + 1].distFromPrev) && (tTo > 0))
            {
                tFrom += 100;
                tTo -= 100;

                if (d > 0)
                {
                    float newX, newY, newZ;
                    newX = keyFrames[i].node->x + (keyFrames[i + 1].node->x - keyFrames[i].node->x) * d / keyFrames[i + 1].distFromPrev;
                    newY = keyFrames[i].node->y + (keyFrames[i + 1].node->y - keyFrames[i].node->y) * d / keyFrames[i + 1].distFromPrev;
                    newZ = keyFrames[i].node->z + (keyFrames[i + 1].node->z - keyFrames[i].node->z) * d / keyFrames[i + 1].distFromPrev;

                    bool teleport = false;
                    if (keyFrames[i].node->mapid != cM)
                    {
                        teleport = true;
                        cM = keyFrames[i].node->mapid;
                    }

                    //                    sLog.outString("T: %d, D: %f, x: %f, y: %f, z: %f", t, d, newX, newY, newZ);
                    WayPoint pos(keyFrames[i].node->mapid, newX, newY, newZ, teleport);
                    if (teleport)
                        m_WayPoints[t] = pos;
                }

                if (tFrom < tTo)                            // caught in tFrom dock's "gravitational pull"
                {
                    if (tFrom <= 30000)
                    {
                        d = 0.5f * (tFrom / 1000) * (tFrom / 1000);
                    }
                    else
                    {
                        d = 0.5f * 30 * 30 + 30 * ((tFrom - 30000) / 1000);
                    }
                    d = d - keyFrames[i].distSinceStop;
                }
                else
                {
                    if (tTo <= 30000)
                    {
                        d = 0.5f * (tTo / 1000) * (tTo / 1000);
                    }
                    else
                    {
                        d = 0.5f * 30 * 30 + 30 * ((tTo - 30000) / 1000);
                    }
                    d = keyFrames[i].distUntilStop - d;
                }
                t += 100;
            }
            t -= 100;
        }

        if (keyFrames[i + 1].tFrom > keyFrames[i + 1].tTo)
            t += 100 - ((long)keyFrames[i + 1].tTo % 100);
        else
            t += (long)keyFrames[i + 1].tTo % 100;

        bool teleport = false;
        if ((keyFrames[i + 1].node->actionFlag == 1) || (keyFrames[i + 1].node->mapid != keyFrames[i].node->mapid))
        {
            teleport = true;
            cM = keyFrames[i + 1].node->mapid;
        }

        WayPoint pos(keyFrames[i + 1].node->mapid, keyFrames[i + 1].node->x, keyFrames[i + 1].node->y, keyFrames[i + 1].node->z, teleport,
            keyFrames[i + 1].node->arrivalEventID, keyFrames[i + 1].node->departureEventID);

        //        sLog.outString("T: %d, x: %f, y: %f, z: %f, t:%d", t, pos.x, pos.y, pos.z, teleport);

        //if (teleport)
        m_WayPoints[t] = pos;

        t += keyFrames[i + 1].node->delay * 1000;
        //        sLog.outString("------");
    }

    uint32 timer = t;

    //    sLog.outDetail("    Generated %lu waypoints, total time %u.", (unsigned long)m_WayPoints.size(), timer);

    m_next = m_WayPoints.begin();                           // will used in MoveToNextWayPoint for init m_curr
    MoveToNextWayPoint();                                   // m_curr -> first point
    MoveToNextWayPoint();                                   // skip first point

    m_pathTime = timer;

    m_nextNodeTime = m_curr->first;

    return true;
}
Exemplo n.º 5
0
void Transport::Update(uint32 diff)
{
    if (!AI())
    {
        if (!AIM_Initialize())
            sLog->outError("Could not initialize GameObjectAI for Transport");
    }
    else
        AI()->UpdateAI(diff);

    if (_isStopped)
        return;

    if (GetKeyFrames().size() <= 1)
        return;

    //_moveTimer = getMSTime() % _transportInfo->pathTime;
    _moveTimer += diff;
    _moveTimer %= _transportInfo->pathTime;
    // need restart path from beginning
    /* if (m_timer < m_curr->pathTime)
    {
        m_curr = keyFrames.begin();
        m_next = m_curr + 1;
    } */
    while (_moveTimer > _nextFrame->pathTime || _moveTimer < _currentFrame->departureTime)
    {
        // arrived at next stop point
        if (_transportInfo->pathTime > _nextFrame->pathTime && _moveTimer < _nextFrame->departureTime)
        {
            if (IsMoving())
            {
                SetMoving(false);
                DoEventIfAny(*_currentFrame, false);
            }
            break;
        }

        MoveToNextWayPoint();

        SetMoving(true);

        DoEventIfAny(*_currentFrame, true);

        // first check help in case client-server transport coordinates de-synchronization
        if (_currentFrame->IsTeleportFrame())
            TeleportTransport(_nextFrame->node->mapid, _nextFrame->node->x, _nextFrame->node->y, _nextFrame->node->z);

        ASSERT(_nextFrame != GetKeyFrames().begin());

        sScriptMgr->OnRelocate(this, _currentFrame->node->index, _currentFrame->node->mapid, _currentFrame->node->x, _currentFrame->node->y, _currentFrame->node->z);

        sLog->outDebug(LOG_FILTER_TRANSPORTS, "%s moved to %f %f %f %d", GetName(), GetPositionX(), GetPositionY(), GetPositionZ(), _currentFrame->node->mapid);
    }

    if (IsMoving())
    {
        if (_moveTimer < _currentFrame->departureTime || _moveTimer > _nextFrame->pathTime)
            sLog->outError("strange times, c.dep:%u, n.pt:%u (%s, %u)", _currentFrame->departureTime, _nextFrame->pathTime, GetName(), m_goInfo->moTransport.mapID);
        float t = CalculateSegmentPos((float)_moveTimer/(float)IN_MILLISECONDS);
        //if (t < -0.01f || t > 1.01f)
        //    sLog.outError("strange t=%f (%s, %u)", t, GetName(), m_goInfo->moTransport.mapID);
        //G3D::Vector3 pos;
        //m_spline->Evaluate(m_curr->node->index - 1, t, pos);
        //G3D::Vector3 dir;
        //m_spline->EvaluateDerivative(m_curr->node->index - 1, t, dir);
        //dir.z = 0.0f;
        //dir = -dir.direction();
        //Relocate(pos.x, pos.y, pos.z);
        float x = _currentFrame->node->x * (1.0f - t) + _nextFrame->node->x * t;
        float y = _currentFrame->node->y * (1.0f - t) + _nextFrame->node->y * t;
        float z = _currentFrame->node->z * (1.0f - t) + _nextFrame->node->z * t;
        float o = GetAngle(_nextFrame->node->x, _nextFrame->node->y) + float(M_PI);
        Relocate(x, y, z, o);
        UpdatePassengerPositions();
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}