/* ============ SetModelNumbers ============ */ void SetModelNumbers (void) { int i; int models; char value[10]; models = 1; for ( i=1 ; i<num_entities ; i++ ) { if ( entities[i].brushes || entities[i].patches ) { sprintf ( value, "*%i", models ); models++; SetKeyValue (&entities[i], "model", value); } } }
int Ardb::ListInsert(Context& ctx, const std::string& key, const std::string* match, const std::string& value, bool head, bool abort_nonexist) { ValueObject meta; int err = GetMetaValue(ctx, key, LIST_META, meta); CHECK_ARDB_RETURN_VALUE(ctx.reply, err); BatchWriteGuard guard(GetKeyValueEngine(), meta.meta.Encoding() != COLLECTION_ENCODING_ZIPLIST); if (0 != err && abort_nonexist) { fill_int_reply(ctx.reply, 0); return 0; } ListInsert(ctx, meta, match, value, head, abort_nonexist); SetKeyValue(ctx, meta); return 0; }
BOOL CALLBACK AddCommandDlgProc ( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { char key[64]; char value[128]; switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: if (!GetDlgItemText(hwndDlg, IDC_CMDMENUTEXT, key, 64)) { common->Printf ("Command not added\n"); return FALSE; } if (!GetDlgItemText(hwndDlg, IDC_CMDCOMMAND, value, 64)) { common->Printf ("Command not added\n"); return FALSE; } if (key[0] == 'b' && key[1] == 's' && key[2] == 'p') { SetKeyValue (g_qeglobals.d_project_entity, key, value); FillBSPMenu (); } else common->Printf ("BSP commands must be preceded by \"bsp\""); EndDialog(hwndDlg, 1); return TRUE; case IDCANCEL: EndDialog(hwndDlg, 0); return TRUE; } } return FALSE; }
/* ================= UpdateEntLump ================= */ void UpdateEntLump (void) { int m, entnum; char mod[80]; m = 1; for (entnum = 1 ; entnum < num_entities ; entnum++) { if (!entities[entnum].brushes) continue; sprintf (mod, "*%i", m); SetKeyValue (&entities[entnum], "model", mod); m++; } UnparseEntities(); }
BOOL CALLBACK EditCommandDlgProc( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { char key[1024]; char value[1024]; const char *temp; int index; HWND hOwner; hOwner = GetParent( hwndDlg ); switch( uMsg ) { case WM_INITDIALOG: index = SendDlgItemMessage( hOwner, IDC_CMD_LIST, LB_GETCURSEL, 0, 0 ); if( index >= 0 ) { SendDlgItemMessage( hOwner, IDC_CMD_LIST, LB_GETTEXT, index, ( LPARAM )( LPCTSTR ) key ); temp = ValueForKey( g_qeglobals.d_project_entity, key ); strcpy( value, temp ); SetDlgItemText( hwndDlg, IDC_CMDMENUTEXT, key ); SetDlgItemText( hwndDlg, IDC_CMDCOMMAND, value ); } return FALSE; break; case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDOK: if( !GetDlgItemText( hwndDlg, IDC_CMDMENUTEXT, key, 64 ) ) { common->Printf( "Command not added\n" ); return FALSE; } if( !GetDlgItemText( hwndDlg, IDC_CMDCOMMAND, value, 64 ) ) { common->Printf( "Command not added\n" ); return FALSE; } SetKeyValue( g_qeglobals.d_project_entity, key, value ); FillBSPMenu(); EndDialog( hwndDlg, 1 ); return TRUE; case IDCANCEL: EndDialog( hwndDlg, 0 ); return TRUE; } } return FALSE; }
int QIniFileImpl::WriteMultiFloat(const char* lpSection, const char* lpKeyName, float *pValues, int nCount) { if (nCount > 0 && nCount <= INI_MAX_SUPPORT_MULTI_VALUE_COUNT) { char Buffer[INI_MAX_SUPPORT_VALUE_SIZE]; int nPos = sprintf(Buffer, "%f", *pValues); while(--nCount) { pValues++; Buffer[nPos++] = ','; nPos += sprintf(Buffer + nPos, "%f", *pValues); } return SetKeyValue(lpSection, lpKeyName, Buffer); } return false; }
int QIniFileImpl::WriteMultiLong(const char* lpSection, const char* lpKeyName, long *pValues, int nCount) { if (nCount > 0 && nCount <= INI_MAX_SUPPORT_MULTI_VALUE_COUNT) { char Buffer[INI_MAX_SUPPORT_VALUE_SIZE]; const char* pFormat = (sizeof(long) == 8) ? "%I64d" : "%d"; int nPos = sprintf(Buffer, pFormat, *pValues); while(--nCount) { pValues++; Buffer[nPos++] = ','; nPos += sprintf(Buffer + nPos, pFormat, *pValues); } return SetKeyValue(lpSection, lpKeyName, Buffer); } return false; }
/* ======================================================================================================================= Map_New ======================================================================================================================= */ void Map_New( void ) { common->Printf( "Map_New\n" ); Map_Free(); Patch_Cleanup(); g_Inspectors->entityDlg.SetEditEntity( NULL ); world_entity = Entity_New(); world_entity->brushes.onext = world_entity->brushes.oprev = &world_entity->brushes; SetKeyValue( world_entity, "classname", "worldspawn" ); world_entity->eclass = Eclass_ForName( "worldspawn", true ); g_pParentWnd->GetCamera()->Camera().angles[YAW] = 0; g_pParentWnd->GetCamera()->Camera().angles[PITCH] = 0; VectorCopy( vec3_origin, g_pParentWnd->GetCamera()->Camera().origin ); g_pParentWnd->GetCamera()->Camera().origin[2] = 48; VectorCopy( vec3_origin, g_pParentWnd->GetXYWnd()->GetOrigin() ); Map_RestoreBetween(); Sys_UpdateWindows( W_ALL ); mapModified = 0; g_qeglobals.mapVersion = MAP_VERSION; }
void SetLightStyles( void ){ int stylenum; char *t; entity_t *e; int i, j; char value[10]; char lighttargets[MAX_SWITCHED_LIGHTS][64]; // any light that is controlled (has a targetname) // must have a unique style number generated for it stylenum = 0; for ( i = 1 ; i < num_entities ; i++ ) { e = &entities[i]; t = ValueForKey( e, "classname" ); if ( Q_strncasecmp( t, "light", 5 ) ) { continue; } t = ValueForKey( e, "targetname" ); if ( !t[0] ) { continue; } // find this targetname for ( j = 0 ; j < stylenum ; j++ ) if ( !strcmp( lighttargets[j], t ) ) { break; } if ( j == stylenum ) { if ( stylenum == MAX_SWITCHED_LIGHTS ) { Error( "stylenum == MAX_SWITCHED_LIGHTS" ); } strcpy( lighttargets[j], t ); stylenum++; } sprintf( value, "%i", 32 + j ); SetKeyValue( e, "style", value ); } }
/* ================= UpdateEntLump ================= */ void UpdateEntLump (void) { int m, entnum; char mod[80]; m = 1; for (entnum = 1 ; entnum < num_entities ; entnum++) { if (!entities[entnum].brushes) continue; sprintf (mod, "*%i", m); SetKeyValue (&entities[entnum], "model", mod); m++; } printf ("Updating entities lump...\n"); LoadBSPFile (bspfilename); WriteEntitiesToString(); WriteBSPFile (bspfilename); }
/* ======================================================================================================================= QE_LoadProject ======================================================================================================================= */ bool QE_LoadProject(char *projectfile) { char *data; ID_TIME_T time; common->Printf("QE_LoadProject (%s)\n", projectfile); if ( fileSystem->ReadFile( projectfile, reinterpret_cast < void ** > (&data), &time) <= 0 ) { return false; } g_strProject = projectfile; g_PrefsDlg.m_strLastProject = projectfile; g_PrefsDlg.SavePrefs(); CString strData = data; fileSystem->FreeFile( data ); StartTokenParsing(strData.GetBuffer(0)); g_qeglobals.d_project_entity = Entity_Parse(true); if (!g_qeglobals.d_project_entity) { Error("Couldn't parse %s", projectfile); } // set here some default project settings you need if (strlen(ValueForKey(g_qeglobals.d_project_entity, "brush_primit")) == 0) { SetKeyValue(g_qeglobals.d_project_entity, "brush_primit", "0"); } g_qeglobals.m_bBrushPrimitMode = IntForKey(g_qeglobals.d_project_entity, "brush_primit"); Eclass_InitForSourceDirectory(ValueForKey(g_qeglobals.d_project_entity, "entitypath")); g_Inspectors->FillClassList(); // list in entity window Map_New(); // FillTextureMenu(); FillBSPMenu(); return true; }
void Entity_Parse( entity_t *pEntity ){ brush_t *pBrush; // CPtrArray *brushes = NULL; char temptoken[1024]; char *token = Token(); while ( 1 ) { GetToken( true ); // { or } or epair if ( !strcmp( token, "}" ) ) { break; } else if ( !strcmp( token, "{" ) ) { pBrush = Brush_Alloc(); if ( Primitive_Parse( pBrush ) ) { ( (CPtrArray*)pEntity->pData )->Add( pBrush ); } else { Brush_Free( pBrush, true ); } } else { strcpy( temptoken, token ); GetToken( false ); SetKeyValue( pEntity, temptoken, token ); if ( g_MapVersion == MAPVERSION_HL ) { // if we've not god a "wads" key/pair already, then break it into a list. if ( !g_WadList && ( stricmp( temptoken,"wad" ) == 0 ) ) { BuildWadList( token ); } } } } }
int Ardb::ZipListConvert(Context& ctx, ValueObject& meta) { meta.meta.SetEncoding(COLLECTION_ENCODING_RAW); meta.meta.SetFlag(COLLECTION_FLAG_SEQLIST); meta.meta.min_index.SetInt64(0); meta.meta.max_index.SetInt64(meta.meta.ziplist.size() - 1); for (uint32 i = 0; i < meta.meta.ziplist.size(); i++) { ValueObject v; v.type = LIST_ELEMENT; v.element = meta.meta.ziplist[i]; v.key.type = LIST_ELEMENT; v.key.key = meta.key.key; v.key.db = ctx.currentDB; v.key.score.SetInt64(i); SetKeyValue(ctx, v); } meta.meta.len = meta.meta.ziplist.size(); meta.meta.ziplist.clear(); return 0; }
//--------------------------------------------------------------------------- // 函数: WriteFloat2 // 功能: 写入一个结构 // 参数: lpSection 节名 // lpKeyName 建名 // lpStruct 结构 // dwSize 结构大小 //--------------------------------------------------------------------------- int QIniFileImpl::WriteStruct( const char* lpSection, // pointer to section name const char* lpKeyName, // pointer to key name void* lpStruct, // pointer to buffer that contains data to add unsigned int dwSize // size, in bytes, of the buffer ) { char Buffer[2048 * 2]; char* lpBuff = Buffer; unsigned char* lpByte; if (dwSize >= 2048) return false; lpByte = (unsigned char*) lpStruct; for (unsigned int i=0; i<dwSize; i++) { sprintf(lpBuff,"%02X",*lpByte); lpBuff++; lpBuff++; lpByte++; } return SetKeyValue(lpSection, lpKeyName, Buffer); }
/* ============ SetModelNumbers ============ */ void SetModelNumbers (void) { int i; int models; char value[10]; models = 1; for (i=1 ; i<num_entities ; i++) { if (!entities[i].numbrushes) continue; if ( !IsFuncOccluder(i) ) { sprintf (value, "*%i", models); models++; } else { sprintf (value, ""); } SetKeyValue (&entities[i], "model", value); } }
void SetLightStyles( void ) { int i, j, style, numStyles; qboolean keepLights; const char *t; entity_t *e; epair_t *ep, *next; char value[ 10 ]; char lightTargets[ MAX_SWITCHED_LIGHTS ][ 64 ]; int lightStyles[ MAX_SWITCHED_LIGHTS ]; /* ydnar: determine if we keep lights in the bsp */ t = ValueForKey( &entities[ 0 ], "_keepLights" ); keepLights = (t[ 0 ] == '1') ? qtrue : qfalse; /* any light that is controlled (has a targetname) must have a unique style number generated for it */ numStyles = 0; for( i = 1; i < numEntities; i++ ) { e = &entities[ i ]; t = ValueForKey( e, "classname" ); if( Q_strncasecmp( t, "light", 5 ) ) continue; t = ValueForKey( e, "targetname" ); if( t[ 0 ] == '\0' ) { /* ydnar: strip the light from the BSP file */ if( keepLights == qfalse ) { ep = e->epairs; while( ep != NULL ) { next = ep->next; free( ep->key ); free( ep->value ); free( ep ); ep = next; } e->epairs = NULL; numStrippedLights++; } /* next light */ continue; } /* get existing style */ style = IntForKey( e, "style" ); if( style < LS_NORMAL || style > LS_NONE ) Error( "Invalid lightstyle (%d) on entity %d", style, i ); /* find this targetname */ for( j = 0; j < numStyles; j++ ) if( lightStyles[ j ] == style && !strcmp( lightTargets[ j ], t ) ) break; /* add a new style */ if( j >= numStyles ) { if( numStyles == MAX_SWITCHED_LIGHTS ) Error( "MAX_SWITCHED_LIGHTS (%d) exceeded, reduce the number of lights with targetnames", MAX_SWITCHED_LIGHTS ); strcpy( lightTargets[ j ], t ); lightStyles[ j ] = style; numStyles++; } /* set explicit style */ sprintf( value, "%d", 32 + j ); SetKeyValue( e, "style", value ); /* set old style */ if( style != LS_NORMAL ) { sprintf( value, "%d", style ); SetKeyValue( e, "switch_style", value ); } } /* emit some statistics */ Sys_FPrintf( SYS_VRB, "%9d light entities stripped\n", numStrippedLights ); }
/*!\todo Possibly make the import Undo-friendly by calling Undo_End for new brushes and ents */ void Map_ImportEntities( CPtrArray *ents, bool bAddSelected = false ){ int num_ents, num_brushes; CPtrArray *brushes; vec3_t mins, maxs; entity_t *e; brush_t *b; face_t *f; int i,j; GPtrArray *new_ents = g_ptr_array_new(); g_qeglobals.bPrimitBrushes = false; brush_t *pBrushList = ( bAddSelected ) ? &selected_brushes : &active_brushes; bool bDoneBPCheck = false; g_qeglobals.bNeedConvert = false; // HACK: find out if this map file was a BP one // check the first brush in the file that is NOT a patch // this will not be necessary when we allow both formats in the same file num_ents = ents->GetSize(); for ( i = 0; !bDoneBPCheck && i < num_ents; i++ ) { e = (entity_t*)ents->GetAt( i ); brushes = (CPtrArray*)e->pData; num_brushes = brushes->GetSize(); for ( j = 0; !bDoneBPCheck && j < num_brushes; j++ ) { /*!todo Allow mixing texdef formats per-face. */ b = (brush_t *)brushes->GetAt( j ); if ( b->patchBrush ) { continue; } bDoneBPCheck = true; int BP_param = -1; if ( b->bBrushDef && !g_qeglobals.m_bBrushPrimitMode ) { BP_param = 0; } else if ( !b->bBrushDef && g_qeglobals.m_bBrushPrimitMode ) { BP_param = 1; } if ( BP_param != -1 ) { switch ( BP_MessageBox( BP_param ) ) { case 0: Map_FreeEntities( ents ); return; case 1: g_qeglobals.bNeedConvert = true; break; case 2: g_qeglobals.bNeedConvert = false; break; } } } } // process the entities into the world geometry num_ents = ents->GetSize(); for ( i = 0; i < num_ents; i++ ) { num_brushes = 0; e = (entity_t*)ents->GetAt( i ); brushes = (CPtrArray*)e->pData; num_brushes = brushes->GetSize(); // link brushes into entity for ( j = 0; j < num_brushes; j++ ) { Entity_LinkBrush( e, (brush_t *)brushes->GetAt( j ) ); g_qeglobals.d_parsed_brushes++; } brushes->RemoveAll(); delete brushes; e->pData = NULL; // set entity origin GetVectorForKey( e, "origin", e->origin ); // set entity eclass /*!\todo Make SetKeyValue check for "classname" change and assign appropriate eclass */ e->eclass = Eclass_ForName( ValueForKey( e, "classname" ), ( e->brushes.onext != &e->brushes ) ); // go through all parsed brushes and build stuff for ( b = e->brushes.onext; b != &e->brushes; b = b->onext ) { for ( f = b->brush_faces; f != NULL; f = f->next ) { f->pShader = QERApp_Shader_ForName( f->texdef.GetName() ); f->d_texture = f->pShader->getTexture(); } // when brushes are in final state, build the planes and windings // NOTE: also converts BP brushes if g_qeglobals.bNeedConvert is true Brush_Build( b ); } //#define TERRAIN_HACK #undef TERRAIN_HACK #ifdef TERRAIN_HACK if ( ( strcmp( ValueForKey( e, "terrain" ),"1" ) == 0 && strcmp( e->eclass->name,"func_group" ) == 0 ) ) { // two aux pointers to the shaders used in the terrain entity // we don't keep refcount on them since they are only temporary // this avoids doing expensive lookups by name for all faces IShader *pTerrainShader, *pCaulk; pTerrainShader = NULL; pCaulk = QERApp_Shader_ForName( SHADER_CAULK ); for ( b = e->brushes.onext; b != &e->brushes; b = b->onext ) { if ( pTerrainShader == NULL ) { for ( f = b->brush_faces; f != NULL; f = f->next ) if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) { pTerrainShader = f->pShader; } } if ( pTerrainShader ) { for ( f = b->brush_faces; f != NULL; f = f->next ) { if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) { // not caulk Face_SetShader( f, pTerrainShader->getName() ); } else{ Face_SetShader( f, pCaulk->getName() ); } } } else{ Sys_FPrintf( SYS_WRN, "WARNING: no terrain shader found for brush\n" ); } } } #endif #define PATCH_HACK #ifdef PATCH_HACK for ( b = e->brushes.onext; b != &e->brushes; b = b->onext ) { // patch hack, to be removed when dependency on brush_faces is removed if ( b->patchBrush ) { Patch_CalcBounds( b->pPatch, mins, maxs ); for ( int i = 0; i < 3; i++ ) { if ( (int)mins[i] == (int)maxs[i] ) { mins[i] -= 4; maxs[i] += 4; } } Brush_Resize( b, mins, maxs ); Brush_Build( b ); } } #endif // add brush for fixedsize entity if ( e->eclass->fixedsize ) { vec3_t mins, maxs; VectorAdd( e->eclass->mins, e->origin, mins ); VectorAdd( e->eclass->maxs, e->origin, maxs ); b = Brush_Create( mins, maxs, &e->eclass->texdef ); Entity_LinkBrush( e, b ); Brush_Build( b ); } for ( b = e->brushes.onext; b != &e->brushes; b = b->onext ) Brush_AddToList( b, pBrushList ); if ( strcmp( e->eclass->name, "worldspawn" ) == 0 ) { if ( world_entity ) { while ( e->brushes.onext != &e->brushes ) { b = e->brushes.onext; Entity_UnlinkBrush( b ); Entity_LinkBrush( world_entity, b ); } Entity_Free( e ); } else { world_entity = e; } } else if ( strcmp( e->eclass->name, "group_info" ) == 0 ) { // it's a group thing! Group_Add( e ); Entity_Free( e ); } else { // fix target/targetname collisions if ( ( g_PrefsDlg.m_bDoTargetFix ) && ( strcmp( ValueForKey( e, "target" ), "" ) != 0 ) ) { GPtrArray *t_ents = g_ptr_array_new(); entity_t *e_target; const char *target = ValueForKey( e, "target" ); qboolean bCollision = FALSE; // check the current map entities for an actual collision for ( e_target = entities.next; e_target != &entities; e_target = e_target->next ) { if ( !strcmp( target, ValueForKey( e_target, "target" ) ) ) { bCollision = TRUE; // make sure the collision is not between two imported entities for ( j = 0; j < (int)new_ents->len; j++ ) { if ( e_target == g_ptr_array_index( new_ents, j ) ) { bCollision = FALSE; } } } } // find the matching targeted entity(s) if ( bCollision ) { for ( j = num_ents - 1; j > 0; j-- ) { e_target = (entity_t*)ents->GetAt( j ); if ( e_target != NULL && e_target != e ) { const char *targetname = ValueForKey( e_target, "targetname" ); if ( ( targetname != NULL ) && ( strcmp( target, targetname ) == 0 ) ) { g_ptr_array_add( t_ents, (gpointer)e_target ); } } } if ( t_ents->len > 0 ) { // link the first to get a unique target/targetname Entity_Connect( e, (entity_t*)g_ptr_array_index( t_ents,0 ) ); // set the targetname of the rest of them manually for ( j = 1; j < (int)t_ents->len; j++ ) SetKeyValue( (entity_t*)g_ptr_array_index( t_ents, j ), "targetname", ValueForKey( e, "target" ) ); } g_ptr_array_free( t_ents, FALSE ); } } // add the entity to the end of the entity list Entity_AddToList( e, &entities ); g_qeglobals.d_num_entities++; // keep a list of ents added to avoid testing collisions against them g_ptr_array_add( new_ents, (gpointer)e ); } } g_ptr_array_free( new_ents, FALSE ); ents->RemoveAll(); g_qeglobals.bNeedConvert = false; }
// FIXME: turn this into an MFC dialog BOOL CALLBACK ProjectDlgProc ( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { char key[1024]; char value[1024]; int index; switch (uMsg) { case WM_INITDIALOG: SetDlgItemText(hwndDlg, IDC_PRJBASEPATH, ValueForKey (g_qeglobals.d_project_entity, "basepath")); SetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, ValueForKey (g_qeglobals.d_project_entity, "mapspath")); SetDlgItemText(hwndDlg, IDC_PRJRSHCMD, ValueForKey (g_qeglobals.d_project_entity, "rshcmd")); SetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, ValueForKey (g_qeglobals.d_project_entity, "remotebasepath")); SetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, ValueForKey (g_qeglobals.d_project_entity, "entitypath")); SetDlgItemText(hwndDlg, IDC_PRJTEXPATH, ValueForKey (g_qeglobals.d_project_entity, "texturepath")); UpdateBSPCommandList (hwndDlg); // Timo // additional fields CheckDlgButton( hwndDlg, IDC_CHECK_BPRIMIT, (g_qeglobals.m_bBrushPrimitMode) ? BST_CHECKED : BST_UNCHECKED ); // SendMessage( ::GetDlgItem( hwndDlg, IDC_CHECK_BPRIMIT ), BM_SETCHECK, (WPARAM) g_qeglobals.m_bBrushPrimitMode, 0 ); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_ADDCMD: // DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, AddCommandDlgProc); DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, AddCommandDlgProc); UpdateBSPCommandList (hwndDlg); break; case IDC_EDITCMD: // DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, g_qeglobals.d_hwndMain, EditCommandDlgProc); DialogBox(g_qeglobals.d_hInstance, (char *)IDD_ADDCMD, hwndDlg, EditCommandDlgProc); UpdateBSPCommandList (hwndDlg); break; case IDC_REMCMD: index = SendDlgItemMessage (hwndDlg, IDC_CMD_LIST, LB_GETCURSEL, 0, 0); SendDlgItemMessage(hwndDlg, IDC_CMD_LIST, LB_GETTEXT, index, (LPARAM) (LPCTSTR) key); DeleteKey (g_qeglobals.d_project_entity, key); common->Printf ("Selected %d\n", index); UpdateBSPCommandList (hwndDlg); break; case IDOK: GetDlgItemText(hwndDlg, IDC_PRJBASEPATH, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "basepath", value); GetDlgItemText(hwndDlg, IDC_PRJMAPSPATH, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "mapspath", value); GetDlgItemText(hwndDlg, IDC_PRJRSHCMD, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "rshcmd", value); GetDlgItemText(hwndDlg, IDC_PRJREMOTEBASE, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "remotebasepath", value); GetDlgItemText(hwndDlg, IDC_PRJENTITYPATH, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "entitypath", value); GetDlgItemText(hwndDlg, IDC_PRJTEXPATH, value, 1024); SetKeyValue (g_qeglobals.d_project_entity, "texturepath", value); // Timo // read additional fields if ( IsDlgButtonChecked( hwndDlg, IDC_CHECK_BPRIMIT ) ) { g_qeglobals.m_bBrushPrimitMode = TRUE; } else { g_qeglobals.m_bBrushPrimitMode = FALSE; } SetKeyValue ( g_qeglobals.d_project_entity, "brush_primit", ( g_qeglobals.m_bBrushPrimitMode ? "1" : "0" ) ); EndDialog(hwndDlg, 1); QE_SaveProject(g_strProject); return TRUE; case IDCANCEL: EndDialog(hwndDlg, 0); return TRUE; } } return FALSE; }
/* ======================================================================================================================= AddProp ======================================================================================================================= */ void CEntityDlg::AddProp() { if (editEntity == NULL) { return; } CString Key, Value; editKey.GetWindowText(Key); editVal.GetWindowText(Value); bool isName = (stricmp(Key, "name") == 0); bool isModel = static_cast<bool>((stricmp(Key, "model") == 0 && Value.GetLength() > 0)); bool isOrigin = ( idStr::Icmp( Key, "origin" ) == 0 ); if (multipleEntities) { brush_t *b; for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { if (isName) { Entity_SetName(b->owner, Value); } else { if ( ! ( ( isModel || isOrigin ) && ( b->owner->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) { SetKeyValue(b->owner, Key, Value); } } } } else { if (isName) { Entity_SetName(editEntity, Value); } else { if ( ! ( ( isModel || isOrigin ) && ( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) ) { SetKeyValue(editEntity, Key, Value); } } if ( isModel && !( editEntity->eclass->nShowFlags & ECLASS_WORLDSPAWN ) ) { idBounds bo; idVec3 mins, maxs; selected_brushes.next->modelHandle = renderModelManager->FindModel( Value ); if ( dynamic_cast<idRenderModelPrt*>( selected_brushes.next->modelHandle ) || dynamic_cast<idRenderModelLiquid*>( selected_brushes.next->modelHandle ) ) { bo.Zero(); bo.ExpandSelf( 12.0f ); } else { bo = selected_brushes.next->modelHandle->Bounds( NULL ); } VectorCopy(bo[0], mins); VectorCopy(bo[1], maxs); VectorAdd(mins, editEntity->origin, mins); VectorAdd(maxs, editEntity->origin, maxs); Brush_RebuildBrush(selected_brushes.next, mins, maxs, false); Brush_Build ( selected_brushes.next , false, false , false, true ); } } // refresh the prop listbox SetKeyValPairs(); Sys_UpdateWindows(W_ALL); }
/** * @brief Perform an entity check */ void CheckEntities (void) { Check_InitEntityDefs(); for (int i = 0; i < num_entities; i++) { entity_t* e = &entities[i]; const char* name = ValueForKey(e, "classname"); const entityDef_t* ed = ED_GetEntityDef(name); const epair_t* kvp; const entityKeyDef_t* kd; if (!ed) { /* check that a definition exists */ Check_Printf(VERB_CHECK, false, i, -1, "Not defined in entities.ufo: %s\n", name); continue; } /* check alignment of info_.+_start */ if (Check_IsInfoStart(name) && !Check_InfoStartAligned(ed, e)) Check_Printf(VERB_CHECK, false, i, -1, "Misaligned %s\n", name); if (Q_strstart(name, "func_")) /* func_* entities should have brushes */ Check_EntityWithBrushes(e, name, i); /* check all keys in the entity - make sure they are OK */ for (kvp = e->epairs; kvp; kvp = kvp->next) { kd = ED_GetKeyDefEntity(ed, kvp->key, 0); /* zero means ignore abstract (radiant only) keys */ if (!kd) { /* make sure it has a definition */ Check_Printf(VERB_CHECK, false, i, -1, "Not defined in entities.ufo: %s in %s\n", kvp->key, name); continue; } if (ED_CheckKey(kd, kvp->value) == ED_ERROR) { /* check values against type and range definitions in entities.ufo */ Check_Printf(VERB_CHECK, false, i, -1, "%s\n", ED_GetLastError()); continue; } if (Q_streq("target", kvp->key) || Q_streq("targetname", kvp->key)) { if (!Check_TargetExists(kvp)) { Check_Printf(VERB_CHECK, false, i, -1, "%s with %s of %s: no corresponding entity with %s with matching value\n", ed->classname, kvp->key, kvp->value, Q_streq("target", kvp->key) ? "targetname" : "target"); } } } /* check keys in the entity definition - make sure mandatory ones are present */ for (kd = ed->keyDefs; kd->name; kd++) { if (kd->flags & ED_MANDATORY) { const char* keyNameInEnt = ValueForKey(e, kd->name); if (keyNameInEnt[0] == '\0') { const char* defaultVal = kd->defaultVal; const bool hasDefault = defaultVal ? true : false; Check_Printf(VERB_CHECK, hasDefault, i, -1, "Mandatory key missing from entity: %s in %s", kd->name, name); if (defaultVal) { Check_Printf(VERB_CHECK, hasDefault, i, -1, ", supplying default: %s", defaultVal); SetKeyValue(e, kd->name, defaultVal); } Check_Printf(VERB_CHECK, hasDefault, i, -1, "\n"); } } } } }
static void SetCloneModelNumbers( void ) { int i, j; int models; char modelValue[ 10 ]; const char *value, *value2, *value3; /* start with 1 (worldspawn is model 0) */ models = 1; for( i = 1; i < numEntities; i++ ) { /* only entities with brushes or patches get a model number */ if( entities[ i ].brushes == NULL && entities[ i ].patches == NULL ) continue; /* is this a clone? */ value = ValueForKey( &entities[ i ], "_clone" ); if( value[ 0 ] != '\0' ) continue; /* add the model key */ sprintf( modelValue, "*%d", models ); SetKeyValue( &entities[ i ], "model", modelValue ); /* increment model count */ models++; } /* fix up clones */ for( i = 1; i < numEntities; i++ ) { /* only entities with brushes or patches get a model number */ if( entities[ i ].brushes == NULL && entities[ i ].patches == NULL ) continue; /* is this a clone? */ value = ValueForKey( &entities[ i ], "_ins" ); if( value[ 0 ] == '\0' ) value = ValueForKey( &entities[ i ], "_instance" ); if( value[ 0 ] == '\0' ) value = ValueForKey( &entities[ i ], "_clone" ); if( value[ 0 ] == '\0' ) continue; /* find an entity with matching clone name */ for( j = 0; j < numEntities; j++ ) { /* is this a clone parent? */ value2 = ValueForKey( &entities[ j ], "_clonename" ); if( value2[ 0 ] == '\0' ) continue; /* do they match? */ if( strcmp( value, value2 ) == 0 ) { /* get the model num */ value3 = ValueForKey( &entities[ j ], "model" ); if( value3[ 0 ] == '\0' ) { Sys_Printf( "WARNING: Cloned entity %s referenced entity without model\n", value2 ); continue; } models = atoi( &value2[ 1 ] ); /* add the model key */ sprintf( modelValue, "*%d", models ); SetKeyValue( &entities[ i ], "model", modelValue ); /* nuke the brushes/patches for this entity (fixme: leak!) */ entities[ i ].brushes = NULL; entities[ i ].patches = NULL; } } } }
int ScaleBSPMain( int argc, char **argv ) { int i; float f, scale; vec3_t vec; char str[ 1024 ]; /* arg checking */ if( argc < 2 ) { Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" ); return 0; } /* get scale */ scale = atof( argv[ argc - 2 ] ); if( scale == 0.0f ) { Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" ); Sys_Printf( "Non-zero scale value required.\n" ); return 0; } /* do some path mangling */ strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); StripExtension( source ); DefaultExtension( source, ".bsp" ); /* load the bsp */ Sys_Printf( "Loading %s\n", source ); LoadBSPFile( source ); ParseEntities(); /* note it */ Sys_Printf( "--- ScaleBSP ---\n" ); Sys_FPrintf( SYS_VRB, "%9d entities\n", numEntities ); /* scale entity keys */ for( i = 0; i < numBSPEntities && i < numEntities; i++ ) { /* scale origin */ GetVectorForKey( &entities[ i ], "origin", vec ); if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) ) { VectorScale( vec, scale, vec ); sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ i ], "origin", str ); } /* scale door lip */ f = FloatForKey( &entities[ i ], "lip" ); if( f ) { f *= scale; sprintf( str, "%f", f ); SetKeyValue( &entities[ i ], "lip", str ); } } /* scale models */ for( i = 0; i < numBSPModels; i++ ) { VectorScale( bspModels[ i ].mins, scale, bspModels[ i ].mins ); VectorScale( bspModels[ i ].maxs, scale, bspModels[ i ].maxs ); } /* scale nodes */ for( i = 0; i < numBSPNodes; i++ ) { VectorScale( bspNodes[ i ].mins, scale, bspNodes[ i ].mins ); VectorScale( bspNodes[ i ].maxs, scale, bspNodes[ i ].maxs ); } /* scale leafs */ for( i = 0; i < numBSPLeafs; i++ ) { VectorScale( bspLeafs[ i ].mins, scale, bspLeafs[ i ].mins ); VectorScale( bspLeafs[ i ].maxs, scale, bspLeafs[ i ].maxs ); } /* scale drawverts */ for( i = 0; i < numBSPDrawVerts; i++ ) VectorScale( bspDrawVerts[ i ].xyz, scale, bspDrawVerts[ i ].xyz ); /* scale planes */ for( i = 0; i < numBSPPlanes; i++ ) bspPlanes[ i ].dist *= scale; /* scale gridsize */ GetVectorForKey( &entities[ 0 ], "gridsize", vec ); if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) == 0.0f ) VectorCopy( gridSize, vec ); VectorScale( vec, scale, vec ); sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ 0 ], "gridsize", str ); /* write the bsp */ UnparseEntities(); StripExtension( source ); DefaultExtension( source, "_s.bsp" ); Sys_Printf( "Writing %s\n", source ); WriteBSPFile( source ); /* return to sender */ return 0; }
/* ================= FinishBrush produces a final brush based on the buildBrush->sides array and links it to the current entity ================= */ brush_t *FinishBrush( void ) { brush_t *b; // create windings for sides and bounds for brush if( !CreateBrushWindings( buildBrush )) return NULL; // origin brushes are removed, but they set the rotation origin for the rest of the brushes in the entity. // after the entire entity is parsed, the planenums and texinfos will be adjusted for the origin brush if( buildBrush->compileFlags & C_ORIGIN ) { char string[32]; vec3_t size, movedir, origin; if( numEntities == 1 ) { Msg( "Entity %i, Brush %i: origin brushes not allowed in world\n", mapEnt->mapEntityNum, entitySourceBrushes ); return NULL; } // calcualte movedir (Xash 0.4 style) VectorAverage( buildBrush->mins, buildBrush->maxs, origin ); VectorSubtract( buildBrush->maxs, buildBrush->mins, size ); if( size[2] > size[0] && size[2] > size[1] ) VectorSet( movedir, 0.0f, 1.0f, 0.0f ); // x-rotate else if( size[1] > size[2] && size[1] > size[0] ) VectorSet( movedir, 1.0f, 0.0f, 0.0f ); // y-rotate else if( size[0] > size[2] && size[0] > size[1] ) VectorSet( movedir, 0.0f, 0.0f, 1.0f ); // z-rotate else VectorClear( movedir ); // custom movedir #if 0 if( !VectorIsNull( movedir )) { com.snprintf( string, sizeof( string ), "%i %i %i", (int)movedir[0], (int)movedir[1], (int)movedir[2] ); SetKeyValue( &entities[numEntities - 1], "movedir", string ); } #endif if(!VectorIsNull( origin )) { com.snprintf( string, sizeof( string ), "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2] ); SetKeyValue( &entities[numEntities - 1], "origin", string ); VectorCopy( origin, entities[numEntities - 1].origin ); } // don't keep this brush return NULL; } // determine if the brush is an area portal if( buildBrush->compileFlags & C_AREAPORTAL ) { if( numEntities != 1 ) { Msg( "Entity %i, Brush %i: areaportals only allowed in world\n", mapEnt->mapEntityNum, entitySourceBrushes ); return NULL; } } AddBrushBevels(); b = CopyBrush( buildBrush ); b->entityNum = mapEnt->mapEntityNum; b->brushNum = entitySourceBrushes; b->original = b; // link opaque brushes to head of list, translucent brushes to end if( b->opaque || mapEnt->lastBrush == NULL ) { b->next = mapEnt->brushes; mapEnt->brushes = b; if( mapEnt->lastBrush == NULL ) mapEnt->lastBrush = b; } else { b->next = NULL; mapEnt->lastBrush->next = b; mapEnt->lastBrush = b; } // link colorMod volume brushes to the entity directly if( b->contentShader != NULL && b->contentShader->colorMod != NULL && b->contentShader->colorMod->type == CM_VOLUME ) { b->nextColorModBrush = mapEnt->colorModBrushes; mapEnt->colorModBrushes = b; } return b; }
/* ================ ParseMapEntity ================ */ qboolean ParseMapEntity (void) { entity_t *mapent; epair_t *e; side_t *s; int i, j; int startbrush, startsides; vec_t newdist; mapbrush_t *b; if (!GetToken (true)) return false; if (strcmp (token, "{") ) Error ("ParseEntity: { not found"); if (num_entities == MAX_MAP_ENTITIES) Error ("num_entities == MAX_MAP_ENTITIES"); startbrush = nummapbrushes; startsides = nummapbrushsides; mapent = &entities[num_entities]; num_entities++; memset (mapent, 0, sizeof(*mapent)); mapent->firstbrush = nummapbrushes; mapent->numbrushes = 0; // mapent->portalareas[0] = -1; // mapent->portalareas[1] = -1; do { if (!GetToken (true)) Error ("ParseEntity: EOF without closing brace"); if (!strcmp (token, "}") ) break; if (!strcmp (token, "{") ) ParseBrush (mapent); else { e = ParseEpair (); e->next = mapent->epairs; mapent->epairs = e; } } while (1); GetVectorForKey (mapent, "origin", mapent->origin); // // if there was an origin brush, offset all of the planes and texinfo // if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2]) { for (i=0 ; i<mapent->numbrushes ; i++) { b = &mapbrushes[mapent->firstbrush + i]; for (j=0 ; j<b->numsides ; j++) { s = &b->original_sides[j]; newdist = mapplanes[s->planenum].dist - DotProduct (mapplanes[s->planenum].normal, mapent->origin); s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist); s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum], &side_brushtextures[s-brushsides], mapent->origin); } MakeBrushWindings (b); } } // group entities are just for editor convenience // toss all brushes into the world entity if (!strcmp ("func_group", ValueForKey (mapent, "classname"))) { MoveBrushesToWorld (mapent); mapent->numbrushes = 0; return true; } // areaportal entities move their brushes, but don't eliminate // the entity if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) { char str[128]; if (mapent->numbrushes != 1) Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1); b = &mapbrushes[nummapbrushes-1]; b->contents = CONTENTS_AREAPORTAL; c_areaportals++; mapent->areaportalnum = c_areaportals; // set the portal number as "style" sprintf (str, "%i", c_areaportals); SetKeyValue (mapent, "style", str); MoveBrushesToWorld (mapent); return true; } return true; }
void UpdateWadKeyPair( void ) { int i,nb; char wads[2048]; // change to CString usage ? wads[0] = 0; char *p1,*p2; entity_t *pEntity; epair_t *pEpair; GSList *wadlist = NULL; face_t *f; brush_t *b; char cleanwadname[QER_MAX_NAMELEN]; const char *actualwad; pEntity = (entity_t *)g_FuncTable.m_pfnGetEntityHandle(0); // get the worldspawn ent Sys_Printf("Searching for in-use wad files...\n"); for(pEpair = pEntity->epairs; pEpair != NULL; pEpair = pEpair->next) { if (stricmp(pEpair->key,"wad") == 0) { strcpy(wads,pEpair->value); ConvertDOSToUnixName(wads,wads); // ok, we got the list of ; delimited wads, now split it into a GSList that contains // just the wad names themselves. p1 = wads; do { p2 = strchr(p1,';'); if (p2) *p2 = 0; // swap the ; with a null terminator if (strchr(p1,'/') || strchr(p1,'\\')) { ExtractFileName(p1,cleanwadname); wadlist = AddToWadList (wadlist, NULL, cleanwadname); } else { wadlist = AddToWadList (wadlist, NULL, p1); } if (p2) p1 = p2+1; // point back to the remainder of the string else p1 = NULL; // make it so we exit the loop. } while (p1); // ok, now we have a list of wads in GSList. // now we need to add any new wadfiles (with their paths) to this list // so scan all brushes and see what wads are in use // FIXME: scan brushes only in the region ? break; // we don't need to process any more key/pairs. } } nb = g_FuncTable.m_pfnAllocateActiveBrushHandles(); for( i = 0; i < nb; i++ ) { b = (brush_t *)g_FuncTable.m_pfnGetActiveBrushHandle(i); if (b->patchBrush) // patches in halflife ? { wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL); } else { for (f=b->brush_faces ; f ; f=f->next) { wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL); } } } g_FuncTable.m_pfnReleaseActiveBrushHandles(); nb = g_FuncTable.m_pfnAllocateSelectedBrushHandles(); for( i = 0; i < nb; i++ ) { b = (brush_t *)g_FuncTable.m_pfnGetSelectedBrushHandle(i); if (b->patchBrush) // patches in halflife ? { wadlist = AddToWadList(wadlist, b->pPatch->pShader->getName(),NULL); } else { for (f=b->brush_faces ; f ; f=f->next) { wadlist = AddToWadList(wadlist, f->pShader->getName(),NULL); } } } g_FuncTable.m_pfnReleaseSelectedBrushHandles(); // Now we have a complete list of wadnames (without paths) so we just have to turn this // back to a ; delimited list. wads[0] = 0; while (wadlist) { if (stricmp((char *)wadlist->data,"common-hydra.wad") == 0) { Sys_Printf("Skipping radiant-supplied wad file %s\n",(char *)wadlist->data); } else { if (wads[0]) strcat(wads,";"); actualwad = vfsGetFullPath((char *)wadlist->data); if (actualwad) { strcat(wads, actualwad); } else { Sys_Printf("WARNING: could not locate wad file %s\n",(char *)wadlist->data); strcat(wads, (char *)wadlist->data); } } free (wadlist->data); wadlist = g_slist_remove (wadlist, wadlist->data); } // store the wad list back in the worldspawn. if (wads[0]) { //free(pEpair->value); //pEpair->value = strdup(wads); SetKeyValue(pEntity, "wad", wads); } }
/* ================= ParseBrush ================= */ void ParseBrush (entity_t *mapent) { mapbrush_t *b; int i,j, k; int mt; side_t *side, *s2; int planenum; brush_texture_t td; int planepts[3][3]; if (nummapbrushes == MAX_MAP_BRUSHES) Error ("nummapbrushes == MAX_MAP_BRUSHES"); b = &mapbrushes[nummapbrushes]; b->original_sides = &brushsides[nummapbrushsides]; b->entitynum = num_entities-1; b->brushnum = nummapbrushes - mapent->firstbrush; do { if (!GetToken (true)) break; if (!strcmp (token, "}") ) break; if (nummapbrushsides == MAX_MAP_BRUSHSIDES) Error ("MAX_MAP_BRUSHSIDES"); side = &brushsides[nummapbrushsides]; // read the three point plane definition for (i=0 ; i<3 ; i++) { if (i != 0) GetToken (true); if (strcmp (token, "(") ) Error ("parsing brush"); for (j=0 ; j<3 ; j++) { GetToken (false); planepts[i][j] = atoi(token); } GetToken (false); if (strcmp (token, ")") ) Error ("parsing brush"); } // // read the texturedef // GetToken (false); strcpy (td.name, token); GetToken (false); td.shift[0] = atoi(token); GetToken (false); td.shift[1] = atoi(token); GetToken (false); td.rotate = atoi(token); GetToken (false); td.scale[0] = atof(token); GetToken (false); td.scale[1] = atof(token); // find default flags and values mt = FindMiptex (td.name); td.flags = textureref[mt].flags; td.value = textureref[mt].value; side->contents = textureref[mt].contents; side->surf = td.flags = textureref[mt].flags; if (TokenAvailable()) { GetToken (false); side->contents = atoi(token); GetToken (false); side->surf = td.flags = atoi(token); GetToken (false); td.value = atoi(token); } // translucent objects are automatically classified as detail if (side->surf & (SURF_TRANS33|SURF_TRANS66) ) side->contents |= CONTENTS_DETAIL; if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) side->contents |= CONTENTS_DETAIL; if (fulldetail) side->contents &= ~CONTENTS_DETAIL; if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) ) side->contents |= CONTENTS_SOLID; // hints and skips are never detail, and have no content if (side->surf & (SURF_HINT|SURF_SKIP) ) { side->contents = 0; side->surf &= ~CONTENTS_DETAIL; } // // find the plane number // planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]); if (planenum == -1) { printf ("Entity %i, Brush %i: plane with no normal\n" , b->entitynum, b->brushnum); continue; } // // see if the plane has been used already // for (k=0 ; k<b->numsides ; k++) { s2 = b->original_sides + k; if (s2->planenum == planenum) { printf ("Entity %i, Brush %i: duplicate plane\n" , b->entitynum, b->brushnum); break; } if ( s2->planenum == (planenum^1) ) { printf ("Entity %i, Brush %i: mirrored plane\n" , b->entitynum, b->brushnum); break; } } if (k != b->numsides) continue; // duplicated // // keep this side // side = b->original_sides + b->numsides; side->planenum = planenum; side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum], &td, vec3_origin); // save the td off in case there is an origin brush and we // have to recalculate the texinfo side_brushtextures[nummapbrushsides] = td; nummapbrushsides++; b->numsides++; } while (1); // get the content for the entire brush b->contents = BrushContents (b); // allow detail brushes to be removed if (nodetail && (b->contents & CONTENTS_DETAIL) ) { b->numsides = 0; return; } // allow water brushes to be removed if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ) { b->numsides = 0; return; } // create windings for sides and bounds for brush MakeBrushWindings (b); // brushes that will not be visible at all will never be // used as bsp splitters if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) { c_clipbrushes++; for (i=0 ; i<b->numsides ; i++) b->original_sides[i].texinfo = TEXINFO_NODE; } // // origin brushes are removed, but they set // the rotation origin for the rest of the brushes // in the entity. After the entire entity is parsed, // the planenums and texinfos will be adjusted for // the origin brush // if (b->contents & CONTENTS_ORIGIN) { char string[32]; vec3_t origin; if (num_entities == 1) { Error ("Entity %i, Brush %i: origin brushes not allowed in world" , b->entitynum, b->brushnum); return; } VectorAdd (b->mins, b->maxs, origin); VectorScale (origin, 0.5, origin); sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue (&entities[b->entitynum], "origin", string); VectorCopy (origin, entities[b->entitynum].origin); // don't keep this brush b->numsides = 0; return; } AddBrushBevels (b); nummapbrushes++; mapent->numbrushes++; }
// this function is called in place of tex_initfromwad for onlyents compiles void HandleWadinclude() { int i; char szTmpWad[1024]; // arbitrary, but needs to be large. char* pszWadFile; wadpath_t* currentwad; Log("\n"); // looks cleaner szTmpWad[0] = 0; #ifdef HLCSG_AUTOWAD if (g_bWadAutoDetect) { autowad_UpdateUsedWads(); } #endif // for eachwadpath for (i = 0; i < g_iNumWadPaths; i++) { bool bExcludeThisWad = false; currentwad = g_pWadPaths[i]; pszWadFile = currentwad->path; #ifdef HLCSG_AUTOWAD/* #ifdef _DEBUG Log("[dbg] HandleWIC: attempting to parse wad '%s'\n", currentwad->path); #endif*/ if (g_bWadAutoDetect && !currentwad->usedtextures) continue;/* #ifdef _DEBUG Log("[dbg] HandleWIC: parsing wad\n"); #endif*/ #endif // HLCSG_AUTOWAD // look and see if we're supposed to include the textures from this WAD in the bsp. WadInclude_i it; for (it = g_WadInclude.begin(); it != g_WadInclude.end(); it++) { if (stristr(pszWadFile, it->c_str())) { Log("Including Wadfile: %s\n", pszWadFile); bExcludeThisWad = true; // wadincluding this one } } if (!bExcludeThisWad) { Log("Using Wadfile: %s\n", pszWadFile); #ifdef HLCSG_STRIPWADPATH char tmp[_MAX_PATH]; ExtractFile (pszWadFile, tmp); safe_snprintf(szTmpWad, 1024, "%s%s;", szTmpWad, tmp); #else safe_snprintf(szTmpWad, 1024, "%s%s;", szTmpWad, pszWadFile); #endif } } Log("\"wad\" is \"%s\"\n", szTmpWad); SetKeyValue(&g_entities[0], "wad", szTmpWad); Log("\n"); CheckFatal(); }
/* =========== QE_LoadProject NOTE: rather than bumping "version", consider bumping "template_version" (see above) NOTE: when QE_LoadProject is called, the prefs are updated with path to the latest project and saved on disk =========== */ bool QE_LoadProject( const char *projectfile ){ char buf[1024]; xmlDocPtr doc; xmlNodePtr node, project; Sys_Printf( "Loading project file: \"%s\"\n", projectfile ); doc = ParseXMLFile( projectfile, true ); if ( doc == NULL ) { return false; } node = doc->children; while ( node != NULL && node->type != XML_DTD_NODE ) node = node->next; if ( node == NULL || strcmp( (char*)node->name, "project" ) != 0 ) { Sys_FPrintf( SYS_ERR, "ERROR: invalid file type\n" ); return false; } while ( node->type != XML_ELEMENT_NODE ) node = node->next; // <project> project = node; if ( g_qeglobals.d_project_entity != NULL ) { Entity_Free( g_qeglobals.d_project_entity ); } g_qeglobals.d_project_entity = Entity_Alloc(); for ( node = project->children; node != NULL; node = node->next ) { if ( node->type != XML_ELEMENT_NODE ) { continue; } // <key> ReplaceTemplates( buf, (char*)node->properties->next->children->content ); SetKeyValue( g_qeglobals.d_project_entity, (char*)node->properties->children->content, buf ); } xmlFreeDoc( doc ); // project file version checking // add a version checking to avoid people loading later versions of the project file and bitching int ver = IntForKey( g_qeglobals.d_project_entity, "version" ); if ( ver > PROJECT_VERSION ) { char strMsg[1024]; sprintf( strMsg, "This is a version %d project file. This build only supports <=%d project files.\n" "Please choose another project file or upgrade your version of Radiant.", ver, PROJECT_VERSION ); gtk_MessageBox( g_pParentWnd->m_pWidget, strMsg, "Can't load project file", MB_ICONERROR | MB_OK ); // set the project file to nothing so we are sure we'll ask next time? g_PrefsDlg.m_strLastProject = ""; g_PrefsDlg.SavePrefs(); return false; } // set here some default project settings you need if ( strlen( ValueForKey( g_qeglobals.d_project_entity, "brush_primit" ) ) == 0 ) { SetKeyValue( g_qeglobals.d_project_entity, "brush_primit", "0" ); } g_qeglobals.m_bBrushPrimitMode = IntForKey( g_qeglobals.d_project_entity, "brush_primit" ); g_qeglobals.m_strHomeMaps = g_qeglobals.m_strHomeGame; const char* str = ValueForKey( g_qeglobals.d_project_entity, "gamename" ); if ( str[0] == '\0' ) { str = g_pGameDescription->mBaseGame.GetBuffer(); } g_qeglobals.m_strHomeMaps += str; g_qeglobals.m_strHomeMaps += '/'; // don't forget to create the dirs Q_mkdir( g_qeglobals.m_strHomeGame.GetBuffer(), 0775 ); Q_mkdir( g_qeglobals.m_strHomeMaps.GetBuffer(), 0775 ); // usefull for the log file and debuggin f****d up configurations from users: // output the basic information of the .qe4 project file // SPoG // all these paths should be unix format, with a trailing slash at the end // if not.. to debug, check that the project file paths are set up correctly Sys_Printf( "basepath : %s\n", ValueForKey( g_qeglobals.d_project_entity, "basepath" ) ); Sys_Printf( "entitypath : %s\n", ValueForKey( g_qeglobals.d_project_entity, "entitypath" ) ); // check whether user_project key exists.. // if not, save the current project under a new name if ( ValueForKey( g_qeglobals.d_project_entity, "user_project" )[0] == '\0' ) { Sys_Printf( "Loaded a template project file\n" ); // create the user_project key SetKeyValue( g_qeglobals.d_project_entity, "user_project", "1" ); if ( IntForKey( g_qeglobals.d_project_entity, "version" ) != PROJECT_VERSION ) { char strMsg[2048]; sprintf( strMsg, "The template project '%s' has version %d. The editor binary is configured for version %d.\n" "This indicates a problem in your setup.\n" "I will keep going with this project till you fix this", projectfile, IntForKey( g_qeglobals.d_project_entity, "version" ), PROJECT_VERSION ); gtk_MessageBox( g_pParentWnd->m_pWidget, strMsg, "Can't load project file", MB_ICONERROR | MB_OK ); } // create the writable project file path strcpy( buf, g_qeglobals.m_strHomeGame.GetBuffer() ); strcat( buf, g_pGameDescription->mBaseGame.GetBuffer() ); strcat( buf, "/scripts/" ); // while the filename is already in use, increment the number we add to the end int counter = 0; char pUser[PATH_MAX]; while ( 1 ) { sprintf( pUser, "%suser%d." PROJECT_FILETYPE, buf, counter ); counter++; if ( access( pUser, R_OK ) != 0 ) { // this is the one strcpy( buf, pUser ); break; } } // saving project will cause a save prefs g_PrefsDlg.m_strLastProject = buf; g_PrefsDlg.m_nLastProjectVer = IntForKey( g_qeglobals.d_project_entity, "version" ); QE_SaveProject( buf ); } else { // update preferences::LastProject with path of this successfully-loaded project // save preferences Sys_Printf( "Setting current project in prefs to \"%s\"\n", g_PrefsDlg.m_strLastProject.GetBuffer() ); g_PrefsDlg.m_strLastProject = projectfile; g_PrefsDlg.SavePrefs(); } return true; }
/* =========== AddRegionBrushes a regioned map will have temp walls put up at the region boundary \todo TODO TTimo old implementation of region brushes we still add them straight in the worldspawn and take them out after the map is saved with the new implementation we should be able to append them in a temporary manner to the data we pass to the map module =========== */ void AddRegionBrushes( void ){ vec3_t mins, maxs; int i; texdef_t td; if ( !region_active ) { #ifdef _DEBUG Sys_FPrintf( SYS_WRN, "Unexpected AddRegionBrushes call.\n" ); #endif return; } memset( &td, 0, sizeof( td ) ); td.SetName( SHADER_NOT_FOUND ); // set mins VectorSet( mins, region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 ); // vary maxs for ( i = 0; i < 3; i++ ) { VectorSet( maxs, region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 ); maxs[i] = region_mins[i]; region_sides[i] = Brush_Create( mins, maxs, &td ); } // set maxs VectorSet( maxs, region_maxs[0] + 32, region_maxs[1] + 32, region_maxs[2] + 32 ); // vary mins for ( i = 0; i < 3; i++ ) { VectorSet( mins, region_mins[0] - 32, region_mins[1] - 32, region_mins[2] - 32 ); mins[i] = region_maxs[i]; region_sides[i + 3] = Brush_Create( mins, maxs, &td ); } // this is a safe check, but it should not really happen anymore vec3_t vOrig; VectorSet( vOrig, (int)g_pParentWnd->GetCamWnd()->Camera()->origin[0], (int)g_pParentWnd->GetCamWnd()->Camera()->origin[1], (int)g_pParentWnd->GetCamWnd()->Camera()->origin[2] ); for ( i = 0 ; i < 3 ; i++ ) { if ( vOrig[i] > region_maxs[i] || vOrig[i] < region_mins[i] ) { Sys_FPrintf( SYS_ERR, "Camera is NOT in the region, it's likely that the region won't compile correctly\n" ); } } // write the info_playerstart region_startpoint = Entity_Alloc(); SetKeyValue( region_startpoint, "classname", "info_player_start" ); region_startpoint->eclass = Eclass_ForName( "info_player_start", false ); char sTmp[1024]; sprintf( sTmp, "%d %d %d", (int)vOrig[0], (int)vOrig[1], (int)vOrig[2] ); SetKeyValue( region_startpoint, "origin", sTmp ); sprintf( sTmp, "%d", (int)g_pParentWnd->GetCamWnd()->Camera()->angles[YAW] ); SetKeyValue( region_startpoint, "angle", sTmp ); // empty array of children region_startpoint->pData = new CPtrArray; }
/* ======================================================================================================================= 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]); }