/* ============ Select_Ray If the origin is inside a brush, that brush will be ignored. ============ */ void Select_Ray (vec3_t origin, vec3_t dir, int flags) { trace_t t; t = Test_Ray (origin, dir, flags); if (!t.brush) return; if (flags == SF_SINGLEFACE) { selected_face = t.face; selected_face_brush = t.brush; Sys_UpdateWindows (W_ALL); g_qeglobals.d_select_mode = sel_brush; Texture_SetTexture (&t.face->texdef); UpdateSurfaceDialog(); return; } // move the brush to the other list g_qeglobals.d_select_mode = sel_brush; if (t.selected) { Brush_RemoveFromList (t.brush); Brush_AddToList (t.brush, &active_brushes); } else { Select_Brush (t.brush, !(GetKeyState(VK_MENU) & 0x8000)); } Sys_UpdateWindows (W_ALL); }
void Terrain_BrushToMesh( void ) { brush_t *b; terrainMesh_t *p; if ( !QE_SingleBrush() ) { return; } b = selected_brushes.next; if ( g_qeglobals.d_terrainWidth < 1 ) { g_qeglobals.d_terrainWidth = 1; } if ( g_qeglobals.d_terrainHeight < 1 ) { g_qeglobals.d_terrainHeight = 1; } p = MakeNewTerrain( g_qeglobals.d_terrainWidth + 1, g_qeglobals.d_terrainHeight + 1, b->brush_faces->d_texture ); p->scale_x = ( b->maxs[ 0 ] - b->mins[ 0 ] ) / float( p->width - 1 ); p->scale_y = ( b->maxs[ 1 ] - b->mins[ 1 ] ) / float( p->height - 1 ); VectorCopy( b->mins, p->origin ); b = AddBrushForTerrain( p ); Select_Delete(); Select_Brush( b ); }
/* ============ Select_Ray If the origin is inside a brush, that brush will be ignored. ============ */ void Select_Ray( vec3_t origin, vec3_t dir, int flags ) { trace_t t; t = Test_Ray( origin, dir, flags ); if ( !t.brush ) return; if ( flags == SF_SINGLEFACE ) { int nCount = g_SelectedFaces.GetSize(); bool bOk = true; for ( int i = 0; i < nCount; i++ ) { if ( t.face == reinterpret_cast<face_s*>( g_SelectedFaces.GetAt( i ) ) ) { bOk = false; // need to move remove i'th entry g_SelectedFaces.RemoveAt( i, 1 ); g_SelectedFaceBrushes.RemoveAt( i, 1 ); } } if ( bOk ) { g_SelectedFaces.Add( t.face ); g_SelectedFaceBrushes.Add( t.brush ); } //selected_face = t.face; //selected_face_brush = t.brush; Sys_UpdateWindows( W_ALL ); clearSelection(); // Texture_SetTexture requires a brushprimit_texdef fitted to the default width=2 height=2 texture brushprimit_texdef_s brushprimit_texdef; ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &brushprimit_texdef, NULL ); Texture_SetTexture( &t.face->texdef, &brushprimit_texdef, false, false ); UpdateSurfaceDialog(); return; } // move the brush to the other list clearSelection(); if ( t.selected ) { Brush_RemoveFromList( t.brush ); Brush_AddToList( t.brush, &active_brushes ); UpdatePatchInspector(); } else { Select_Brush( t.brush, !( GetKeyState( VK_MENU ) & 0x8000 ) ); } Sys_UpdateWindows( W_ALL ); }
void WINAPI QERApp_SelectBrush (LPVOID pv) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); brush_t *pBrush = g_pParentWnd->GetPlugInMgr().FindBrushHandle(pv); if (pBrush != NULL) { Select_Brush(pBrush, false); Sys_UpdateWindows(W_ALL); } }
void CEntityListDlg::OnSelect() { int index = listEntities.GetCurSel(); if( index != LB_ERR ) { entity_t *ent = reinterpret_cast<entity_t *>( listEntities.GetItemDataPtr( index ) ); if( ent ) { Select_Deselect(); Select_Brush( ent->brushes.onext ); } } Sys_UpdateWindows( W_ALL ); }
// creates a dummy brush in the active brushes list // FIXME : is this one really USED ? void WINAPI QERApp_CreateBrush(vec3_t vMin, vec3_t vMax) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); brush_t* pBrush = Brush_Create(vMin, vMax, &g_qeglobals.d_texturewin.texdef); Entity_LinkBrush (world_entity, pBrush); Brush_Build(pBrush); Brush_AddToList (pBrush, &active_brushes); Select_Brush(pBrush); Sys_UpdateWindows(W_ALL); }
/* =============== ConnectEntities Sets target / targetname on the two entities selected from the first selected to the secon =============== */ void ConnectEntities( void ){ entity_t *e1, *e2; const char *target; char *newtarg = NULL; if ( g_qeglobals.d_select_count != 2 ) { Sys_Status( "Must have two brushes selected", 0 ); Sys_Beep(); return; } e1 = g_qeglobals.d_select_order[0]->owner; e2 = g_qeglobals.d_select_order[1]->owner; if ( e1 == world_entity || e2 == world_entity ) { Sys_Status( "Can't connect to the world", 0 ); Sys_Beep(); return; } if ( e1 == e2 ) { Sys_Status( "Brushes are from same entity", 0 ); Sys_Beep(); return; } target = ValueForKey( e1, "target" ); if ( target && target[0] ) { newtarg = g_strdup( target ); } else { target = ValueForKey( e2, "targetname" ); if ( target && target[0] ) { newtarg = g_strdup( target ); } else{ Entity_Connect( e1, e2 ); } } if ( newtarg != NULL ) { SetKeyValue( e1, "target", newtarg ); SetKeyValue( e2, "targetname", newtarg ); g_free( newtarg ); } Sys_UpdateWindows( W_XY | W_CAMERA ); Select_Deselect(); Select_Brush( g_qeglobals.d_select_order[1] ); }
void Select_Reselect() { brush_s* b; CPtrArray holdArray; for ( b = selected_brushes.next ; b && b != &selected_brushes ; b = b->next ) { holdArray.Add( reinterpret_cast<void*>( b ) ); } int n = holdArray.GetSize(); while ( n-- > 0 ) { b = reinterpret_cast<brush_s*>( holdArray.GetAt( n ) ); Select_Brush( b ); } Sys_UpdateWindows( W_ALL ); }
void CPlugInManager::CommitBrushHandleToMap(void * vp) { g_bScreenUpdates = false; for (int i = 0; i < m_BrushHandles.GetSize(); i++) { brush_t *pb = reinterpret_cast<brush_t*>(m_BrushHandles.GetAt(i)); if (pb == reinterpret_cast<brush_t*>(vp)) { m_BrushHandles.RemoveAt(i); Entity_LinkBrush (world_entity, pb); Brush_Build(pb); Brush_AddToList (pb, &active_brushes); Select_Brush(pb); } } g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); }
void CPlugInManager::CommitPatchHandleToMap(int index, patchMesh_t *pMesh, char *texName) { if (PatchesMode==EAllocatedPatches) { patchMesh_t *pPatch = reinterpret_cast<patchMesh_t *>( m_PluginPatches.GetAt(index) ); memcpy( pPatch, pMesh, sizeof( patchMesh_t ) ); // patch texturing, if none given use current texture if (texName) pPatch->d_texture = Texture_ForName(texName); if ( !pPatch->d_texture ) { pPatch->d_texture = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); // checking .. just in case if (!pPatch->d_texture) { #ifdef _DEBUG Sys_Printf("WARNING: failed to set patch to current texture in CPlugInManager::CommitPatchHandleToMap\n"); #endif pPatch->d_texture = notexture; } } g_bScreenUpdates = false; // the bLinkToWorld flag in AddBrushForPatch takes care of Brush_AddToList Entity_linkBrush and Brush_Build brush_t *pb = AddBrushForPatch( pPatch, true ); Select_Brush( pb ); g_bScreenUpdates = true; Sys_UpdateWindows(W_ALL); } else { brush_t *pBrush = reinterpret_cast<brush_t *>( m_PatchesHandles.GetAt(index) ); patchMesh_t *pPatch = pBrush->pPatch; pPatch->width = pMesh->width; pPatch->height = pMesh->height; pPatch->contents = pMesh->contents; pPatch->flags = pMesh->flags; pPatch->value = pMesh->value; pPatch->type = pMesh->type; memcpy( pPatch->ctrl, pMesh->ctrl, sizeof(drawVert_t)*MAX_PATCH_HEIGHT*MAX_PATCH_WIDTH ); pPatch->bDirty = true; } }
/* If the origin is inside a brush, that brush will be ignored. */ void Select_Ray (vec3_t origin, vec3_t dir, int flags) { trace_t t; t = Test_Ray (origin, dir, flags); if(!t.brush) return; if (flags == SF_SINGLEFACE) { // [12/8/2012] Don't let them select entity faces ~hogsy // [22/8/2012] Simplified ~hogsy if(t.brush->owner->eclass->fixedsize) return; selected_face = t.face; selected_face_brush = t.brush; Sys_UpdateWindows (W_ALL); g_qeglobals.d_select_mode = sel_brush; return; } // move the brush to the other list g_qeglobals.d_select_mode = sel_brush; if (t.selected) { Brush_RemoveFromList (t.brush); Brush_AddToList (t.brush, &active_brushes); } else Select_Brush (t.brush); 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 ); }
/* =============== ConnectEntities Sets target / targetname on the two entities selected from the first selected to the secon =============== */ void ConnectEntities (void) { entity_t *e1, *e2, *e; char *target, *tn; int maxtarg, targetnum; char newtarg[32]; if (g_qeglobals.d_select_count != 2) { Sys_Status ("Must have two brushes selected.", 0); Sys_Beep (); return; } e1 = g_qeglobals.d_select_order[0]->owner; e2 = g_qeglobals.d_select_order[1]->owner; if (e1 == world_entity || e2 == world_entity) { Sys_Status ("Can't connect to the world.", 0); Sys_Beep (); return; } if (e1 == e2) { Sys_Status ("Brushes are from same entity.", 0); Sys_Beep (); return; } target = ValueForKey (e1, "target"); if (target && target[0]) strcpy (newtarg, target); else { target = ValueForKey (e2, "targetname"); if (target && target[0]) strcpy (newtarg, target); else { // make a unique target value maxtarg = 0; for (e=entities.next ; e != &entities ; e=e->next) { tn = ValueForKey (e, "targetname"); if (tn && tn[0]) { targetnum = atoi(tn+1); if (targetnum > maxtarg) maxtarg = targetnum; } } sprintf (newtarg, "t%i", maxtarg+1); } } SetKeyValue (e1, "target", newtarg); SetKeyValue (e2, "targetname", newtarg); Sys_UpdateWindows (W_XY | W_CAMERA); Select_Deselect(); Select_Brush (g_qeglobals.d_select_order[1]); }
// return is simply a count of how many texture replacements took place, only used for friendly-stats on completion... // // the arg list for this is getting pretty gay now, the reason being that the various update-windows routines that // radiant has don't work like windows ones, where paint messages are just issued then it returns instantly // (and eliminates dup paint calls), radiant actually goes off and performs them, so I need to stop it doing that // when calling this in the middle of a loop... // int FindReplaceTextures(const char* pFind, const char* pReplace, bool bSelected, bool bForce, bool bReScale, bool bSelectOnlyNoReplace, bool bInhibitCameraUpdate /*= false*/, bool bCalledDuringLoopAndNotFirstTime /*= false*/ // sigh, but saves an update-all-windows call ) { int iReplacedCount = 0; if (bSelectOnlyNoReplace) { bSelected = false; bForce = false; } const brush_t* const pList = (bSelected) ? &selected_brushes : &active_brushes; if (!bSelected) { if (!bCalledDuringLoopAndNotFirstTime) Select_Deselect(); } const qtexture_t * const pReplaceTex = Texture_ForName(pReplace); // count them first, so I can show progress.. // int iBrushCount = 0; for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next) { iBrushCount++; } Sys_Printf("\n"); brush_t* pNextBrush = pList->next->prev; // doesn't matter what value assigned here really. Note sneaky workaround here because can't point at non-const item, so use next->prev for (pBrush = pList->next ; pBrush != pList; pBrush = pNextBrush) { pNextBrush = pBrush->next; // just so they don't think it's locked up... // if ( !((iBrushCount--) & 15)) { Sys_Printf("."); } OutputDebugString(va("iBrushCount = %d\n",iBrushCount)); if (pBrush->patchBrush) { if (bSelectOnlyNoReplace) { if (!stricmp(pFind,Patch_FromBrush_GetTextureName(pBrush))) { g_bScreenUpdates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Select_Brush(pBrush, false); g_bScreenUpdates = true; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! continue; } } else { iReplacedCount += (Patch_FindReplaceTexture(pBrush, pFind, pReplace, bForce))?1:0; } } for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next) { if(bForce || strcmpi(pFace->texdef.name, pFind) == 0) { iReplacedCount++; if (bSelectOnlyNoReplace) { g_bScreenUpdates = false; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! Select_Brush(pBrush, false); g_bScreenUpdates = true; // !!!!!!!!!!!!!!!!!!!!!!!!!!!! break; } else { if (bReScale) { if (pFace->d_texture == pReplaceTex) {//not changing textures, so reset the scale instead const float fXAspect = fTEXTURE_SCALE / (float) pFace->texdef.scale[0]; const float fYAspect = fTEXTURE_SCALE / (float) pFace->texdef.scale[1]; pFace->texdef.scale[0] = fTEXTURE_SCALE; pFace->texdef.scale[1] = fTEXTURE_SCALE; pFace->texdef.shift[0] /= fXAspect; pFace->texdef.shift[1] /= fYAspect; } else { const float fXAspect = (float)(pFace->d_texture->width) / (float) pReplaceTex->width; const float fYAspect = (float)(pFace->d_texture->height) / (float) pReplaceTex->height; pFace->texdef.scale[0] *= fXAspect; pFace->texdef.scale[1] *= fYAspect; pFace->texdef.shift[0] /= fXAspect; pFace->texdef.shift[1] /= fYAspect; } } strcpy(pFace->texdef.name, pReplace); pFace->d_texture = (qtexture_t *)pReplaceTex; } } } if (!bSelectOnlyNoReplace) { Brush_Build(pBrush); } } Sys_Printf("\n"); if (!bInhibitCameraUpdate) { Sys_UpdateWindows (W_CAMERA); } return iReplacedCount; }
/* ======================================================================================================================= ConnectEntities Sets target / name on the two entities selected from the first selected to the secon ======================================================================================================================= */ void ConnectEntities(void) { entity_t *e1; const char *target; idStr strTarget; int i, t; if (g_qeglobals.d_select_count < 2) { Sys_Status("Must have at least two brushes selected.", 0); Sys_Beep(); return; } e1 = g_qeglobals.d_select_order[0]->owner; for (i = 0; i < g_qeglobals.d_select_count; i++) { if (g_qeglobals.d_select_order[i]->owner == world_entity) { Sys_Status("Can't connect to the world.", 0); Sys_Beep(); return; } } for (i = 1; i < g_qeglobals.d_select_count; i++) { if (e1 == g_qeglobals.d_select_order[i]->owner) { Sys_Status("Brushes are from same entity.", 0); Sys_Beep(); return; } } target = ValueForKey(e1, "target"); if ( target && *target) { for (t = 1; t < 2048; t++) { target = ValueForKey(e1, va("target%i", t)); if (target && *target) { continue; } else { break; } } } else { t = 0; } for (i = 1; i < g_qeglobals.d_select_count; i++) { target = ValueForKey(g_qeglobals.d_select_order[i]->owner, "name"); if (target && *target) { strTarget = target; } else { UniqueTargetName(strTarget); } if (t == 0) { SetKeyValue(e1, "target", strTarget); } else { SetKeyValue(e1, va("target%i", t), strTarget); } t++; } Sys_UpdateWindows(W_XY | W_CAMERA); Select_Deselect(); Select_Brush(g_qeglobals.d_select_order[1]); }
// // ======================================================================================================================= // CreateEntity Creates a new entity based on the currently selected brush and entity type. // ======================================================================================================================= // void CEntityDlg::CreateEntity() { entity_t *petNew; bool forceFixed = false; // check to make sure we have a brush CXYWnd *pWnd = g_pParentWnd->ActiveXY(); if (pWnd) { CRect rctZ; pWnd->GetClientRect(rctZ); brush_t *pBrush; if (selected_brushes.next == &selected_brushes) { pBrush = CreateEntityBrush(g_nSmartX, rctZ.Height() - 1 - g_nSmartY, pWnd); forceFixed = true; } } else { if (selected_brushes.next == &selected_brushes) { MessageBox("You must have a selected brush to create an entity", "info", 0); return; } } int index = comboClass.GetCurSel(); if (index == LB_ERR) { MessageBox("You must have a selected class to create an entity", "info", 0); return; } CString str; comboClass.GetLBText(index, str); if (!stricmp(str, "worldspawn")) { MessageBox("Can't create an entity with worldspawn.", "info", 0); return; } eclass_t *pecNew = Eclass_ForName (str, false); // create it if ((GetAsyncKeyState(VK_CONTROL) & 0x8000)) { // MAJOR hack for xian extern void Brush_CopyList(brush_t *pFrom, brush_t *pTo); brush_t temp_brushes; temp_brushes.next = &temp_brushes; Brush_CopyList(&selected_brushes, &temp_brushes); Select_Deselect(); brush_t *pBrush = temp_brushes.next; while (pBrush != NULL && pBrush != &temp_brushes) { brush_t *pNext = pBrush->next; Brush_RemoveFromList(pBrush); Brush_AddToList(pBrush, &selected_brushes); pBrush = pNext; petNew = Entity_Create(pecNew, forceFixed); Select_Deselect(); } } else if ((GetAsyncKeyState(VK_SHIFT) & 0x8000)) { Select_Ungroup(); petNew = Entity_Create(pecNew, forceFixed); } else { petNew = Entity_Create(pecNew, forceFixed); } if (petNew == NULL) { MessageBox("Failed to create entity.", "info", 0); return; } if (selected_brushes.next == &selected_brushes) { editEntity = world_entity; } else { editEntity = selected_brushes.next->owner; } SetKeyValPairs(); Select_Deselect(); Select_Brush(editEntity->brushes.onext); Sys_UpdateWindows(W_ALL); }
void CreateEntity(void) { eclass_t *pecNew; entity_t *petNew; int i; HWND hwnd; char sz[1024]; // check to make sure we have a brush if (selected_brushes.next == &selected_brushes) { MessageBox(g_qeglobals.d_hwndMain, "You must have a selected brush to create an entity" , "info", 0); return; } // find out what type of entity we are trying to create hwnd = hwndEnt[EntList]; i = SendMessage(hwndEnt[EntList], LB_GETCURSEL, 0, 0); if (i < 0) { MessageBox(g_qeglobals.d_hwndMain, "You must have a selected class to create an entity" , "info", 0); return; } SendMessage(hwnd, LB_GETTEXT, i, (LPARAM)sz); if (!stricmp(sz, "worldspawn")) { MessageBox(g_qeglobals.d_hwndMain, "Can't create an entity with worldspawn.", "info", 0); return; } pecNew = Eclass_ForName(sz, false); // create it petNew = Entity_Create(pecNew); if (petNew == NULL) { MessageBox(g_qeglobals.d_hwndMain, "Failed to create entity.", "info", 0); return; } if (selected_brushes.next == &selected_brushes) edit_entity = world_entity; else edit_entity = selected_brushes.next->owner; SetKeyValuePairs(); Select_Deselect (); Select_Brush (edit_entity->brushes.onext); Sys_UpdateWindows(W_ALL); }
// // ======================================================================================================================= // Map_ImportFile Timo 09/01/99:: called by CXYWnd::Paste & Map_ImportFile if Map_ImportFile ( prefab ), the buffer // may contain brushes in old format ( conversion needed ) // ======================================================================================================================= // void Map_ImportBuffer(char *buf, bool renameEntities) { entity_t *ent; brush_t *b = NULL; CPtrArray ptrs; Select_Deselect(); Undo_Start("import buffer"); g_qeglobals.d_parsed_brushes = 0; if (buf) { CMapStringToString mapStr; StartTokenParsing(buf); g_qeglobals.d_num_entities = 0; // // Timo will be used in Entity_Parse to detect if a conversion between brush // formats is needed // g_qeglobals.bNeedConvert = false; g_qeglobals.bOldBrushes = false; g_qeglobals.bPrimitBrushes = false; g_qeglobals.mapVersion = 1.0; if (GetToken(true)) { if (stricmp(token, "Version") == 0) { GetToken(false); g_qeglobals.mapVersion = atof(token); common->Printf("Map version: %1.2f\n", g_qeglobals.mapVersion); } else { UngetToken(); } } idDict RemappedNames; // since I can't use "map <string, string>"... sigh. So much for STL... while (1) { // // use the selected brushes list as it's handy ent = Entity_Parse (false, // &selected_brushes); // ent = Entity_Parse(false, &active_brushes); if (!ent) { break; } // end entity for undo Undo_EndEntity(ent); // end brushes for undo for (b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) { Undo_EndBrush(b); } if (!strcmp(ValueForKey(ent, "classname"), "worldspawn")) { // world brushes need to be added to the current world entity b = ent->brushes.onext; while (b && b != &ent->brushes) { brush_t *bNext = b->onext; Entity_UnlinkBrush(b); Entity_LinkBrush(world_entity, b); ptrs.Add(b); b = bNext; } } else { // the following bit remaps conflicting target/targetname key/value pairs CString str = ValueForKey(ent, "target"); CString strKey; CString strTarget(""); if (str.GetLength() > 0) { if (FindEntity("target", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { idStr key; UniqueTargetName(key); strKey = key; mapStr.SetAt(str, strKey); } strTarget = strKey; SetKeyValue(ent, "target", strTarget.GetBuffer(0)); } } /* * str = ValueForKey(ent, "name"); if (str.GetLength() > 0) { if * (FindEntity("name", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { * UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } Entity_SetName(ent, * strKey.GetBuffer(0)); } } */ CString cstrNameOld = ValueForKey(ent, "name"); Entity_Name(ent, renameEntities); CString cstrNameNew = ValueForKey(ent, "name"); if (cstrNameOld != cstrNameNew) { RemappedNames.Set(cstrNameOld, cstrNameNew); } // // if (strTarget.GetLength() > 0) SetKeyValue(ent, "target", // strTarget.GetBuffer(0)); // add the entity to the end of the entity list // ent->next = &entities; ent->prev = entities.prev; entities.prev->next = ent; entities.prev = ent; g_qeglobals.d_num_entities++; for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { ptrs.Add(b); } } } // now iterate through the remapped names, and see if there are any target-connections that need remaking... // // (I could probably write this in half the size with STL, but WTF, work with what we have...) // int iNumKeyVals = RemappedNames.GetNumKeyVals(); for (int iKeyVal=0; iKeyVal < iNumKeyVals; iKeyVal++) { const idKeyValue *pKeyVal = RemappedNames.GetKeyVal( iKeyVal ); LPCSTR psOldName = pKeyVal->GetKey().c_str(); LPCSTR psNewName = pKeyVal->GetValue().c_str(); entity_t *pEntOld = FindEntity("name", psOldName); // original ent we cloned from entity_t *pEntNew = FindEntity("name", psNewName); // cloned ent if (pEntOld && pEntNew) { CString cstrTargetNameOld = ValueForKey(pEntOld, "target"); if (!cstrTargetNameOld.IsEmpty()) { // ok, this ent was targeted at another ent, so it's clone needs updating to point to // the clone of that target, so... // entity_t *pEntOldTarget = FindEntity("name", cstrTargetNameOld); if ( pEntOldTarget ) { LPCSTR psNewTargetName = RemappedNames.GetString( cstrTargetNameOld ); if (psNewTargetName && psNewTargetName[0]) { SetKeyValue(pEntNew, "target", psNewTargetName); } } } } } } // // ::ShowWindow(g_qeglobals.d_hwndEntity, FALSE); // ::LockWindowUpdate(g_qeglobals.d_hwndEntity); // g_bScreenUpdates = false; for (int i = 0; i < ptrs.GetSize(); i++) { Brush_Build(reinterpret_cast < brush_t * > (ptrs[i]), true, false); Select_Brush(reinterpret_cast < brush_t * > (ptrs[i]), true, false); } // ::LockWindowUpdate(NULL); g_bScreenUpdates = true; ptrs.RemoveAll(); // // reset the "need conversion" flag conversion to the good format done in // Map_BuildBrushData // g_qeglobals.bNeedConvert = false; Sys_UpdateWindows(W_ALL); // Sys_MarkMapModified(); mapModified = 1; Undo_End(); }
/* ============= 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_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); }
// //================ //Map_ImportFile // Timo 09/01/99 : called by CXYWnd::Paste & Map_ImportFile // if Map_ImportFile ( prefab ), the buffer may contain brushes in old format ( conversion needed ) //================ // void Map_ImportBuffer (char* buf) { entity_t* ent; brush_t* b = NULL; CPtrArray ptrs; Select_Deselect(); Undo_Start("import buffer"); g_qeglobals.d_parsed_brushes = 0; if (buf) { CMapStringToString mapStr; StartTokenParsing (buf); g_qeglobals.d_num_entities = 0; // Timo // will be used in Entity_Parse to detect if a conversion between brush formats is needed g_qeglobals.bNeedConvert = false; g_qeglobals.bOldBrushes = false; g_qeglobals.bPrimitBrushes = false; while (1) { // use the selected brushes list as it's handy //ent = Entity_Parse (false, &selected_brushes); ent = Entity_Parse (false, &active_brushes); if (!ent) break; //end entity for undo Undo_EndEntity(ent); //end brushes for undo for(b = ent->brushes.onext; b && b != &ent->brushes; b = b->onext) { Undo_EndBrush(b); } if (!strcmp(ValueForKey (ent, "classname"), "worldspawn")) { // world brushes need to be added to the current world entity b=ent->brushes.onext; while (b && b != &ent->brushes) { brush_t* bNext = b->onext; Entity_UnlinkBrush(b); Entity_LinkBrush(world_entity, b); ptrs.Add(b); b = bNext; } } else { // the following bit remaps conflicting target/targetname key/value pairs CString str = ValueForKey(ent, "target"); CString strKey; CString strTarget(""); if (str.GetLength() > 0) { if (FindEntity("target", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } strTarget = strKey; SetKeyValue(ent, "target", strTarget.GetBuffer(0)); } } str = ValueForKey(ent, "targetname"); if (str.GetLength() > 0) { if (FindEntity("targetname", str.GetBuffer(0))) { if (!mapStr.Lookup(str, strKey)) { UniqueTargetName(strKey); mapStr.SetAt(str, strKey); } SetKeyValue(ent, "targetname", strKey.GetBuffer(0)); } } //if (strTarget.GetLength() > 0) // SetKeyValue(ent, "target", strTarget.GetBuffer(0)); // add the entity to the end of the entity list ent->next = &entities; ent->prev = entities.prev; entities.prev->next = ent; entities.prev = ent; g_qeglobals.d_num_entities++; for (b=ent->brushes.onext ; b != &ent->brushes ; b=b->onext) { ptrs.Add(b); } } } } //::ShowWindow(g_qeglobals.d_hwndEntity, FALSE); //::LockWindowUpdate(g_qeglobals.d_hwndEntity); g_bScreenUpdates = false; for (int i = 0; i < ptrs.GetSize(); i++) { Brush_Build(reinterpret_cast<brush_t*>(ptrs[i]), true, false); Select_Brush(reinterpret_cast<brush_t*>(ptrs[i]), true, false); } //::LockWindowUpdate(NULL); g_bScreenUpdates = true; ptrs.RemoveAll(); // reset the "need conversion" flag // conversion to the good format done in Map_BuildBrushData g_qeglobals.bNeedConvert=false; Sys_UpdateWindows (W_ALL); //Sys_MarkMapModified(); modified = true; Undo_End(); }