int C4GameObjects::Load(C4Group &hGroup, bool fKeepInactive) { Clear(!fKeepInactive); // Load data component StdStrBuf Source; if (!hGroup.LoadEntryString(C4CFN_ScenarioObjects, Source)) return 0; // Compile StdStrBuf Name = hGroup.GetFullName() + DirSep C4CFN_ScenarioObjects; if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkParAdapt(*this, false), Source, Name.getData())) return 0; // Process objects C4ObjectLink *cLnk = nullptr; C4Object *pObj = nullptr; bool fObjectNumberCollision = false; int32_t iMaxObjectNumber = 0; for (cLnk = Last; cLnk; cLnk = cLnk->Prev) { C4Object *pObj = cLnk->Obj; // check object number collision with inactive list if (fKeepInactive) { for (C4ObjectLink *clnk = InactiveObjects.First; clnk; clnk = clnk->Next) if (clnk->Obj->Number == pObj->Number) fObjectNumberCollision = true; } // keep track of numbers iMaxObjectNumber = Max<long>(iMaxObjectNumber, pObj->Number); // add to list of backobjects if (pObj->Category & C4D_Background) Game.BackObjects.Add(pObj, C4ObjectList::stMain, this); // add to list of foreobjects if (pObj->Category & C4D_Foreground) Game.ForeObjects.Add(pObj, C4ObjectList::stMain, this); // Unterminate end } // Denumerate pointers // if object numbers collideded, numbers will be adjusted afterwards // so fake inactive object list empty meanwhile C4ObjectLink *pInFirst = nullptr; if (fObjectNumberCollision) { pInFirst = InactiveObjects.First; InactiveObjects.First = NULL; } // denumerate pointers Denumerate(); // update object enumeration index now, because calls like UpdateTransferZone // might create objects Game.ObjectEnumerationIndex = Max(Game.ObjectEnumerationIndex, iMaxObjectNumber); // end faking and adjust object numbers if (fObjectNumberCollision) { InactiveObjects.First = pInFirst; // simply renumber all inactive objects for (cLnk = InactiveObjects.First; cLnk; cLnk = cLnk->Next) if ((pObj = cLnk->Obj)->Status) pObj->Number = ++Game.ObjectEnumerationIndex; } // special checks: // -contained/contents-consistency // -StaticBack-objects zero speed for (cLnk = First; cLnk; cLnk = cLnk->Next) if ((pObj = cLnk->Obj)->Status) { // staticback must not have speed if (pObj->Category & C4D_StaticBack) { pObj->xdir = pObj->ydir = 0; } // contained must be in contents list if (pObj->Contained) if (!pObj->Contained->Contents.GetLink(pObj)) { DebugLogF( "Error in Objects.txt: Container of #%d is #%d, but not found in " "contents list!", pObj->Number, pObj->Contained->Number); pObj->Contained->Contents.Add(pObj, C4ObjectList::stContents); } // all contents must have contained set; otherwise, remove them! C4Object *pObj2; for (C4ObjectLink *cLnkCont = pObj->Contents.First; cLnkCont; cLnkCont = cLnkCont->Next) { // check double links if (pObj->Contents.GetLink(cLnkCont->Obj) != cLnkCont) { DebugLogF("Error in Objects.txt: Double containment of #%d by #%d!", cLnkCont->Obj->Number, pObj->Number); // this remove-call will only remove the previous (dobuled) link, so // cLnkCont should be save pObj->Contents.Remove(cLnkCont->Obj); // contents checked already continue; } // check contents/contained-relation if ((pObj2 = cLnkCont->Obj)->Status) if (pObj2->Contained != pObj) { DebugLogF( "Error in Objects.txt: Object #%d not in container #%d as " "referenced!", pObj2->Number, pObj->Number); pObj2->Contained = pObj; } } } // sort out inactive objects C4ObjectLink *cLnkNext; for (cLnk = First; cLnk; cLnk = cLnkNext) { cLnkNext = cLnk->Next; if (cLnk->Obj->Status == C4OS_INACTIVE) { if (cLnk->Prev) cLnk->Prev->Next = cLnkNext; else First = cLnkNext; if (cLnkNext) cLnkNext->Prev = cLnk->Prev; else Last = cLnk->Prev; if (cLnk->Prev = InactiveObjects.Last) InactiveObjects.Last->Next = cLnk; else InactiveObjects.First = cLnk; InactiveObjects.Last = cLnk; cLnk->Next = NULL; Mass -= pObj->Mass; } } { C4DebugRecOff DBGRECOFF; // - script callbacks that would kill // DebugRec-sync for runtime start // update graphics UpdateGraphics(false); // Update faces UpdateFaces(false); // Update ocf SetOCF(); } // make sure list is sorted by category - after sorting out inactives, because // inactives aren't sorted into the main list FixObjectOrder(); // Sectors.Dump(); // misc updates for (cLnk = First; cLnk; cLnk = cLnk->Next) if ((pObj = cLnk->Obj)->Status) { // add to plrview pObj->PlrFoWActualize(); // update flipdir (for old objects.txt with no flipdir defined) // assigns Action.DrawDir as well pObj->UpdateFlipDir(); } // Done return ObjectCount(); }
extern "C" void OBJECT_CB(int var){ int i,temp; switch(var){ case VISAXISLABELS: updatemenu=1; break; case UPDATE_LIST: switch(wall_case){ case WALL_1: temp=surface_indices_bak[UP_Z]; if(nsurfinfo>0){ for(i=0;i<6;i++){ surface_indices[i]=temp; LIST_surface[i]->set_int_val(temp); } } break; case WALL_3: if(nsurfinfo>0){ for(i=0;i<6;i++){ temp=surface_indices_bak[i]; surface_indices[i]=temp; LIST_surface[i]->set_int_val(temp); } } break; case WALL_6: if(nsurfinfo>0){ for(i=0;i<6;i++){ temp=surface_indices_bak[i]; surface_indices[i]=temp; LIST_surface[i]->set_int_val(temp); } } break; default: ASSERT(FFALSE); break; } if(bchighlight!=NULL){ for(i=0;i<6;i++){ bchighlight->surf[i]=surfinfo+sorted_surfidlist[surface_indices_bak[i]]; bchighlight->surf_index[i]=sorted_surfidlist[surface_indices_bak[i]]; } bchighlight->changed_surface=1; if(bchighlight->blockage_id>0&&bchighlight->blockage_id<=nchanged_idlist){ changed_idlist[bchighlight->blockage_id]=1; } blockages_dirty=1; updateusetextures(); UpdateFaces(); } break; case RADIO_WALL: if(nsurfinfo==0)break; if(bchighlight!=NULL){ bchighlight->walltype=wall_case; } switch(wall_case){ case WALL_6: for(i=0;i<6;i++){ LIST_surface[i]->enable(); } LIST_surface[DOWN_Z]->set_name("z lower face"); LIST_surface[UP_Z]->set_name("z upper face"); LIST_surface[DOWN_Y]->set_name("y lower face"); LIST_surface[UP_Y]->set_name("y upper face"); LIST_surface[DOWN_X]->set_name("x lower face"); LIST_surface[UP_X]->set_name("x upper face"); break; case WALL_3: for(i=0;i<6;i++){ LIST_surface[i]->disable(); } LIST_surface[DOWN_Z]->enable(); LIST_surface[UP_Z]->enable(); LIST_surface[UP_Y]->enable(); LIST_surface[DOWN_Z]->set_name("z lower face"); LIST_surface[UP_Z]->set_name("z upper face"); LIST_surface[UP_Y]->set_name("side faces"); LIST_surface[DOWN_Y]->set_name(""); LIST_surface[DOWN_X]->set_name(""); LIST_surface[UP_X]->set_name(""); break; case WALL_1: for(i=0;i<6;i++){ LIST_surface[i]->disable(); } LIST_surface[UP_Z]->enable(); LIST_surface[UP_Z]->set_name("All faces"); LIST_surface[DOWN_Z]->set_name(""); LIST_surface[DOWN_Y]->set_name(""); LIST_surface[UP_Y]->set_name(""); LIST_surface[DOWN_X]->set_name(""); LIST_surface[UP_X]->set_name(""); break; default: ASSERT(FFALSE); break; } OBJECT_CB(UPDATE_LIST); break; case BLOCKAGE_AS_INPUT2: case BLOCKAGE_AS_INPUT: if(var==BLOCKAGE_AS_INPUT2){ blockage_snapped=1-blockage_as_input; CHECKBOX_blockage->set_int_val(blockage_snapped); } blockage_as_input=1-blockage_snapped; if(blocklocation!=BLOCKlocation_cad){ if(blockage_as_input==1){ blocklocation=BLOCKlocation_exact; } else{ blocklocation=BLOCKlocation_grid; } } Update_Blockvals(NOT_SELECT_BLOCKS); break; default: ASSERT(FFALSE); break; } }
void update_ShowScene(void){ if(update_playmovie==1){ enable_disable_playmovie(); update_playmovie = 0; } update_render_start_button(); if(update_makemovie == 1)MakeMovie(); if(compute_fed == 1)DefineAllFEDs(); if(restart_time == 1){ restart_time = 0; reset_itimes0(); } if(loadfiles_at_startup==1&&update_load_Files == 1){ load_Files(); } if(update_startup_view == 1){ camera *ca; ca = get_camera(label_startup_view); if(ca != NULL){ ResetMenu(ca->view_id); } update_rotation_center = 0; update_rotation_center_ini = 0; update_startup_view = 0; } if(menusmooth == 1 && smoothing_blocks == 0 && updatesmoothblocks == 1){ smooth_blockages(); } if(update_tourlist == 1){ Update_Tourlist(); } if(update_gslice == 1){ update_gslice_parms(); } #define MESH_LIST 4 if(update_rotation_center == 1){ camera_current->rotation_index = glui_rotation_index; Motion_CB(MESH_LIST); update_rotation_center = 0; } if(update_rotation_center_ini == 1){ camera_current->rotation_index = glui_rotation_index_ini; Motion_CB(MESH_LIST); update_rotation_center_ini = 0; } if(camera_current->dirty == 1){ update_camera(camera_current); } if(updateclipvals == 1){ clip2cam(camera_current); update_clip_all(); updateclipvals = 0; } if(update_selectedtour_index == 1){ update_tourindex(); } if(trainer_mode == 1 && fontindex != LARGE_FONT)FontMenu(LARGE_FONT); if(updateindexcolors == 1){ UpdateIndexColors(); } if(force_isometric == 1){ force_isometric = 0; projection_type = 1; camera_current->projection_type = projection_type; ZoomMenu(UPDATE_PROJECTION); } if(convert_ini == 1){ writeini(SCRIPT_INI, ini_to); exit(0); } Update_Show(); if(global_times!=NULL&&updateUpdateFrameRateMenu==1)FrameRateMenu(frameratevalue); if(updatefaces==1)UpdateFaces(); if(updatefacelists==1)UpdateFacelists(); }