Page 1 of 1

CrowTourney sample code

Posted: Tue Jun 04, 2013 5:29 pm
by Mit
Hallo,
Here you'll find some details on the basic 'crow tourney' script i've used on the worlds so far. Its not a completely straightforward example (intermediate coder level 1 :]) but it shouldn't be terribly difficult to add and adapt this to your own world.. and if anyone wants to use it as a basis for something more complicated (team matches, multi-round duels or whatever) feel free to share your own variants. :]

There are 2 files involved in the crow tourney.. one for the script itself, one for the associated cutscene. You can get these files here:
http://theuniversal.net/samples/CrowTou ... Sample.mit
http://theuniversal.net/samples/CrowTou ... Sample.cut

Quick-start guide
If you don't want the gory details, you can include the sample in your own world by following these steps:
1 - Copy those 2 files into your world's Data\Scripts folder
2 - Add the following to your ServerScript.mit file :

Code: Select all

#include "CrowTourneySample.mit"
global $kPlayerVarCrowGameSignUp  = 12 
3 - Press f11 to reload the script
4 - Type *event [your_name] Crows to activate the tourney.

The Gory Details
I will now endeavour to explain each and every line.. Open up the sample and read along with mit :)

Code: Select all

//--------------------------------------------------------
// CrowTourney stuff 
//--------------------------------------------------------
// *** Uses  $gPlayerVar[$kPlayerVarCrowGameSignUp] to record opt-in state
//--------------------------------------------------------
Ok.. first off we start off with a nice little header comment block, so we know what we're dealing with. Its CrowTourney stuff, yay.

Unfortunately it has to start a little complicated by mentioning the use of a player var.
As it says, the crow tourney script uses a single player var to record whether or not each player is currently signed up for the tourney.
For Aramathea " $kPlayerVarCrowGameSignUp " is defined in a separate file as such..

Code: Select all

global $kPlayerVarCrowGameSignUp = 12
so " $gPlayerVar[$kPlayerVarCrowGameSignUp] " is the same as saying $gPlayerVar[12]. Using a separate global variable to specify the playervar number just means you have to just change that one variable if you want to use a different playervar (perhaps you're already using playervar 12 for something else..)

Ok, thats the hard bit over.. everything else is easy from now on :). Next..

Code: Select all

$mCrowTourneyGameHighestScore = 0
$mCrowTourneyGameHighestPlayerID = 0
$mCrowTourneyNumSignups = 0
These are the script's 'Module Variables'. More on these in a bit.

Code: Select all

//----------------------------------------------------------------
//  SignUp Phase
//----------------------------------------------------------------
Another wee comment block.. This just helps organise the code a bit so its easier to find the stuff you're looking for. The following bits of script code refer to the signup section, prior to the cutscene. Ok, so on to our first bit of proper code :

Code: Select all

//-------------------------------------------------
//  Use  *event [OWNER] crows  
//  to start a crow tourney off
//-------------------------------------------------
Event( "Custom", "crows" )
{
	$mCrowTourneyGameHighestScore = 0
	$mCrowTourneyGameHighestPlayerID = 0
	$mCrowTourneyNumSignups = 0

	*eao initialsignupmessage
	$timerID = sysSetTimer( 30, "SecondSignupMessage", "" ) 
}
So we start with a few more comments.. Always handy to remind yourself how to operate your script by including a few comments - otherwise you will forget and waste a lot of time trying to work out what you did. The comment here should be pretty clear.. to start off a tourney I would type " *event Mit Crows ".
Below the comment is the custom event function that gets triggered when i type that.
The first 3 lines just make sure our module variables are set back to 0. More on those in a bit :)
The next line :

Code: Select all

	*eao initialsignupmessage
uses the *eao command (*eventallonline) which means the 'initialsignupmessage' event is triggered for all users currently online.
The next line then sets a timer so that the event "SecondSignupMessage" is activated after 30 seconds.
Next we have the 'initialsignupmessage' event that is triggered for all users..

Code: Select all

Event( "custom", "initialsignupmessage" )
{
	$gPlayerVar[$kPlayerVarCrowGameSignUp] = 0
	*msg %PLAYER% 2 min crow tourney starts in 60 seconds. Type  &joincrow   to sign up
}
Hopefully this is pretty straightforward.. For everyone currently online, the first line sets their signup playervar (i.e. gPlayerVar[12] ) to 0, indicating the player is not currently signed up for the tourney. The second line sends each player a message that appears in the chat log, urging them to sign up.

Whether or not they do, 30 seconds later that timer we created earlier will be set off, and the next code block is triggered

Code: Select all

Event( "Timer", "SecondSignupMessage" )
{
	*soundeffect 24
	*say 2 min crow tourney starts in 30 seconds. Type  &joincrow   to sign up if you haven't already done so
	$timerID = sysSetTimer( 25, "CrowTourneyStart", "" ) 
}
Line 1.. we play a sound effect and wake Fooli up. Line 2 is another message prompting the players to sign up (Aramathea does this slightly differently by using another *eao event .. but i've simplified it here :] ). Finally we set another timer to be triggered in 25 seconds, and that 'CrowTourneyStart' event will be the thing that gets the tourney going.
Before we move on to the tourney start, theres the code that handles the user signup..

Code: Select all

Event( "&command", "joincrow" )
{
	$ret = CrowTourneySignUp()
}
This event reacts to the user typeing "&joincrow" - the reaction being to call a custom function called 'CrowTourneySignUp'. The function is defined next :

Code: Select all

Function	CrowTourneySignUp( )
{
	if ( $gPlayerVar[$kPlayerVarCrowGameSignUp] == 0 )
	{
		$gPlayerVar[$kPlayerVarCrowGameSignUp] = 1
		*say %PLAYER% signed up for the crow tourney
		$mCrowTourneyNumSignups = $mCrowTourneyNumSignups + 1
		*crowspawn %PLAYER% 162 112
	}
	else
	{
		*msg %PLAYER% You're already signed up
	}
}
In english, this says : If the player hasn't already signed up, set the sign-up state in their playerVar, send a message out to everyone to say they've signed up, increase the module variable recording the number of people who've signed up, then set the player's crow spawn position to a certain point on the map (162,112). If they have already signed up, just send them a message back.

(Note the reason that code is in a function, rather than just being in the &command event, is so that we can call the same block from other places - e.g. we could pop up a little window with a button labelled 'Join the Crow Game'.)

Ok next.. 25 seconds after the second sign up message, the 'CrowTourneyStart' timer event is triggered for the owner.

Code: Select all

Event( "Timer", "CrowTourneyStart" )
{
	if ( $mCrowTourneyNumSignups >= 2 )
	{
		*soundeffect 8
		Sleep(60)			// 6 seconds (for trumpet sound)
		*lockweapons
		*resetallcrowscores
		*say Crow Tournament commencing!
		*eao crowcutscenestart

		$timerID = sysSetTimer( 25, "CrowGameLeadInSequence", "" ) 
	}
	else if ( $mCrowTourneyNumSignups == 1 )
	{
		*say Tournaments need at least 2 players.. 
	}
	else
	{
		*say Tournament cancelled
	}
}
First this bit of code checks if theres enough players signed up to make the event worthwhile - if none or only 1 player signed up, a message is printed and we're done. If there's 2 or more players active, then we go through a number of steps. First we player a sound (soundeffect 8 is the bugle sound), then we wait for 6 seconds. After that we lock all weapons, reset the crow scores (kills & deaths), print a message to everyone indicating the tourney is about to start, trigger the "crowcutscenestart" event for everyone online (see below), then activate a timer called "CrowGameLeadInSequence" that'll fire off in 25 seconds.

Code: Select all

Event( "Custom", "crowcutscenestart" )
{
	if ( $gPlayerVar[$kPlayerVarCrowGameSignUp] == 1 )
	{
		*playmusic %PLAYER% http://gameislands.net/gamecontent/genesis/crowtoons/honey-2mincrowedit.mp3
		*cutscene %PLAYER% CrowTourneySample.cut
	}
}
So assuming the tourney has started, this event is called for everyone currently online. The script checks if the player signed up, and if so plays some music and activates the cutscene. (If they aren't signed up, it doesnt do anything).

I'll describe the cutscene separately, but if you open the .cut file you may notice about halfway down the line

Code: Select all

	CustomEvent( 5.0,"tourneycutgocrow","0" );
.. this bit means that everyone running the cutscene triggers a script event, 5 seconds into section 2 of the cutscene. Back in the script file, the event is :

Code: Select all

Event( "Custom", "tourneycutgocrow" )
{
	*gocrow %PLAYER%
}
which is about the most straightforward bit of script here :). It just sends the player to crow mode.

Now remember a little while ago we set up a timer - while the cutscene is still going on the following event will fire :

Code: Select all

Event( "Timer", "CrowGameLeadInSequence" )
{
	*say Weapons are locked... Get to your positions.
	Sleep(50)		// 5 seconds
	*say Weapons unlocked in 10 seconds. Ready up!
	Sleep (70)
	*say 3 seconds..
	Sleep(10)
	*say 2...
	Sleep(10)
	*say 1...
	Sleep(10)
	*unlockweapons
	*eao CrowTourneyAddTimer
	$timerID = sysSetTimer( 105, "CrowGameEndSequence", "" ) 
}
This prints a message, waits 5 seconds, prints another message, waits 7 seconds, does a wee countdown, then unlocks weapons, triggers the "CrowTourneyAddTimer" event for everyone online, and sets up a timer that'll deal with the end of the match.

Code: Select all

Event( "Custom", "CrowTourneyAddTimer" )
{
	if ( $gPlayerVar[$kPlayerVarCrowGameSignUp] == 1 )
	{
		*onscreentimer %PLAYER%,0,120
	}
}
This event just checks whether the user is signed up for the tourney or not, and if so adds a on-screen timer clock.

Nearly done now.. On the home stretch.. :)
Our participants have now been flying about blasting each other for almost 2 minutes when the end sequence timer we set off earlier is activated..

Code: Select all

Event( "Timer", "CrowGameEndSequence" )
{
	*say ----------------------- 15 seconds remaining ---------------------------------
	Sleep (150)		// 15 secs

	*exitcrowall
	*eao showcrowscores
	Sleep (50)		// 5 secs

.....
If you've got this far, first bit shouldn't need explanation.. we print a message and wait a bit. We then use the *exitcrowall command to send everyone back to their normal vehicles. We trigger the "showcrowscores" event for everyone online (see below) then wait a little while. I've split the code off here because it makes more sense to look at that event first..

Code: Select all

Event( "Custom", "showcrowscores" )
{
	if ( $gPlayerRobocrowKills > 0 )
	{
		*say %PLAYER% - Kills: $gPlayerRobocrowKills    Deaths: $gPlayerRobocrowDeaths

		// Calc players score
		$crowScore = $gPlayerRobocrowKills * 1000

		if ( $gPlayerRobocrowDeaths == 0 )
		{
			$crowScore = $crowScore + 999
		}
		else 
		{
			$ratio = $gPlayerRobocrowKills * 50
			$ratio = $ratio / $gPlayerRobocrowDeaths
			$crowScore = $crowScore + $ratio
		}

		// If score is higher than any others already registered
		if ( $crowScore > $mCrowTourneyGameHighestScore )
		{
			$mCrowTourneyGameHighestScore = $crowScore
			$mCrowTourneyGameHighestPlayerID = $gPlayerID
		}
	}
	*fademusic %PLAYER% 5
	// Clear the sign up state now, ready for the next game
	$gPlayerVar[$kPlayerVarCrowGameSignUp] = 0
}
I'll let you figure out the specifics of what the maths is doing here, but suffice to say that everyone who had at least one kill will sendt out their score to everyone else, and if their overall score was better than anyone else, their ID is stored in the module variables we initialised at the start. For good measure we also fade off the music and reset their signup state ready for the next time round.

With that event triggered for all active users, we now go back to the last bit of the endSequence event to finish off..

Code: Select all

	$winnerID = $mCrowTourneyGameHighestPlayerID
	if ( $winnerID > 0 )
	{
		$name = sysGetPlayerName( $winnerID )
		*say Shamanic crow tournament winner is $name
	}
	else
	{
		*say Tournament over - no winner
	}
	$mCrowTourneyNumSignups = 0
}
The playerID with the best score has now been stored in $mCrowTourneyGameHighestPlayerID, and we announce the winner in red text. We could give em cash or points or items or whatever too, of course.
Job done.