/* ============= Undo_AddBrush ============= */ void Undo_AddBrush(brush_t *pBrush) { if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) return; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; if (pBrush->owner && !(pBrush->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN)) { Undo_AddEntity(pBrush->owner); } //save the old undo ID for previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); }
/* ============= Undo_Clear Clears the undo buffer. ============= */ void Undo_Clear(void) { undo_t *undo, *nextundo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity; Undo_ClearRedo(); for (undo = g_undolist; undo; undo = nextundo) { nextundo = undo->next; for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush) { pNextBrush = pBrush->next; g_undoMemorySize -= Brush_MemorySize(pBrush); Brush_Free(pBrush); } for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity) { pNextEntity = pEntity->next; g_undoMemorySize -= Entity_MemorySize(pEntity); Entity_Free(pEntity); } g_undoMemorySize -= sizeof(undo_t); Mem_Free(undo); } g_undolist = NULL; g_lastundo = NULL; g_undoSize = 0; g_undoMemorySize = 0; g_undoId = 1; }
/* ============= Undo_FreeFirstUndo ============= */ void Undo_FreeFirstUndo(void) { undo_t *undo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity; //remove the oldest undo from the undo buffer undo = g_undolist; g_undolist = g_undolist->next; g_undolist->prev = NULL; // for (pBrush = undo->brushlist.next ; pBrush != NULL && pBrush != &undo->brushlist ; pBrush = pNextBrush) { pNextBrush = pBrush->next; g_undoMemorySize -= Brush_MemorySize(pBrush); Brush_Free(pBrush); } for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = pNextEntity) { pNextEntity = pEntity->next; g_undoMemorySize -= Entity_MemorySize(pEntity); Entity_Free(pEntity); } g_undoMemorySize -= sizeof(undo_t); Mem_Free(undo); g_undoSize--; }
/* ============= Undo_AddBrush ============= */ void Undo_AddBrush(brush_t *pBrush) { // spog - disable undo if undo levels = 0 if (g_PrefsDlg.m_nUndoLevels == 0) { #ifdef DBG_UNDO Sys_Printf("Undo_AddBrush: undo is disabled.\n"); #endif return; } if (!g_lastundo) { Sys_Printf("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Printf("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) return; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; //save the old undo ID for previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); }
int Entity_MemorySize( entity_t *e ) { brush_t *b; int size; size = sizeof( entity_t ) + e->epairs.Size(); for( b = e->brushes.onext; b != &e->brushes; b = b->onext ) { size += Brush_MemorySize( b ); } return( size ); }
/* ============= Undo_AddBrushList TTimo: some brushes are just there for UI, and the information is somewhere else for patches it's in the patchMesh_t structure, so when we clone the brush we get that information (brush_t::pPatch) but: models are stored in pBrush->owner->md3Class, and owner epairs and origin parameters are important so, we detect models and push the entity in the undo session (as well as it's BBox brush) same for other items like weapons and ammo etc. ============= */ void Undo_AddBrushList(brush_t *brushlist) { // spog - disable undo if undo levels = 0 if (g_PrefsDlg.m_nUndoLevels == 0) { #ifdef DBG_UNDO Sys_Printf("Undo_AddBrushList: undo is disabled.\n"); #endif return; } brush_t *pBrush; if (!g_lastundo) { Sys_Printf("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Printf("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //copy the brushes to the undo for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) { //if the brush is already in the undo //++timo FIXME: when does this happen? if (Undo_BrushInUndo(g_lastundo, pBrush)) continue; // do we need to store this brush's entity in the undo? // if it's a fixed size entity, the brush that reprents it is not really relevant, it's used for selecting and moving around // what we want to store for undo is the owner entity, epairs and origin/angle stuff //++timo FIXME: if the entity is not fixed size I don't know, so I don't do it yet if (pBrush->owner->eclass->fixedsize == 1) Undo_AddEntity( pBrush->owner ); // clone the brush brush_t* pClone = Brush_FullClone(pBrush); // save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; // save the old undo ID from previous undos pClone->undoId = pBrush->undoId; Brush_AddToList (pClone, &g_lastundo->brushlist); // track memory size used by undo g_undoMemorySize += Brush_MemorySize(pClone); } }
/* ============= Undo_AddBrushList ============= */ void Undo_AddBrushList(brush_t *brushlist) { brush_t *pBrush; if (!g_lastundo) { Sys_Status("Undo_AddBrushList: no last undo.\n"); return; } if (g_lastundo->entitylist.next != &g_lastundo->entitylist) { Sys_Status("Undo_AddBrushList: WARNING adding brushes after entity.\n"); } //copy the brushes to the undo for (pBrush = brushlist->next ; pBrush != NULL && pBrush != brushlist; pBrush=pBrush->next) { //if the brush is already in the undo if (Undo_BrushInUndo(g_lastundo, pBrush)) continue; //clone the brush brush_t* pClone = Brush_FullClone(pBrush); //save the ID of the owner entity pClone->ownerId = pBrush->owner->entityId; //save the old undo ID from previous undos pClone->undoId = pBrush->undoId; if ( pBrush->owner && pBrush->owner != world_entity ) { Undo_AddEntity(pBrush->owner); } Brush_AddToList (pClone, &g_lastundo->brushlist); // g_undoMemorySize += Brush_MemorySize(pClone); } }
/* ============= Undo_Redo ============= */ void Undo_Redo(void) { undo_t *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pRedoEntity; if (!g_lastredo) { Sys_Status("Nothing left to redo.\n"); return; } if (g_lastundo) { if (!g_lastundo->done) { Sys_Status("WARNING: last undo not finished.\n"); } } // get the last redo redo = g_lastredo; if (g_lastredo->prev) g_lastredo->prev->next = NULL; else g_redolist = NULL; g_lastredo = g_lastredo->prev; // Undo_GeneralStart(redo->operation); // remove current selection Select_Deselect(); // move "created" brushes back to the last undo for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pNextBrush) { pNextBrush = pBrush->next; if (pBrush->redoId == redo->id) { //move the brush to the undo Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &g_lastundo->brushlist); g_undoMemorySize += Brush_MemorySize(pBrush); pBrush->ownerId = pBrush->owner->entityId; Entity_UnlinkBrush(pBrush); } } // move "created" entities back to the last undo for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) { pNextEntity = pEntity->next; if (pEntity->redoId == redo->id) { // check if this entity is in the redo for (pRedoEntity = redo->entitylist.next; pRedoEntity != NULL && pRedoEntity != &redo->entitylist; pRedoEntity = pRedoEntity->next) { // move brushes to the redo entity if (pRedoEntity->entityId == pEntity->entityId) { pRedoEntity->brushes.next = pEntity->brushes.next; pRedoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &g_lastundo->entitylist); g_undoMemorySize += Entity_MemorySize(pEntity); } } // add the undo entities back into the entity list for (pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = redo->entitylist.next) { //if this is the world entity if (pEntity->entityId == world_entity->entityId) { //free the epairs of the world entity Entity_FreeEpairs(world_entity); //set back the original epairs world_entity->epairs = pEntity->epairs; //free the world_entity clone that stored the epairs Entity_Free(pEntity); } else { Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &entities); } } // add the redo brushes back into the selected brushes for (pBrush = redo->brushlist.next; pBrush != NULL && pBrush != &redo->brushlist; pBrush = redo->brushlist.next) { Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &active_brushes); for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->entityId == pBrush->ownerId) { Entity_LinkBrush(pEntity, pBrush); break; } } //if the brush is not linked then it should be linked into the world entity if (pEntity == NULL || pEntity == &entities) { Entity_LinkBrush(world_entity, pBrush); } //build the brush //Brush_Build(pBrush); Select_Brush(pBrush); } // Undo_End(); // common->Printf("%s redone.\n", redo->operation); // g_redoId--; // free the undo Mem_Free(redo); // g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }
/* ============= Undo_Undo ============= */ void Undo_Undo(void) { undo_t *undo, *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pUndoEntity; if (!g_lastundo) { Sys_Status("Nothing left to undo.\n"); return; } if (!g_lastundo->done) { Sys_Status("Undo_Undo: WARNING: last undo not yet finished!\n"); } // get the last undo undo = g_lastundo; if (g_lastundo->prev) g_lastundo->prev->next = NULL; else g_undolist = NULL; g_lastundo = g_lastundo->prev; //allocate a new redo redo = (undo_t *) Mem_ClearedAlloc(sizeof(undo_t), TAG_TOOLS); if (!redo) return; memset(redo, 0, sizeof(undo_t)); redo->brushlist.next = &redo->brushlist; redo->brushlist.prev = &redo->brushlist; redo->entitylist.next = &redo->entitylist; redo->entitylist.prev = &redo->entitylist; if (g_lastredo) g_lastredo->next = redo; else g_redolist = redo; redo->prev = g_lastredo; redo->next = NULL; g_lastredo = redo; redo->time = Sys_DoubleTime(); redo->id = g_redoId++; redo->done = true; redo->operation = undo->operation; //reset the redo IDs of all brushes using the new ID for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } //reset the redo IDs of all entities using thew new ID for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->redoId == redo->id) { pEntity->redoId = 0; } } // remove current selection Select_Deselect(); // move "created" brushes to the redo for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush=pNextBrush) { pNextBrush = pBrush->next; if (pBrush->undoId == undo->id) { //Brush_Free(pBrush); //move the brush to the redo Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &redo->brushlist); //make sure the ID of the owner is stored pBrush->ownerId = pBrush->owner->entityId; //unlink the brush from the owner entity Entity_UnlinkBrush(pBrush); } } // move "created" entities to the redo for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) { pNextEntity = pEntity->next; if (pEntity->undoId == undo->id) { // check if this entity is in the undo for (pUndoEntity = undo->entitylist.next; pUndoEntity != NULL && pUndoEntity != &undo->entitylist; pUndoEntity = pUndoEntity->next) { // move brushes to the undo entity if (pUndoEntity->entityId == pEntity->entityId) { pUndoEntity->brushes.next = pEntity->brushes.next; pUndoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &redo->entitylist); } } // add the undo entities back into the entity list for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = undo->entitylist.next) { g_undoMemorySize -= Entity_MemorySize(pEntity); //if this is the world entity if (pEntity->entityId == world_entity->entityId) { //free the epairs of the world entity Entity_FreeEpairs(world_entity); //set back the original epairs world_entity->epairs = pEntity->epairs; //free the world_entity clone that stored the epairs Entity_Free(pEntity); } else { Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &entities); pEntity->redoId = redo->id; } } // add the undo brushes back into the selected brushes for (pBrush = undo->brushlist.next; pBrush != NULL && pBrush != &undo->brushlist; pBrush = undo->brushlist.next) { g_undoMemorySize -= Brush_MemorySize(pBrush); Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &active_brushes); for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->entityId == pBrush->ownerId) { Entity_LinkBrush(pEntity, pBrush); break; } } //if the brush is not linked then it should be linked into the world entity if (pEntity == NULL || pEntity == &entities) { Entity_LinkBrush(world_entity, pBrush); } //build the brush //Brush_Build(pBrush); Select_Brush(pBrush); pBrush->redoId = redo->id; } // common->Printf("%s undone.\n", undo->operation); // free the undo g_undoMemorySize -= sizeof(undo_t); Mem_Free(undo); g_undoSize--; g_undoId--; if (g_undoId <= 0) g_undoId = 2 * g_undoMaxSize; // Sys_BeginWait(); brush_t *b, *next; for (b = active_brushes.next ; b != NULL && b != &active_brushes ; b=next) { next = b->next; Brush_Build( b, true, false, false ); } for (b = selected_brushes.next ; b != NULL && b != &selected_brushes ; b=next) { next = b->next; Brush_Build( b, true, false, false ); } Sys_EndWait(); g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }
/* ============= Undo_Undo ============= */ void Undo_Undo(boolean bSilent) { // spog - disable undo if undo levels = 0 if (g_PrefsDlg.m_nUndoLevels == 0) { Sys_Printf("Undo_Undo: undo is disabled.\n"); return; } undo_t *undo, *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pUndoEntity; if (!g_lastundo) { Sys_Printf("Nothing left to undo.\n"); return; } if (!g_lastundo->done) { Sys_Printf("Undo_Undo: WARNING: last undo not yet finished!\n"); } // get the last undo undo = g_lastundo; if (g_lastundo->prev) g_lastundo->prev->next = NULL; else g_undolist = NULL; g_lastundo = g_lastundo->prev; //allocate a new redo redo = (undo_t *) malloc(sizeof(undo_t)); if (!redo) return; memset(redo, 0, sizeof(undo_t)); redo->brushlist.next = &redo->brushlist; redo->brushlist.prev = &redo->brushlist; redo->entitylist.next = &redo->entitylist; redo->entitylist.prev = &redo->entitylist; if (g_lastredo) g_lastredo->next = redo; else g_redolist = redo; redo->prev = g_lastredo; redo->next = NULL; g_lastredo = redo; redo->time = Sys_DoubleTime(); redo->id = g_redoId++; redo->done = true; redo->operation = undo->operation; //reset the redo IDs of all brushes using the new ID for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } for (pBrush = selected_brushes.next; pBrush != NULL && pBrush != &selected_brushes; pBrush = pBrush->next) { if (pBrush->redoId == redo->id) { pBrush->redoId = 0; } } //reset the redo IDs of all entities using thew new ID for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) { if (pEntity->redoId == redo->id) { pEntity->redoId = 0; } } // deselect current sutff Select_Deselect(); // move "created" brushes to the redo for (pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush=pNextBrush) { pNextBrush = pBrush->next; if (pBrush->undoId == undo->id) { //Brush_Free(pBrush); //move the brush to the redo Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &redo->brushlist); //make sure the ID of the owner is stored pBrush->ownerId = pBrush->owner->entityId; //unlink the brush from the owner entity Entity_UnlinkBrush(pBrush); } } // move "created" entities to the redo for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity) { pNextEntity = pEntity->next; if (pEntity->undoId == undo->id) { // check if this entity is in the undo for (pUndoEntity = undo->entitylist.next; pUndoEntity != NULL && pUndoEntity != &undo->entitylist; pUndoEntity = pUndoEntity->next) { // move brushes to the undo entity if (pUndoEntity->entityId == pEntity->entityId) { pUndoEntity->brushes.next = pEntity->brushes.next; pUndoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &redo->entitylist); } } // add the undo entities back into the entity list for (pEntity = undo->entitylist.next; pEntity != NULL && pEntity != &undo->entitylist; pEntity = undo->entitylist.next) { g_undoMemorySize -= Entity_MemorySize(pEntity); //if this is the world entity if (pEntity->entityId == world_entity->entityId) { epair_t* tmp = world_entity->epairs; world_entity->epairs = pEntity->epairs; pEntity->epairs = tmp; Entity_Free(pEntity); } else { Entity_RemoveFromList(pEntity); Entity_AddToList(pEntity, &entities); pEntity->redoId = redo->id; } } // add the undo brushes back into the selected brushes for (pBrush = undo->brushlist.next; pBrush != NULL && pBrush != &undo->brushlist; pBrush = undo->brushlist.next) { //Sys_Printf("Owner ID: %i\n",pBrush->ownerId); g_undoMemorySize -= Brush_MemorySize(pBrush); Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &active_brushes); for (pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next) // fixes broken undo on entities { //Sys_Printf("Entity ID: %i\n",pEntity->entityId); if (pEntity->entityId == pBrush->ownerId) { Entity_LinkBrush(pEntity, pBrush); break; } } //if the brush is not linked then it should be linked into the world entity //++timo FIXME: maybe not, maybe we've lost this entity's owner! if (pEntity == NULL || pEntity == &entities) { Entity_LinkBrush(world_entity, pBrush); } //build the brush //Brush_Build(pBrush); Select_Brush(pBrush); pBrush->redoId = redo->id; } if (!bSilent) Sys_Printf("%s undone.\n", undo->operation); // free the undo g_undoMemorySize -= sizeof(undo_t); free(undo); g_undoSize--; g_undoId--; if (g_undoId <= 0) g_undoId = 2 * g_undoMaxSize; // g_bScreenUpdates = true; UpdateSurfaceDialog(); Sys_UpdateWindows(W_ALL); }
/* ============= Undo_Redo ============= */ void Undo_Redo( void ){ // spog - disable undo if undo levels = 0 if ( g_PrefsDlg.m_nUndoLevels == 0 ) { Sys_Printf( "Undo_Redo: undo is disabled.\n" ); return; } undo_t *redo; brush_t *pBrush, *pNextBrush; entity_t *pEntity, *pNextEntity, *pRedoEntity; if ( !g_lastredo ) { Sys_Printf( "Nothing left to redo.\n" ); return; } if ( g_lastundo ) { if ( !g_lastundo->done ) { Sys_Printf( "WARNING: last undo not finished.\n" ); } } // get the last redo redo = g_lastredo; if ( g_lastredo->prev ) { g_lastredo->prev->next = NULL; } else{g_redolist = NULL; } g_lastredo = g_lastredo->prev; // Undo_GeneralStart( redo->operation ); // remove current selection Select_Deselect(); // move "created" brushes back to the last undo for ( pBrush = active_brushes.next; pBrush != NULL && pBrush != &active_brushes; pBrush = pNextBrush ) { pNextBrush = pBrush->next; if ( pBrush->redoId == redo->id ) { //move the brush to the undo Brush_RemoveFromList( pBrush ); Brush_AddToList( pBrush, &g_lastundo->brushlist ); g_undoMemorySize += Brush_MemorySize( pBrush ); pBrush->ownerId = pBrush->owner->entityId; Entity_UnlinkBrush( pBrush ); } } // move "created" entities back to the last undo for ( pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pNextEntity ) { pNextEntity = pEntity->next; if ( pEntity->redoId == redo->id ) { // check if this entity is in the redo for ( pRedoEntity = redo->entitylist.next; pRedoEntity != NULL && pRedoEntity != &redo->entitylist; pRedoEntity = pRedoEntity->next ) { // move brushes to the redo entity if ( pRedoEntity->entityId == pEntity->entityId ) { pRedoEntity->brushes.next = pEntity->brushes.next; pRedoEntity->brushes.prev = pEntity->brushes.prev; pEntity->brushes.next = &pEntity->brushes; pEntity->brushes.prev = &pEntity->brushes; } } // //Entity_Free(pEntity); //move the entity to the redo Entity_RemoveFromList( pEntity ); Entity_AddToList( pEntity, &g_lastundo->entitylist ); g_undoMemorySize += Entity_MemorySize( pEntity ); } } // add the undo entities back into the entity list for ( pEntity = redo->entitylist.next; pEntity != NULL && pEntity != &redo->entitylist; pEntity = redo->entitylist.next ) { //if this is the world entity if ( pEntity->entityId == world_entity->entityId ) { epair_t* tmp = world_entity->epairs; world_entity->epairs = pEntity->epairs; pEntity->epairs = tmp; Entity_Free( pEntity ); } else { Entity_RemoveFromList( pEntity ); Entity_AddToList( pEntity, &entities ); } } // add the redo brushes back into the selected brushes for ( pBrush = redo->brushlist.next; pBrush != NULL && pBrush != &redo->brushlist; pBrush = redo->brushlist.next ) { Brush_RemoveFromList( pBrush ); Brush_AddToList( pBrush, &active_brushes ); for ( pEntity = entities.next; pEntity != NULL && pEntity != &entities; pEntity = pEntity->next ) // fixes broken undo on entities { if ( pEntity->entityId == pBrush->ownerId ) { Entity_LinkBrush( pEntity, pBrush ); break; } } //if the brush is not linked then it should be linked into the world entity if ( pEntity == NULL || pEntity == &entities ) { Entity_LinkBrush( world_entity, pBrush ); } //build the brush //Brush_Build(pBrush); Select_Brush( pBrush ); } // Undo_End(); // Sys_Printf( "%s redone.\n", redo->operation ); // g_redoId--; // free the undo free( redo ); // g_bScreenUpdates = true; UpdateSurfaceDialog(); Sys_UpdateWindows( W_ALL ); }