⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmapexp.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  if ( obj != (Object*)tri)   // delete work object if needed
    tri->DeleteThis() ;  

  return FALSE ;
} ;

int qmap_save(const TCHAR *filename, ExpInterface *ei, Interface *gi, QMapExport *exp)
{

	// Put up the options dialog to find out how they want the file written!
	int result = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_EXPORTOPTIONS), 
		gi->GetMAXHWnd(), ExportOptionsDlgProc, (LPARAM)exp);
	if(result <= 0)
		return 0;

	// Make sure there are nodes we're interested in!
	// Ask the scene to enumerate all its nodes so we can determine if there are any we can use
	MySceneEnumProc myScene(ei->theScene, gi->GetTime(), gi);

	// Any useful nodes?
	if(!myScene.Count()) 
  {
		Alert(IDS_TH_NODATATOEXPORT);
		return 1;
	} ;

  // init flags
  BOOL playerStartFound = FALSE ;   // remember if theres a player start entity
  errorBrushes = 0 ;                // remember how many brushes have errors

  // Output the file as text
	WorkFile theFile(filename,_T("w"));
	FILE *stream = theFile.Stream();
	if(!stream) 
  {
		Alert(IDS_TH_CANTCREATE);
		return -1;						// Didn't open!
	}

	// Build a bounding box for the objects we're exporting
	Box3 bbox = myScene.Bound();

	// Let's get busy!

	int ox;
	TSTR layername;
	
	// Write header stuff 

  if (fprintf(stream,"// Quake Map file exported from 3DS MAX by QMAPEXP v1.04\n")<0)
    goto wrterr ;   // well if Tom Hudson can use labels....

  // write the worldspawn entity that holds all the non-linked brushes
  if (fprintf(stream,"{\n"
                     "\"classname\" \"worldspawn\"\n"
                     "\"wad\" \"%s\"\n"
                     "\"message\" \"%s\"\n"
                     "\"worldtype\" \"%d\"\n"
                     "\"sounds\" \"1\"\n",
                     exp->WADName,
                     exp->MapName,
                     exp->WorldType
              )<0)
    goto wrterr ;
	
  // first loop looking for all suitable Quake brushes 
  for (ox = 0 ; ox<myScene.Count(); ++ox )
  {
    MySceneEntry* sEntry ;
    sEntry = myScene[ox] ;
 
    int objType ;
    objType = myScene[ox]->type ;
    if (objType == OBTYPE_MESH )      // found a mesh
    {
      // check Hierarchy
      BOOL globalMesh = TRUE ;        // assume its not attched to an entity
      INode* parent = sEntry->node->GetParentNode() ; // find parent
      if (!parent->IsRootNode())                      // parent is a real object
      {
        Object* parentObj = parent->GetObjectRef() ;  // determine parent type
        if ( (parentObj->SuperClassID() == HELPER_CLASS_ID ) &&
			       (parentObj->ClassID()      == QENTHELP_CLASS_ID)) // brush is linked to entity
          globalMesh = FALSE ;

      } ;
      if (globalMesh)   // if not attached to entity
      {
        if (WriteMesh(sEntry, gi, stream))
          goto wrterr ;
      } ;
    } ;
  } ; // for

  if (fprintf(stream,"}\n")<0)
    goto wrterr ;

  // next loop looking for all suitable Quake entities
  for (ox = 0 ; ox<myScene.Count(); ++ox )
  {
    MySceneEntry* sEntry ;
    sEntry = myScene[ox] ;
    if ( sEntry->type == OBTYPE_OMNILIGHT )   // if MAX omni light
    {
      // derive the light parameters
			INode* node = sEntry->node;
			Object* obj = sEntry->obj;
			LightObject* lt= (LightObject *)obj;
			GenLight* gl = (GenLight *)obj;
			LightState ls;
    	Interval valid;
			lt->EvalLightState(myScene.time, valid, &ls);
			Matrix3 mat = node->GetNodeTM(myScene.time);			
			Point3 pos = mat.GetRow(3);

      // issue quake light
      if (fprintf(stream, "{\n"
                          "// %s\n"
                          "\"classname\" \"light\"\n"
                          "\"origin\" \"%ld %ld %ld\"\n"
                          "\"light\" \"%d\"\n"
                          "}\n"
                          ,node->GetName()
                          ,(int)pos.x,(int)pos.y,(int)pos.z
                          ,(int)ls.attenEnd  // MAX attenuation end controls Quake intensity
          )<0)
      goto wrterr ;

    } 
    else
    {
      if ( sEntry->type == OBTYPE_QENTITY )   // quake entity helper object
      {
        INode* node = sEntry->node ;
        QEntHelpObject* ent = (QEntHelpObject*)sEntry->obj ;
			  Matrix3 mat = node->GetNodeTM(myScene.time);			
			  Point3 pos = mat.GetRow(3);

        // check if its part of a tree
        int numChild = node->NumberOfChildren() ; 
        if ( numChild == 0 )        // if unatttached, standard entity
        {
          // issue standard quake entity
          if (fprintf(stream, "{\n"
                              "// %s\n"
                              "\"classname\" \"%s\"\n"
                              "\"origin\" \"%ld %ld %ld\"\n"
                              ,node->GetName()
                              ,ent->QClassName
                              ,(int)pos.x,(int)pos.y,(int)pos.z
              )<0)
          goto wrterr ;
          // issue map params
          DecodeMapParams(ent->Data.MapParams,stream) ;
          // check if its the player start entity
          if ( strcmp(ent->QClassName,"info_player_start") == 0)
            playerStartFound = TRUE ;
          if (fprintf(stream,"}\n") <0)
            goto wrterr ;
        } 
        else      // its an entity linked to a brush
        {
          if ( strcmp(ent->QClassName,"func_door") == 0 )   // its a door
          {
            // write entity
            if (fprintf(stream, "{\n"
                                "// %s\n"
                                "\"classname\" \"%s\"\n"
                                "\"angle\" \"%ld\"\n"
                                "\"speed\" \"%ld\"\n"
                                "\"sounds\" \"%ld\"\n"
                                "\"wait\" \"%ld\"\n"
                                "\"lip\" \"%ld\"\n"
                                "\"dmg\" \"%ld\"\n"
                                ,node->GetName()
                                ,ent->QClassName
                                ,ent->Data.Angle
                                ,ent->Data.Speed
                                ,ent->Data.Sounds
                                ,ent->Data.Wait
                                ,ent->Data.Lip
                                ,ent->Data.Dmg
                )<0)
            goto wrterr ;

            if (strlen(ent->Data.TargetName) != 0)
            {
              if (fprintf(stream, "\"targetname\" \"%s\"\n"
                                  ,ent->Data.TargetName
                  )<0)
              goto wrterr ;
            } ;
            if (strlen(ent->Data.Message) != 0)
            {
              if (fprintf(stream, "\"message\" \"%s\"\n"
                                  ,ent->Data.Message
                  )<0)
              goto wrterr ;
            } ;
            if ( ent->Data.Health != 0)
            {
              if (fprintf(stream, "\"health\" \"%ld\"\n"
                                  ,ent->Data.Health
                  )<0)
              goto wrterr ;
            } ;
            if ( ent->Data.Toggle)
            {
              if (fprintf(stream, "\"toggle\"\n")<0)
              goto wrterr ;
            } ;
            if ( ent->Data.StartOpen)
            {
              if (fprintf(stream, "\"start_open\"\n")<0)
              goto wrterr ;
            } ;
            if ( ent->Data.DoorDontLink)
            {
              if (fprintf(stream, "\"door_dont_link\"\n")<0)
              goto wrterr ;
            } ;
            if ( ent->Data.GoldKey)
            {
              if (fprintf(stream, "\"gold_key\"\n")<0)
              goto wrterr ;
            } ;
            if ( ent->Data.SilverKey)
            {
              if (fprintf(stream, "\"silver_key\"\n")<0)
              goto wrterr ;
            } ;
            // issue map params
            DecodeMapParams(ent->Data.MapParams,stream) ;

            int childNum = 0;
            while ( childNum < numChild )
            {
              INode* childNode = node->GetChildNode(childNum) ;
              Object* childObj =  childNode->GetObjectRef() ;
	            if( childObj->CanConvertToType(triObjectClassID) ) 
              {
                // dummy up a temp scene object
                MySceneEntry ent(childNode,childObj,OBTYPE_MESH) ;
                // write child brush
                if (WriteMesh(&ent, gi, stream))
                  goto wrterr ;
		            
	            }
              else
              {
                char errStr [ 80 ] ;
                sprintf(errStr,"Error: Entity '%s' linked to non-mesh object",ent->QClassName) ; 
                MessageBox(GetActiveWindow(),errStr,"QMAPEXP", MB_OK) ;
              } 
              childNum ++ ;
            } ;
            if (fprintf(stream,"}\n")<0)
              goto wrterr ;
          }
          else    // unknown link - just issue params
          {
            if (fprintf(stream, "{\n"
                                "// %s\n"
                                "\"classname\" \"%s\"\n"
                                ,node->GetName()
                                ,ent->QClassName
                )<0)
            goto wrterr ;
            // issue map params
            DecodeMapParams(ent->Data.MapParams,stream) ;
            // issue linked brushes
            int childNum = 0;
            while ( childNum < numChild )
            {
              INode* childNode = node->GetChildNode(childNum) ;
              Object* childObj =  childNode->GetObjectRef() ;
              // check if its a meshable object
	            if( childObj->CanConvertToType(triObjectClassID) ) 
              {
                // dummy up a temp scene object
                MySceneEntry ent(childNode,childObj,OBTYPE_MESH) ;
                // write child brush
                if (WriteMesh(&ent, gi, stream))
                  goto wrterr ;
		            
	            }
              else
              {
                char errStr [ 80 ] ;
                sprintf(errStr,"Error: Entity '%s' linked to non-mesh object",ent->QClassName) ; 
                MessageBox(GetActiveWindow(),errStr,"QMAPEXP", MB_OK) ;
              } 
              childNum ++ ;
            } ;
            if (fprintf(stream,"}\n")<0)
              goto wrterr ;
          } ;
        } ;
      } ;
    } ;
  } ;
  // finish off file
  if (!playerStartFound)      // all maps must have a player start
  {
    MessageBox(GetActiveWindow(),"Map has no player start entity. Default start added at 10,10,10","QMAPEXP", MB_OK) ;
    if (fprintf(stream, "{\n"
                        "\"classname\"	\"info_player_start\"\n"
                        "\"origin\"	\"10 10 10\"\n"
                        "}\n"
               ) <0 )
      goto wrterr ;
  } ;


  // all done, close MAP file
	if(theFile.Close())
		goto wrterr;

  // check for bad brushes
  if ( errorBrushes != 0 )
  {
    char errStr[80] ;
    sprintf(errStr,"Warning: %d brushes have errors, see MAP file.",errorBrushes) ;
    MessageBox(GetActiveWindow(),errStr,"QMAPEXP", MB_OK) ;
  } ;

	return 1;	

wrterr:
  Alert(IDS_TH_WRITEERROR) ;
  theFile.Close() ;
  remove(filename) ;
  return 0 ;
} ;

int QMapExport::DoExport(const TCHAR *filename,ExpInterface *ei,Interface *gi) 
{
	int status;
		
	status=qmap_save(filename, ei, gi, this);

	if(status == 0)
		return 1;		// Dialog cancelled
	if(status > 0)	{
#ifdef DBGQMAP
DebugPrint("QMAP status OK!\n");
#endif
		}
#ifdef DBGQMAP
	else
	if(status < 0)
		DebugPrint("Error somewhere in QMAP!\n");
#endif

	return(status);
} ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -