Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: VMF2Map

  1. #11
    ... connecting
    Join Date
    Jan 2014
    Posts
    7
    Thanks
    0
    Thanked 4 Times in 3 Posts
    I changed some parts of the script to prevent texture replacement and exported the original textures from cs source to codwaw. This is how it looks.










    I'm still trying to port the models but i accidentally deleted cs source. I'll try to get back to work on that as soon as possible.

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

    kung foo man (28th March 2014)

  3. #12
    ... connecting
    Join Date
    Jan 2014
    Posts
    7
    Thanks
    0
    Thanked 4 Times in 3 Posts
    Ported the models and added my own touch to the script to place the models to the correct origins. Here's what i have now. I realized the size of a unit in source engine doesn't match cod's though, so i have to realign the models and the map will be pretty much done. Thank you guys for the vmf parser by the way, it saved me lots of time
    Attached Thumbnails Attached Thumbnails shot0032.jpg   shot0033.jpg   shot0034.jpg   shot0035.jpg   shot0036.jpg  

    shot0037.jpg   shot0038.jpg   shot0039.jpg   shot0040.jpg  

  4. The Following 2 Users Say Thank You to johndoe For This Useful Post:

    kung foo man (28th March 2014),Ni3ls (6th May 2014)

  5. #13
    ... 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);
    	}

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

    Ni3ls (6th May 2014)

  7. #14
    ... connecting
    Join Date
    Jan 2014
    Posts
    7
    Thanks
    0
    Thanked 4 Times in 3 Posts
    I know most people on here will not be interested, but i'm trying to convert the terrain patches as well. I was planning on making an application that ports source engine maps to cod using the vmf parser and the only missing thing is the terrain patches which i couldn't manage to convert. I don't know much about both vmf and map file formats so i thought it'd be best to ask it here. If any of you guys can help me it'll be really great. Thanks in advance.

  8. #15
    Sergeant serthy's Avatar
    Join Date
    Nov 2012
    Posts
    450
    Thanks
    96
    Thanked 296 Times in 188 Posts
    Quote Originally Posted by johndoe View Post
    ...terrain patches which i couldn't manage to convert...
    iirc i used the vmf2map converter only with terrain patches :0
    http://killtube.org/showthread.php?1...2Map-mesh-wise

  9. #16
    ... connecting
    Join Date
    Jan 2014
    Posts
    7
    Thanks
    0
    Thanked 4 Times in 3 Posts
    Quote Originally Posted by serthy View Post
    iirc i used the vmf2map converter only with terrain patches :0
    http://killtube.org/showthread.php?1...2Map-mesh-wise
    unfortunately obj2map doesn't do the trick for me. i can however convert the terrain patches from a source map to an obj file and convert it to a map file, but the map file created with obj2map isn't really memory-friendly and i never got it with the correct size of the map. even if it does convert the patches correctly, it still makes the whole porting process more complicated and harder. that's why i asked for help on this topic, but if i'm wrong about obj2map, please inform me. thanks for replying btw

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
  •