Tweaked makeZooMapForModels cmd with better sorting

This commit is contained in:
Robert Beckebans 2022-02-25 22:14:45 +01:00
parent 9cc5fa7a3a
commit 75d55a7ed3

View file

@ -2778,171 +2778,6 @@ void idDeclManagerLocal::ExportDeclsToTrenchBroom_f( const idCmdArgs& args )
common->FatalError( "Exporting successful, need to restart manually" );
}
void idDeclManagerLocal::ExportModelsToTrenchBroom_f( const idCmdArgs& args )
{
extern idCVar postLoadExportModels;
postLoadExportModels.SetBool( true );
// avoid media cache
com_editors |= EDITOR_EXPORTDEFS;
int totalModelsCount = 0;
int totalEntitiesCount = 0;
idFileList* files = fileSystem->ListFilesTree( "generated", ".blwo|.base|.bmd5mesh", true, true );
idStr fgdFileName;
fgdFileName.Format( "exported/_tb/DOOM-3-models.fgd" );
idFileLocal fgdFile( fileSystem->OpenFileWrite( fgdFileName, "fs_basepath" ) );
if( fgdFile == NULL )
{
common->Printf( "Failed to write entity declarations data to FGD.\n" );
}
fgdFile->Printf( "// DOOM 3 BFG models definition file (.fgd) generated by %s\n\n", ENGINE_VERSION );
fgdFile->Printf( "@BaseClass color(0 127 204) = auto_generated_model : \"Just a model\"\n[\n" );
//fgdFile->Printf( "name(string) : \"\" : \"\"\n" );
fgdFile->Printf( "\t spawnclass(string) : \"\" : \"idStaticEntity\"\n" );
fgdFile->Printf( "\t solid(boolean) : \"whether the object should be solid or not.\" : 1\n" );
fgdFile->Printf( "\t noclipmodel(boolean) : \"0 by default. Sets whether or not to generate a collision model for an ASE/LWO func_static at level load. (Set to 1 for stuff the player can't interact with. This will save memory.)\" : 0\n" );
fgdFile->Printf( "\t hide(boolean) : \"whether the object should be visible when spawned. you need to set a value for triggering on/off to work\"\n" );
fgdFile->Printf( "\t gui_noninteractive(boolean) : \"any gui attached will not be interactive\"\n" );
fgdFile->Printf( "\t inline(boolean) : \"If true, turn the model into map geometry at dmap time\"\n" );
fgdFile->Printf( "\t angles(string) : \"\" : \"0 0 0\"\n" );
fgdFile->Printf( "\t gui(string) : \"gui attached to this static, gui2 and gui3 also work\"\n" );
fgdFile->Printf( "\t gui_demonic(string) : \"demonic gui attached to this statit, gui_demonic2 and gui_demonic3 also work\"\n]\n\n" );
for( int f = 0; f < files->GetList().Num(); f++ )
{
totalModelsCount++;
idStr modelName = files->GetList()[ f ];
modelName.StripLeadingOnce( "generated/rendermodels/" );
idStr ext;
modelName.ExtractFileExtension( ext );
bool dynamicModel = false;
if( ext.Icmp( "blwo" ) == 0 )
{
modelName.SetFileExtension( "lwo" );
}
if( ext.Icmp( "base" ) == 0 )
{
modelName.SetFileExtension( "ase" );
}
if( ext.Icmp( "bdae" ) == 0 )
{
modelName.SetFileExtension( "dae" );
}
if( ext.Icmp( "bmd5mesh" ) == 0 )
{
modelName.SetFileExtension( "md5mesh" );
dynamicModel = true;
}
idLib::Printf( "Exporting model '%s'\n", modelName.c_str() );
// make an OBJ version of the model for TrenchBroom
idRenderModel* renderModel = renderModelManager->FindModel( modelName );
#if 1
if( idStr::Icmpn( modelName, "models/mapobjects", 17 ) != 0 )
{
continue;
}
#endif
if( idStr::Icmpn( modelName, "models/items", 12 ) == 0 )
{
continue;
}
if( idStr::Icmpn( modelName, "models/particles", 16 ) == 0 )
{
continue;
}
if( idStr::Icmpn( modelName, "models/weapons", 14 ) == 0 )
{
continue;
}
idBounds bounds = renderModel->Bounds();
// put model as mapobject into the models FGD
if( !renderModel->IsDefaultModel() && bounds.GetVolume() > 0 && bounds.GetRadius() < 1400 )
{
idStrStatic< MAX_OSPATH > exportedModelFileName;
exportedModelFileName = "_tb/";
exportedModelFileName.AppendPath( modelName );
exportedModelFileName.SetFileExtension( ".obj" );
idStrStatic< MAX_OSPATH > entityName;
if( idStr::Icmpn( modelName, "models/mapobjects", 17 ) == 0 )
{
modelName.StripLeadingOnce( "models/mapobjects" );
entityName = "mob";
entityName.AppendPath( modelName );
}
else
{
modelName.StripLeadingOnce( "models/" );
entityName = "mdl";
entityName.AppendPath( modelName );
}
entityName.BackSlashesToSlashes();
entityName.ReplaceChar( '/', '_' );
entityName.ReplaceChar( '(', '_' );
entityName.ReplaceChar( ')', '_' );
entityName.StripFileExtension();
fgdFile->Printf( "@PointClass " );
#if 0
if( bounds.GetVolume() > 0 )
{
fgdFile->Printf( "size(%i %i %i, %i %i %i) ",
int( bounds[0].x ), int( bounds[0].y ), int( bounds[0].z ),
int( bounds[1].x ), int( bounds[1].y ), int( bounds[1].z ) );
}
#endif
fgdFile->Printf( "base(auto_generated_model) model({ \"path\": \"%s\" }) = %s : \"Just a model\" []\n", exportedModelFileName.c_str(), entityName.c_str() );
//fgdFile->Printf( "[\n\t angles(string) : \"\" : \"0 0 0\"\n]\n\n", exportedModelFileName.c_str() );
totalEntitiesCount++;
}
}
fileSystem->FreeFileList( files );
com_editors &= ~EDITOR_EXPORTDEFS;
postLoadExportModels.SetBool( false );
fgdFile->Flush();
common->Printf( "\nFGD written to %s\n", fgdFileName.c_str() );
common->Printf( "----------------------------\n" );
common->Printf( "Wrote %d Entities.\n", totalEntitiesCount );
common->Printf( "Wrote %d Models.\n", totalModelsCount );
common->FatalError( "Exporting successful, need to restart manually" );
}
void idDeclManagerLocal::ExportImagesToTrenchBroom_f( const idCmdArgs& args )
{
int totalImagesCount = 0;
@ -3140,6 +2975,195 @@ void idDeclManagerLocal::ExportImagesToTrenchBroom_f( const idCmdArgs& args )
}
void idDeclManagerLocal::ExportModelsToTrenchBroom_f( const idCmdArgs& args )
{
extern idCVar postLoadExportModels;
postLoadExportModels.SetBool( true );
// avoid media cache
com_editors |= EDITOR_EXPORTDEFS;
int totalModelsCount = 0;
int totalEntitiesCount = 0;
idFileList* files = fileSystem->ListFilesTree( "generated", ".blwo|.base|.bmd5mesh", true, true );
idStr fgdFileName;
fgdFileName.Format( "exported/_tb/DOOM-3-models.fgd" );
idFileLocal fgdFile( fileSystem->OpenFileWrite( fgdFileName, "fs_basepath" ) );
if( fgdFile == NULL )
{
common->Printf( "Failed to write entity declarations data to FGD.\n" );
}
fgdFile->Printf( "// DOOM 3 BFG models definition file (.fgd) generated by %s\n\n", ENGINE_VERSION );
fgdFile->Printf( "@SolidClass color(0 0 0) = worldspawn : \"Every map should have exactly one worldspawn.\"\n[\n" );
fgdFile->Printf( "\t spawnclass(string) : \"\" : \"idWorldspawn\"\n" );
fgdFile->Printf( "]\n\n" );
fgdFile->Printf( "@SolidClass color(0 127 204) = func_static : \"A brush model that just sits there, doing nothing. Can be used for conditional walls and models. When triggered, toggles between visible and hidden (see hide). Entity is non-solid when hidden.\"\n[\n" );
//fgdFile->Printf( "name(string) : \"\" : \"\"\n" );
fgdFile->Printf( "\t spawnclass(string) : \"\" : \"idStaticEntity\"\n" );
fgdFile->Printf( "\t solid(boolean) : \"whether the object should be solid or not.\" : 1\n" );
fgdFile->Printf( "\t noclipmodel(boolean) : \"0 by default. Sets whether or not to generate a collision model for an ASE/LWO func_static at level load. (Set to 1 for stuff the player can't interact with. This will save memory.)\" : 0\n" );
fgdFile->Printf( "\t hide(boolean) : \"whether the object should be visible when spawned. you need to set a value for triggering on/off to work\"\n" );
fgdFile->Printf( "\t gui_noninteractive(boolean) : \"any gui attached will not be interactive\"\n" );
fgdFile->Printf( "\t inline(boolean) : \"If true, turn the model into map geometry at dmap time\"\n" );
fgdFile->Printf( "\t angles(string) : \"\" : \"0 0 0\"\n" );
fgdFile->Printf( "\t gui(string) : \"gui attached to this static, gui2 and gui3 also work\"\n" );
fgdFile->Printf( "\t gui_demonic(string) : \"demonic gui attached to this statit, gui_demonic2 and gui_demonic3 also work\"\n]\n\n" );
fgdFile->Printf( "@PointClass base(func_static) color(0 127 204) size(-12 -12 -12, 12 12 12) model({ \"path\" : model }) = misc_model : \"Just a model\"\n[\n" );
//fgdFile->Printf( "name(string) : \"\" : \"\"\n" );
fgdFile->Printf( "\t angles(string) : \"\" : \"0 0 0\"\n" );
fgdFile->Printf( "]\n\n" );
fgdFile->Printf( "@PointClass base(misc_model) = auto_generated_model : \"Entity definition for a specific model\" []\n\n" );
for( int f = 0; f < files->GetList().Num(); f++ )
{
totalModelsCount++;
idStr modelName = files->GetList()[ f ];
modelName.StripLeadingOnce( "generated/rendermodels/" );
idStr ext;
modelName.ExtractFileExtension( ext );
bool dynamicModel = false;
if( ext.Icmp( "blwo" ) == 0 )
{
modelName.SetFileExtension( "lwo" );
}
if( ext.Icmp( "base" ) == 0 )
{
modelName.SetFileExtension( "ase" );
}
if( ext.Icmp( "bdae" ) == 0 )
{
modelName.SetFileExtension( "dae" );
}
if( ext.Icmp( "bmd5mesh" ) == 0 )
{
modelName.SetFileExtension( "md5mesh" );
dynamicModel = true;
}
// skip TB specific helper models
if( idStr::Icmpn( modelName, "_tb", 3 ) == 0 )
{
continue;
}
idLib::Printf( "Exporting model '%s'\n", modelName.c_str() );
// make an OBJ version of the model for TrenchBroom
idRenderModel* renderModel = renderModelManager->FindModel( modelName );
#if 1
if( idStr::Icmpn( modelName, "models/mapobjects", 17 ) != 0 )
{
continue;
}
#endif
if( idStr::Icmpn( modelName, "models/items", 12 ) == 0 )
{
continue;
}
if( idStr::Icmpn( modelName, "models/particles", 16 ) == 0 )
{
continue;
}
if( idStr::Icmpn( modelName, "models/weapons", 14 ) == 0 )
{
continue;
}
idBounds bounds = renderModel->Bounds();
// put model as mapobject into the models FGD
if( !renderModel->IsDefaultModel() && bounds.GetVolume() > 0 && bounds.GetRadius() < 1400 )
{
idStrStatic< MAX_OSPATH > originalModelFileName;
originalModelFileName = modelName;
idStrStatic< MAX_OSPATH > exportedModelFileName;
exportedModelFileName = "_tb/";
exportedModelFileName.AppendPath( modelName );
exportedModelFileName.SetFileExtension( ".obj" );
idStrStatic< MAX_OSPATH > entityName;
if( idStr::Icmpn( modelName, "models/mapobjects", 17 ) == 0 )
{
modelName.StripLeadingOnce( "models/mapobjects" );
entityName = "mob";
entityName.AppendPath( modelName );
}
else
{
modelName.StripLeadingOnce( "models/" );
entityName = "mdl";
entityName.AppendPath( modelName );
}
entityName.BackSlashesToSlashes();
entityName.ReplaceChar( '/', '_' );
entityName.ReplaceChar( '(', '_' );
entityName.ReplaceChar( ')', '_' );
entityName.StripFileExtension();
fgdFile->Printf( "@PointClass " );
#if 0
if( bounds.GetVolume() > 0 )
{
fgdFile->Printf( "size(%i %i %i, %i %i %i) ",
int( bounds[0].x ), int( bounds[0].y ), int( bounds[0].z ),
int( bounds[1].x ), int( bounds[1].y ), int( bounds[1].z ) );
}
#endif
fgdFile->Printf( "base(auto_generated_model) model({ \"path\": \"%s\" }) = %s : \"Display entity\"\n[\n", exportedModelFileName.c_str(), entityName.c_str() );
//fgdFile->Printf( "[\n\t angles(string) : \"\" : \"0 0 0\"\n]\n\n");
fgdFile->Printf( "\t model(string) : \"\" : \"%s\"\n", exportedModelFileName.c_str() );
fgdFile->Printf( "\t origmodel(string) : \"\" : \"%s\"\n", originalModelFileName.c_str() );
fgdFile->Printf( "]\n\n", exportedModelFileName.c_str() );
totalEntitiesCount++;
}
}
fileSystem->FreeFileList( files );
com_editors &= ~EDITOR_EXPORTDEFS;
postLoadExportModels.SetBool( false );
fgdFile->Flush();
common->Printf( "\nFGD written to %s\n", fgdFileName.c_str() );
common->Printf( "----------------------------\n" );
common->Printf( "Wrote %d Entities.\n", totalEntitiesCount );
common->Printf( "Wrote %d Models.\n", totalModelsCount );
common->FatalError( "Exporting successful, need to restart manually" );
}
static idMapBrush* MakeCharBrush( const idVec3& brushOrigin, const idVec3& uvOrigin, int ch )
{
@ -3291,7 +3315,99 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
mapFile.AddEntity( worldspawn );
worldspawn->epairs.Set( "classname", "worldspawn" );
// TODO bottom plate or big hall brushes
idStrList ignoreList;
// non modular models, should probably a .cfg or .ini defined by an artist
ignoreList.AddUnique( "models/mapobjects/alphalabs3/vagary/vagary_webs" );
ignoreList.AddUnique( "models/mapobjects/caves/caves1_1" );
ignoreList.AddUnique( "models/mapobjects/caves/caves1_2a" );
ignoreList.AddUnique( "models/mapobjects/caves/caves1_6" );
ignoreList.AddUnique( "models/mapobjects/caves/caves1_7" );
ignoreList.AddUnique( "models/mapobjects/caves/caves2_" );
ignoreList.AddUnique( "models/mapobjects/caves/cav_corns" );
ignoreList.AddUnique( "models/mapobjects/com/com_underground1" );
ignoreList.AddUnique( "models/mapobjects/cpu/cpu_hell2" );
ignoreList.AddUnique( "models/mapobjects/cpu/cpu_hell3" );
ignoreList.AddUnique( "models/mapobjects/cpu/cpu_hell4" );
ignoreList.AddUnique( "models/mapobjects/cpu/sab_lightning1" );
ignoreList.AddUnique( "_clip" );
ignoreList.AddUnique( "models/mapobjects/delta3/hellgoo_door1/hellgoo_door1" );
ignoreList.AddUnique( "models/mapobjects/delta3/hellgoo_elev2/hellgoo_elev2" );
ignoreList.AddUnique( "models/mapobjects/deltax/hall_hellgrowth" );
ignoreList.AddUnique( "models/mapobjects/deltax/room1_hellgrowth" );
ignoreList.AddUnique( "models/mapobjects/erebus/berzerker_hellgoo_2" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus2_puzzle_cavea_lo" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus4_cave" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus_cave2_puzzle_cave2" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus_cave2_room1" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus_cave2_room2" );
ignoreList.AddUnique( "models/mapobjects/erebus/erebus_lounge_ceiling" );
ignoreList.AddUnique( "models/mapobjects/erebus/mp_hellshaft" );
ignoreList.AddUnique( "models/mapobjects/exis/exis_terrain" );
ignoreList.AddUnique( "models/mapobjects/exis/existel_railing" );
ignoreList.AddUnique( "models/mapobjects/hangar/hangar1tower" );
ignoreList.AddUnique( "models/mapobjects/hangar/pillar1" );
ignoreList.AddUnique( "models/mapobjects/hell/delta5/doora/eyeskin_b" );
ignoreList.AddUnique( "models/mapobjects/hell/delta5/doorb/hornskin" );
ignoreList.AddUnique( "models/mapobjects/hell/doom3ex/phobos/d3ex_goo_1a" );
ignoreList.AddUnique( "models/mapobjects/hell/maggotroom/worm" );
ignoreList.AddUnique( "models/mapobjects/hell/site3/fleshtube1/fleshtube_01" );
ignoreList.AddUnique( "models/mapobjects/hell/site3/landscapesradar/canyona" );
ignoreList.AddUnique( "models/mapobjects/hell/site3/birthhole" );
ignoreList.AddUnique( "models/mapobjects/hell/guardian_lightning2" );
ignoreList.AddUnique( "models/mapobjects/hell/hellhalldown3" );
ignoreList.AddUnique( "models/mapobjects/hell/mancroomfloor" );
ignoreList.AddUnique( "models/mapobjects/hell/vagarycave" );
ignoreList.AddUnique( "models/mapobjects/hell/vagarycavehall" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_brokensteps" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_brokenwall" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_hallcorner" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_rock" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_staircave2" );
ignoreList.AddUnique( "models/mapobjects/hellhole/d3xp_temple_rubble" );
ignoreList.AddUnique( "models/mapobjects/hellhole/hellhole_cave" );
ignoreList.AddUnique( "models/mapobjects/hellhole/hellhole_coffinbricks2" );
ignoreList.AddUnique( "models/mapobjects/hellhole/hellhole_crushstairs" );
ignoreList.AddUnique( "models/mapobjects/hellhole/hellhole_firstroom" );
ignoreList.AddUnique( "models/mapobjects/hellhole/hellhole_secondroom" );
ignoreList.AddUnique( "models/mapobjects/mc_underground/outside/mc_ug_out3" );
ignoreList.AddUnique( "models/mapobjects/phobos/berg_lightning_fx" );
ignoreList.AddUnique( "models/mapobjects/phobos/phobos1_brockerybeef" );
ignoreList.AddUnique( "models/mapobjects/phobos/phobos_cave" );
ignoreList.AddUnique( "models/mapobjects/recycle/skybridge/skybridge_clip" );
ignoreList.AddUnique( "models/mapobjects/recycle/mancubusroom" );
ignoreList.AddUnique( "models/mapobjects/recycle/rec1bigfloor" );
ignoreList.AddUnique( "models/mapobjects/recycle/rec1cave1" );
ignoreList.AddUnique( "models/mapobjects/recycle/rec1sfloor" );
ignoreList.AddUnique( "models/mapobjects/recycle/rec1sfloorgoop" );
ignoreList.AddUnique( "models/mapobjects/recycle/rec1tunnel1" );
ignoreList.AddUnique( "models/mapobjects/ruins/ruin_wire" );
ignoreList.AddUnique( "models/mapobjects/site/site3_exitpit" );
ignoreList.AddUnique( "models/mapobjects/site/site3_tunnel" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1ceiling1" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1floor" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1hall1" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1hall1ceiling" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1hall" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hell1lasthall" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hellcaves_1ahall" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hellcaves_" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hellcaveshole1" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hellhalldown2" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/hornramp2" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/map10_hell1" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/map10_hell2" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/map10_hell3" );
ignoreList.AddUnique( "models/mapobjects/hell/pillar/pillar_hellrock_a" );
ignoreList.AddUnique( "models/mapobjects/hell/pillar/pillar_hellrock_b" );
ignoreList.AddUnique( "models/mapobjects/hell/pillar/pillar_hellrock_c" );
ignoreList.AddUnique( "models/mapobjects/ruins/pillarbroke" );
ignoreList.AddUnique( "models/mapobjects/delta3/teleporter_warpfx/betrugger_lightning" );
ignoreList.AddUnique( "models/mapobjects/steve_temp/map10_hell_smoke" );
ignoreList.AddUnique( "models/mapobjects/phobos/bridge/bridge_roof_1" );
// collect all folders that actually contain models
idHashTable<ModelsGroup_t*> entitiesPerFolder;
@ -3328,8 +3444,31 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
dynamicModel = true;
}
// skip TB specific helper models
if( idStr::Icmpn( modelName, "_tb", 3 ) == 0 )
{
continue;
}
idRenderModel* renderModel = renderModelManager->FindModel( modelName );
// skip non modular models
bool ignore = false;
for( int i = 0; i < ignoreList.Num(); i++ )
{
const char* ignoreStr = ignoreList[ i ].c_str();
if( modelName.Find( ignoreStr ) != -1 )
{
ignore = true;
break;
}
}
if( ignore )
{
continue;
}
#if 1
// discard everything that is not a mapobjects model
if( idStr::Icmpn( modelName, "models/mapobjects", 17 ) != 0 )
@ -3448,6 +3587,7 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
EntityInfo_t* entInfo = group->entityList[ e ];
entInfo->packedPos = outputPositions[ e ];
entInfo->packedPos.y *= -1.0f;
}
}
@ -3513,6 +3653,7 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
mapEnt->epairs.Set( "classname", "func_static" );
mapEnt->epairs.Set( "name", entityName );
mapEnt->epairs.Set( "model", entityName );
#if 1
@ -3523,14 +3664,16 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
int wordLen = 0;
for( int i = 0; i < group->folder.Length(); i++ )
{
float y = -outputPositions[ g ].y - group->totalSize.y;
idVec3 brushOrigin;
brushOrigin.x = outputPositions[ g ].x + wordLen * 8;
brushOrigin.y = outputPositions[ g ].y;
brushOrigin.y = y;
brushOrigin.z = topHeight - numSlashes * 8;
idVec3 uvOrigin;
uvOrigin.x = outputPositions[ g ].x + wordLen * 8;
uvOrigin.y = outputPositions[ g ].y;
uvOrigin.y = y;
uvOrigin.z = topHeight + numSlashes * 8;
wordLen++;
@ -3559,7 +3702,7 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
idVec3 origin;
origin.x = outputPositions[ g ].x + entInfo->packedPos.x;
origin.y = outputPositions[ g ].y + entInfo->packedPos.y;
origin.y = -outputPositions[ g ].y + entInfo->packedPos.y;
origin.z = 0;
entInfo->entity->epairs.SetVector( "origin", origin );
@ -3569,13 +3712,14 @@ void idDeclManagerLocal::MakeZooMapForModels_f( const idCmdArgs& args )
mapFile.ConvertToValve220Format();
worldspawn->epairs.Set( "_tb_textures", "textures/common;textures/editor;textures/decals" );
worldspawn->epairs.Set( "_tb_def", "external:base/exported/_tb/DOOM-3-models.fgd" );
mapFile.Write( mapName, ".map" );
common->Printf( "\nZoo map written to %s\n", mapName.c_str() );
common->Printf( "----------------------------\n" );
common->Printf( "Found %d Models.\n", totalModelsCount );
common->Printf( "Wrote %d Entities.\n", totalEntitiesCount );
common->Printf( "Wrote %d Entities in %d Groups.\n", totalEntitiesCount, entitiesPerFolder.Num() );
}
// RB end