Found a Gamemode-Script (Game-Rule-script)

You can talk about ManiaScript for ManiaPlanet here

Moderator: English Moderator

Post Reply
r3d_5haDow
Posts: 20
Joined: 20 Sep 2011, 15:27

Found a Gamemode-Script (Game-Rule-script)

Post by r3d_5haDow »

Hey Guys,

What I want to show you is the Gamemode-Script example I found in the Game Data.
It is called "TMSplitScreen_Competition.Script.txt"

I always thought that it's not possible to create your own gamemodes so far.

I will post the script here, so you can have a look at it:

Code: Select all

// *********************** ** ** *   *
// *    SplitScreen competition
// ******************* ** ** *   *

#RequireContext CTrackManiaRaceRules

#Setting PointsLimit 10
#Const RoundPoints [10,6,4,3,2,1]


// === Scores ===
Boolean IsRaceBetter(CTMRaceResultNod _Race1, CTMRaceResultNod _Race2)
{
	declare Comp = _Race1.Compare(_Race2, CTMRaceResultNod::ETMRaceResultCriteria::Time);
	return Comp > 0;
}

Text GetFrameMapTimes()
{
	declare Integer[Text] Times;
	Times["Gold"] = Map.MapParameters.GoldTime;
	foreach (Score in Scores) {
		if (Score.BestRace.Time != -1)
			Times[Score.PlayerInfo.Name] = Score.BestRace.Time;
	}
	Times = Times.sort();
	
	declare Frame = """	<frame posn="-160 86">
						<label posn="1 3" 	style="TextRaceStaticSmall" sizen="50 2" halign="left" text="$oBest times:"  />""";
	declare Line = 0;
	foreach (Name => Time in Times) {
		Frame ^= """<label posn="2 {{{-3*Line}}}" 	
                style="TextRaceStaticSmall" sizen="25 3" halign="left" text="{{{Name}}}"  />
		<label posn="30 {{{-3*Line}}}" 	style="TextPlayerCardScore" sizen="25 3" halign="left"
                text="$fff{{{Util_TimeToText(Time, True)}}}"  />""";
		Line += 1;
	}
	
	Frame ^=  """</frame>""" ;
	
	return Frame;
}

// === Race rounds ==
Void Race_DoRound()
{
	UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::Playing;
	
	CutOffTimeLimit = 0;
	Players_SpawnAll(Now + 2000);
	foreach(Score, Scores) {
		Score.PrevRaceDeltaPoints = 0;
	}
	sleep(500);	
	Synchro_DoBarrier();

	declare RoundArrivalOrder = Integer[Text];
	declare RoundArrivalOrderDirty = True; 
	declare MatchBestTime for Map = -1;
	
	UIManager.UIAll.ManialinkPage = GetFrameMapTimes();

	
	declare NbContestants = Players.count;
	while(  PlayersRacing.count > 0) {
		RunGame();
		EndRaceSequence_Update();
		
		if (MatchEndRequested)
			return;

		// Process events queue
		foreach(Event, PendingEvents) {	
			PassOn(Event);

			if (Event.Type == CTmRaceRulesEvent::EType::WayPoint && Event.IsEndRace) {
				declare Player <=> Event.Player;
				
				assert(Player.CurRace.Time == Event.RaceTime);
				Player.Score.PrevRace = Player.CurRace;
				if (IsRaceBetter(Player.CurRace, Player.Score.BestRace)) {
					Player.Score.BestRace = Player.CurRace;
					if (MatchBestTime == -1 || MatchBestTime > Event.RaceTime) {
						MatchBestTime = Event.RaceTime;
						EndRaceSequence_Add(Player, "$iNew match record! $o$112" ^
                                                Util_TimeToText(Event.RaceTime, True));
					} else {
						EndRaceSequence_Add(Player, "Personal record! $o$112" ^
                                                Util_TimeToText(Event.RaceTime, True));
					}
				} else {
					EndRaceSequence_Add(Player, "");
				}
				
				assert(!RoundArrivalOrder.existskey(Player.Id));
				RoundArrivalOrder[Player.Id] = Event.RaceTime;
				RoundArrivalOrderDirty = True;
				if (CutOffTimeLimit == 0) {		// grace preiod for the others to finish
					CutOffTimeLimit = Now + 5000 + Map.MapParameters.GoldTime/6;
				}
			}
		}
		
		// Refresh score table.		
		if (RoundArrivalOrderDirty) {
			RoundArrivalOrderDirty = False;
			RoundArrivalOrder = RoundArrivalOrder.sort();
			
			declare Index = 0;
			declare Table = """<scoretable type="time">""";
			foreach (PlayerId => Time in RoundArrivalOrder) {
				declare Player <=> Players[PlayerId];		// faut le PlayerInfo
				declare ScoreInc = 0;
				if (Index < RoundPoints.count)
					ScoreInc = RoundPoints[Index];
				else
					ScoreInc = 1;
				Index += 1;
				if (Index == NbContestants)		// last players gets no points.
					ScoreInc = 0;				
				
				Table ^= """<score login="{{{Player.Login}}}" value="{{{Time}}}" 
                                inc="{{{ScoreInc}}}"/>""";		
			}
			Table ^= """</scoretable>""";
			UIManager.UIAll.SmallScoreTable = Table;
			UIManager.UIAll.ManialinkPage = GetFrameMapTimes();
		}
		
		// end grace period if needed
		if (CutOffTimeLimit != 0 && Now > CutOffTimeLimit) {
			Players_UnspawnAll();
		}
	}
	
	Synchro_DoBarrier();

	// endround sequence
	sleep(1000);
	UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::EndRound;
	UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::ForcedVisible;
	
	// Compute result  (TODO: not duplicate the ScoreInc computation)
	declare Index = 0;
	foreach (PlayerId => Time in RoundArrivalOrder) {
		declare Player <=> Players[PlayerId];
		declare ScoreInc = 0;
		if (Index < RoundPoints.count)
			ScoreInc = RoundPoints[Index];
		else
			ScoreInc = 1;
		Index += 1;
		if (Index == NbContestants)		// last players gets no points.
			ScoreInc = 0;				

		Player.Score.PrevRaceDeltaPoints = ScoreInc;
	}

	sleep(2000);

	foreach(Score, Scores) {
		Score.Points += Score.PrevRaceDeltaPoints;
		Score.PrevRaceDeltaPoints = 0;
	}
	Scores_Sort(::ETMScoreSortOrder::TotalPoints);	

	sleep(2500);
	UIManager.UIAll.SmallScoreTable = "";
	UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::Normal;
	
	sleep(500);	
	Synchro_DoBarrier();
}

// === Main ===
main() 
{
	UIManager.ResetAll();
	log("restart...");
	
	IndependantLaps = False;
	UiRounds = True;
	AutoRespawnToGiveup = False;

	// loop on the playlist
	while( !ServerShutdownRequested ) {
		UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::ForcedVisible;
		UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::Intro;
		LoadMap();
		
		Players_UnspawnAll();
		Scores_Clear();
		
		
		//  ============ Séquence d'intro:
		{
			sleep(0);	// flush loading lag.
			UIManager.UIAll.ManialinkPage = GetFrameMapTimes();
	
			UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::ForcedVisible;
			UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::Intro;
			sleep(4000);	// HACK; should be "wait(sequences over)"
			
			UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::Normal;
			UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::Playing;
			foreach(Player, Players) {
				declare UI <=> UIManager.UI[Player];
				UI.BigMessage = Player.PlayerInfo.Name;
				UI.BigMessageAvatar = Player.PlayerInfo.Login;
				UI.BigMessageAvatarVariant = CGamePlaygroundUIConfig::EAvatarVariant::Default;
				Player.RaceStartTime = Now + 100000;			// spawn the cars.
			}
			sleep(3000);
			
			UIManager.UIAll.BigMessage = "";
			UIManager.UIAll.StatusMessage = "";
			foreach(Player, Players) {
				declare UI <=> UIManager.UI[Player];
				UI.BigMessage = "";
				UI.BigMessageAvatar = "";
				UI.StatusMessage = "";
			}
		}

		// ============ Play the rounds until the ending condition is reached.:
		while( !MatchEndRequested ) {
			Race_DoRound();
			
			declare BestScore = 0;
			if (Scores.count > 0 && Scores[0].Points >= PointsLimit)
				break; 		// score limit reached.
		}
		
		// ============ Séquence de fin:
		Players_UnspawnAll();
		if (Scores.count > 0 && Scores[0].Points > 0 && !ServerShutdownRequested) {
			UIManager.UIAll.ManialinkPage = GetFrameMapTimes();
			UIManager.UIAll.UISequence = CGamePlaygroundUIConfig::EUISequence::Podium;
			sleep(2500);
			UIManager.UIAll.ManialinkPage = GetFrameMapTimes() ^
				"""<frame posn="0 60">
				<quad  posn="0 3 -1"	sizen="130 14"	halign="center"	style="Bgs1InRace" 
                                substyle="BgTitle3"  />
				<label posn="0 0" halign="center" scale="2" 
                                text="{{{Scores[0].PlayerInfo.Name}}}$z wins the match!" />
				</frame>""";

			sleep(3000);
			UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::ForcedVisible;
			sleep(5000);
		}
		
		Synchro_DoBarrier();

		UIManager.UIAll.ScoreTableVisibility = CGamePlaygroundUIConfig::EVisibility::Normal;
		UIManager.UIAll.ManialinkPage = "";
		Scores_Clear();
		
		UnloadMap();
	}
}
You can find this script in the following folder: %GameFolder%\PublicFiles\PacksCache\TMCanyon_extras.zip\Scripts\Rules\Trackmania\

For me there are a lot of new variables inside this script.
You can use this script as it's own gamemode by starting a new server and choosing "Script" as gamemode.
I tried it out and it worked!

So as you can see it seems to be possible already to create you own gamemode.

The only problem is, that there isn't a documentation about all the variables and classes you can use in Game-Rule-scripts, I guess.

But maybe you know about such a documentation?

Greetings
metoxys
Translator
Translator
Posts: 1969
Joined: 15 Jun 2010, 20:45
Location: Germany
Contact:

Re: Found a Gamemode-Script (Game-Rule-script)

Post by metoxys »

Good job
nocturne
Posts: 208
Joined: 23 Jun 2010, 21:31

Re: Found a Gamemode-Script (Game-Rule-script)

Post by nocturne »

Cool... was wondering if there were any examples...

Gotta admit I was pretty damn confused when I tried mode 0 and ended up in a previously unmentioned 'script' mode... Seemed interesting, though I haven't come across any other info about it up until this point.

Nadeo has never been too great at documentation.. Most of the invaluable info we now have about the GBX format, the built-in image styles, and xmlrpc was almost exclusively made available by a few dedicated community members who spent untold amounts of time reverse engineering TM -- and there's still so, so much we're being left in the dark on..
User avatar
w1lla
Posts: 2287
Joined: 15 Jun 2010, 11:09
Location: Netherlands
Contact:

Re: Found a Gamemode-Script (Game-Rule-script)

Post by w1lla »

TM² Info
SM Info
QM Info

OS: Windows 10 x64 Professional
MB: MSI 970A-G46
Processor: AMD FX-6300 3500 mHz
RAM Memory: 16 GB DDR3
Video: SAPPHIRE DUAL-X R9 280X 3GB GDDR5
KB: Logitech G510s
Mouse: Logitech G300s
Mode Creation
ManiaScript Docs
konte
Posts: 236
Joined: 15 Jun 2010, 12:36
Location: Germany

Re: Found a Gamemode-Script (Game-Rule-script)

Post by konte »

Just wondering... would anyone be interesting in having this documented? I thought about doing it already when I first saw this but never managed to do it so far, and now I have the time to do it, but the question is, if anyone needs it at all.
(I would add it to my ManiaScript Documentation; probably a bit more explained...)
metoxys
Translator
Translator
Posts: 1969
Joined: 15 Jun 2010, 20:45
Location: Germany
Contact:

Re: Found a Gamemode-Script (Game-Rule-script)

Post by metoxys »

konte wrote:Just wondering... would anyone be interesting in having this documented? I thought about doing it already when I first saw this but never managed to do it so far, and now I have the time to do it, but the question is, if anyone needs it at all.
(I would add it to my ManiaScript Documentation; probably a bit more explained...)
Yeeheeehees, document it!
Wonderful to see a post of you here
Post Reply

Return to “ManiaScript”

Who is online

Users browsing this forum: No registered users and 2 guests