예제 #1
0
void CAutoBase::FreezeCargo(bool bFreeze)
{
    CObject*    pObj;
    CPhysics*   physics;
    Math::Vector    oPos;
    float       dist;
    int         i;

    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(m_iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        pObj->SetCargo(false);

        if ( pObj == m_object )  continue;  // yourself?
        if ( pObj->GetTruck() != 0 )  continue;  // transport object?

        oPos = pObj->GetPosition(0);
        dist = Math::DistanceProjected(m_pos, oPos);
        if ( dist < 32.0f )
        {
            if ( bFreeze )
            {
                pObj->SetCargo(true);
            }

            physics = pObj->GetPhysics();
            if ( physics != 0 )
            {
                physics->SetFreeze(bFreeze);
            }
        }
    }
}
예제 #2
0
bool CAutoFactory::CreateVehicle()
{
    CObject*    vehicle;
    Math::Matrix*   mat;
    CPhysics*   physics;
    Math::Vector    pos;
    float       angle;
    char*       name;
    int         i;

    angle = m_object->GetAngleY(0);

    mat = m_object->GetWorldMatrix(0);
    if ( m_type == OBJECT_MOBILErt ||
         m_type == OBJECT_MOBILErc ||
         m_type == OBJECT_MOBILErr ||
         m_type == OBJECT_MOBILErs )
    {
        pos = Math::Vector(2.0f, 0.0f, 0.0f);
    }
    else
    {
        pos = Math::Vector(4.0f, 0.0f, 0.0f);
    }
    pos = Transform(*mat, pos);

    vehicle = new CObject();
    if ( !vehicle->CreateVehicle(pos, angle, m_type, -1.0f, false, false) )
    {
        delete vehicle;
        m_displayText->DisplayError(ERR_TOOMANY, m_object);
        return false;
    }
    vehicle->UpdateMapping();
    vehicle->SetLock(true);  // not usable
    vehicle->SetRange(30.0f);

    physics = vehicle->GetPhysics();
    if ( physics != 0 )
    {
        physics->SetFreeze(true);  // it doesn't move
    }

    for ( i=0 ; i<10 ; i++ )
    {
        name = m_main->GetNewScriptName(m_type, i);
        if ( name == 0 )  break;
        vehicle->ReadProgram(i, name);
    }

    return true;
}
예제 #3
0
CObject* CAutoTower::SearchTarget(Math::Vector &impact)
{
    CObject*    pObj;
    CObject*    pBest = 0;
    CPhysics*   physics;
    Math::Vector    iPos, oPos;
    ObjectType  oType;
    float       distance, min, radius, speed;

    iPos = m_object->GetPosition(0);
    min = 1000000.0f;
    
    for(auto it : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        pObj = it.second;

        oType = pObj->GetType();
        if ( oType != OBJECT_MOTHER &&
             oType != OBJECT_ANT    &&
             oType != OBJECT_SPIDER &&
             oType != OBJECT_BEE    &&
             oType != OBJECT_WORM   )  continue;

        if ( !pObj->GetActif() )  continue;  // inactive?

//?     if ( g_researchDone & RESEARCH_QUICK )
        if ( false )
        {
            physics = pObj->GetPhysics();
            if ( physics != 0 )
            {
                speed = fabs(physics->GetLinMotionX(MO_REASPEED));
                if ( speed > 20.0f )  continue;  // moving too fast?
            }
        }

        if ( !pObj->GetCrashSphere(0, oPos, radius) )  continue;
        distance = Math::Distance(oPos, iPos);
        if ( distance > TOWER_SCOPE )  continue;  // too far
        if ( distance < min )
        {
            min = distance;
            pBest = pObj;
        }
    }
    if ( pBest == 0 )  return 0;

    impact = pBest->GetPosition(0);
    return pBest;
}
예제 #4
0
CObject* CAutoTower::SearchTarget(Math::Vector &impact)
{
    Math::Vector iPos = m_object->GetPosition();
    float min = 1000000.0f;

    CObject* best = nullptr;
    for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects())
    {
        int oTeam=obj->GetTeam();
        int myTeam=m_object->GetTeam();
        ObjectType oType = obj->GetType();
        if ( oType != OBJECT_MOTHER &&
                oType != OBJECT_ANT    &&
                oType != OBJECT_SPIDER &&
                oType != OBJECT_BEE    &&
                oType != OBJECT_WORM   &&
                (oTeam == myTeam        ||
                 oTeam == 0)             )  continue;

        if ( !obj->GetDetectable() )  continue;  // inactive?

//?     if ( g_researchDone & RESEARCH_QUICK )
        if ( false )
        {
            if ( obj->Implements(ObjectInterfaceType::Movable) )
            {
                CPhysics* physics = dynamic_cast<CMovableObject*>(obj)->GetPhysics();
                float speed = fabs(physics->GetLinMotionX(MO_REASPEED));
                if ( speed > 20.0f )  continue;  // moving too fast?
            }
        }

        if (obj->GetCrashSphereCount() == 0) continue;

        Math::Vector oPos = obj->GetFirstCrashSphere().sphere.pos;
        float distance = Math::Distance(oPos, iPos);
        if ( distance > TOWER_SCOPE )  continue;  // too far
        if ( distance < min )
        {
            min = distance;
            best = obj;
        }
    }
    if ( best == nullptr )  return nullptr;

    impact = best->GetPosition();
    return best;
}
예제 #5
0
bool CAutoFactory::CreateVehicle()
{
    float angle = m_object->GetRotationY();

    Math::Vector pos;
    if ( m_type == OBJECT_MOBILErt ||
         m_type == OBJECT_MOBILErc ||
         m_type == OBJECT_MOBILErr ||
         m_type == OBJECT_MOBILErs )
    {
        pos = Math::Vector(2.0f, 0.0f, 0.0f);
    }
    else
    {
        pos = Math::Vector(4.0f, 0.0f, 0.0f);
    }
    Math::Matrix* mat = m_object->GetWorldMatrix(0);
    pos = Transform(*mat, pos);

    ObjectCreateParams params;
    params.pos = pos;
    params.angle = angle;
    params.type = m_type;
    params.team = m_object->GetTeam();
    CObject* vehicle = CObjectManager::GetInstancePointer()->CreateObject(params);

    vehicle->SetLock(true);  // not usable

    assert(vehicle->Implements(ObjectInterfaceType::Movable));
    CPhysics* physics = dynamic_cast<CMovableObject*>(vehicle)->GetPhysics();
    physics->SetFreeze(true);  // it doesn't move

    if (vehicle->Implements(ObjectInterfaceType::ProgramStorage))
    {
        CProgramStorageObject* programStorage = dynamic_cast<CProgramStorageObject*>(vehicle);
        for ( int i=0 ; ; i++ )
        {
            std::string name = m_main->GetNewScriptName(m_type, i);
            if (name.empty()) break;
            Program* prog = programStorage->GetOrAddProgram(i);
            programStorage->ReadProgram(prog, InjectLevelPathsForCurrentLevel(name));
            prog->readOnly = true;
            prog->filename = name;
        }
    }

    return true;
}
예제 #6
0
파일: taskfire.cpp 프로젝트: CHmSID/colobot
bool CTaskFire::EventProcess(const Event &event)
{
    CPhysics*   physics;
    Math::Matrix*   mat;
    Math::Vector    pos, speed, dir, vib;
    ObjectType  type;
    Math::Point     dim;
    float       energy, fire;
    int         i, channel;

    if ( m_engine->GetPause() )  return true;
    if ( event.type != EVENT_FRAME )  return true;
    if ( m_bError )  return false;

    m_time += event.rTime;
    m_lastSound -= event.rTime;
    m_progress += event.rTime*m_speed;

    CPowerContainerObject* power = nullptr;
    if (m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer))
    {
        power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
        energy = power->GetEnergy();
             if ( m_bOrganic )  fire = ENERGY_FIREi;
        else if ( m_bRay     )  fire = ENERGY_FIREr;
        else                    fire = ENERGY_FIRE;
        energy -= event.rTime*fire;
        power->SetEnergy(energy);
    }

    if ( m_lastParticle+0.05f <= m_time )
    {
        m_lastParticle = m_time;

        if ( m_bOrganic )
        {
            mat = m_object->GetWorldMatrix(1);  // insect-cannon

            for ( i=0 ; i<6 ; i++ )
            {
                pos = Math::Vector(0.0f, 2.5f, 0.0f);
                pos = Math::Transform(*mat, pos);

                speed = Math::Vector(200.0f, 0.0f, 0.0f);

                physics = m_object->GetPhysics();
                if ( physics != nullptr )
                {
                    speed += physics->GetLinMotion(MO_REASPEED);
                }

                speed.x += (Math::Rand()-0.5f)*10.0f;
                speed.y += (Math::Rand()-0.5f)*20.0f;
                speed.z += (Math::Rand()-0.5f)*30.0f;
                speed = Math::Transform(*mat, speed);
                speed -= pos;

                dim.x = Math::Rand()*0.5f+0.5f;
                dim.y = dim.x;

                channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN4, 0.8f, 0.0f, 0.0f);
                m_particle->SetObjectFather(channel, m_object);
            }
        }
        else if ( m_bRay )
        {
            mat = m_object->GetWorldMatrix(2);  // cannon

            for ( i=0 ; i<4 ; i++ )
            {
                pos = Math::Vector(4.0f, 0.0f, 0.0f);
                pos.y += (rand()%3-1)*1.5f;
                pos.z += (rand()%3-1)*1.5f;
                pos = Math::Transform(*mat, pos);

                speed = Math::Vector(200.0f, 0.0f, 0.0f);
                speed.x += (Math::Rand()-0.5f)*6.0f;
                speed.y += (Math::Rand()-0.5f)*12.0f;
                speed.z += (Math::Rand()-0.5f)*12.0f;
                speed = Math::Transform(*mat, speed);
                speed -= pos;

                dim.x = 1.0f;
                dim.y = dim.x;
                channel = m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK11,
                                                   2.0f, 200.0f, 0.5f, 1.0f);
                m_particle->SetObjectFather(channel, m_object);

                speed = Math::Vector(5.0f, 0.0f, 0.0f);
                speed.x += (Math::Rand()-0.5f)*1.0f;
                speed.y += (Math::Rand()-0.5f)*2.0f;
                speed.z += (Math::Rand()-0.5f)*2.0f;
                speed = Math::Transform(*mat, speed);
                speed -= pos;
                speed.y += 5.0f;

                dim.x = 2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE2, 2.0f, 0.0f, 0.5f);
            }
        }
        else
        {
            type = m_object->GetType();

            if ( type == OBJECT_MOBILErc )
            {
                mat = m_object->GetWorldMatrix(2);  // cannon
            }
            else
            {
                mat = m_object->GetWorldMatrix(1);  // cannon
            }

            for ( i=0 ; i<3 ; i++ )
            {
                if ( type == OBJECT_MOBILErc )
                {
                    pos = Math::Vector(0.0f, 0.0f, 0.0f);
                }
                else
                {
                    pos = Math::Vector(3.0f, 1.0f, 0.0f);
                }
                pos.y += (Math::Rand()-0.5f)*1.0f;
                pos.z += (Math::Rand()-0.5f)*1.0f;
                pos = Math::Transform(*mat, pos);

                speed = Math::Vector(200.0f, 0.0f, 0.0f);

                physics = m_object->GetPhysics();
                if ( physics != nullptr )
                {
                    speed += physics->GetLinMotion(MO_REASPEED);
                }

                speed.x += (Math::Rand()-0.5f)*3.0f;
                speed.y += (Math::Rand()-0.5f)*6.0f;
                speed.z += (Math::Rand()-0.5f)*6.0f;
                speed = Math::Transform(*mat, speed);
                speed -= pos;

                dim.x = Math::Rand()*0.7f+0.7f;
                dim.y = dim.x;

                channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN1, 0.8f, 0.0f, 0.0f);
                m_particle->SetObjectFather(channel, m_object);
            }

            if ( type != OBJECT_MOBILErc &&
                 m_progress > 0.3f )
            {
                pos = Math::Vector(-1.0f, 1.0f, 0.0f);
                pos.y += (Math::Rand()-0.5f)*0.4f;
                pos.z += (Math::Rand()-0.5f)*0.4f;
                pos = Math::Transform(*mat, pos);

                speed = Math::Vector(-4.0f, 0.0f, 0.0f);
                speed.x += (Math::Rand()-0.5f)*2.0f;
                speed.y += (Math::Rand()-0.2f)*4.0f;
                speed.z += (Math::Rand()-0.5f)*4.0f;
                speed = Math::Transform(*mat, speed);
                speed -= pos;

                dim.x = Math::Rand()*1.2f+1.2f;
                dim.y = dim.x;

                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 0.0f);
//?             m_particle->CreateParticle(pos, speed, dim, PARTISMOKE2, 4.0f, 0.0f, 0.0f);
            }
        }

        dir = Math::Vector(0.0f, 0.0f, 0.0f);
        if ( m_progress < 0.1f )
        {
            dir.z = (Math::PI*0.04f)*(m_progress*10.0f);
        }
        else if ( m_progress < 0.9f )
        {
            dir.z = (Math::PI*0.04f);
        }
        else
        {
            dir.z = (Math::PI*0.04f)*(1.0f-(m_progress-0.9f)*10.0f);
        }
        m_object->SetTilt(dir);

        vib.x = (Math::Rand()-0.5f)*0.01f;
        vib.y = (Math::Rand()-0.5f)*0.02f;
        vib.z = (Math::Rand()-0.5f)*0.02f;
        m_object->SetCirVibration(vib);

        vib.x = (Math::Rand()-0.5f)*0.20f;
        vib.y = (Math::Rand()-0.5f)*0.05f;
        vib.z = (Math::Rand()-0.5f)*0.20f;
        m_object->SetLinVibration(vib);
    }

    if ( m_bRay && m_lastSound <= 0.0f )
    {
        m_lastSound = Math::Rand()*0.4f+0.4f;
        m_sound->Play(SOUND_FIREp, m_object->GetPosition());
    }

    return true;
}
예제 #7
0
bool CAutoFactory::EventProcess(const Event &event)
{
    ObjectType  type;
    CObject*    fret;
    CObject*    vehicle;
    Math::Matrix*   mat;
    CPhysics*   physics;
    Math::Vector    pos, speed;
    Math::Point     dim;
    float       zoom, angle, prog;
    int         i;

    CAuto::EventProcess(event);

    if ( m_engine->GetPause() )  return true;

    if ( m_object->GetSelect() )  // factory selected?
    {
        if ( event.type == EVENT_UPDINTERFACE )
        {
            CreateInterface(true);
        }

        type = OBJECT_NULL;
        if ( event.type == EVENT_OBJECT_FACTORYwa )  type = OBJECT_MOBILEwa;
        if ( event.type == EVENT_OBJECT_FACTORYta )  type = OBJECT_MOBILEta;
        if ( event.type == EVENT_OBJECT_FACTORYfa )  type = OBJECT_MOBILEfa;
        if ( event.type == EVENT_OBJECT_FACTORYia )  type = OBJECT_MOBILEia;
        if ( event.type == EVENT_OBJECT_FACTORYws )  type = OBJECT_MOBILEws;
        if ( event.type == EVENT_OBJECT_FACTORYts )  type = OBJECT_MOBILEts;
        if ( event.type == EVENT_OBJECT_FACTORYfs )  type = OBJECT_MOBILEfs;
        if ( event.type == EVENT_OBJECT_FACTORYis )  type = OBJECT_MOBILEis;
        if ( event.type == EVENT_OBJECT_FACTORYwc )  type = OBJECT_MOBILEwc;
        if ( event.type == EVENT_OBJECT_FACTORYtc )  type = OBJECT_MOBILEtc;
        if ( event.type == EVENT_OBJECT_FACTORYfc )  type = OBJECT_MOBILEfc;
        if ( event.type == EVENT_OBJECT_FACTORYic )  type = OBJECT_MOBILEic;
        if ( event.type == EVENT_OBJECT_FACTORYwi )  type = OBJECT_MOBILEwi;
        if ( event.type == EVENT_OBJECT_FACTORYti )  type = OBJECT_MOBILEti;
        if ( event.type == EVENT_OBJECT_FACTORYfi )  type = OBJECT_MOBILEfi;
        if ( event.type == EVENT_OBJECT_FACTORYii )  type = OBJECT_MOBILEii;
        if ( event.type == EVENT_OBJECT_FACTORYrt )  type = OBJECT_MOBILErt;
        if ( event.type == EVENT_OBJECT_FACTORYrc )  type = OBJECT_MOBILErc;
        if ( event.type == EVENT_OBJECT_FACTORYrr )  type = OBJECT_MOBILErr;
        if ( event.type == EVENT_OBJECT_FACTORYrs )  type = OBJECT_MOBILErs;
        if ( event.type == EVENT_OBJECT_FACTORYsa )  type = OBJECT_MOBILEsa;

        Error err = StartAction(type);
        if( err != ERR_OK && err != ERR_GENERIC )
            m_displayText->DisplayError(err, m_object);

        if( err != ERR_GENERIC )
            return false;
    }

    if ( event.type != EVENT_FRAME )  return true;

    m_progress += event.rTime*m_speed;
    EventProgress(event.rTime);

    if ( m_phase == AFP_WAIT )
    {
        if ( m_progress >= 1.0f )
        {
            m_phase    = AFP_WAIT;  // still waiting ...
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_CLOSE_S )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f;
                if ( zoom < 0.30f )  zoom = 0.30f;
                if ( zoom > 1.00f )  zoom = 1.00f;
                m_object->SetZoomZ( 1+i, zoom);
                m_object->SetZoomZ(10+i, zoom);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetZoomZ( 1+i, 1.0f);
                m_object->SetZoomZ(10+i, 1.0f);
            }

            SoundManip(2.0f, 1.0f, 1.2f);

            m_phase    = AFP_CLOSE_T;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_CLOSE_T )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f;
                m_object->SetAngleZ( 1+i,  angle);
                m_object->SetAngleZ(10+i, -angle);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetAngleZ( 1+i, 0.0f);
                m_object->SetAngleZ(10+i, 0.0f);
            }

            m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->GetPosition(0), 0.0f, 1.0f, true);
            m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f,  2.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f,  2.0f, SOPER_STOP);

            m_phase    = AFP_BUILD;
            m_progress = 0.0f;
            m_speed    = 1.0f/15.0f;
        }
    }

    if ( m_phase == AFP_BUILD )
    {
        if ( m_progress == 0.0f )
        {
            if ( !CreateVehicle() )
            {
                fret = SearchFret();  // transform metal?
                if ( fret != 0 )
                {
                    fret->SetLock(false);  // metal usable again
                }

                if ( m_channelSound != -1 )
                {
                    m_sound->FlushEnvelope(m_channelSound);
                    m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
                    m_channelSound = -1;
                }

                m_phase    = AFP_OPEN_T;
                m_progress = 0.0f;
                m_speed    = 1.0f/2.0f;
                return true;
            }
        }

        if ( m_progress < 1.0f )
        {
            if ( m_type == OBJECT_MOBILErt ||
                 m_type == OBJECT_MOBILErc ||
                 m_type == OBJECT_MOBILErr ||
                 m_type == OBJECT_MOBILErs )
            {
                prog = 1.0f-m_progress*1.5f;
                if ( prog < 0.0f )  prog = 0.0f;
            }
            else
            {
                prog = 1.0f-m_progress;
            }
            angle = powf(prog*10.0f, 2.0f)+m_object->GetAngleY(0);

            vehicle = SearchVehicle();
            if ( vehicle != 0 )
            {
                vehicle->SetAngleY(0, angle+Math::PI);
                vehicle->SetZoom(0, m_progress);
            }

            fret = SearchFret();  // transform metal?
            if ( fret != 0 )
            {
                fret->SetZoom(0, 1.0f-m_progress);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time )
            {
                m_lastParticle = m_time;

#if 0
                pos = m_fretPos;
                pos.x += (Math::Rand()-0.5f)*20.0f;
                pos.z += (Math::Rand()-0.5f)*20.0f;
                pos.y += 1.0f;
                speed.x = (Math::Rand()-0.5f)*12.0f;
                speed.z = (Math::Rand()-0.5f)*12.0f;
                speed.y = Math::Rand()*12.0f;
                dim.x = Math::Rand()*12.0f+10.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f);
#else
                mat = m_object->GetWorldMatrix(0);
                pos = Math::Vector(-12.0f, 20.0f, -4.0f);  // position of chimney
                pos = Math::Transform(*mat, pos);
                pos.y += 2.0f;
                pos.x += (Math::Rand()-0.5f)*2.0f;
                pos.z += (Math::Rand()-0.5f)*2.0f;
                speed.x = 0.0f;
                speed.z = 0.0f;
                speed.y = 6.0f+Math::Rand()*6.0f;
                dim.x = Math::Rand()*1.5f+1.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f);
#endif
            }
        }
        else
        {
            m_displayText->DisplayError(INFO_FACTORY, m_object);
            SoundManip(2.0f, 1.0f, 1.2f);

            fret = SearchFret();  // transform metal?
            if ( fret != 0 )
            {
                fret->DeleteObject();  // removes the metal
                delete fret;
            }

            m_vehicle = vehicle = SearchVehicle();
            if ( vehicle != 0 )
            {
                physics = vehicle->GetPhysics();
                if ( physics != 0 )
                {
                    physics->SetFreeze(false);  // can move
                }

                vehicle->SetLock(false);  // vehicle useable
//?             vehicle->GetPhysics()->GetBrain()->StartTaskAdvance(16.0f);
                vehicle->SetAngleY(0, m_object->GetAngleY(0)+Math::PI);
                vehicle->SetZoom(0, 1.0f);
            }

            m_main->CreateShortcuts();

            m_phase    = AFP_OPEN_T;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_OPEN_T )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f;
                m_object->SetAngleZ( 1+i,  angle);
                m_object->SetAngleZ(10+i, -angle);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time )
            {
                m_lastParticle = m_time;

                pos = m_fretPos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                pos.y += Math::Rand()*10.0f;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetAngleZ( 1+i,  Math::PI/2.0f);
                m_object->SetAngleZ(10+i, -Math::PI/2.0f);
            }

            SoundManip(3.0f, 1.0f, 0.5f);

            m_phase    = AFP_OPEN_S;
            m_progress = 0.0f;
            m_speed    = 1.0f/3.0f;
        }
    }

    if ( m_phase == AFP_OPEN_S )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f;
                if ( zoom < 0.30f )  zoom = 0.30f;
                if ( zoom > 1.00f )  zoom = 1.00f;
                m_object->SetZoomZ( 1+i, zoom);
                m_object->SetZoomZ(10+i, zoom);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time )
            {
                m_lastParticle = m_time;

                pos = m_fretPos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                pos.y += Math::Rand()*10.0f;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetZoomZ( 1+i, 0.30f);
                m_object->SetZoomZ(10+i, 0.30f);
            }

            if ( m_program != nullptr )
            {
                CBrain* brain = m_vehicle->GetBrain();
                if ( brain != nullptr )
                {
                    brain->SendProgram(0, const_cast<const char*>(m_program));
                    brain->SetScriptRun(0);
                    brain->RunProgram(0);
                }
            }

            SetBusy(false);
            UpdateInterface();

            m_phase    = AFP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    return true;
}
예제 #8
0
CObject* CObjectManager::Radar(CObject* pThis, Math::Vector thisPosition, float thisAngle, std::vector<ObjectType> type, float angle, float focus, float minDist, float maxDist, bool furthest, RadarFilter filter, bool cbotTypes)
{
    CObject     *pObj, *pBest;
    Math::Vector    iPos, oPos;
    float       best, iAngle, d, a;
    ObjectType  oType;

    minDist *= g_unit;
    maxDist *= g_unit;

    iPos   = thisPosition;
    iAngle = thisAngle+angle;
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    int filter_team = filter & 0xFF;
    RadarFilter filter_flying = static_cast<RadarFilter>(filter & (FILTER_ONLYLANDING | FILTER_ONLYFLYING));
    RadarFilter filter_enemy = static_cast<RadarFilter>(filter & (FILTER_FRIENDLY | FILTER_ENEMY | FILTER_NEUTRAL));

    if ( !furthest )  best = 100000.0f;
    else              best = 0.0f;
    pBest = nullptr;
    for ( auto it = m_objects.begin() ; it != m_objects.end() ; ++it )
    {
        pObj = it->second.get();
        if ( pObj == pThis )  continue; // pThis may be nullptr but it doesn't matter

        if (pObj == nullptr) continue;
        if (IsObjectBeingTransported(pObj))  continue;
        if ( !pObj->GetDetectable() )  continue;
        if ( pObj->GetProxyActivate() )  continue;

        oType = pObj->GetType();

        if (cbotTypes)
        {
            // TODO: handle this differently (new class describing types? CObjectType::GetBaseType()?)
            if ( oType == OBJECT_RUINmobilew2 ||
                oType == OBJECT_RUINmobilet1 ||
                oType == OBJECT_RUINmobilet2 ||
                oType == OBJECT_RUINmobiler1 ||
                oType == OBJECT_RUINmobiler2 )
            {
                oType = OBJECT_RUINmobilew1;  // any ruin
            }

            if ( oType == OBJECT_BARRIER2 ||
                oType == OBJECT_BARRIER3 )  // barriers?
            {
                oType = OBJECT_BARRIER1;  // any barrier
            }
            // END OF TODO
        }

        if ( std::find(type.begin(), type.end(), oType) == type.end() && type.size() > 0 )  continue;

        if ( (oType == OBJECT_TOTO || oType == OBJECT_CONTROLLER) && type.size() == 0 )  continue; // allow OBJECT_TOTO and OBJECT_CONTROLLER only if explicitly asked in type parameter

        if ( filter_flying == FILTER_ONLYLANDING )
        {
            if ( pObj->Implements(ObjectInterfaceType::Movable) )
            {
                CPhysics* physics = dynamic_cast<CMovableObject*>(pObj)->GetPhysics();
                if ( physics != nullptr )
                {
                    if ( !physics->GetLand() )  continue;
                }
            }
        }
        if ( filter_flying == FILTER_ONLYFLYING )
        {
            if ( !pObj->Implements(ObjectInterfaceType::Movable) ) continue;
            CPhysics* physics = dynamic_cast<CMovableObject*>(pObj)->GetPhysics();
            if ( physics == nullptr ) continue;
            if ( physics->GetLand() ) continue;
        }

        if ( filter_team != 0 && pObj->GetTeam() != filter_team )
            continue;

        if( pThis != nullptr )
        {
            RadarFilter enemy = FILTER_NONE;
            if ( pObj->GetTeam() == 0 ) enemy = static_cast<RadarFilter>(enemy | FILTER_NEUTRAL);
            if ( pObj->GetTeam() != 0 && pObj->GetTeam() == pThis->GetTeam() ) enemy = static_cast<RadarFilter>(enemy | FILTER_FRIENDLY);
            if ( pObj->GetTeam() != 0 && pObj->GetTeam() != pThis->GetTeam() ) enemy = static_cast<RadarFilter>(enemy | FILTER_ENEMY);
            if ( filter_enemy != 0 && (filter_enemy & enemy) == 0 ) continue;
        }

        oPos = pObj->GetPosition();
        d = Math::DistanceProjected(iPos, oPos);
        if ( d < minDist || d > maxDist )  continue;  // too close or too far?

        a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW !
        if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) || focus >= Math::PI*2.0f )
        {
            if ( (!furthest && d < best) ||
                (furthest && d > best) )
            {
                best = d;
                pBest = pObj;
            }
        }
    }

    return pBest;
}
예제 #9
0
// main
void PhysicsWorld::Step(float dt, unsigned char velocityIterations, unsigned char positionIterations)
{
	const TimeStep timeStep(dt, velocityIterations, positionIterations, mParams, mStats);
	Stopwatch timer;
	mStats.Clear();

	// update rigid bodies
	const float linearDampFactor = 1.0f - Clamp(mParams.linearDamping  * timeStep.dt, 0.0f, 1.0f);
	const float angularDampFactor = 1.0f - Clamp(mParams.angularDamping * timeStep.dt, 0.0f, 1.0f);
	timer.Start();
	for (auto &body : mRigidBodies)
	{
		// TODOKai mass
		if (!body.CollidersValid())
			body.ValidateColliders();

		// update
		body.UpdateMassAndLocalCentroid();
		body.UpdateOrientation();
		body.UpdatePositionFromGlobalCentroid();
		body.UpdateGlobalInverseInertiaTensor();
		body.UpdateProxies();

		timeStep.stats.colliders += body.mColliders.size();
	}
	timeStep.stats.rigidBodies = mRigidBodies.size();
	timeStep.stats.integration += timer.Stop();

	// broadphase
	timer.Start();
	auto &pairList = mBroadphase->ComputePairs();
	timeStep.stats.broadphasePairs = pairList.size();
	timeStep.stats.broadphase += timer.Stop();

	// narrowphase
	timer.Start();
	mContactManager.PreNarrowphase();
	for (ColliderPair &pair : pairList)
	{
		Collider *colliderA = pair.mCollider1;
		Collider *colliderB = pair.mCollider2;
		RigidBody &bodyA = *colliderA->mParent;
		RigidBody &bodyB = *colliderB->mParent;
		CPhysics* cphyA = bodyA.mParent->cphy;
		CPhysics* cphyB = bodyB.mParent->cphy;

		if (!bodyA.CanCollide(bodyB) || !colliderA->CanBeCollide(*colliderB))
			continue;

		// collision table check
		if (!cphyA->gameObject->GetState()->GetCollisionTable()->GetDoesIDsCollide(cphyA->GetCOllisionID(), cphyB->GetCOllisionID()))
			continue;

		// make sure colliderA is always less than colliderB in memory address for consistency
		if (colliderA > colliderB)
		{
			std::swap(colliderA, colliderB);
			auto temp = cphyA;
			cphyA = cphyB;
			cphyB = temp;
		}


		ContactManifold *manifold = new (mManifoldAllocator.Allocate()) ContactManifold();
		manifold->colliderA = colliderA;
		manifold->colliderB = colliderB;

		//TODO
		manifold->isColliding =
			Collide(*manifold, *colliderA->mGeometry, *colliderB->mGeometry, mContactAllocator);

		if (!manifold->isColliding
			|| !mContactManager.Add(*manifold, mParams.contactPersistenceThreshold * mParams.contactPersistenceThreshold))
		{
			// manifold not colliding OR persistent manifold already exists, delete
			manifold->~ContactManifold();
			mManifoldAllocator.Free(manifold);
		}
		else
		{
			//these will be deleted by the script subsystem
			CollisionData* dataA = new CollisionData();
			CollisionData* dataB = new CollisionData();

			// send manifold to OnCollide function
			{
				dataA->isA = true;
				dataA->collidedObj = cphyB->gameObject;
				dataA->selfCPhy = cphyA;
				dataA->collidedObjCPhy = cphyB;
				dataA->numContacts = manifold->numContacts;
				for (int i = 0; i < dataA->numContacts; ++i)
				{
					dataA->normals.push_back(manifold->contacts[i]->normal);
				}
				ScriptSubsystem::getInstance()->QueueEvent<CollisionData>(cphyA->gameObject, "OnCollisionEnter", dataA);
			}
			{
				dataB->isA = false;
				dataB->collidedObj = cphyA->gameObject;
				dataB->selfCPhy = cphyB;
				dataB->collidedObjCPhy = cphyA;
				dataB->numContacts = manifold->numContacts;
				for (int i = 0; i < dataB->numContacts; ++i)
				{
					dataB->normals.push_back(manifold->contacts[i]->normal);
				}
				ScriptSubsystem::getInstance()->QueueEvent<CollisionData>(cphyB->gameObject, "OnCollisionEnter", dataB);
			}
			if (cphyA->mIsTriggered || cphyB->mIsTriggered)
			{
				manifold->~ContactManifold();
				mManifoldAllocator.Free(manifold);
			}
		}
	}
	mContactManager.PostNarrowphase();
	timeStep.stats.narrowphase += timer.Stop();

	SimulateIslands(timeStep);

	// update broadphase after position integration
	mBroadphase->Update(timeStep);

	mContactManager.Draw();

}
예제 #10
0
bool CAutoFactory::EventProcess(const Event &event)
{
    ObjectType  type;
    CObject*    cargo;
    CObject*    vehicle;
    Math::Matrix*   mat;
    CPhysics*   physics;
    Math::Vector    pos, speed;
    Math::Point     dim;
    float       zoom, angle, prog;
    int         i;

    CAuto::EventProcess(event);

    if ( m_engine->GetPause() )  return true;

    if ( m_object->GetSelect() )  // factory selected?
    {
        if ( event.type == EVENT_UPDINTERFACE )
        {
            CreateInterface(true);
        }

        type = ObjectTypeFromFactoryButton(event.type);

        Error err = StartAction(type);
        if( err != ERR_OK && err != ERR_UNKNOWN )
            m_main->DisplayError(err, m_object);

        if( err != ERR_UNKNOWN )
            return false;
    }

    if ( event.type != EVENT_FRAME )  return true;

    m_progress += event.rTime*m_speed;
    EventProgress(event.rTime);

    if ( m_phase == AFP_WAIT )
    {
        if ( m_progress >= 1.0f )
        {
            m_phase    = AFP_WAIT;  // still waiting ...
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_CLOSE_S )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                zoom = 0.30f+(m_progress-0.5f+i/16.0f)*2.0f*0.70f;
                if ( zoom < 0.30f )  zoom = 0.30f;
                if ( zoom > 1.00f )  zoom = 1.00f;
                m_object->SetPartScaleZ( 1+i, zoom);
                m_object->SetPartScaleZ(10+i, zoom);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetPartScaleZ( 1+i, 1.0f);
                m_object->SetPartScaleZ(10+i, 1.0f);
            }

            SoundManip(2.0f, 1.0f, 1.2f);

            m_phase    = AFP_CLOSE_T;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_CLOSE_T )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                angle = -m_progress*(Math::PI/2.0f)+Math::PI/2.0f;
                m_object->SetPartRotationZ( 1+i,  angle);
                m_object->SetPartRotationZ(10+i, -angle);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetPartRotationZ( 1+i, 0.0f);
                m_object->SetPartRotationZ(10+i, 0.0f);
            }

            m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->GetPosition(), 0.0f, 1.0f, true);
            m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f,  2.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f,  2.0f, SOPER_STOP);

            m_phase    = AFP_BUILD;
            m_progress = 0.0f;
            m_speed    = 1.0f/15.0f;
        }
    }

    if ( m_phase == AFP_BUILD )
    {
        if ( m_progress == 0.0f )
        {
            if ( !CreateVehicle() )
            {
                cargo = SearchCargo();  // transform metal?
                if ( cargo != nullptr )
                {
                    cargo->SetLock(false);  // metal usable again
                }

                if ( m_channelSound != -1 )
                {
                    m_sound->FlushEnvelope(m_channelSound);
                    m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 1.0f, SOPER_STOP);
                    m_channelSound = -1;
                }

                m_phase    = AFP_OPEN_T;
                m_progress = 0.0f;
                m_speed    = 1.0f/2.0f;
                return true;
            }
        }

        if ( m_progress < 1.0f )
        {
            if ( m_type == OBJECT_MOBILErt ||
                 m_type == OBJECT_MOBILErc ||
                 m_type == OBJECT_MOBILErr ||
                 m_type == OBJECT_MOBILErs )
            {
                prog = 1.0f-m_progress*1.5f;
                if ( prog < 0.0f )  prog = 0.0f;
            }
            else
            {
                prog = 1.0f-m_progress;
            }
            angle = powf(prog*10.0f, 2.0f)+m_object->GetRotationY();

            vehicle = SearchVehicle();
            if ( vehicle != nullptr )
            {
                vehicle->SetRotationY(angle+Math::PI);
                vehicle->SetScale(m_progress);
            }

            cargo = SearchCargo();  // transform metal?
            if ( cargo != nullptr )
            {
                cargo->SetScale(1.0f-m_progress);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time )
            {
                m_lastParticle = m_time;

                mat = m_object->GetWorldMatrix(0);
                pos = Math::Vector(-12.0f, 20.0f, -4.0f);  // position of chimney
                pos = Math::Transform(*mat, pos);
                pos.y += 2.0f;
                pos.x += (Math::Rand()-0.5f)*2.0f;
                pos.z += (Math::Rand()-0.5f)*2.0f;
                speed.x = 0.0f;
                speed.z = 0.0f;
                speed.y = 6.0f+Math::Rand()*6.0f;
                dim.x = Math::Rand()*1.5f+1.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f);
            }
        }
        else
        {
            m_main->DisplayError(INFO_FACTORY, m_object);
            SoundManip(2.0f, 1.0f, 1.2f);

            cargo = SearchCargo();  // transform metal?
            if ( cargo != nullptr )
            {
                CObjectManager::GetInstancePointer()->DeleteObject(cargo);
            }

            vehicle = SearchVehicle();
            if ( vehicle != nullptr )
            {
                assert(vehicle->Implements(ObjectInterfaceType::Movable));
                physics = dynamic_cast<CMovableObject*>(vehicle)->GetPhysics();
                physics->SetFreeze(false);  // can move

                vehicle->SetLock(false);  // vehicle useable
                vehicle->SetRotationY(m_object->GetRotationY()+Math::PI);
                vehicle->SetScale(1.0f);

                if ( !m_program.empty() )
                {
                    if (vehicle->Implements(ObjectInterfaceType::Programmable) && vehicle->Implements(ObjectInterfaceType::ProgramStorage))
                    {
                        Program* program = dynamic_cast<CProgramStorageObject*>(vehicle)->AddProgram();

                        if (boost::regex_search(m_program, boost::regex("^[A-Za-z0-9_]+$"))) // Public function name?
                        {
                            std::string code = "extern void object::Start_"+m_program+"()\n{\n\t\n\t//Automatically generated by object.factory()\n\t"+m_program+"();\n\t\n}\n";
                            program->script->SendScript(code.c_str());
                        }
                        else if (boost::regex_search(m_program, boost::regex("\\.txt$"))) // File name (with .txt extension)?
                        {
                            program->script->ReadScript(m_program.c_str());
                        }
                        else // Program code?
                        {
                            program->script->SendScript(m_program.c_str());
                        }

                        dynamic_cast<CProgrammableObject*>(vehicle)->RunProgram(program);
                    }
                }
            }

            m_main->CreateShortcuts();

            m_phase    = AFP_OPEN_T;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AFP_OPEN_T )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                angle = -(1.0f-m_progress)*(Math::PI/2.0f)+Math::PI/2.0f;
                m_object->SetPartRotationZ( 1+i,  angle);
                m_object->SetPartRotationZ(10+i, -angle);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time )
            {
                m_lastParticle = m_time;

                pos = m_cargoPos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                pos.y += Math::Rand()*10.0f;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetPartRotationZ( 1+i,  Math::PI/2.0f);
                m_object->SetPartRotationZ(10+i, -Math::PI/2.0f);
            }

            SoundManip(3.0f, 1.0f, 0.5f);

            m_phase    = AFP_OPEN_S;
            m_progress = 0.0f;
            m_speed    = 1.0f/3.0f;
        }
    }

    if ( m_phase == AFP_OPEN_S )
    {
        if ( m_progress < 1.0f )
        {
            for ( i=0 ; i<9 ; i++ )
            {
                zoom = 0.30f+((1.0f-m_progress)-0.5f+i/16.0f)*2.0f*0.70f;
                if ( zoom < 0.30f )  zoom = 0.30f;
                if ( zoom > 1.00f )  zoom = 1.00f;
                m_object->SetPartScaleZ( 1+i, zoom);
                m_object->SetPartScaleZ(10+i, zoom);
            }

            if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time )
            {
                m_lastParticle = m_time;

                pos = m_cargoPos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                pos.y += Math::Rand()*10.0f;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f);
            }
        }
        else
        {
            for ( i=0 ; i<9 ; i++ )
            {
                m_object->SetPartScaleZ( 1+i, 0.30f);
                m_object->SetPartScaleZ(10+i, 0.30f);
            }

            SetBusy(false);
            UpdateInterface();

            m_phase    = AFP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    return true;
}