コード例 #1
0
ファイル: taskmanip.cpp プロジェクト: ManuelBlanc/colobot
bool CTaskManip::IsFreeDeposeObject(Math::Vector pos)
{
    CObject*    pObj;
    Math::Matrix*   mat;
    Math::Vector    iPos, oPos;
    float       oRadius;
    int         i, j;

    mat = m_object->GetWorldMatrix(0);
    iPos = Transform(*mat, pos);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        if ( pObj == m_object )  continue;
        if ( !pObj->GetActif() )  continue;  // inactive?
        if ( pObj->GetTruck() != 0 )  continue;  // object transported?

        j = 0;
        while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
        {
            if ( Math::Distance(iPos, oPos)-(oRadius+1.0f) < 2.0f )
            {
                return false;  // location occupied
            }
        }
    }
    return true;  // location free
}
コード例 #2
0
ファイル: taskbuild.cpp プロジェクト: pol51/colobot
void CTaskBuild::DeleteMark(Math::Vector pos, float radius)
{
    CObject*    pObj;
    Math::Vector    oPos;
    ObjectType  type;
    float       distance;
    int         i;

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        type = pObj->GetType();
        if ( type != OBJECT_MARKSTONE   &&
             type != OBJECT_MARKURANIUM &&
             type != OBJECT_MARKKEYa    &&
             type != OBJECT_MARKKEYb    &&
             type != OBJECT_MARKKEYc    &&
             type != OBJECT_MARKKEYd    &&
             type != OBJECT_MARKPOWER   )  continue;

        oPos = pObj->GetPosition(0);
        distance = Math::Distance(oPos, pos);
        if ( distance <= radius )
        {
            pObj->DeleteObject();  // removes the mark
            delete pObj;
            i --;
        }
    }
}
コード例 #3
0
bool CTaskTerraform::Terraform()
{
    CObject*    pObj;
    CBrain*     brain;
    CMotion*    motion;
    Gfx::CPyro* pyro;
    ObjectType  type;
    float       dist;
    int         i;

    m_camera->StartEffect(Gfx::CAM_EFFECT_TERRAFORM, m_terraPos, 1.0f);

    m_sound->Play(SOUND_THUMP, m_terraPos);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        type = pObj->GetType();
        if ( type == OBJECT_NULL )  continue;

        if ( type == OBJECT_TEEN34 )  // stone?
        {
            dist = Math::Distance(m_terraPos, pObj->GetPosition(0));
            if ( dist > 20.0f )  continue;

            pyro = new Gfx::CPyro();
            pyro->Create(Gfx::PT_FRAGT, pObj);
        }
        else
        {
            motion = pObj->GetMotion();
            if ( motion == 0 )  continue;

            dist = Math::Distance(m_terraPos, pObj->GetPosition(0));
            if ( dist > ACTION_RADIUS )  continue;

            if ( type == OBJECT_ANT )
            {
                brain = pObj->GetBrain();
                if ( brain != 0 )  brain->StopTask();
                motion->SetAction(MAS_BACK1, 0.8f+Math::Rand()*0.3f);
                pObj->SetFixed(true);  // not moving
            }
            if ( type == OBJECT_SPIDER )
            {
                brain = pObj->GetBrain();
                if ( brain != 0 )  brain->StopTask();
                motion->SetAction(MSS_BACK1, 0.8f+Math::Rand()*0.3f);
                pObj->SetFixed(true);  // not moving
            }
        }
    }

    return true;
}
コード例 #4
0
ファイル: taskmanip.cpp プロジェクト: ManuelBlanc/colobot
CObject* CTaskManip::SearchTakeUnderObject(Math::Vector &pos, float dLimit)
{
    CObject     *pObj, *pBest;
    Math::Vector    iPos, oPos;
    ObjectType  type;
    float       min, distance;
    int         i;

    iPos   = m_object->GetPosition(0);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    min = 1000000.0f;
    pBest = 0;
    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        type = pObj->GetType();

        if ( type != OBJECT_FRET    &&
             type != OBJECT_STONE   &&
             type != OBJECT_URANIUM &&
             type != OBJECT_BULLET  &&
             type != OBJECT_METAL   &&
             type != OBJECT_POWER   &&
             type != OBJECT_ATOMIC  &&
             type != OBJECT_BBOX    &&
             type != OBJECT_KEYa    &&
             type != OBJECT_KEYb    &&
             type != OBJECT_KEYc    &&
             type != OBJECT_KEYd    &&
             type != OBJECT_TNT     )  continue;

        if ( pObj->GetTruck() != 0 )  continue;  // object transported?
        if ( pObj->GetLock() )  continue;
        if ( pObj->GetZoomY(0) != 1.0f )  continue;

        oPos = pObj->GetPosition(0);
        distance = Math::Distance(oPos, iPos);
        if ( distance <= dLimit &&
             distance < min     )
        {
            min = distance;
            pBest = pObj;
        }
    }
    if ( pBest != 0 )
    {
        pos = pBest->GetPosition(0);
    }
    return pBest;
}
コード例 #5
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//インスタンスを削除する
//戻り値
// TRUE(成功)、FALSE(失敗)
//引数:
// id				[IN]識別ID
BOOL WINAPI DeleteCtrl(
	DWORD id
	)
{
	if( g_instMng.pop(id) == NULL ){
		return FALSE;
	}

	return TRUE;
}
コード例 #6
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//ファイル保存を終了する
//戻り値:
// TRUE(成功)、FALSE(失敗)
//引数:
// id					[IN]識別ID
BOOL WINAPI StopSave(
	DWORD id
	)
{
	std::shared_ptr<CWriteMain> ptr = g_instMng.find(id);
	if( ptr == NULL ){
		return FALSE;
	}

	return ptr->_StopSave();
}
コード例 #7
0
ファイル: displaytext.cpp プロジェクト: Insolita/colobot
CObject* CDisplayText::SearchToto()
{
    ObjectType  type;
    CObject*    pObj;
    int         i;

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        type = pObj->GetType();
        if ( type == OBJECT_TOTO )
        {
            return pObj;
        }
    }
    return 0;
}
コード例 #8
0
ファイル: tasksearch.cpp プロジェクト: DanielVartanov/colobot
void CTaskSearch::DeleteMark(ObjectType type)
{
    CObject*    pObj;
    Math::Vector    oPos;
    int         i;

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        if ( type == pObj->GetType() )
        {
            pObj->DeleteObject();  // removes the mark
            delete pObj;
            break;
        }
    }
}
コード例 #9
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//実際に保存しているファイルパスを取得する(再生やバッチ処理に利用される)
//filePathがNULL時は必要なサイズをfilePathSizeで返す
//通常filePathSize=512で呼び出し
//戻り値:
// TRUE(成功)、FALSE(失敗)
//引数:
// id					[IN]識別ID
// filePath				[OUT]保存ファイルフルパス
// filePathSize			[IN/OUT]filePathのサイズ(WCHAR単位)
BOOL WINAPI GetSaveFilePath(
	DWORD id,
	WCHAR* filePath,
	DWORD* filePathSize
	)
{
	std::shared_ptr<CWriteMain> ptr = g_instMng.find(id);
	if( ptr == NULL ){
		return FALSE;
	}

	return ptr->_GetSaveFilePath(filePath, filePathSize);
}
コード例 #10
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//ファイル保存を開始する
//戻り値:
// TRUE(成功)、FALSE(失敗)
//引数:
// id					[IN]識別ID
// fileName				[IN]保存ファイルフルパス(必要に応じて拡張子変えたりなど行う)
// overWriteFlag		[IN]同一ファイル名存在時に上書きするかどうか(TRUE:する、FALSE:しない)
// createSize			[IN]入力予想容量(188バイトTSでの容量。即時録画時など総時間未定の場合は0。延長などの可能性もあるので目安程度)
BOOL WINAPI StartSave(
	DWORD id,
	LPCWSTR fileName,
	BOOL overWriteFlag,
	ULONGLONG createSize
	)
{
	std::shared_ptr<CWriteMain> ptr = g_instMng.find(id);
	if( ptr == NULL ){
		return FALSE;
	}

	return ptr->_StartSave(fileName, overWriteFlag, createSize, g_Instance);
}
コード例 #11
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//保存用TSデータを送る
//空き容量不足などで書き出し失敗した場合、writeSizeの値を元に
//再度保存処理するときの送信開始地点を決める
//戻り値:
// TRUE(成功)、FALSE(失敗)
//引数:
// id					[IN]識別ID
// data					[IN]TSデータ
// size					[IN]dataのサイズ
// writeSize			[OUT]保存に利用したサイズ
BOOL WINAPI AddTSBuff(
	DWORD id,
	BYTE* data,
	DWORD size,
	DWORD* writeSize
	)
{
	std::shared_ptr<CWriteMain> ptr = g_instMng.find(id);
	if( ptr == NULL ){
		return FALSE;
	}

	return ptr->_AddTSBuff(data, size, writeSize);
}
コード例 #12
0
ファイル: taskinfo.cpp プロジェクト: DanielVartanov/colobot
CObject* CTaskInfo::SearchInfo(float power)
{
    CObject      *pObj, *pBest;
    Math::Vector iPos, oPos;
    ObjectType   type;
    float        dist, min;
    int          i;

    iPos = m_object->GetPosition(0);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    min = 100000.0f;
    pBest = 0;
    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        type = pObj->GetType();
        if ( type != OBJECT_INFO )  continue;

        if ( !pObj->GetActif() )  continue;

        oPos = pObj->GetPosition(0);
        dist = Math::Distance(oPos, iPos);
        if ( dist > power )  continue;  // too far?
        if ( dist < min )
        {
            min = dist;
            pBest = pObj;
        }
    }

    return pBest;
}
コード例 #13
0
ファイル: Write_AVIVO.cpp プロジェクト: PyYoshi/EDCB
//複数保存対応のためインスタンスを新規に作成する
//複数対応できない場合はこの時点でエラーとする
//戻り値
// TRUE(成功)、FALSE(失敗)
//引数:
// id				[OUT]識別ID
BOOL WINAPI CreateCtrl(
	DWORD* id
	)
{
	if( id == NULL ){
		return FALSE;
	}

	try{
		std::shared_ptr<CWriteMain> ptr = std::make_shared<CWriteMain>();
		*id = g_instMng.push(ptr);
	}catch( std::bad_alloc& ){
		return FALSE;
	}

	return TRUE;
}
コード例 #14
0
ファイル: taskbuild.cpp プロジェクト: pol51/colobot
CObject* CTaskBuild::SearchMetalObject(float &angle, float dMin, float dMax,
                                       float aLimit, Error &err)
{
    CObject     *pObj, *pBest;
    Math::Vector    iPos, oPos;
    ObjectType  type;
    float       min, iAngle, a, aa, aBest, distance, magic;
    int         i;
    bool        bMetal;

    iPos   = m_object->GetPosition(0);
    iAngle = m_object->GetAngleY(0);
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    min = 1000000.0f;
    pBest = 0;
    bMetal = false;
    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        if ( !pObj->GetActif() )  continue;  // objet inactive?
        if ( pObj->GetTruck() != 0 )  continue;  // object transported?

        type = pObj->GetType();
        if ( type != OBJECT_METAL )  continue;

        bMetal = true;  // metal exists

        oPos = pObj->GetPosition(0);
        distance = Math::Distance(oPos, iPos);
        a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW!

        if ( distance > dMax )  continue;
        if ( !Math::TestAngle(a, iAngle-aLimit, iAngle+aLimit) )  continue;

        if ( distance < dMin )
        {
            err = ERR_BUILD_METALNEAR;  // too close
            return pObj;
        }

        aa = fabs(a-iAngle);
        if ( aa > Math::PI )  aa = Math::PI*2.0f-aa;
        magic = distance*aa;

        if ( magic < min )
        {
            min = magic;
            aBest = a;
            pBest = pObj;
        }
    }

    if ( pBest == 0 )
    {
        if ( bMetal )  err = ERR_BUILD_METALAWAY;  // too far
        else           err = ERR_BUILD_METALINEX;  // non-existent
    }
    else
    {
        angle = aBest;
        err = ERR_OK;
    }
    return pBest;
}
コード例 #15
0
ファイル: lightning.cpp プロジェクト: DanielVartanov/colobot
CObject* CLightning::SearchObject(Math::Vector pos)
{
    // Lightning conductors
    std::vector<CObject*> paraObj;
    paraObj.reserve(100);
    std::vector<Math::Vector> paraObjPos;
    paraObjPos.reserve(100);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    // Seeking the object closest to the point of impact of lightning.
    CObject* bestObj = 0;
    float min = 100000.0f;
    for (int i = 0; i < 1000000; i++)
    {
        CObject* obj = static_cast<CObject*>( iMan->SearchInstance(CLASS_OBJECT, i) );
        if (obj == nullptr) break;

        if (!obj->GetActif()) continue;  // inactive object?
        if (obj->GetTruck() != nullptr) continue;  // object transported?

        ObjectType type = obj->GetType();
        if ( type == OBJECT_BASE ||
             type == OBJECT_PARA )  // building a lightning effect?
        {
            paraObj.push_back(obj);
            paraObjPos.push_back(obj->GetPosition(0));
        }

        float detect = 0.0f;
        if ( type == OBJECT_BASE     ||
             type == OBJECT_DERRICK  ||
             type == OBJECT_FACTORY  ||
             type == OBJECT_REPAIR   ||
             type == OBJECT_DESTROYER||
             type == OBJECT_STATION  ||
             type == OBJECT_CONVERT  ||
             type == OBJECT_TOWER    ||
             type == OBJECT_RESEARCH ||
             type == OBJECT_RADAR    ||
             type == OBJECT_INFO     ||
             type == OBJECT_ENERGY   ||
             type == OBJECT_LABO     ||
             type == OBJECT_NUCLEAR  ||
             type == OBJECT_PARA     ||
             type == OBJECT_SAFE     ||
             type == OBJECT_HUSTON   )
        {
            detect = m_magnetic;
        }
        if ( type == OBJECT_METAL    ||
             type == OBJECT_POWER    ||
             type == OBJECT_ATOMIC   )
        {
            detect = m_magnetic*0.3f;
        }
        if ( type == OBJECT_MOBILEfa ||
             type == OBJECT_MOBILEta ||
             type == OBJECT_MOBILEwa ||
             type == OBJECT_MOBILEia ||
             type == OBJECT_MOBILEfc ||
             type == OBJECT_MOBILEtc ||
             type == OBJECT_MOBILEwc ||
             type == OBJECT_MOBILEic ||
             type == OBJECT_MOBILEfi ||
             type == OBJECT_MOBILEti ||
             type == OBJECT_MOBILEwi ||
             type == OBJECT_MOBILEii ||
             type == OBJECT_MOBILEfs ||
             type == OBJECT_MOBILEts ||
             type == OBJECT_MOBILEws ||
             type == OBJECT_MOBILEis ||
             type == OBJECT_MOBILErt ||
             type == OBJECT_MOBILErc ||
             type == OBJECT_MOBILErr ||
             type == OBJECT_MOBILErs ||
             type == OBJECT_MOBILEsa ||
             type == OBJECT_MOBILEft ||
             type == OBJECT_MOBILEtt ||
             type == OBJECT_MOBILEwt ||
             type == OBJECT_MOBILEit ||
             type == OBJECT_MOBILEdr )
        {
            detect = m_magnetic*0.5f;
        }
        if (detect == 0.0f) continue;

        Math::Vector oPos = obj->GetPosition(0);
        float dist = Math::DistanceProjected(oPos, pos);
        if (dist > detect) continue;
        if (dist < min)
        {
            min = dist;
            bestObj = obj;
        }
    }

    if (bestObj == nullptr)
        return nullptr;  // nothing found

    // Under the protection of a lightning conductor?
    Math::Vector oPos = bestObj->GetPosition(0);
    for (int i = paraObj.size()-1; i >= 0; i--)
    {
        float dist = Math::DistanceProjected(oPos, paraObjPos[i]);
        if (dist <= LTNG_PROTECTION_RADIUS)
            return paraObj[i];
    }

    return bestObj;
}
コード例 #16
0
ファイル: taskreset.cpp プロジェクト: OdyX/colobot
bool CTaskReset::SearchVehicle()
{
    CObject*    pObj;
    Math::Vector    oPos;
    ObjectType  type;
    float       oRadius, dist;
    int         i;

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        if ( pObj == m_object )  continue;

        type = pObj->GetType();
        if ( type != OBJECT_HUMAN    &&
                type != OBJECT_TECH     &&
                type != OBJECT_MOBILEfa &&
                type != OBJECT_MOBILEta &&
                type != OBJECT_MOBILEwa &&
                type != OBJECT_MOBILEia &&
                type != OBJECT_MOBILEfc &&
                type != OBJECT_MOBILEtc &&
                type != OBJECT_MOBILEwc &&
                type != OBJECT_MOBILEic &&
                type != OBJECT_MOBILEfi &&
                type != OBJECT_MOBILEti &&
                type != OBJECT_MOBILEwi &&
                type != OBJECT_MOBILEii &&
                type != OBJECT_MOBILEfs &&
                type != OBJECT_MOBILEts &&
                type != OBJECT_MOBILEws &&
                type != OBJECT_MOBILEis &&
                type != OBJECT_MOBILErt &&
                type != OBJECT_MOBILErc &&
                type != OBJECT_MOBILErr &&
                type != OBJECT_MOBILErs &&
                type != OBJECT_MOBILEsa &&
                type != OBJECT_MOBILEtg &&
                type != OBJECT_MOBILEft &&
                type != OBJECT_MOBILEtt &&
                type != OBJECT_MOBILEwt &&
                type != OBJECT_MOBILEit &&
                type != OBJECT_MOBILEdr &&
                type != OBJECT_MOTHER   &&
                type != OBJECT_ANT      &&
                type != OBJECT_SPIDER   &&
                type != OBJECT_BEE      &&
                type != OBJECT_WORM     )  continue;

        if ( !pObj->GetCrashSphere(0, oPos, oRadius) )  continue;
        dist = Math::Distance(oPos, m_goal)-oRadius;

        if ( dist < 5.0f )  return true;
    }

    return false;
}
コード例 #17
0
ファイル: taskmanip.cpp プロジェクト: ManuelBlanc/colobot
CObject* CTaskManip::SearchTakeBackObject(bool bAdvance, Math::Vector &pos,
                                          float &distance, float &angle)
{
    CObject     *pObj, *pBest;
    Math::Vector    iPos, oPos;
    ObjectType  type;
    float       min, iAngle, bAngle, aLimit, dLimit, f;
    int         i;

    iPos   = m_object->GetPosition(0);
    iAngle = m_object->GetAngleY(0)+Math::PI;
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    if ( bAdvance && m_energy > 0.0f )
    {
        aLimit = 60.0f*Math::PI/180.0f;
        dLimit = MARGIN_BACK+5.0f;
    }
    else
    {
        aLimit = 7.0f*Math::PI/180.0f;
        dLimit = MARGIN_BACK;
    }

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    min = 1000000.0f;
    pBest = 0;
    bAngle = 0.0f;
    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        type = pObj->GetType();

        if ( type != OBJECT_FRET    &&
             type != OBJECT_STONE   &&
             type != OBJECT_URANIUM &&
             type != OBJECT_BULLET  &&
             type != OBJECT_METAL   &&
             type != OBJECT_POWER   &&
             type != OBJECT_ATOMIC  &&
             type != OBJECT_BBOX    &&
             type != OBJECT_KEYa    &&
             type != OBJECT_KEYb    &&
             type != OBJECT_KEYc    &&
             type != OBJECT_KEYd    &&
             type != OBJECT_TNT     &&
             type != OBJECT_SCRAP1  &&
             type != OBJECT_SCRAP2  &&
             type != OBJECT_SCRAP3  &&
             type != OBJECT_SCRAP4  &&
             type != OBJECT_SCRAP5  )  continue;

        if ( pObj->GetTruck() != 0 )  continue;  // object transported?
        if ( pObj->GetLock() )  continue;
        if ( pObj->GetZoomY(0) != 1.0f )  continue;

        oPos = pObj->GetPosition(0);
        distance = fabs(Math::Distance(oPos, iPos)-TAKE_DIST);
        f = 1.0f-distance/50.0f;
        if ( f < 0.5f )  f = 0.5f;

        angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW !
        if ( !Math::TestAngle(angle, iAngle-aLimit*f, iAngle+aLimit*f) )  continue;

        if ( distance < -dLimit ||
             distance >  dLimit )  continue;

        if ( distance < min )
        {
            min = distance;
            pBest = pObj;
            bAngle = angle;
        }
    }
    if ( pBest == 0 )
    {
        distance = 1000000.0f;
        angle = 0.0f;
    }
    else
    {
        pos = pBest->GetPosition(0);
        distance = min;
        angle = bAngle;
    }
    return pBest;
}
コード例 #18
0
ファイル: taskbuild.cpp プロジェクト: pol51/colobot
Error CTaskBuild::FlatFloor()
{
    CObject     *pObj;
    ObjectType  type;
    Math::Vector    center, pos, oPos, bPos;
    Math::Point     c, p;
    float       radius, max, oRadius, bRadius, angle, dist;
    int         i, j;
    bool        bLittleFlat, bBase;

    radius = 0.0f;
    if ( m_type == OBJECT_DERRICK  )  radius =  5.0f;
    if ( m_type == OBJECT_FACTORY  )  radius = 15.0f;
    if ( m_type == OBJECT_REPAIR   )  radius = 12.0f;
    if ( m_type == OBJECT_STATION  )  radius = 12.0f;
    if ( m_type == OBJECT_CONVERT  )  radius = 12.0f;
    if ( m_type == OBJECT_TOWER    )  radius =  7.0f;
    if ( m_type == OBJECT_RESEARCH )  radius = 10.0f;
    if ( m_type == OBJECT_RADAR    )  radius =  5.0f;
    if ( m_type == OBJECT_ENERGY   )  radius =  8.0f;
    if ( m_type == OBJECT_LABO     )  radius = 12.0f;
    if ( m_type == OBJECT_NUCLEAR  )  radius = 20.0f;
    if ( m_type == OBJECT_PARA     )  radius = 20.0f;
    if ( m_type == OBJECT_INFO     )  radius =  5.0f;
    if ( m_type == OBJECT_DESTROYER)  radius = 20.0f;
    if ( radius == 0.0f )  return ERR_GENERIC;

    center = m_metal->GetPosition(0);
    angle = m_terrain->GetFineSlope(center);
    bLittleFlat = ( angle < Gfx::TERRAIN_FLATLIMIT);

    max = m_terrain->GetFlatZoneRadius(center, radius);
    if ( max < radius )  // area too small?
    {
        if ( bLittleFlat )
        {
            m_main->SetShowLimit(1, Gfx::PARTILIMIT3, m_metal, center, max, 10.0f);
        }
        return bLittleFlat?ERR_BUILD_FLATLIT:ERR_BUILD_FLAT;
    }

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

    max = 100000.0f;
    bBase = false;
    for ( i=0 ; i<1000000 ; i++ )
    {
        pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
        if ( pObj == 0 )  break;

        if ( !pObj->GetActif() )  continue;  // inactive?
        if ( pObj->GetTruck() != 0 )  continue;  // object transported?
        if ( pObj == m_metal )  continue;
        if ( pObj == m_object )  continue;

        type = pObj->GetType();
        if ( type == OBJECT_BASE )
        {
            oPos = pObj->GetPosition(0);
            dist = Math::Distance(center, oPos)-80.0f;
            if ( dist < max )
            {
                max = dist;
                bPos = oPos;
                bRadius = oRadius;
                bBase = true;
            }
        }
        else
        {
            j = 0;
            while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
            {
                dist = Math::Distance(center, oPos)-oRadius;
                if ( dist < max )
                {
                    max = dist;
                    bPos = oPos;
                    bRadius = oRadius;
                    bBase = false;
                }
            }
        }
    }
    if ( max < radius )
    {
        m_main->SetShowLimit(1, Gfx::PARTILIMIT2, m_metal, center, max, 10.0f);
        if ( bRadius < 2.0f )  bRadius = 2.0f;
        m_main->SetShowLimit(2, Gfx::PARTILIMIT3, m_metal, bPos, bRadius, 10.0f);
        return bBase?ERR_BUILD_BASE:ERR_BUILD_BUSY;
    }

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

        if ( !pObj->GetActif() )  continue;  // inactive?
        if ( pObj->GetTruck() != 0 )  continue;  // object transported?
        if ( pObj == m_metal )  continue;
        if ( pObj == m_object )  continue;

        type = pObj->GetType();
        if ( type == OBJECT_DERRICK  ||
             type == OBJECT_FACTORY  ||
             type == OBJECT_STATION  ||
             type == OBJECT_CONVERT  ||
             type == OBJECT_REPAIR   ||
             type == OBJECT_TOWER    ||
             type == OBJECT_RESEARCH ||
             type == OBJECT_RADAR    ||
             type == OBJECT_ENERGY   ||
             type == OBJECT_LABO     ||
             type == OBJECT_NUCLEAR  ||
             type == OBJECT_DESTROYER||
             type == OBJECT_START    ||
             type == OBJECT_END      ||
             type == OBJECT_INFO     ||
             type == OBJECT_PARA     ||
             type == OBJECT_SAFE     ||
             type == OBJECT_HUSTON   )  // building?
        {
            j = 0;
            while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
            {
                dist = Math::Distance(center, oPos)-oRadius;
                if ( dist < max )
                {
                    max = dist;
                    bPos = oPos;
                    bRadius = oRadius;
                }
            }
        }
    }
    if ( max-BUILDMARGIN < radius )
    {
        m_main->SetShowLimit(1, Gfx::PARTILIMIT2, m_metal, center, max-BUILDMARGIN, 10.0f);
        m_main->SetShowLimit(2, Gfx::PARTILIMIT3, m_metal, bPos, bRadius+BUILDMARGIN, 10.0f);
        return bBase?ERR_BUILD_BASE:ERR_BUILD_NARROW;
    }

    return ERR_OK;
}
コード例 #19
0
ファイル: taskmanip.cpp プロジェクト: ManuelBlanc/colobot
CObject* CTaskManip::SearchOtherObject(bool bAdvance, Math::Vector &pos,
                                       float &distance, float &angle,
                                       float &height)
{
    Character*  character;
    CObject*    pObj;
    CObject*    pPower;
    Math::Matrix*   mat;
    Math::Vector    iPos, oPos;
    ObjectType  type, powerType;
    float       iAngle, iRad, oAngle, oLimit, aLimit, dLimit;
    int         i;

    distance = 1000000.0f;
    angle = 0.0f;

    if ( m_bSubm )  return 0;  // impossible with the submarine

    if ( !m_object->GetCrashSphere(0, iPos, iRad) )  return 0;
    iAngle = m_object->GetAngleY(0);
    iAngle = Math::NormAngle(iAngle);  // 0..2*Math::PI

    if ( bAdvance && m_energy > 0.0f )
    {
        aLimit = 60.0f*Math::PI/180.0f;
        dLimit = MARGIN_FRIEND+10.0f;
    }
    else
    {
        aLimit = 7.0f*Math::PI/180.0f;
        dLimit = MARGIN_FRIEND;
    }

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        if ( pObj == m_object )  continue;  // yourself?

        type = pObj->GetType();
        if ( type != OBJECT_MOBILEfa &&
             type != OBJECT_MOBILEta &&
             type != OBJECT_MOBILEwa &&
             type != OBJECT_MOBILEia &&
             type != OBJECT_MOBILEfc &&
             type != OBJECT_MOBILEtc &&
             type != OBJECT_MOBILEwc &&
             type != OBJECT_MOBILEic &&
             type != OBJECT_MOBILEfi &&
             type != OBJECT_MOBILEti &&
             type != OBJECT_MOBILEwi &&
             type != OBJECT_MOBILEii &&
             type != OBJECT_MOBILEfs &&
             type != OBJECT_MOBILEts &&
             type != OBJECT_MOBILEws &&
             type != OBJECT_MOBILEis &&
             type != OBJECT_MOBILErt &&
             type != OBJECT_MOBILErc &&
             type != OBJECT_MOBILErr &&
             type != OBJECT_MOBILErs &&
             type != OBJECT_MOBILEsa &&
             type != OBJECT_MOBILEtg &&
             type != OBJECT_MOBILEft &&
             type != OBJECT_MOBILEtt &&
             type != OBJECT_MOBILEwt &&
             type != OBJECT_MOBILEit &&
             type != OBJECT_TOWER    &&
             type != OBJECT_RESEARCH &&
             type != OBJECT_ENERGY   &&
             type != OBJECT_LABO     &&
             type != OBJECT_NUCLEAR  )  continue;

        pPower = pObj->GetPower();
        if ( pPower != 0 )
        {
            if ( pPower->GetLock() )  continue;
            if ( pPower->GetZoomY(0) != 1.0f )  continue;

            powerType = pPower->GetType();
            if ( powerType == OBJECT_NULL ||
                 powerType == OBJECT_FIX  )  continue;
        }

        mat = pObj->GetWorldMatrix(0);
        character = pObj->GetCharacter();
        oPos = Transform(*mat, character->posPower);

        oAngle = pObj->GetAngleY(0);
        if ( type == OBJECT_TOWER    ||
             type == OBJECT_RESEARCH )
        {
            oLimit = 45.0f*Math::PI/180.0f;
        }
        else if ( type == OBJECT_ENERGY )
        {
            oLimit = 90.0f*Math::PI/180.0f;
        }
        else if ( type == OBJECT_LABO )
        {
            oLimit = 120.0f*Math::PI/180.0f;
        }
        else if ( type == OBJECT_NUCLEAR )
        {
            oLimit = 45.0f*Math::PI/180.0f;
        }
        else
        {
            oLimit = 45.0f*Math::PI/180.0f;
            oAngle += Math::PI;  // is behind
        }
        oAngle = Math::NormAngle(oAngle);  // 0..2*Math::PI
        angle = Math::RotateAngle(iPos.x-oPos.x, oPos.z-iPos.z);  // CW !
        if ( !Math::TestAngle(angle, oAngle-oLimit, oAngle+oLimit) )  continue;

        distance = fabs(Math::Distance(oPos, iPos)-TAKE_DIST);
        if ( distance <= dLimit )
        {
            angle = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z);  // CW !
            if ( Math::TestAngle(angle, iAngle-aLimit, iAngle+aLimit) )
            {
                character = pObj->GetCharacter();
                height = character->posPower.y;
                pos = oPos;
                return pObj;
            }
        }
    }

    distance = 1000000.0f;
    angle = 0.0f;
    return 0;
}
コード例 #20
0
ファイル: target.cpp プロジェクト: DanielVartanov/colobot
CObject* CTarget::DetectFriendObject(Math::Point pos)
{
    ObjectType  type;
    CObject     *pObj, *pTarget;
    int         objRank, i, j, rank;

    objRank = m_engine->DetectObject(pos);

    CInstanceManager* iMan = CInstanceManager::GetInstancePointer();

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

        if ( !pObj->GetActif() )  continue;
        if ( pObj->GetProxyActivate() )  continue;
        if ( pObj->GetSelect() )  continue;

        pTarget = 0;
        type = pObj->GetType();
        if ( type == OBJECT_DERRICK      ||
             type == OBJECT_FACTORY      ||
             type == OBJECT_REPAIR       ||
             type == OBJECT_DESTROYER    ||
             type == OBJECT_STATION      ||
             type == OBJECT_CONVERT      ||
             type == OBJECT_TOWER        ||
             type == OBJECT_RESEARCH     ||
             type == OBJECT_RADAR        ||
             type == OBJECT_INFO         ||
             type == OBJECT_ENERGY       ||
             type == OBJECT_LABO         ||
             type == OBJECT_NUCLEAR      ||
             type == OBJECT_PARA         ||
             type == OBJECT_SAFE         ||
             type == OBJECT_HUSTON       ||
             type == OBJECT_HUMAN        ||
             type == OBJECT_TECH         ||
             type == OBJECT_TOTO         ||
             type == OBJECT_MOBILEfa     ||
             type == OBJECT_MOBILEta     ||
             type == OBJECT_MOBILEwa     ||
             type == OBJECT_MOBILEia     ||
             type == OBJECT_MOBILEfc     ||
             type == OBJECT_MOBILEtc     ||
             type == OBJECT_MOBILEwc     ||
             type == OBJECT_MOBILEic     ||
             type == OBJECT_MOBILEfi     ||
             type == OBJECT_MOBILEti     ||
             type == OBJECT_MOBILEwi     ||
             type == OBJECT_MOBILEii     ||
             type == OBJECT_MOBILEfs     ||
             type == OBJECT_MOBILEts     ||
             type == OBJECT_MOBILEws     ||
             type == OBJECT_MOBILEis     ||
             type == OBJECT_MOBILErt     ||
             type == OBJECT_MOBILErc     ||
             type == OBJECT_MOBILErr     ||
             type == OBJECT_MOBILErs     ||
             type == OBJECT_MOBILEsa     ||
             type == OBJECT_MOBILEft     ||
             type == OBJECT_MOBILEtt     ||
             type == OBJECT_MOBILEwt     ||
             type == OBJECT_MOBILEit     ||
             type == OBJECT_MOBILEdr     )
        {
            pTarget = pObj;
        }
        else if ( (type == OBJECT_POWER  ||
                  type == OBJECT_ATOMIC ) &&
             pObj->GetTruck() != 0 )  // battery used?
        {
            pTarget = pObj->GetTruck();
            if ( pTarget->GetType() == OBJECT_MOBILEtg )
            {
                pTarget = 0;
            }
        }

        for ( j=0 ; j<OBJECTMAXPART ; j++ )
        {
            rank = pObj->GetObjectRank(j);
            if ( rank == -1 )  continue;
            if ( rank != objRank )  continue;
            return pTarget;
        }
    }
    return 0;
}