Results 1 to 10 of 16

Thread: VMF2Map

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    ... connecting
    Join Date
    Jan 2014
    Posts
    7
    Thanks
    0
    Thanked 4 Times in 3 Posts
    I feel like people stopped paying attention to this topic but what the hell. I changed some parts of the script to prevent texture replacement so that i could find the textures i needed to port. Also found the difference between iw engine's and source engine's unit size and added an extra function to fix the it. Also added some extra lines to add the models. After converting a .vmf file to a .map file, this is what i got after fixing the texture alignments.



    All i had to do was convert the models to .obj files, then convert the models and textures for waw, then convert the .vmf file to a .map file. Here's the script that i've edited. Note that this one below doesn't change the texture names and stuff. You'll need to get the texture names and convert them for whatever cod version you have and it'll work just fine.

    Code:
    <?php
    function convertunit($origin) {
    	$exp = explode(' ',$origin);
    	foreach($exp as $unit) {
    	 $origin .= trim($unit)*1.3344.' ';
    	}
    	return trim($origin);
    }
    	function parseVMF($vmfString)
    	{
    	
    		$debug = false;
    		
    		$len = strlen($vmfString);
    		if ($debug) $len = 2098;
    		
    		$stack = array();
    		
    		$isInQuote = false;
    		$key = "";
    		$value = "";
    		$quoteKey = "";
    		$quoteValue = "";
    		$quoteWhat = "key";
    		
    		for ($i=0; $i<$len; $i++)
    		{
    			$c = $vmfString{$i}; // current char
    			
    			switch ($c)
    			{
    				case "\r":
    					break;
    				case "\n":
    					if (strlen(trim($key))) {
    						//echo "new key: \"$key\"";
    						$stack[] = $key;
    						$key = "";
    					}
    					//echo "\n";
    					break;
    				case "\"":
    				
    					if ($isInQuote) // so we are CLOSING key or value
    					{
    						if (strlen($quoteKey) && strlen($quoteValue))
    						{
    							//echo "(NEW PAIR \"$quoteKey\"->\"$quoteValue\")";
    							$stack[] = array($quoteKey=>$quoteValue);
    							$quoteKey = "";
    							$quoteValue = "";
    						}
    										
    						if ($quoteWhat == "key")
    							$quoteWhat = "value";
    						else if ($quoteWhat == "value")
    							$quoteWhat = "key";
    					}
    					
    					$isInQuote = !$isInQuote;
    					break;
    				case "{":
    					$stack[] = "ENTER-GROUP";
    					if ($debug) echo "{";
    					break;
    				case "}":
    					$stack[] = "LEAVE-GROUP";
    					if ($debug) echo "}";
    					break;
    					
    				case "\t":
    					break;
    				//case " ":
    				//	break;
    				default:
    					if (!$isInQuote && strlen(trim($c)))
    					{
    						$key .= $c;
    					}
    						
    					if ($isInQuote)
    						if ($quoteWhat == "key")
    							$quoteKey .= $c;
    						else
    							$quoteValue .= $c;
    							
    					
    					//echo $c;
    			}
    		}
    		
    		if ($debug) echo "<hr>";
    		
    		$vmf = array();
    		
    		//$addTo = undefined;
    		
    		$depth = 0;
    		$parent = &$vmf;
    		$history = array();
    		$groupname = "not init";
    		foreach ($stack as $element)
    		{
    			if (!is_array($element)) // is groupname or GROUP-indicator
    			{
    				/*
    				if (!isset($vmf[$element]))
    					$vmf[$element] = array();
    				$vmf[$element][] = array();
    				//$addTo = &$
    				*/
    				
    				if ($element == "ENTER-GROUP")
    				{
    					if ($debug) echo "ENTER GROUP depth=$depth\n";
    					continue;
    				}
    				if ($element == "LEAVE-GROUP")
    				{
    					if ($debug) echo "LEAVE GROUP\n";
    					
    					$depth--;
    					$parent = &$history[$depth];
    					continue;
    				}
    				
    				$groupname = $element;
    				
    				if (!isset($parent[$groupname]))
    				{
    					$parent[$groupname] = array();
    					//$parent[$groupname][] = array();
    				}
    				$history[$depth] = &$parent;
    				$parent = &$parent[$groupname][];
    				$depth++;
    				
    				//$i = count($parent[$groupname]);
    				//$parent[$groupname][$i] = $groupname . $i;
    				
    				//$parent = &$parent[$groupname][$i];
    				
    				if ($debug) echo "NEW GROUP $groupname\n";
    			} else {
    				$keys = array_keys($element);
    				$key = $keys[0];
    				$val = $element[$key];
    				
    				$n = count($parent);
    				//echo $n . "\n";
    				//$parent[$n] = $groupname . $n;
    				
    				$parent[$key] = $val;
    				//echo $key . "->" . $element[$key];
    			}
    			
    			//echo "\n";
    		}
    		
    
    		if ($debug) echo "<hr>";
    		if ($debug) var_dump($vmf);
    		
    		
    		return $vmf;
    	}
    
    	function fixWaterBrush(&$solid)
    	{
    		$isOnlyWaterAndNodraw = true;
    		$watername = "";
    		foreach ($solid["side"] as $side)
    			if (strpos(strtoupper($side["material"]), "WATER")!==false || strpos(strtoupper($side["material"]), "TOOLSNODRAW")!==false) {
    				if (strpos(strtoupper($side["material"]), "WATER")!==false)
    					$watername = $side["material"];
    			} else
    				return false;
    		
    		if (trim($watername) == "") // its completely nodraw
    			return false;
    		
    		foreach ($solid["side"] as &$side)
    			$side["material"] = $watername;
    
    		return true;
    	}
    	
    	function exportVMFasGSC($vmf)
    	{
    		$gsc = "main()\n{\n";
    	
    		foreach ($vmf["entity"] as $entity)
    		{
    			if (
    				$entity["classname"] != "item_ammopack_medium"
    				&& $entity["classname"] != "item_healthkit_medium"
    				&& $entity["classname"] != "item_ammopack_small"
    				&& $entity["classname"] != "item_healthkit_small"
    			)
    				continue;
    			
    
    			$classname = $entity["classname"];
    			$origin = str_replace(" ", ",", convertunit($entity["origin"]));
    			$angles = str_replace(" ", ",", $entity["angles"]);
    			$gsc .= "\tstd\item::addItem(\"$classname\", ($origin), ($angles));\n";
    		}
    		
    		$gsc .= "\n";
    		
    		foreach ($vmf["entity"] as $entity)
    		{
    			if ( ! isset($entity["model"]))
    				continue;
    			if ($entity["classname"] != "prop_dynamic" && $entity["model"] != "models/props_gameplay/resupply_locker.mdl")
    				continue;
    
    			$name = $entity["targetname"];
    			$origin = str_replace(" ", ",", convertunit($entity["origin"]));
    			$angles = str_replace(" ", ",", $entity["angles"]);
    			$gsc .= "\tstd\item::addItem(\"$name\", ($origin), ($angles));\n";
    		}
    		$gsc .= "}";
    		
    		return $gsc;
    	}
    	
    	function exportVMFasMAP($vmf, $extend_map)
    	{
    		$map = "";
    		$map .= "iwmap 4\n";
    		
    		// PRINT NORMAL BRUSHES
    		$map .= "{\n";
    		$map .= "\t\"classname\" \"worldspawn\"\n";
    		
    		// some brushes are in world
    		foreach ($vmf["world"][0]["solid"] as $solid)
    		{
    			if ($solid["side"][0]["material"] == "TOOLS/TOOLSPLAYERCLIP") // ONLY FOR SURF_UTOPIA
    				continue;
    			if ($solid["side"][0]["material"] == "TOOLS/TOOLSSKYBOX") // ONLY FOR SURF_UTOPIA
    				continue;
    
    			if (fixWaterBrush($solid) && 0)
    					echo "Fixed Water on Brush Solid-ID=" . $solid["id"] . "\n";
    				
    			$map .= "\t{\n";
    			foreach ($solid["side"] as $side)
    			{
    				//$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray -248 192 -96 120 0 0 \n";
    				$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray 16384 16384 0 0 0 0 \n";
    			}
    			$map .= "\t}\n";
    		}
    		
    		// others are func_detail-entities
    		foreach ($vmf["entity"] as $entity)
    		{
    			if (
    				$entity["classname"] != "func_detail"
    				&& $entity["classname"] != "func_brush"
    				&& $entity["classname"] != "func_illusionary" /*could be detail also but who cares*/ /*later: lol this one would to to many nodes: no compile*/
    			)
    				continue;
    			
    			// if illusionary: add clip_player PLUS normal textures as non-colliding.
    			// so ppl can shoot through but cant go through.
    			
    			if ($entity["classname"] == "func_illusionary")
    			{
    				foreach ($entity["solid"] as $solid)
    				{
    					$map .= "\t// func_illusionary\n";
    					$map .= "\t{\n";
    					foreach ($solid["side"] as $side)
    					{
    						$map .= "\t\t" . $side["plane"] . " clip 64 64 -88 8 0 0 lightmap_gray 16384 16384 0 0 0 0\n";
    					}
    					$map .= "\t}\n";
    				}
    			}
    			
    			foreach ($entity["solid"] as $solid)
    			{
    				if ($solid["side"][0]["material"] == "TOOLS/TOOLSPLAYERCLIP") // ONLY FOR SURF_UTOPIA
    					continue;
    				if ($solid["side"][0]["material"] == "TOOLS/TOOLSSKYBOX") // ONLY FOR SURF_UTOPIA
    					continue;
    				
    
    				if (fixWaterBrush($solid) && 0)
    						echo "Fixed Water on Brush Entity-ID=" . $entity["id"] . "\n";
    					
    					
    					
    					
    				$map .= "\t{\n";
    				if ($entity["classname"] == "func_illusionary")
    				{
    					//break;
    					//contents detail;
    					//contents nonColliding;
    					//$map .= "\tcontents detail;\n";
    					$map .= "\tcontents nonColliding;\n";
    				}
    				foreach ($solid["side"] as $side)
    				{
    					//$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray -248 192 -96 120 0 0 \n";
    					$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray 16384 16384 0 0 0 0 \n";
    				}
    				$map .= "\t}\n";
    			}
    		}
    		
    		$map .= $extend_map;
    		
    		$map .= "}\n\n"; // all brushes are in worldspawn
    		
    		// now the entities:
    		
    		// spawnpoints
    		foreach ($vmf["entity"] as $entity)
    		{
    			if ($entity["classname"] != "info_player_teamspawn")
    				continue;
    			if ( ! isset($entity["TeamNum"]))
    				continue;
    				
    			if ($entity["TeamNum"] == "2")
    				$classname = "mp_ctf_spawn_allied";
    			else
    				$classname = "mp_ctf_spawn_axis";
    			$origin = convertunit($entity["origin"]);
    			$angles = $entity["angles"];
    			$map .= "{\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"classname\" \"$classname\"\n";
    			$map .= "\t\"angles\" \"$angles\"\n";
    			$map .= "}\n";
    		}
    		
    		
    		foreach ($vmf["entity"] as $entity)
    		{
    			if ($entity["classname"] != "info_player_counterterrorist")
    				continue;
    			$origin = convertunit($entity["origin"]);
    			$angles = $entity["angles"];
    			$map .= "{\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"classname\" \"mp_ctf_spawn_allied\"\n";
    			$map .= "\t\"angles\" \"$angles\"\n";
    			$map .= "}\n";
    		}
    		foreach ($vmf["entity"] as $entity)
    		{
    			if ($entity["classname"] != "info_player_terrorist")
    				continue;
    			$origin = convertunit($entity["origin"]);
    			$angles = $entity["angles"];
    			$map .= "{\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"classname\" \"mp_ctf_spawn_axis\"\n";
    			$map .= "\t\"angles\" \"$angles\"\n";
    			$map .= "}\n";
    		}
    		
    		// 
    		foreach ($vmf["entity"] as $entity)
    		{
    			if (
    				$entity["classname"] != "trigger_teleport"
    				&& $entity["classname"] != "trigger_push"
    				&& $entity["classname"] != "func_regenerate"
    				&& $entity["classname"] != "func_respawnroom"
    			)
    				continue;
    				
    			foreach ($entity["solid"] as $solid)
    			{
    				$map .= "{\n";
    				$map .= "\t\"classname\" \"trigger_multiple\"\n";
    				$map .= "\t\"targetname\" \"{$entity["classname"]}\"\n";
    				
    				if (isset($entity["target"])) $map .= "\t\"target\" \"{$entity["target"]}\"\n";
    				
    				$count = 0;
    				if (isset($entity["speed"])) { $map .= "\t\"speed\" \"{$entity["speed"]}\"\n"; $count++; }
    				if (isset($entity["pushdir"])) { $map .= "\t\"pushdir\" \"{$entity["pushdir"]}\"\n"; $count++; }
    				if ($count == 2) // hack... add later support for other key-values inside server
    				{
    					$map .= "\t\"target\" \"{$entity["speed"]}|{$entity["pushdir"]}\"\n";
    				}
    	
    				if (isset($entity["TeamNum"])) { $map .= "\t\"target\" \"{$entity["TeamNum"]}\"\n"; $count++; }
    	
    				$map .= "\t{\n";
    				foreach ($solid["side"] as $side)
    				{
    					//$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray -248 192 -96 120 0 0 \n";
    					$map .= "\t\t" . $side["plane"] . " " .getNewMaterial($side["material"]). " 64 64 0 0 0 0 lightmap_gray 16384 16384 0 0 0 0 \n";
    				}
    				$map .= "\t}\n";
    				$map .= "}\n";
    			}
    		}
    		
    		// global intermissions
    		foreach ($vmf["cameras"][0]["camera"] as $camera)
    		{
    			$origin = substr($camera["position"], 1, -1);
    			$map .= "{\n";
    			$map .= "\t\"classname\" \"mp_global_intermission\"\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"angles\" \"0 0 0\"\n";
    			$map .= "}\n";
    		}
    		
    		// origins
    		foreach ($vmf["entity"] as $entity)
    		{
    			if ($entity["classname"] != "info_teleport_destination")
    				continue;
    			$origin = convertunit($entity["origin"]);
    			$targetname = $entity["targetname"];
    			$map .= "{\n";
    			$map .= "\t\"classname\" \"script_origin\"\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"angles\" \"" . $entity["angles"] . "\"\n";
    			$map .= "\t\"targetname\" \"$targetname\"\n";
    			$map .= "}\n";
    			
    			// HACK HACK HACK -> otherwise those rooms are invisible
    			$map .= "{\n";
    			$map .= "\t\"classname\" \"mp_global_intermission\"\n";
    			$map .= "\t\"origin\" \"$origin\"\n";
    			$map .= "\t\"angles\" \"0 0 0\"\n";
    			$map .= "}\n";
    		}
    		foreach($vmf['entity'] as $entity) {
    			$model = $entity['model'];
    			$model = str_replace('-','_',$model);
    			$model = str_replace('.mdl,'_',$model);
    			if(preg_match('#.mdl#si',$model)) {
    				$origin = convertunit($entity['origin']);
    				$angles = $entity['angles'];
    				$model = explode('/',$model);
    				$model = $model[count($model)-1];
    				$map .= "{\n";
    				$map .= '"classname" "misc_model"';
    				$map .= '"model" "'.$model.'"';
    				$map .= '"origin" "'.$origin.'"';
    				$map .= '"angles" "'.$angles.'"';
    				$map .= "}\n";
    			}
    
    		}
    		
    		return $map;
    	}
    
    	function getNewMaterial($materialname)
    	{
    		return $materialname;
    	}
    	
    	ini_set("memory_limit", "500M");
    	
    	
    	$maps = array("cs_assault_d");
    
    	foreach ($maps as $name)
    	{
    		$missingTextures = array(); // global used to detect every missing texture only once
    		
    		
    		echo "Converting $name.vmf!\n";
    
    		$vmfString = file_get_contents("$name.vmf");
    		$vmf = parseVMF($vmfString);
    		$map = exportVMFasMAP($vmf, $extend_map);
    		$gsc = exportVMFasGSC($vmf);
    
    		//$map = convertVMF2Map($name . ".vmf");
    		if (!$map)
    			die("ERROR: Converting failed.\n");
    		
    		if (count($missingTextures))
    		{
    			$textureNames = array_keys($missingTextures);
    			foreach ($textureNames as $textureName)
    				echo "WARNING: no texture for $textureName\n";
    		}
    		
    		file_put_contents($name.".map", $map);
    	}

  2. The Following User Says Thank You to johndoe For This Useful Post:

    Ni3ls (6th May 2014)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •