PHP GD + Far Cry 3

I’ve never had as much fun with PHP since the day I stopped using it for building websites. There’s a lot of fun to get out of it as a general scripting language and here’s another example.

I wanted to get stats about Far Cry 3 weapons, so I decided to do a bit of reverse engineering. The game has an iPhone app that lets you do “load outs” displaying weapons and bar charts for each property (damage, range, accuracy, fire rate and mobility). All I needed to do was to calculate the length of each property bar in pixels.

P416

Now, the code which I’m going to go through is targeting particular areas of the image but in order to get to that point I needed to do a couple things.
1) Find the rgb color of the bar charts, I’ve used pixlr.com for that.
2) Find which ranges I needed to iterate through, a couple of horizontal and vertical loops did the trick.

Right, let’s look at some code now.

First we need to init the main variables.

$stats_color = 7833746;
$stats_base_px = 242;
$stats_boxes_top = array(590, 636, 682, 728, 774);
$stats_boxes_height = 12;

$stats_color is the int value of the rgb color returned by the imagecolorat function, that’s the value I’ve picked up using pixlr.com.
$stats_base_px represents the x value of where the bar charts start.
$stats_boxes_top contains the y values of the top of each bar chart.
$stats_boxes_height is the height of the bar chart itself.

Then, for each screenshot to process (one per weapon) we need to init some more variables.

$image_info = getimagesize ($image_file);
$image_width = $image_info[0];

$im = imagecreatefrompng($image_file);
$stats_values = array(0, 0, 0, 0, 0);

We make a call to getimagesize in order to get the image width so we don’t loop outside the image boundary. We then load the image in memory using imagecreatefrompng. $stats_values will hold each property (range, damage, accuracy, fire rate and mobility) which we will then display.

$sb_i = 0;
$sb_n = count($stats_boxes_top);

while($sb_i < $sb_n)
{
	$y = $stats_boxes_top[$sb_i];
	$y_bottom = $y + $stats_boxes_height;

	while($y < $y_bottom)
	{
		$x = $stats_base_px;

		while ($x < $image_width) 		{ 			$rgb = imagecolorat($im, $x, $y); 			if($rgb == 7833746 && $x - $stats_base_px > $stats_values[$sb_i])
				$stats_values[$sb_i] = $x - $stats_base_px + 1;
			$x++;
		}
		$y++;
	}
$sb_i++;
}

So, we loop through each bar charts representing range, damage, accuracy, etc; vertically through all 12 pixels height and horizontally from $stats_base_px where the bar chart starts to the end the image.

We could argue that we only need to do it for the first pixel (top down) and until we reach a different colour (across).
The reason for this is that the bar chart is not a solid rectangle, there is a filter applied to it which, at times, makes the bar “discontinuous” on a single pixel height. This is why we have to find the farthest “grey” pixel from the $stats_base_px position (on x axis) across all 12 pixels height of the bar chart (on the y axis).

finally, although absent from the code snippet I have echo lines to display the result in Sublime Text, ready to be copied/pasted into excel. So for each weapon you can see the property value measured in pixels.

output

Full php script available here.
iPhone screenshots available here.

Advertisements
PHP GD + Far Cry 3

One thought on “PHP GD + Far Cry 3

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s