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 }
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 --; } } }
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; }
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; }
//インスタンスを削除する //戻り値 // TRUE(成功)、FALSE(失敗) //引数: // id [IN]識別ID BOOL WINAPI DeleteCtrl( DWORD id ) { if( g_instMng.pop(id) == NULL ){ return FALSE; } return TRUE; }
//ファイル保存を終了する //戻り値: // 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(); }
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; }
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; } } }
//実際に保存しているファイルパスを取得する(再生やバッチ処理に利用される) //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); }
//ファイル保存を開始する //戻り値: // 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); }
//保存用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); }
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; }
//複数保存対応のためインスタンスを新規に作成する //複数対応できない場合はこの時点でエラーとする //戻り値 // 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }