Building Browsergames: Swapping Weapons (Perl)

The results of our poll from earlier have been decided, and the option ‘Toggle active weapons’ won by a slim margin. So, that’s what we’ll be building today!

The ’swap weapon’ page is a simple one – we’ve already written most of the code when we wrote the purchasing logic in our weapon shop from earlier. To start off with, we’ll need a template(named equipment.tmpl):

<html>
<head>
	<title>Equipment Management</title>
</head>
<body>
	<h3>Current Equipment:</h3>
	<p><a href='index.cgi'>Back to main</a></p>
	<ul>
		<li>
			Primary Hand:
			<tmpl_if name='phand'>
				<!--tmpl_var name='phand'-->
				<form action='weapon-shop.cgi' method='post'>
					<input type='hidden' name='sell' value='phand' />
					<input type='submit' value='Sell' />
				</form>
			<tmpl_else>
				None
			</tmpl_if>
		</li>
		<li>
			Secondary Hand:
			<tmpl_if name='shand'>
				<!--tmpl_var name='shand'-->
				<form action='weapon-shop.cgi' method='post'>
					<input type='hidden' name='sell' value='shand' />
					<input type='submit' value='Sell' />
				</form>
			<tmpl_else>
				None
			</tmpl_if>
		</li>
	</ul>
	<p>
		<form action='equipment.cgi' method='post'>
			<input type='submit' value='Swap' name='swap' />
		</form>
	</p>
</body>
</html>

This is a simple template, and is actually a duplication of our weapon shop’s template – right down to the ‘Sell’ button. By leaving the ‘Sell’ button on this page, users can sell their weapons from the equipment management screen if they so choose(also, because of this duplication we can trim this down to a common template – but that will come later). We have to make sure that the ’swap’ button has a ‘name’ attribute, so that we can make sure our page was POSTed to and swap the player’s weapons.

Next, we’ll build equipment.cgi, which is the page responsible for retrieiving the weapons a user is user, and displaying our template:

 

#!/usr/bin/perl -w
 
use strict;
use CGI qw(:cgi);
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use HTML::Template;
use DBI;
use config;
 
my $query = new CGI;
my %arguments = $query->Vars;
 
my $dbh = DBI->connect("DBI:mysql:$config{dbName}:$config{dbHost}",$config{dbUser},$config{dbPass},{RaiseError => 1});
my $sth;
my %parameters;
 
use stats;
 
my $cookie = $query->cookie('username+password');
my ($username) = split(/\+/,$cookie);
$sth = $dbh->prepare("SELECT id FROM users WHERE UPPER(username) = UPPER(?)");
$sth->execute($username);
my $userID;
$sth->bind_columns(\$userID);
$sth->fetch;
 
my $phand = stats::getStat('phand',$userID);
my $shand = stats::getStat('shand',$userID);
 
$sth = $dbh->prepare("SELECT name FROM items WHERE id = ?");
$sth->execute($phand);
my $phand_name;
$sth->bind_columns(\$phand_name);
$sth->fetch;
if($phand_name) {
	$parameters{phand} = $phand_name;
}
 
# $sth is already prepared, so all we do is re-execute
$sth->execute($shand);
my $shand_name;
$sth->bind_columns(\$shand_name);
$sth->fetch;
$parameters{shand} = $shand_name if $shand_name;
my $template = HTML::Template->new(
		filename	=>	'equipment.tmpl',
		associate	=>	$query,
	);
$template->param(%parameters);
print $query->header(), $template->output;

We don’t need to add much to implement weapon swapping; just a simple swap when users click on the ’swap’ button. We do this by checking to see if the page has been POSTed to – if it has, we perform the swap:

 

if(%arguments) {
	stats::setStat('phand',$userID,$shand);
	stats::setStat('shand',$userID,$phand);
	my $temp = $shand;
	$shand = $phand;
	$phand = $temp;	
}

With that done, we’re finished! Users can now swap the weapons in their primary and secondary hands quickly and easily from the equipment management page. All we have left to do is add a link to the equipment management page to our index template:

 

<p><a href='equipment.cgi'>Equipment Management</a></p>

And we’re done! Here’s our template:

 

<html>
<head>
	<title>Equipment Management</title>
</head>
<body>
	<h3>Current Equipment:</h3>
	<p><a href='index.cgi'>Back to main</a></p>
	<ul>
		<li>
			Primary Hand:
			<tmpl_if name='phand'>
				<!--tmpl_var name='phand'-->
				<form action='weapon-shop.cgi' method='post'>
					<input type='hidden' name='sell' value='phand' />
					<input type='submit' value='Sell' />
				</form>
			<tmpl_else>
				None
			</tmpl_if>
		</li>
		<li>
			Secondary Hand:
			<tmpl_if name='shand'>
				<!--tmpl_var name='shand'-->
				<form action='weapon-shop.cgi' method='post'>
					<input type='hidden' name='sell' value='shand' />
					<input type='submit' value='Sell' />
				</form>
			<tmpl_else>
				None
			</tmpl_if>
		</li>
	</ul>
	<p>
		<form action='equipment.cgi' method='post'>
			<input type='submit' value='Swap' name='swap' />
		</form>
	</p>
</body>
</html>

And here’s the code responsible for displaying it and handling the swap:

 

#!/usr/bin/perl -w
 
use strict;
use CGI qw(:cgi);
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use HTML::Template;
use DBI;
use config;
 
my $query = new CGI;
my %arguments = $query->Vars;
 
my $dbh = DBI->connect("DBI:mysql:$config{dbName}:$config{dbHost}",$config{dbUser},$config{dbPass},{RaiseError => 1});
my $sth;
my %parameters;
 
use stats;
 
my $cookie = $query->cookie('username+password');
my ($username) = split(/\+/,$cookie);
$sth = $dbh->prepare("SELECT id FROM users WHERE UPPER(username) = UPPER(?)");
$sth->execute($username);
my $userID;
$sth->bind_columns(\$userID);
$sth->fetch;
 
my $phand = stats::getStat('phand',$userID);
my $shand = stats::getStat('shand',$userID);
if(%arguments) {
	stats::setStat('phand',$userID,$shand);
	stats::setStat('shand',$userID,$phand);
	my $temp = $shand;
	$shand = $phand;
	$phand = $temp;	
}
 
$sth = $dbh->prepare("SELECT name FROM items WHERE id = ?");
$sth->execute($phand);
my $phand_name;
$sth->bind_columns(\$phand_name);
$sth->fetch;
if($phand_name) {
	$parameters{phand} = $phand_name;
}
 
# $sth is already prepared, so all we do is re-execute
$sth->execute($shand);
my $shand_name;
$sth->bind_columns(\$shand_name);
$sth->fetch;
$parameters{shand} = $shand_name if $shand_name;
my $template = HTML::Template->new(
		filename	=>	'equipment.tmpl',
		associate	=>	$query,
	);
$template->param(%parameters);
print $query->header(), $template->output;