#if !__FINAL #include "blockview.h" #include "atl/array.h" #include "atl/string.h" #include "bank/bkmgr.h" #include "bank/bank.h" #include "bank/bank.h" #include "bank/combo.h" #include "grcore/debugdraw.h" #include "camera/CamInterface.h" #include "camera/debug/DebugDirector.h" #include "camera/helpers/Frame.h" #include "peds/PlayerInfo.h" #include "scene/world/gameWorld.h" #include "script/script.h" #include "fwscene/mapdata/mapdatadebug.h" #include "fwdebug/picker.h" #define TIME_TO_UPDATE_BLOCKS (10000) // every 10 seconds should be enough for the update struct CBlock { static const int MAX_POINTS = 4; atString name; atString user; atString owner; atString time; s32 flags; s32 numPoints; Vector3 points[MAX_POINTS]; Vector3 min; Vector3 max; }; struct CUserInfo { const char* name; atArray blockList; s32 currentIdx; }; // info about the root of a lod hierarchy, to allow filtering by lod tree class CLodTreeRootInfo { public: CEntity* m_pRootEntity; u32 m_nHierarchyIndex; }; #define NAME_LENGTH 128 #define BLOCKVIEW_MAX_BLOCKS (1400) DEBUG_DRAW_ONLY(static u32 s_TimeStepCheck); static s32 s_blockSorts[BLOCKVIEW_MAX_BLOCKS]; static CBlock* s_blocks; static atArray s_blockNames; static atArray s_lodTreeNames; static atArray s_lodTreeRootInfo; static s32 s_numBlocks(0); static s32 s_currentBlock(0); static s32 s_currentBlockInside(0); static s32 s_currentBlockNameIdx(0); #if __BANK static s32 s_currentLodTree(0); #endif static s32 s_numBlockNames(0); static bool bValidBlockList = true; static atArray s_users; static CUserInfo *s_userInfo; static s32 s_numUsers(0); static char s_currentBlockName[NAME_LENGTH]; static s32 s_currentUser; static bool s_IsolateBlock(false); static bool s_IsolateLodTree(false); #if __BANK static bool s_IsolateArtist(false); static bool s_IsolateDates(false); #endif static bool s_DisplayInfo(false); DEBUG_DRAW_ONLY(static bool s_DisplayPlayerBlock(true)); static bool s_FilterArtist(false); static bool s_Filter1stPass(false); static bool s_Filter2ndPassStarted(false); static bool s_Filter2ndPassOutsourced(false); static bool s_Filter2ndPassComplete(false); static bool s_Filter3rdPass(false); static bool s_FilterComplete(false); #if __BANK static s32 s_StartYear(2005); static s32 s_StartMonth(1); static s32 s_StartDay(1); static s32 s_EndYear(2005); static s32 s_EndMonth(1); static s32 s_EndDay(1); #endif #if __BANK static bkCombo* s_BlockCombo(NULL); #endif #if __DEV PARAM(NoDisplayBlockInfo,""); #endif // __DEV //////////////////////////////////////////////////////////////////////////// // name: Initialise // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// void CBlockView::Init(unsigned /*initMode*/) { USE_DEBUG_MEMORY(); RAGE_TRACK(Debug); DEBUG_DRAW_ONLY(s_TimeStepCheck = TIME_TO_UPDATE_BLOCKS); Assert(!s_blocks); s_blocks = rage_new CBlock[BLOCKVIEW_MAX_BLOCKS]; Assert(!s_userInfo); s_userInfo = rage_new CUserInfo[BLOCKVIEW_MAX_BLOCKS]; for(s32 i=0;i= TIME_TO_UPDATE_BLOCKS) // only check once in a while... { s_TimeStepCheck = 0; CEntity* pEntity = (CEntity*) g_PickerManager.GetSelectedEntity(); if (pEntity) { if(pEntity->GetTransformPtr()) s_currentBlockInside = GetCurrentBlockInside(VEC3V_TO_VECTOR3(pEntity->GetTransformPtr()->GetPosition())); } else { camDebugDirector& debugDirector = camInterface::GetDebugDirector(); if (debugDirector.IsFreeCamActive()) s_currentBlockInside = GetCurrentBlockInside(debugDirector.GetFreeCamFrame().GetPosition()); else s_currentBlockInside = GetCurrentBlockInside(CGameWorld::FindLocalPlayerCentreOfWorld()); } } s_TimeStepCheck += fwTimer::GetTimeStepInMilliseconds(); } #endif // DEBUG_DRAW if (!s_DisplayInfo) return; // only display block selected stuff when a block is selected #if __BANK bkBank* pBankFind = BANKMGR.FindBank("Blocks"); if(pBankFind && pBankFind->AreAnyWidgetsShown()) { char debugText[512]; Vector2 vCurrentPoint[4]; // for the 4 points int c=0; vCurrentPoint[0] = Vector2(CBlockView::GetPoint(s_currentBlock, c).x, CBlockView::GetPoint(s_currentBlock, c).y); vCurrentPoint[1] = Vector2(CBlockView::GetPoint(s_currentBlock, c+1).x, CBlockView::GetPoint(s_currentBlock, c+1).y); vCurrentPoint[2] = Vector2(CBlockView::GetPoint(s_currentBlock, c+2).x, CBlockView::GetPoint(s_currentBlock, c+2).y); vCurrentPoint[3] = Vector2(CBlockView::GetPoint(s_currentBlock, c+3).x, CBlockView::GetPoint(s_currentBlock, c+3).y); sprintf (debugText, "BLOCK SELECTED: %d - %s (%s) (%s) (a: %f,%f b: %f,%f c: %f,%f d:%f,%f) ", s_currentBlock, (const char*)(s_blocks[s_currentBlock].name), (const char*)(s_blocks[s_currentBlock].user), (const char*)(s_blocks[s_currentBlock].owner), vCurrentPoint[0].x,vCurrentPoint[0].y, vCurrentPoint[1].x,vCurrentPoint[1].y, vCurrentPoint[2].x,vCurrentPoint[2].y, vCurrentPoint[3].x,vCurrentPoint[3].y ); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_FIRST_PASS) strcat (debugText, ": 1st pass"); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_SECOND_PASS_STARTED) strcat (debugText, ": 2nd pass"); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_SECOND_PASS_OUTSOURCED) strcat (debugText, ": 2nd pass outsourced"); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_SECOND_PASS_COMPLETE) strcat (debugText, ": 2nd pass complete"); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_THIRD_PASS_COMPLETE) strcat (debugText, ": 3rd pass complete"); if(s_blocks[s_currentBlock].flags & BLOCKFLAGS_COMPLETE) strcat (debugText, ": complete"); grcDebugDraw::AddDebugOutput(debugText); // add all the text to the debug view if(s_DisplayPlayerBlock) { vCurrentPoint[0] = Vector2(CBlockView::GetPoint(s_currentBlockInside, c).x, CBlockView::GetPoint(s_currentBlockInside, c).y); vCurrentPoint[1] = Vector2(CBlockView::GetPoint(s_currentBlockInside, c+1).x, CBlockView::GetPoint(s_currentBlockInside, c+1).y); vCurrentPoint[2] = Vector2(CBlockView::GetPoint(s_currentBlockInside, c+2).x, CBlockView::GetPoint(s_currentBlockInside, c+2).y); vCurrentPoint[3] = Vector2(CBlockView::GetPoint(s_currentBlockInside, c+3).x, CBlockView::GetPoint(s_currentBlockInside, c+3).y); sprintf (debugText, "BLOCK INSIDE: %d - %s (%s) (%s) (a: %f,%f b: %f,%f c: %f,%f d:%f,%f) ", s_currentBlock, (const char*)(s_blocks[s_currentBlockInside].name), (const char*)(s_blocks[s_currentBlockInside].user), (const char*)(s_blocks[s_currentBlockInside].owner), vCurrentPoint[0].x,vCurrentPoint[0].y, vCurrentPoint[1].x,vCurrentPoint[1].y, vCurrentPoint[2].x,vCurrentPoint[2].y, vCurrentPoint[3].x,vCurrentPoint[3].y ); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_FIRST_PASS) strcat (debugText, ": 1st pass"); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_SECOND_PASS_STARTED) strcat (debugText, ": 2nd pass"); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_SECOND_PASS_OUTSOURCED) strcat (debugText, ": 2nd pass outsourced"); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_SECOND_PASS_COMPLETE) strcat (debugText, ": 2nd pass complete"); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_THIRD_PASS_COMPLETE) strcat (debugText, ": 3rd pass complete"); if(s_blocks[s_currentBlockInside].flags & BLOCKFLAGS_COMPLETE) strcat (debugText, ": complete"); grcDebugDraw::AddDebugOutput(debugText); // add all the text to the debug view } } #endif // __BANK } //////////////////////////////////////////////////////////////////////////// int CbCompareBlocks(const void* pVoidA, const void* pVoidB) { const s32* pA = (const s32*)pVoidA; const s32* pB = (const s32*)pVoidB; return stricmp(s_blocks[*pA].name,s_blocks[*pB].name); } //////////////////////////////////////////////////////////////////////////// // name: InitLevelWidgets // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// #if __BANK void CBlockView::InitLevelWidgets() { s32 i; if(s_numBlocks==0) return; bkBank* pBank = &BANKMGR.CreateBank("Blocks"); if (AssertVerify(pBank)) { for(i=0;im_pRootEntity->GetBaseModelInfo()->GetModelName(); s_lodTreeNames.PushAndGrow(pszName); } pBank->AddToggle("Display Info", &s_DisplayInfo); pBank->AddToggle("Display Info On Ped Pos", &s_DisplayPlayerBlock); pBank->AddToggle("Filter Artist", &s_FilterArtist, UpdateBlockList); pBank->AddToggle("Filter 1st Pass", &s_Filter1stPass, UpdateBlockList); pBank->AddToggle("Filter 2nd Pass Started", &s_Filter2ndPassStarted, UpdateBlockList); pBank->AddToggle("Filter 2nd Pass Outsourced", &s_Filter2ndPassOutsourced, UpdateBlockList); pBank->AddToggle("Filter 2nd Pass Complete", &s_Filter2ndPassComplete, UpdateBlockList); pBank->AddToggle("Filter 3rd Pass", &s_Filter3rdPass, UpdateBlockList); pBank->AddToggle("Filter Complete", &s_FilterComplete, UpdateBlockList); s_BlockCombo = pBank->AddCombo("Block", &s_currentBlockNameIdx, s_blockNames.GetCount(), &s_blockNames[0], UpdateCurrentBlock); pBank->AddButton("Warp to Selected",SelectBlock); pBank->AddText("Block Name", s_currentBlockName, NAME_LENGTH); pBank->AddButton("Warp to Name",SelectBlockByName); pBank->AddToggle("Isolate Block", &s_IsolateBlock); pBank->AddCombo("Artist", &s_currentUser, s_users.GetCount(), &s_users[0], UpdateBlockList); pBank->AddButton("Warp to Artist",SelectUser); pBank->AddButton("Next",SelectNext); pBank->AddButton("Previous",SelectPrevious); pBank->AddToggle("Isolate Artist", &s_IsolateArtist); if (s_lodTreeNames.GetCount()) { pBank->AddToggle("Isolate Lod Tree", &s_IsolateLodTree); pBank->AddCombo("LodTree", &s_currentLodTree, s_lodTreeNames.GetCount(), &s_lodTreeNames[0]); } pBank->AddSlider("Start Year", &s_StartYear, 2004, 2010, 1); pBank->AddSlider("Start Month", &s_StartMonth, 1, 12, 1); pBank->AddSlider("Start Day", &s_StartDay, 1, 31, 1); pBank->AddSlider("End Year", &s_EndYear, 2004, 2010, 1); pBank->AddSlider("End Month", &s_EndMonth, 1, 12, 1); pBank->AddSlider("End Day", &s_EndDay, 1, 31, 1); pBank->AddToggle("Isolate Dates", &s_IsolateDates); } UpdateBlockList(); } void CBlockView::ShutdownLevelWidgets() { bkBank* pBankFind = BANKMGR.FindBank("Blocks"); if (pBankFind) BANKMGR.DestroyBank(*pBankFind); } #endif // __BANK bool CBlockView::IsCurrentUser(s32 index) { if(stricmp(s_blocks[index].user,s_users[s_currentUser]) != 0) return true; else return false; } //////////////////////////////////////////////////////////////////////////// // name: UpdateBlockList // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// void CBlockView::UpdateBlockList() { s_numBlockNames = 0; for(s32 i=0;iSetString(0, "N/A"); s_BlockCombo->UpdateCombo("Block", &s_currentBlockNameIdx, 1, NULL, UpdateCurrentBlock); } else { s_currentBlock = s_blockSorts[0]; for (int i = 0; i < s_numBlockNames; ++i) { s_BlockCombo->SetString(i, s_blockNames[i]); } if (!bValidBlockList) { s_BlockCombo->UpdateCombo("Block", &s_currentBlockNameIdx, s_numBlockNames, &s_blockNames[0], UpdateCurrentBlock); } } bValidBlockList = (s_numBlockNames > 0); #endif } //////////////////////////////////////////////////////////////////////////// void CBlockView::UpdateCurrentBlock() { s_currentBlock = s_blockSorts[s_currentBlockNameIdx]; } //////////////////////////////////////////////////////////////////////////// int CbCompareIndices(const s32* pA, const s32* pB) { return (*pA - *pB); } //////////////////////////////////////////////////////////////////////////// int CbCompareUsers(const void* pVoidA, const void* pVoidB) { const CUserInfo* pA = (const CUserInfo*)pVoidA; const CUserInfo* pB = (const CUserInfo*)pVoidB; return stricmp(pA->name,pB->name); } void CBlockView::AddLodTree(CEntity* pRootEntity) { if (pRootEntity) { CLodTreeRootInfo treeInfo; treeInfo.m_pRootEntity = pRootEntity; treeInfo.m_nHierarchyIndex = 0; s_lodTreeRootInfo.PushAndGrow(treeInfo); } } //////////////////////////////////////////////////////////////////////////// // name: AddBlock // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// //void CBlockView::AddBlock(const char* pName,const char* pUser,const char* pTime,s32 flags,s32 numPoints,const Vector3* points) void CBlockView::AddBlock(const char* pName,const char* pExportedBy,const char* pOwner,const char* pTime,s32 flags,s32 numPoints,const Vector3* points) { if (flags & BLOCKFLAGS_UNUSED) // dont add any Unused blocks to the list... just return out return; if (!Verifyf(s_numBlocks < BLOCKVIEW_MAX_BLOCKS, "BlockView - Exceeded the maximum number of blocks - see a programmer!")) return; static s32 LastUser = -1; char actualname[128]; safecpy(actualname,pName); s32 i = 0; s_blocks[s_numBlocks].name = actualname; s_blocks[s_numBlocks].user = pExportedBy; s_blocks[s_numBlocks].owner = pOwner; s_blocks[s_numBlocks].time = pTime; s_blocks[s_numBlocks].flags = flags; s_blocks[s_numBlocks].numPoints = 0; if((numPoints > 0) && points) { if(numPoints > CBlock::MAX_POINTS) numPoints = CBlock::MAX_POINTS; for(i=0;i= s_userInfo[s_currentUser].blockList.GetCount()) { s_userInfo[s_currentUser].currentIdx = 0; } s_currentBlock = s_userInfo[s_currentUser].blockList[s_userInfo[s_currentUser].currentIdx]; SelectBlock(); } //////////////////////////////////////////////////////////////////////////// // name: SelectPrevious // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// void CBlockView::SelectPrevious() { s_userInfo[s_currentUser].currentIdx--; if(s_userInfo[s_currentUser].currentIdx < 0) { s_userInfo[s_currentUser].currentIdx = s_userInfo[s_currentUser].blockList.GetCount() - 1; } s_currentBlock = s_userInfo[s_currentUser].blockList[s_userInfo[s_currentUser].currentIdx]; SelectBlock(); } //////////////////////////////////////////////////////////////////////////// // name: WarpToCurrent // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// void CBlockView::WarpToCurrent() { // if(!s_blocks[s_currentBlock].posSetOnce) // return; Vector3 pos; GetBlockPos(s_currentBlock,pos); pos.z += 50.0f; camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrameNonConst(); freeCamFrame.SetWorldMatrix(M34_IDENTITY); freeCamFrame.SetPosition(pos); } //////////////////////////////////////////////////////////////////////////// // name: GetNumPoints // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// s32 CBlockView::GetNumPoints(s32 index) { return s_blocks[index].numPoints; } //////////////////////////////////////////////////////////////////////////// // name: GetPoint // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// Vector3 CBlockView::GetPoint(s32 index,s32 point) { return s_blocks[index].points[point]; } //////////////////////////////////////////////////////////////////////////// // name: ShouldDisplayInfo // purpose: returns whether to display block info // params: none // returns: true or false //////////////////////////////////////////////////////////////////////////// bool CBlockView::ShouldDisplayInfo() { return (s_DisplayInfo && s_numBlocks > 0); } void CBlockView::SetDisplayInfo(bool bDisplayInfo) { s_DisplayInfo = bDisplayInfo; } //////////////////////////////////////////////////////////////////////////// // name: ShouldRenderToMap // purpose: returns whether to display block info based on the flag // params: none // returns: s32 containing what flags to render to the map //////////////////////////////////////////////////////////////////////////// bool CBlockView::ShouldRenderToMap(s32 flag) { if (flag == BLOCKFLAGS_FIRST_PASS) return s_Filter1stPass; if (flag == BLOCKFLAGS_SECOND_PASS_STARTED) return s_Filter2ndPassStarted; if (flag == BLOCKFLAGS_SECOND_PASS_OUTSOURCED) return s_Filter2ndPassOutsourced; if (flag == BLOCKFLAGS_SECOND_PASS_COMPLETE) return s_Filter2ndPassComplete; if (flag == BLOCKFLAGS_THIRD_PASS_COMPLETE) return s_Filter3rdPass; if (flag == BLOCKFLAGS_COMPLETE) return s_FilterComplete; return false; } bool CBlockView::FilterArtist() { return s_FilterArtist; } bool CBlockView::FilterBlock() { return ( s_IsolateBlock && bValidBlockList ); } bool CBlockView::FilterLodTree() { return s_IsolateLodTree; } bool CBlockView::IsCurrentBlock(s32 index) { return (s_currentBlock == index); } //////////////////////////////////////////////////////////////////////////// // name: ShouldDraw // purpose: // params: none // returns: nothing //////////////////////////////////////////////////////////////////////////// bool CBlockView::ShouldDraw(CEntity* BANK_ONLY(pEntity)) { #if __BANK if( (pEntity->GetType() == ENTITY_TYPE_VEHICLE) || (pEntity->GetType() == ENTITY_TYPE_PED)) return true; if(!FilterBlock() && !s_IsolateArtist && !s_IsolateDates && !s_IsolateLodTree) return true; s32 blockIdx = fwMapDataDebug::GetBlockIndex(pEntity->GetIplIndex()); if(blockIdx < 0 || blockIdx >= s_numBlocks) return false; if(s_IsolateBlock && blockIdx != s_currentBlock) return false; if(s_IsolateArtist && (stricmp(s_userInfo[s_currentUser].name,s_blocks[blockIdx].user) != 0)) return false; if(s_IsolateDates) { char StartDate[128]; char EndDate[128]; sprintf(StartDate,"%d:%02d:%02d:0:0:0",s_StartYear,s_StartMonth,s_StartDay); sprintf(EndDate,"%d:%02d:%02d:23:59:59",s_EndYear,s_EndMonth,s_EndDay); if(stricmp(s_blocks[blockIdx].time,StartDate) < 0) return false; if(stricmp(s_blocks[blockIdx].time,EndDate) > 0) return false; } if (s_IsolateLodTree) { if (pEntity->GetLodData().IsOrphanHd()) return false; if (pEntity->GetRootLod() != s_lodTreeRootInfo[s_currentLodTree].m_pRootEntity) return false; } return true; #else return false; #endif } #endif //#if !__FINAL