// // ======================================================================================================================= // Entity_WriteSelected to a CMemFile // ======================================================================================================================= // void Entity_WriteSelected(entity_t *e, CMemFile *pMemFile) { brush_t *b; idVec3 origin; char text[128]; int count; for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { if (IsBrushSelected(b)) { break; // got one } } if (b == &e->brushes) { return; // nothing selected } // if fixedsize, calculate a new origin based on the current brush position if (e->eclass->fixedsize || EntityHasModel(e)) { if (!GetVectorForKey(e, "origin", origin)) { VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); } } MemFile_fprintf(pMemFile, "{\n"); count = e->epairs.GetNumKeyVals(); for (int j = 0; j < count; j++) { MemFile_fprintf(pMemFile, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str()); } if (!EntityHasModel(e)) { count = 0; for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { if (e->eclass->fixedsize && !b->entityModel) { continue; } if (IsBrushSelected(b)) { MemFile_fprintf(pMemFile, "// brush %i\n", count); count++; Brush_Write( b, pMemFile, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) ); } } } MemFile_fprintf(pMemFile, "}\n"); }
idMapEntity *EntityToMapEntity(entity_t *e, bool use_region, CWaitDlg *dlg) { idMapEntity *mapent = new idMapEntity; mapent->epairs = e->epairs; idStr status; int count = 0; long lastUpdate = 0; if ( !EntityHasModel( e ) ) { for ( brush_t *b = e->brushes.onext; b != &e->brushes; b = b->onext ) { count++; if ( e->eclass->fixedsize && !b->entityModel ) { continue; } if ( !use_region || !Map_IsBrushFiltered( b ) ) { // Update 20 times a second if ( GetTickCount() - lastUpdate > 50 ) { lastUpdate = GetTickCount(); if ( b->pPatch ) { sprintf( status, "Adding primitive %i (patch)", count ); dlg->SetText( status, true ); } else { sprintf( status, "Adding primitive %i (brush)", count ); dlg->SetText( status, true ); } } idMapPrimitive *prim = BrushToMapPrimitive( b, e->origin ); if ( prim ) { mapent->AddPrimitive( prim ); } } } } return mapent; }
/* ======================================================================================================================= ======================================================================================================================= */ void TrackMD3Angles(entity_t *e, const char *key, const char *value) { if ( idStr::Icmp(key, "angle") != 0 ) { return; } if ((e->eclass->fixedsize && e->eclass->nShowFlags & ECLASS_MISCMODEL) || EntityHasModel(e)) { float a = FloatForKey(e, "angle"); float b = atof(value); if (a != b) { idVec3 vAngle; vAngle[0] = vAngle[1] = 0; vAngle[2] = -a; Brush_Rotate(e->brushes.onext, vAngle, e->origin, true); vAngle[2] = b; Brush_Rotate(e->brushes.onext, vAngle, e->origin, true); } } }
entity_t *Entity_PostParse(entity_t *ent, brush_t *pList) { bool has_brushes; eclass_t *e; brush_t *b; idVec3 mins, maxs, zero; idBounds bo; zero.Zero(); Entity_SetCurveData( ent ); if (ent->brushes.onext == &ent->brushes) { has_brushes = false; } else { has_brushes = true; } bool needsOrigin = !GetVectorForKey(ent, "origin", ent->origin); const char *pModel = ValueForKey(ent, "model"); const char *cp = ValueForKey(ent, "classname"); if (strlen(cp)) { e = Eclass_ForName(cp, has_brushes); } else { const char *cp2 = ValueForKey(ent, "name"); if (strlen(cp2)) { char buff[1024]; strcpy(buff, cp2); int len = strlen(buff); while ((isdigit(buff[len-1]) || buff[len-1] == '_') && len > 0) { buff[len-1] = '\0'; len--; } e = Eclass_ForName(buff, has_brushes); SetKeyValue(ent, "classname", buff, false); } else { e = Eclass_ForName("", has_brushes); } } idStr str; if (e->defArgs.GetString("model", "", str) && e->entityModel == NULL) { e->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &e->defArgs ); } ent->eclass = e; bool hasModel = EntityHasModel(ent); if (hasModel) { ent->eclass->defArgs.GetString("model", "", str); if (str.Length()) { hasModel = false; ent->epairs.Delete("model"); } } if (e->nShowFlags & ECLASS_WORLDSPAWN) { ent->origin.Zero(); needsOrigin = false; ent->epairs.Delete( "model" ); } else if (e->nShowFlags & ECLASS_LIGHT) { if (GetVectorForKey(ent, "light_origin", ent->lightOrigin)) { GetMatrixForKey(ent, "light_rotation", ent->lightRotation); ent->trackLightOrigin = true; } else if (hasModel) { SetKeyValue(ent, "light_origin", ValueForKey(ent, "origin")); ent->lightOrigin = ent->origin; if (GetMatrixForKey(ent, "rotation", ent->lightRotation)) { SetKeyValue(ent, "light_rotation", ValueForKey(ent, "rotation")); } ent->trackLightOrigin = true; } } else if ( e->nShowFlags & ECLASS_ENV ) { // need to create an origin from the bones here idVec3 org; idAngles ang; bo.Clear(); bool hasBody = false; const idKeyValue *arg = ent->epairs.MatchPrefix( "body ", NULL ); while ( arg ) { sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll ); bo.AddPoint( org ); arg = ent->epairs.MatchPrefix( "body ", arg ); hasBody = true; } if (hasBody) { ent->origin = bo.GetCenter(); } } if (e->fixedsize || hasModel) // fixed size entity { if (ent->brushes.onext != &ent->brushes) { for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { b->entityModel = true; } } if (hasModel) { // model entity idRenderModel *modelHandle = renderModelManager->FindModel( pModel ); if ( dynamic_cast<idRenderModelPrt*>( modelHandle ) || dynamic_cast<idRenderModelLiquid*>( modelHandle ) ) { bo.Zero(); bo.ExpandSelf( 12.0f ); } else { bo = modelHandle->Bounds( NULL ); } VectorCopy(bo[0], mins); VectorCopy(bo[1], maxs); for (int i = 0; i < 3; i++) { if (mins[i] == maxs[i]) { mins[i]--; maxs[i]++; } } VectorAdd(mins, ent->origin, mins); VectorAdd(maxs, ent->origin, maxs); b = Brush_Create(mins, maxs, &e->texdef); b->modelHandle = modelHandle; float yaw = 0; bool convertAngles = GetFloatForKey(ent, "angle", &yaw); extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild); extern void Brush_Rotate(brush_t *b, idVec3 rot, idVec3 origin, bool bBuild); if (convertAngles) { idVec3 rot(0, 0, yaw); Brush_Rotate(b, rot, ent->origin, false); } if (GetMatrixForKey(ent, "rotation", ent->rotation)) { idBounds bo2; bo2.FromTransformedBounds(bo, ent->origin, ent->rotation); b->owner = ent; Brush_Resize(b, bo2[0], bo2[1]); } Entity_LinkBrush(ent, b); } if (!hasModel || (ent->eclass->nShowFlags & ECLASS_LIGHT && hasModel)) { // create a custom brush if (ent->trackLightOrigin) { mins = e->mins + ent->lightOrigin; maxs = e->maxs + ent->lightOrigin; } else { mins = e->mins + ent->origin; maxs = e->maxs + ent->origin; } b = Brush_Create(mins, maxs, &e->texdef); GetMatrixForKey(ent, "rotation", ent->rotation); Entity_LinkBrush(ent, b); b->trackLightOrigin = ent->trackLightOrigin; if ( e->texdef.name == NULL ) { brushprimit_texdef_t bp; texdef_t td; td.SetName( ent->eclass->defMaterial ); Brush_SetTexture( b, &td, &bp, false ); } } } else // brush entity { if (ent->brushes.next == &ent->brushes) { printf("Warning: Brush entity with no brushes\n"); } if (!needsOrigin) { idStr cn = ValueForKey(ent, "classname"); idStr name = ValueForKey(ent, "name"); idStr model = ValueForKey(ent, "model"); if (cn.Icmp("func_static") == 0) { if (name.Icmp(model) == 0) { needsOrigin = true; } } } if (needsOrigin) { idVec3 mins, maxs, mid; int i; char text[32]; mins[0] = mins[1] = mins[2] = 999999; maxs[0] = maxs[1] = maxs[2] = -999999; // add in the origin for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { Brush_Build(b, true, false, false); for (i = 0; i < 3; i++) { if (b->mins[i] < mins[i]) { mins[i] = b->mins[i]; } if (b->maxs[i] > maxs[i]) { maxs[i] = b->maxs[i]; } } } for (i = 0; i < 3; i++) { ent->origin[i] = (mins[i] + ((maxs[i] - mins[i]) / 2)); } sprintf(text, "%i %i %i", (int)ent->origin[0], (int)ent->origin[1], (int)ent->origin[2]); SetKeyValue(ent, "origin", text); } if (!(e->nShowFlags & ECLASS_WORLDSPAWN)) { if (e->defArgs.FindKey("model") == NULL && (pModel == NULL || (pModel && strlen(pModel) == 0))) { SetKeyValue(ent, "model", ValueForKey(ent, "name")); } } else { DeleteKey(ent, "origin"); } } // add all the brushes to the main list if (pList) { for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { b->next = pList->next; pList->next->prev = b; b->prev = pList; pList->next = b; } } FixFloats(&ent->epairs); return ent; }
/* ======================================================================================================================= Entity_Write ======================================================================================================================= */ void Entity_Write(entity_t *e, FILE *f, bool use_region) { brush_t *b; idVec3 origin; char text[128]; int count; // if none of the entities brushes are in the region, don't write the entity at all if (use_region) { // in region mode, save the camera position as playerstart if (!strcmp(ValueForKey(e, "classname"), "info_player_start")) { fprintf(f, "{\n"); fprintf(f, "\"classname\" \"info_player_start\"\n"); fprintf ( f, "\"origin\" \"%i %i %i\"\n", (int)g_pParentWnd->GetCamera()->Camera().origin[0], (int)g_pParentWnd->GetCamera()->Camera().origin[1], (int)g_pParentWnd->GetCamera()->Camera().origin[2] ); fprintf(f, "\"angle\" \"%i\"\n", (int)g_pParentWnd->GetCamera()->Camera().angles[YAW]); fprintf(f, "}\n"); return; } for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { if (!Map_IsBrushFiltered(b)) { break; // got one } } if (b == &e->brushes) { return; // nothing visible } } if (e->eclass->nShowFlags & ECLASS_PLUGINENTITY) { // NOTE: the whole brush placement / origin stuff is a mess VectorCopy(e->origin, origin); sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); } // if fixedsize, calculate a new origin based on the current brush position else if (e->eclass->fixedsize || EntityHasModel(e)) { if (!GetVectorForKey(e, "origin", origin)) { VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); } } fprintf(f, "{\n"); count = e->epairs.GetNumKeyVals(); for (int j = 0; j < count; j++) { fprintf(f, "\"%s\" \"%s\"\n", e->epairs.GetKeyVal(j)->GetKey().c_str(), e->epairs.GetKeyVal(j)->GetValue().c_str()); } if (!EntityHasModel(e)) { count = 0; for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { if (e->eclass->fixedsize && !b->entityModel) { continue; } if (!use_region || !Map_IsBrushFiltered(b)) { fprintf(f, "// brush %i\n", count); count++; Brush_Write( b, f, e->origin, ( g_PrefsDlg.m_bNewMapFormat != FALSE ) ); } } } fprintf(f, "}\n"); }