/* =============== 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] ); }
/* =============== CheckBspProcess See if the BSP is done yet =============== */ void CheckBspProcess (void) { char outputpath[1024]; char temppath[512]; DWORD exitcode; char *out; BOOL ret; if (!bsp_process) return; ret = GetExitCodeProcess (bsp_process, &exitcode); if (!ret) Error ("GetExitCodeProcess failed"); if (exitcode == STILL_ACTIVE) return; bsp_process = 0; GetTempPath(512, temppath); sprintf (outputpath, "%sjunk.txt", temppath); LoadFile (outputpath, (void *)&out); Sys_Printf ("%s", out); Sys_Printf ("\ncompleted.\n"); free (out); Sys_Beep (); Pointfile_Check (); }
/* =========== Map_SaveFile \todo FIXME remove the use_region, this is broken .. work with a global flag to set region mode or not =========== */ void Map_SaveFile( const char *filename, qboolean use_region ){ clock_t start, finish; double elapsed_time; start = clock(); Sys_Printf( "Saving map to %s\n",filename ); Pointfile_Clear(); if ( !use_region ) { char backup[1024]; // rename current to .bak strcpy( backup, filename ); StripExtension( backup ); strcat( backup, ".bak" ); unlink( backup ); rename( filename, backup ); } Sys_Printf( "Map_SaveFile: %s\n", filename ); // build the out data stream FileStream file; if ( !file.Open( filename,"w" ) ) { Sys_FPrintf( SYS_ERR, "ERROR: couldn't open %s for write\n", filename ); return; } // extract filetype Map_Export( &file, filename_get_extension( filename ), use_region ); file.Close(); finish = clock(); elapsed_time = (double)( finish - start ) / CLOCKS_PER_SEC; Sys_Printf( "Saved in %-.2f second(s).\n",elapsed_time ); modified = false; if ( !strstr( filename, "autosave" ) ) { Sys_SetTitle( filename ); } if ( !use_region ) { time_t timer; time( &timer ); Sys_Beep(); Sys_Status( "Saved.", 0 ); } }
void CheckBspProcess( void ) { char outputpath[1024]; char temppath[512]; DWORD exitcode; char* out; BOOL ret; if ( !bsp_process ) return; ret = GetExitCodeProcess( bsp_process, &exitcode ); if ( !ret ) Error( "GetExitCodeProcess failed" ); if ( exitcode == STILL_ACTIVE ) return; bsp_process = 0; GetTempPath( 512, temppath ); sprintf( outputpath, "%sjunk.txt", temppath ); LoadFile( outputpath, ( void** )&out ); Sys_Printf( "%s", out ); Sys_Printf( "\ncompleted.\n" ); free( out ); CTime tEnd = CTime::GetCurrentTime(); CTimeSpan tElapsed = tEnd - g_tBegin; CString strElapsed; strElapsed.Format( "Run time was %i hours, %i minutes and %i seconds", tElapsed.GetHours(), tElapsed.GetMinutes(), tElapsed.GetSeconds() ); Sys_Printf( strElapsed.GetBuffer( 0 ) ); Sys_Beep(); Pointfile_Check(); // run game if no PointFile and pref is set //++timo needs to stop after BSP if leaked .. does run through vis and light instead .. if ( g_PrefsDlg.m_bRunQuake == TRUE && !g_qeglobals.d_pointfile_display_list ) { char cCurDir[1024]; GetCurrentDirectory( 1024, cCurDir ); CString strExePath = "../../qio.exe"; //= g_PrefsDlg.m_strQuake2; CString strOrgPath; CString strOrgFile; ExtractPath_and_Filename( currentmap, strOrgPath, strOrgFile ); if ( g_PrefsDlg.m_bSetGame == TRUE ) // run in place with set game.. don't copy map { CString strBasePath = ValueForKey( g_qeglobals.d_project_entity, "basepath" ); strExePath += " +set game "; strExePath += strBasePath; WinExec( strExePath, SW_SHOW ); } else { CString strCopyPath = strExePath; char* pBuffer = strCopyPath.GetBufferSetLength( _MAX_PATH + 1 ); pBuffer[strCopyPath.ReverseFind( '\\' ) + 1] = '\0'; strCopyPath.ReleaseBuffer(); SetCurrentDirectory( strCopyPath ); CString strOrgPath; CString strOrgFile; ExtractPath_and_Filename( currentmap, strOrgPath, strOrgFile ); AddSlash( strCopyPath ); FindReplace( strOrgFile, ".map", ".bsp" ); //++timo modified for Quake3 !! strCopyPath += "baseq3\\maps\\"; strCopyPath += strOrgFile; AddSlash( strOrgPath ); strOrgPath += strOrgFile; bool bRun = ( strOrgPath.CompareNoCase( strCopyPath ) == 0 ); if ( !bRun ) bRun = ( CopyFile( strOrgPath, strCopyPath, FALSE ) == TRUE ); if ( bRun ) { FindReplace( strOrgFile, ".bsp", "" ); strExePath += " +map "; strExePath += strOrgFile; WinExec( strExePath, SW_SHOW ); } } SetCurrentDirectory( cCurDir ); } }
/* ======================================================================================================================= 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]); }
void DoTower(void) { brush_t* brush1 = NULL; brush_t* brush2 = NULL; brush_t* newBrush = NULL; brush_t* tempBrush = NULL; face_t* topFace = NULL; face_t* bottomFace = NULL; face_t* curFace; face_t* faceList; int zFlag = 0; int i = 0; // loop counter if (g_qeglobals.d_select_count != 2) { Sys_Printf ("Error: you must have exactly 2 brushes selected\n"); Sys_Beep (); return; } brush1 = selected_brushes.next; brush2 = selected_brushes.next->next; // establish brush1 as the upper brush if (brush2->maxs[2] > brush1->mins[2]) { tempBrush = brush1; brush1 = brush2; brush2 = tempBrush; } // test to insure brushes do not "overlap" in the Z direction if (brush2->maxs[2] > brush1->mins[2]) { Sys_Printf ("Brushes are not separated in the Z direction!"); Sys_Beep(); return; } // find the bottom Z plane (topFace) in 1 and top Z plane in 2 (bottomFace) topFace = brush1->brush_faces; while (topFace != NULL) { zFlag = 0; for (i = 0; i<3; i++) { if (abs(topFace->planepts[i][2] - brush1->mins[2]) < TOWER_EPSILON) { zFlag++; } } if (zFlag == 3) { break; } else { topFace = topFace->next; } } if (topFace == NULL) { Sys_Printf("Couldn't find flat bottom-face in top brush", 0); Sys_Beep(); return; } bottomFace = brush2->brush_faces; while (bottomFace != NULL) { zFlag = 0; for (i = 0; i<3; i++) { if (abs(bottomFace->planepts[i][2] - brush2->maxs[2]) < TOWER_EPSILON) { zFlag++; } } if (zFlag == 3) { break; } else { bottomFace = bottomFace->next; } } if (bottomFace == NULL) { Sys_Printf ("Couldn't find flat top-face in bottom brush", 0); Sys_Beep(); return; } // count vertices on top and bottom planes to make sure they are equal if (topFace->face_winding->numpoints != bottomFace->face_winding->numpoints) { Sys_Printf ("Top and Bottom faces don't have same #'s of vertices!", 0); Sys_Beep(); return; } // put top and bottom faces on brush // reverse winding for top and bottom faceList = Face_Alloc(); for ( i = 0; i<3; i++) { VectorCopy(topFace->planepts[2-i],faceList->planepts[i]); } curFace = Face_Alloc(); for ( i = 0; i < 3; i++) { VectorCopy(bottomFace->planepts[2-i],curFace->planepts[i]); } curFace->next = faceList; faceList = curFace; curFace = MakePlaneList(topFace, bottomFace); if (curFace == NULL) { Sys_Printf ("Couldn't make planes for tower!", 0); Sys_Beep(); return; } else { faceList->next->next = curFace; } newBrush = (brush_t*)qmalloc(sizeof(brush_t)); newBrush->brush_faces = faceList; Select_Deselect(); Brush_AddToList (newBrush, &selected_brushes); Entity_LinkBrush (world_entity, newBrush); Brush_Build(newBrush); // UNDO_FinishBrushAdd("&Undo Tower"); Sys_UpdateWindows(W_ALL); return; }
/* ======================================================================================================================= Entity_Create Creates a new entity out of the selected_brushes list. If the entity class is fixed size, the brushes are only used to find a midpoint. Otherwise, the brushes have their ownership transfered to the new entity. ======================================================================================================================= */ entity_t *Entity_Create(eclass_t *c, bool forceFixed) { entity_t *e; brush_t *b; idVec3 mins, maxs, origin; char text[32]; texdef_t td; brushprimit_texdef_t bp; // check to make sure the brushes are ok for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { if (b->owner != world_entity) { Sys_Status("Entity NOT created, brushes not all from world\n"); Sys_Beep(); return NULL; } } idStr str; if (c->defArgs.GetString("model", "", str) && c->entityModel == NULL) { c->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &c->defArgs ); } // create it e = Entity_New(); e->brushes.onext = e->brushes.oprev = &e->brushes; e->eclass = c; e->epairs.Copy(c->args); SetKeyValue(e, "classname", c->name); Entity_Name(e, false); // add the entity to the entity list Entity_AddToList(e, &entities); if (c->fixedsize) { // // just use the selection for positioning b = selected_brushes.next; for (i=0 ; // i<3 ; i++) { e->origin[i] = b->mins[i] - c->mins[i]; } // Select_GetMid(e->origin); VectorCopy(e->origin, origin); // create a custom brush VectorAdd(c->mins, e->origin, mins); VectorAdd(c->maxs, e->origin, maxs); b = Brush_Create(mins, maxs, &c->texdef); Entity_LinkBrush(e, b); if (c->defMaterial.Length()) { td.SetName(c->defMaterial); Brush_SetTexture(b, &td, &bp, false); } // delete the current selection Select_Delete(); // select the new brush b->next = b->prev = &selected_brushes; selected_brushes.next = selected_brushes.prev = b; Brush_Build(b); } else { Select_GetMid(origin); // change the selected brushes over to the new entity for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { Entity_UnlinkBrush(b); Entity_LinkBrush(e, b); Brush_Build(b); // so the key brush gets a name if (c->defMaterial.Length()) { td.SetName(c->defMaterial); Brush_SetTexture(b, &td, &bp, false); } } //for (int i = 0; i < 3; i++) { // origin[i] = vMin[i] + vMax[i] * 0.5; //} if (!forceFixed) { SetKeyValue(e, "model", ValueForKey(e, "name")); } } sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); VectorCopy(origin, e->origin); Sys_UpdateWindows(W_ALL); return e; }
/* ============ Entity_Create Creates a new entity out of the selected_brushes list. If the entity class is fixed size, the brushes are only used to find a midpoint. Otherwise, the brushes have their ownershi[ transfered to the new entity. ============ */ entity_t *Entity_Create (eclass_t *c) { entity_t *e; brush_t *b; vec3_t mins, maxs; int i; // check to make sure the brushes are ok for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) if (b->owner != world_entity) { Sys_Printf ("Entity NOT created, brushes not all from world\n"); Sys_Beep (); return NULL; } // create it e = (entity_t*)qmalloc(sizeof(*e)); e->brushes.onext = e->brushes.oprev = &e->brushes; e->eclass = c; SetKeyValue (e, "classname", c->name); // add the entity to the entity list e->next = entities.next; entities.next = e; e->next->prev = e; e->prev = &entities; if (c->fixedsize) { // // just use the selection for positioning // b = selected_brushes.next; for (i=0 ; i<3 ; i++) e->origin[i] = b->mins[i] - c->mins[i]; // create a custom brush VectorAdd (c->mins, e->origin, mins); VectorAdd (c->maxs, e->origin, maxs); b = Brush_Create (mins, maxs, &c->texdef); Entity_LinkBrush (e, b); // delete the current selection Select_Delete (); // select the new brush b->next = b->prev = &selected_brushes; selected_brushes.next = selected_brushes.prev = b; Brush_Build( b ); } else { // // change the selected brushes over to the new entity // for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) { Entity_UnlinkBrush (b); Entity_LinkBrush (e, b); Brush_Build( b ); // so the key brush gets a name } } Sys_UpdateWindows (W_ALL); return e; }
/* =============== 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]); }