Hier geht es darum, wie man auf dem HUD seine aktuellen stats angezeigt bekommt.
Als erstes erarbeiten wir uns jetzt einmal die Datei, die das ganze letztendlich auch bewerkstelligen soll.
Erstellt eine Datei mit der Endung '.gsc', ich nenne sie hier stats.gsc.
In diese schreiben wir nun als erstes unsere Initialisierungsfunktion, welche sobald eine Map geladen wird als allererstes aufgerufen wird.
Alle Texte/Bilder die als HUD auf dem Bildschirm zu sehen sind, müssen in erstem Serverframe geladen werden, ansonsten wird es zu Serverabstürzen kommen.
Also machen wir das gleich mal:
php: |
1:
2:
3:
4:
5:
|
init()
{
precacheString( &"^5~>^7Score: &&1" ); //&&1 wird dann mit einer variablen ersetzt
precacheString( &"^5~>^7Deaths: &&1" );
} |
|
Als nächstes müssen wir jetzt alle Spieler die auf den Server connecten erfassen, sowohl ls auch wenn sie spawnen, um das HUD auch anzeigen zu lassen.
Das passiert hiermit:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
|
init()
{
precacheString( &"^5~>^7Score: &&1" );
precacheString( &"^5~>^7Deaths: &&1" );
level thread onPlayerConnected(); //Funktionsaufruf
}
onPlayerConnected()
{
while( true )
{
level waittill( "connected" , player ); //warten bis Spieler connected
if( !isDefined( player.score ) ) //stats initialisieren, falls nocht nicht geschehen
player.score = 0;
if( !isDefined( player.deaths ) )
player.deaths = 0;
player thread onPlayerSpawned(); //Spieler führt jetzt vers. Funktionen aus
}
}
onPlayerSpawned() //überwacht Spawns des Spielers (self = Spieler)
{
self endon( "disconnect" ); //wenn Spieler das Spiel verlässt, beendet sich die Funktion
while( isDefined( self ) )
{
self waittill( "spawned" );
wait( 0.05 );
if( self.pers["team"] == "spectator" )
{
//kein StatsHUD für Zuschauer
self thread destroyStatsboard();
}
else
{
//hier nun HUD anzeigen lassen
self thread drawStatsboard();
self thread monitorPlayer();
}
}
} |
|
Jetzt schreiben wir die Funktion, welche die HUD's erzeugt. Diese wird an jedem Spawn neu aufgerufen:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
drawStatsboard()
{
self endon( "disconnect" );
//HUDs von Funktion erstellen lassen
self.hud_stats_score = self createStatsboardLine( 0 , &"^5~>^7Score: &&1" );
self.hud_stats_deaths = self createStatsboardLine( 1 , &"^5~>^7Deaths: &&1" );
}
createStatsboardLine( lineCount , label ) //erstellt das HUD
{
x = -100;
y = 0;
vertAlign = "middle";
horzAlign = "right";
lineHeight = 10;
hud = newClientHudElem( self ); //erstellt HUD das nur für 1 Spieler zu sehen ist (self = Spieler)
hud.x = x;
hud.y = y + ( lineCount * lineHeight ); //legt Reihe fest
hud.vertAlign = vertAlign; //Alignment auf dem Bildschirm
hud.horzAlign = horzAlign; //Alignment auf dem Bildschirm
hud.archived = true; //.archived legt fest, ob das HUD in der Killcam zusehen ist
hud.label = label; //.label beinhaltet unseren String, somit können noch mit setText() oder setValue() andere Werte mit dem selben HUD angezeigt werden
hud setValue( 0 );
return hud; //und HUD wieder zurückgeben
} |
|
Okay, nun wird das HUD am Spawn erzeugt, nun kommt der Teil, wo das HUD aktualisiert wird. Diese Funktion wird überall da aufgerufen, wo die Werte sich verändertn (Kill...)
Zudem werde ich hier nur 2 Werte (score/deaths) betrachten, für headshots etc müsst ihr in die jeweiligen gametypes (tdm.gsc/sd.gsc...) gehen und in der Funktion 'Callback_PlayerKilled' einen headshotcounter einführen (if( sMeansOfDeath == "MOD_HEAD_SHOT" ) eAttacker.headshots++
, und noch einige Dinge mehr, aber das würde jetzt zu viel Aufwand auf einmal sein
Zugegeben die monitorPlayer()-Funktion ist nicht besonders schön, dafür aber einfach. Besser wäre es wirklich direkt beim Kill in die oben genannte Funktion zu gehen und eAttacker thread mod\stats::updateLivestats(); sowie das selbe für den Toten zu machen, das spart uns einen Loop für jeden Spieler.
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
|
updateStatsboard()
{
if( isDefined( self.hud_stats_score ) )
self.hud_stats_score setValue( self.score );
if( isDefined( self.hud_stats_deaths ) )
self.hud_stats_deaths setValue( self.deaths );
}
monitorPlayer()
{
self endon( "disconnect" );
score = 0;
deaths = 0;
while( isDefined( self ) )
{
update = false;
if( score != self.score )
update = true;
else if( deaths != self.deaths )
update = true;
if( update )
self thread updateStatsboard();
if( self.sessionstate != "playing" )
break;
wait( 1.0 );
}
} |
|
nun fehlt noch eine letzte Kleinigkeit. Irgendwie muss der Bildschirm wieder freigemacht werden, dazu müssen wir die HUDS wieder beseitigen:
php: |
1:
2:
3:
4:
5:
6:
7:
|
destroyStatsboard()
{
if( isDefined( self.hud_stats_score ) )
self.hud_stats_score destroy();
if( isDefined( self.hud_stats_deaths ) )
self.hud_stats_deaths destroy();
} |
|
Alles zusammen sieht dann so aus (ich habe noch einige Kleinigkeiten hinzugefügt, die sollten aber verständlich sein):
Code angehängt. Klicke hier zum Ein-/Ausblenden
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
|
init()
{
precacheString( &"^5~>^7Score: &&1" );
precacheString( &"^5~>^7Deaths: &&1" );
level thread onPlayerConnected(); //Funktionsaufruf
}
onPlayerConnected()
{
while( true )
{
level waittill( "connected" , player ); //warten bis Spieler connected
if( !isDefined( player.score ) ) //stats initialisieren, falls nocht nicht geschehen
player.score = 0;
if( !isDefined( player.deaths ) )
player.deaths = 0;
player thread onPlayerSpawned(); //Spieler führt jetzt vers. Funktionen aus
}
}
onPlayerSpawned() //überwacht Spawns des Spielers (self = Spieler)
{
self endon( "disconnect" ); //wenn Spieler das Spiel verlässt, beendet sich die Funktion
while( isDefined( self ) )
{
self waittill( "spawned" );
wait( 0.05 );
if( self.pers["team"] == "spectator" )
{
//kein StatsHUD für Zuschauer
self thread destroyStatsboard();
}
else
{
//hier nun HUD anzeigen lassen
self thread drawStatsboard();
self thread monitorPlayer();
}
}
}
monitorPlayer()
{
self endon( "disconnect" );
score = 0;
deaths = 0;
while( isDefined( self ) )
{
update = false;
if( score != self.score )
update = true;
else if( deaths != self.deaths )
update = true;
if( update )
self thread updateStatsboard();
if( self.sessionstate != "playing" )
break;
wait( 1.0 );
}
}
drawStatsboard()
{
self endon( "disconnect" );
self thread destroyStatsboard(); //falls schon vorhanden, erst entfernen!
//HUDs von Funktion erstellen lassen
self.hud_stats_score = self createStatsboardLine( 0 , &"^5~>^7Score: &&1" );
self.hud_stats_deaths = self createStatsboardLine( 1 , &"^5~>^7Deaths: &&1" );
}
createStatsboardLine( lineCount , label ) //erstellt das HUD
{
x = -100;
y = 0;
vertAlign = "middle";
horzAlign = "right";
lineHeight = 10;
hud = newClientHudElem( self ); //erstellt HUD das nur für 1 Spieler zu sehen ist (self = Spieler)
hud.x = x;
hud.y = y + ( lineCount * lineHeight ); //legt Reihe fest
hud.vertAlign = vertAlign; //Alignment auf dem Bildschirm
hud.horzAlign = horzAlign; //Alignment auf dem Bildschirm
hud.archived = true; //.archived legt fest, ob das HUD in der Killcam zusehen ist
hud.label = label; //.label beinhaltet unseren String, somit können noch mit setText() oder setValue() andere Werte mit dem selben HUD angezeigt werden
hud setValue( 0 );
return hud; //und HUD wieder zurückgeben
}
updateStatsboard()
{
if( isDefined( self.hud_stats_score ) )
self.hud_stats_score setValue( self.score );
if( isDefined( self.hud_stats_deaths ) )
self.hud_stats_deaths setValue( self.deaths );
}
destroyStatsboard()
{
if( isDefined( self.hud_stats_score ) )
self.hud_stats_score destroy();
if( isDefined( self.hud_stats_deaths ) )
self.hud_stats_deaths destroy();
} |
|
So, das spiechert ihr in eurer stats.gsc, meine liegt im Verzeichnis cod2/fs_game/mod/stats.gsc
Als letztes geht in in die maps/mp/gametypes/_callbacksetup.gsc, diese wird von allen Spieltypen verwendet, so braucht man die folgende Zeilen nicht in jede sd.gsc etc neu einfügen.
In der ersten Funktion, Callback_StartGameType ruft ihr eure stats.gsc nun auf:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
Callback_StartGameType()
{
// If the gametype has not beed started, run the startup
level thread mod\stats::init();
if(!isDefined(level.gametypestarted) || !level.gametypestarted)
{
[[level.callbackStartGameType]]();
level.gametypestarted = true; // so we know that the gametype has been started up
}
} |
|
Soweit sollte alles klappen, viel Spaß =)
cheers Serthy