commit 4E version
This commit is contained in:
2077
Sources/Classes/SmartCTF.uc
Normal file
2077
Sources/Classes/SmartCTF.uc
Normal file
File diff suppressed because it is too large
Load Diff
35
Sources/Classes/SmartCTFAudioMsg.uc
Normal file
35
Sources/Classes/SmartCTFAudioMsg.uc
Normal file
@@ -0,0 +1,35 @@
|
||||
// This is a fix to be able to get certain sounds to play. Certain sounds like Assist and Capture only
|
||||
// work on the client. By simply sending this message instead of ClientPlaySound on the server we don't need
|
||||
// to include the sounds in the pack.
|
||||
|
||||
class SmartCTFAudioMsg expands LocalMessagePlus;
|
||||
|
||||
static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static simulated function ClientReceive( PlayerPawn P, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
super.ClientReceive( P, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
|
||||
switch( Switch )
|
||||
{
|
||||
case 0: P.ClientPlaySound( sound'Announcer.capture', , true );
|
||||
break;
|
||||
case 1: P.ClientPlaySound( sound'Announcer.assist', , true );
|
||||
break;
|
||||
case 2: P.ClientPlaySound( sound'Announcer.nicecatch', , true );
|
||||
break;
|
||||
case 3: P.ClientPlaySound( sound'Announcer.takenlead', , true );
|
||||
break;
|
||||
case 4: P.ClientPlaySound( sound'Announcer.lostlead', , true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bIsConsoleMessage=False
|
||||
Lifetime=0
|
||||
}
|
||||
8
Sources/Classes/SmartCTFBinds.uc
Normal file
8
Sources/Classes/SmartCTFBinds.uc
Normal file
@@ -0,0 +1,8 @@
|
||||
class SmartCTFBinds expands UTExtraKeyBindings;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
SectionName="SmartCTF"
|
||||
LabelList(0)="Toggle Stats"
|
||||
AliasNames(0)="mutate smartctf showstats"
|
||||
}
|
||||
58
Sources/Classes/SmartCTFCoolMsg.uc
Normal file
58
Sources/Classes/SmartCTFCoolMsg.uc
Normal file
@@ -0,0 +1,58 @@
|
||||
class SmartCTFCoolMsg expands LocalMessagePlus;
|
||||
|
||||
var(Messages) string LongRangeString;
|
||||
var(Messages) string UberLongRangeString;
|
||||
var(Messages) string SpawnLamerString;
|
||||
var(Messages) string OvertimeEnabledString;
|
||||
var(Messages) string OvertimeDisabledString;
|
||||
var Color EnabledColor, DisabledColor, SpawnLamerColor;
|
||||
|
||||
static function float GetOffset(int Switch, float YL, float ClipY )
|
||||
{
|
||||
return ( default.YPos / 768.0 ) * ClipY - 2 * YL;
|
||||
}
|
||||
|
||||
static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
switch( Switch )
|
||||
{
|
||||
case 1: return default.LongRangeString;
|
||||
case 2: return default.UberLongRangeString;
|
||||
case 3: return default.OvertimeEnabledString;
|
||||
case 4: return default.OvertimeDisabledString;
|
||||
case 5: return default.SpawnLamerString;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static function Color GetColor( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 )
|
||||
{
|
||||
switch( Switch )
|
||||
{
|
||||
case 1: return default.DrawColor;
|
||||
case 2: return default.DrawColor;
|
||||
case 3: return default.EnabledColor;
|
||||
case 4: return default.DisabledColor;
|
||||
case 5: return default.SpawnLamerColor;
|
||||
}
|
||||
return default.DrawColor;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
LongRangeString="Long Range Kill!"
|
||||
UberLongRangeString="Über Long Range Kill!"
|
||||
SpawnLamerString="Spawnkill..."
|
||||
OvertimeEnabledString="Sudden Death Overtime = Enabled"
|
||||
OvertimeDisabledString="Sudden Death Overtime = DISABLED"
|
||||
EnabledColor=(R=128,G=255,B=192)
|
||||
DisabledColor=(R=255,G=192,B=128)
|
||||
SpawnLamerColor=(R=255,G=64)
|
||||
FontSize=1
|
||||
bIsSpecial=True
|
||||
bIsUnique=True
|
||||
bFadeMessage=True
|
||||
DrawColor=(G=224,B=224)
|
||||
YPos=196.000000
|
||||
bCenter=True
|
||||
}
|
||||
32
Sources/Classes/SmartCTFEndStats.uc
Normal file
32
Sources/Classes/SmartCTFEndStats.uc
Normal file
@@ -0,0 +1,32 @@
|
||||
class SmartCTFEndStats expands EndStats config( user );
|
||||
|
||||
replication
|
||||
{
|
||||
reliable if( Role == ROLE_Authority )
|
||||
MostPoints, MostFrags, MostCaps, MostFlagKills, MostCovers, MostHeadShots;
|
||||
}
|
||||
|
||||
struct BestSomething {
|
||||
var int Count;
|
||||
var string PlayerName;
|
||||
var string MapName;
|
||||
var string RecordDate;
|
||||
};
|
||||
|
||||
var globalconfig BestSomething MostPoints;
|
||||
var globalconfig BestSomething MostFrags;
|
||||
var globalconfig BestSomething MostCaps;
|
||||
var globalconfig BestSomething MostFlagKills;
|
||||
var globalconfig BestSomething MostCovers;
|
||||
var globalconfig BestSomething MostHeadShots;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MostPoints=(Count=2970,PlayerName="The_Cowboy",MapName="Pure Action",RecordDate="06/03/2009 15:58:14")
|
||||
MostFrags=(Count=406,PlayerName="Aryss",MapName="Pure Action",RecordDate="06/03/2009 21:31:44")
|
||||
MostCaps=(Count=105,PlayerName="Archon",MapName="Liandri Docks",RecordDate="05/29/2009 14:09:35")
|
||||
MostFlagKills=(Count=189,PlayerName="The_Cowboy",MapName="Pure Action",RecordDate="06/03/2009 15:58:14")
|
||||
MostCovers=(Count=61,PlayerName="Aryss",MapName="Pure Action",RecordDate="06/03/2009 21:31:44")
|
||||
MostHeadShots=(Count=64,PlayerName="{-_-}",MapName="Facing Worlds",RecordDate="05/14/2009 23:05:14")
|
||||
bAlwaysRelevant=True
|
||||
}
|
||||
56
Sources/Classes/SmartCTFEnhancedDeathMessagePlus.uc
Normal file
56
Sources/Classes/SmartCTFEnhancedDeathMessagePlus.uc
Normal file
@@ -0,0 +1,56 @@
|
||||
class SmartCTFEnhancedDeathMessagePlus extends DeathMessagePlus;
|
||||
|
||||
static function ClientReceive( PlayerPawn P, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
local string MultiStr;
|
||||
|
||||
if( RelatedPRI_1 == P.PlayerReplicationInfo )
|
||||
{
|
||||
// Interdict and send the child message instead.
|
||||
if( TournamentPlayer( P ).myHUD != None )
|
||||
{
|
||||
//if( class'DeathMessagePlus'.default.ChildMessage == class'KillerMessagePlus' ) class'KillerMessagePlus'.default.YouKilled = "You" @ TournamentGameInfo( P.Level.Game ).default.deathmessage[Rand(32)];
|
||||
TournamentPlayer( P ).myHUD.LocalizedMessage( default.ChildMessage, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
TournamentPlayer( P ).myHUD.LocalizedMessage( default.Class, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
}
|
||||
|
||||
if( default.bIsConsoleMessage )
|
||||
{
|
||||
TournamentPlayer( P ).Player.Console.AddString( static.GetString( Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ) );
|
||||
}
|
||||
|
||||
if( ( RelatedPRI_1 != RelatedPRI_2 ) && ( RelatedPRI_2 != None ) )
|
||||
{
|
||||
if( ( TournamentPlayer( P ).Level.TimeSeconds - TournamentPlayer( P ).LastKillTime < 3 ) && ( Switch != 1 ) )
|
||||
{
|
||||
TournamentPlayer( P ).MultiLevel++;
|
||||
TournamentPlayer( P ).ReceiveLocalizedMessage( class'SmartCTFEnhancedMultiKillMessage', TournamentPlayer( P ).MultiLevel , RelatedPRI_1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
TournamentPlayer( P ).MultiLevel = 0;
|
||||
}
|
||||
TournamentPlayer( P ).LastKillTime = TournamentPlayer( P ).Level.TimeSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
TournamentPlayer( P ).MultiLevel = 0;
|
||||
}
|
||||
|
||||
if( ChallengeHUD( P.MyHUD ) != None ) ChallengeHUD( P.MyHUD ).ScoreTime = TournamentPlayer( P ).Level.TimeSeconds;
|
||||
}
|
||||
else if( RelatedPRI_2 == P.PlayerReplicationInfo )
|
||||
{
|
||||
//class'VictimMessage'.default.YouWereKilledBy = "You were" @ TournamentGameInfo( P.Level.Game ).default.deathmessage[Rand(32)] @ "by";
|
||||
TournamentPlayer( P ).ReceiveLocalizedMessage( class'VictimMessage', 0, RelatedPRI_1 );
|
||||
super( LocalMessagePlus ).ClientReceive( P, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
}
|
||||
else
|
||||
{
|
||||
super( LocalMessagePlus ).ClientReceive( P, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
94
Sources/Classes/SmartCTFEnhancedMultiKillMessage.uc
Normal file
94
Sources/Classes/SmartCTFEnhancedMultiKillMessage.uc
Normal file
@@ -0,0 +1,94 @@
|
||||
//=============================================================================
|
||||
// SmartCTFEnhancedMultiKillMessage.
|
||||
// - v1.0 29-Feb-2004 by {DnF2}SiNiSTeR -
|
||||
//=============================================================================
|
||||
class SmartCTFEnhancedMultiKillMessage extends MultiKillMessage;
|
||||
|
||||
// Extended Multikills adds 2 more to the list :]
|
||||
// These Announcer sounds already were included in the orginal game, just not used.
|
||||
// It also doesn't stop after 9 times ;p
|
||||
|
||||
#exec OBJ LOAD FILE=..\Sounds\Announcer.uax
|
||||
|
||||
var(Messages) localized string MegaKillString;
|
||||
|
||||
static function int GetFontSize( int Switch )
|
||||
{
|
||||
if( Switch < 3 ) return default.FontSize;
|
||||
else return 2;
|
||||
}
|
||||
|
||||
static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
switch( Switch )
|
||||
{
|
||||
case 0: return "";
|
||||
break;
|
||||
case 1: return default.DoubleKillString;
|
||||
break;
|
||||
case 2: return default.TripleKillString;
|
||||
break;
|
||||
case 3: return default.MultiKillString;
|
||||
break;
|
||||
case 4: return default.MegaKillString;
|
||||
break;
|
||||
case 5: return default.UltraKillString;
|
||||
break;
|
||||
default: return default.MonsterKillString;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static function string GetBroadcastString( int MultiLevel )
|
||||
{
|
||||
if( MultiLevel == 5 ) return "had an" @ static.GetString( MultiLevel );
|
||||
else return "had a" @ static.GetString( MultiLevel );
|
||||
}
|
||||
|
||||
static simulated function ClientReceive( PlayerPawn P, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
super( LocalMessagePlus ).ClientReceive( P, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
|
||||
switch( Switch )
|
||||
{
|
||||
case 0: break;
|
||||
case 1: P.ClientPlaySound( sound'Announcer.DoubleKill', , true );
|
||||
break;
|
||||
case 2: P.ClientPlaySound( sound'Announcer.TripleKill', , true );
|
||||
break;
|
||||
case 3: P.ClientPlaySound( sound'Announcer.MultiKill', , true );
|
||||
break;
|
||||
case 4: P.ClientPlaySound( sound'Announcer.MegaKill', , true );
|
||||
break;
|
||||
case 5: P.ClientPlaySound( sound'Announcer.UltraKill', , true );
|
||||
break;
|
||||
default: P.ClientPlaySound( sound'Announcer.MonsterKill', , true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static function color GetColor( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 )
|
||||
{
|
||||
local Color cres;
|
||||
|
||||
cres = Default.DrawColor;
|
||||
if( Switch >= 1 && Switch <= 5 )
|
||||
{
|
||||
cres.G = 48 * ( 5 - Switch );
|
||||
return cres;
|
||||
}
|
||||
else if( Switch > 5 )
|
||||
{
|
||||
cres.B = Min( 48 * ( Switch - 5 ), 255 );
|
||||
return cres;
|
||||
}
|
||||
else
|
||||
{
|
||||
return cres;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MegaKillString="MEGA KILL!"
|
||||
}
|
||||
38
Sources/Classes/SmartCTFFlagCheckerInventory.uc
Normal file
38
Sources/Classes/SmartCTFFlagCheckerInventory.uc
Normal file
@@ -0,0 +1,38 @@
|
||||
class SmartCTFFlagCheckerInventory expands TournamentPickup;
|
||||
|
||||
// This inventory item gets added to every player by default.
|
||||
// Now, each time this inventory item gets destroyed it means either the player left the game or died.
|
||||
// If he simply died, then the original code already made sure the flag is dropped, before we get here,
|
||||
// and nothing special happens.
|
||||
// When we're here, we will check if he was actually carrying the flag. If he still has a flag, it means
|
||||
// the player left the server and we drop the flag manually.
|
||||
// All this happens before the code that would send the flag home.
|
||||
// Quite ingenious if I may say so :p (c) {DnF2}SiNiSTeR imo xD
|
||||
|
||||
var string DroppedMessage;
|
||||
|
||||
function Destroyed()
|
||||
{
|
||||
local CTFFlag flag;
|
||||
|
||||
// Use Other.Class==Class'ClassName' if you want a specific Actor type
|
||||
if( Owner != none && Owner.IsA('Pawn') ) {
|
||||
if( Pawn( Owner ).bIsPlayer ) { // Pawn is a player
|
||||
flag = CTFFlag( Pawn( Owner ).PlayerReplicationInfo.HasFlag );
|
||||
|
||||
if( flag != None ) { // Should handle casting failure
|
||||
flag.Drop( 0.5 * Pawn( Owner ).Velocity );
|
||||
BroadcastMessage( Pawn( Owner ).PlayerReplicationInfo.PlayerName @ DroppedMessage );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.Destroyed(); // Call Destroyed() on super class TournamentPickup
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
DroppedMessage="had the flag but disconnected. Flag is dropped!"
|
||||
bHeldItem=True
|
||||
bHidden=True
|
||||
}
|
||||
125
Sources/Classes/SmartCTFGameReplicationInfo.uc
Normal file
125
Sources/Classes/SmartCTFGameReplicationInfo.uc
Normal file
@@ -0,0 +1,125 @@
|
||||
// This class gets spawned in the mutator, serverside.
|
||||
// Because of its Role, it will also get copied to clients.
|
||||
// The replicated variables are accessible there.
|
||||
|
||||
class SmartCTFGameReplicationInfo expands ReplicationInfo;
|
||||
|
||||
var int TickRate;
|
||||
var bool bShowFCLocation, bStatsDrawFaces, bPlay30SecSound, bDrawLogo, bExtraStats, bShowSpecs, bDoKeybind, bSCTFSbDef, bSnowyScoreboard, bXmasImages;
|
||||
var float SbDelayC;
|
||||
var color SpectatorColor;
|
||||
var string CountryFlagsPackage;
|
||||
var class<ScoreBoard> NormalScoreBoardClass;
|
||||
var SmartCTFEndStats EndStats;
|
||||
var SmartCTFPlayerReplicationInfo PRIArray[64];
|
||||
var bool bInitialized, bServerInfoSetServerSide, bDoneBind;
|
||||
var class<HUD> DefaultHUDType;
|
||||
|
||||
replication
|
||||
{
|
||||
// Settings
|
||||
reliable if( Role == ROLE_Authority )
|
||||
bShowFCLocation, bPlay30SecSound, bStatsDrawFaces, bDrawLogo, bExtraStats, CountryFlagsPackage, bShowSpecs, bSCTFSbDef, bDoKeybind, bSnowyScoreboard, bXmasImages;
|
||||
|
||||
reliable if( Role == ROLE_Authority )
|
||||
bInitialized, TickRate, NormalScoreBoardClass, EndStats, bServerInfoSetServerSide, DefaultHUDType, DoBind, SbDelayC, SpectatorColor;
|
||||
}
|
||||
|
||||
simulated function PostBeginPlay()
|
||||
{
|
||||
//default.NormalScoreBoardClass = Level.Game.ScoreBoardType;
|
||||
SetTimer( 0.5, True );
|
||||
}
|
||||
|
||||
simulated function Timer()
|
||||
{
|
||||
local PlayerPawn P;
|
||||
|
||||
RefreshPRI();
|
||||
|
||||
if (Level.Netmode == NM_DedicatedServer || bDoneBind || !bDoKeybind) return; // Only execute on clients, if bind hasn't been done yet and if bind should be done.
|
||||
|
||||
foreach AllActors(class 'PlayerPawn', P)
|
||||
if (Viewport(P.Player) != None) break;
|
||||
if(P!=None) DoBind(P);
|
||||
bDoneBind=true;
|
||||
}
|
||||
|
||||
simulated function SmartCTFPlayerReplicationInfo GetStats( Actor P )
|
||||
{
|
||||
local int i;
|
||||
local PlayerReplicationInfo PRI;
|
||||
|
||||
if( !P.IsA( 'Pawn' ) ) return None;
|
||||
PRI = Pawn( P ).PlayerReplicationInfo;
|
||||
if( PRI == None ) return None;
|
||||
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
if( PRIArray[i] == None ) break;
|
||||
if( PRIArray[i].Owner == PRI ) return PRIArray[i];
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
simulated function SmartCTFPlayerReplicationInfo GetStatsByPRI( PlayerReplicationInfo PRI )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( PRI == None ) return None;
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
if( PRIArray[i] == None ) break;
|
||||
if( PRIArray[i].Owner == PRI ) return PRIArray[i];
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
simulated function SmartCTFPlayerReplicationInfo GetStatNr( byte i )
|
||||
{
|
||||
return PRIArray[i];
|
||||
}
|
||||
|
||||
simulated function ClearStats()
|
||||
{
|
||||
local int i;
|
||||
for( i = 0; i < 64; i++ )
|
||||
{
|
||||
if( PRIArray[i] == None ) break;
|
||||
PRIArray[i].ClearStats();
|
||||
}
|
||||
}
|
||||
|
||||
simulated function RefreshPRI()
|
||||
{
|
||||
local SmartCTFPlayerReplicationInfo PRI;
|
||||
local int i;
|
||||
|
||||
for( i = 0; i < 64; i++ ) PRIArray[i] = None;
|
||||
|
||||
i = 0;
|
||||
ForEach AllActors( class'SmartCTFPlayerReplicationInfo', PRI )
|
||||
{
|
||||
if( i < 64 )
|
||||
{
|
||||
if( PRI.Owner != None ) PRIArray[i++] = PRI;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function DoBind(PlayerPawn P)
|
||||
{
|
||||
local string keyBinding;
|
||||
|
||||
if ((InStr( Caps(P.ConsoleCommand("Keybinding F3")), "MUTATE SMARTCTF SHOWSTATS") == -1))
|
||||
{
|
||||
keyBinding = P.ConsoleCommand("Keybinding F3");
|
||||
P.ConsoleCommand("SET INPUT F3 mutate smartctf showstats|"$keyBinding);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
RemoteRole=ROLE_SimulatedProxy
|
||||
}
|
||||
82
Sources/Classes/SmartCTFMessage.uc
Normal file
82
Sources/Classes/SmartCTFMessage.uc
Normal file
@@ -0,0 +1,82 @@
|
||||
// Above all other messages.
|
||||
class SmartCTFMessage extends LocalMessagePlus;
|
||||
|
||||
var string CoveredMsg, YouCoveredMsg;
|
||||
var string CoverSpreeMsg, YouCoverSpreeMsg;
|
||||
var string UltraCoverMsg, YouUltraCoverMsg;
|
||||
var string SealMsg, YouSealMsg;
|
||||
var string SavedMsg, YouSavedMsg;
|
||||
var string SpawnKillMsg;
|
||||
|
||||
static function float GetOffset( int Switch, float YL, float ClipY )
|
||||
{
|
||||
return ( default.YPos / 768.0 ) * ClipY - 3 * YL;
|
||||
}
|
||||
|
||||
static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
if (RelatedPRI_1 == None) return "";
|
||||
|
||||
switch( Switch )
|
||||
{
|
||||
case 0: // Cover FC
|
||||
return RelatedPRI_1.PlayerName @ default.CoveredMsg;
|
||||
case 1: // Seal base
|
||||
return RelatedPRI_1.PlayerName @ default.SealMsg;
|
||||
case 4: // Ultra cover
|
||||
return RelatedPRI_1.PlayerName @ default.UltraCoverMsg;
|
||||
case 5: // Cover spree
|
||||
return RelatedPRI_1.PlayerName @ default.CoverSpreeMsg;
|
||||
case 7: // Saved by ...
|
||||
return default.SavedMsg @ RelatedPRI_1.PlayerName $ "!";
|
||||
case 10: // Spawnkilling
|
||||
return RelatedPRI_1.PlayerName @ default.SpawnKillMsg;
|
||||
|
||||
case 0 + 64:
|
||||
return default.YouCoveredMsg;
|
||||
case 1 + 64:
|
||||
return default.YouSealMsg;
|
||||
case 4 + 64:
|
||||
return default.YouUltraCoverMsg;
|
||||
case 5 + 64:
|
||||
return default.YouCoverSpreeMsg;
|
||||
case 7 + 64:
|
||||
return default.YouSavedMsg;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static simulated function ClientReceive( PlayerPawn P, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
super.ClientReceive( P, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
|
||||
|
||||
switch( Switch )
|
||||
{
|
||||
case 5: // Cover spree - guitarsound for player, spreesound for all
|
||||
if( RelatedPRI_1 == P.PlayerReplicationInfo ) P.ClientPlaySound( sound'CaptureSound', , true );
|
||||
else P.PlaySound( sound'SpreeSound', , 4.0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
CoveredMsg="covered the flagcarrier!"
|
||||
YouCoveredMsg="You covered the flagcarrier!"
|
||||
CoverSpreeMsg="is on a cover spree!"
|
||||
YouCoverSpreeMsg="You are on a cover spree!"
|
||||
UltraCoverMsg="got a multi cover!"
|
||||
YouUltraCoverMsg="You got a multi cover!"
|
||||
SealMsg="is sealing off the base!"
|
||||
YouSealMsg="You are sealing off the base!"
|
||||
SavedMsg="Saved By"
|
||||
YouSavedMsg="Close save!!"
|
||||
SpawnKillMsg="is a spawnkilling lamer!"
|
||||
FontSize=1
|
||||
bIsSpecial=True
|
||||
bIsUnique=True
|
||||
bFadeMessage=True
|
||||
DrawColor=(R=24,G=192,B=24)
|
||||
YPos=196.000000
|
||||
bCenter=True
|
||||
}
|
||||
167
Sources/Classes/SmartCTFPlayerReplicationInfo.uc
Normal file
167
Sources/Classes/SmartCTFPlayerReplicationInfo.uc
Normal file
@@ -0,0 +1,167 @@
|
||||
class SmartCTFPlayerReplicationInfo expands ReplicationInfo;
|
||||
|
||||
// Replicated
|
||||
var int Captures, Assists, Grabs, Covers, Seals, FlagKills, DefKills;
|
||||
var int Frags, HeadShots, ShieldBelts, Amps;
|
||||
|
||||
var string CountryPrefix; // for IpToCountry
|
||||
|
||||
// Server side
|
||||
var float LastKillTime;
|
||||
var int MultiLevel;
|
||||
var int FragSpree, CoverSpree, SealSpree, SpawnKillSpree;
|
||||
var float SpawnTime;
|
||||
var bool bHadFirstSpawn;
|
||||
|
||||
// Client side
|
||||
var bool bViewingStats;
|
||||
var bool bEndStats;
|
||||
var float IndicatorStartShow;
|
||||
var byte IndicatorVisibility;
|
||||
|
||||
var Actor IpToCountry;
|
||||
var bool bIpToCountry;
|
||||
|
||||
replication
|
||||
{
|
||||
// Stats
|
||||
reliable if( Role == ROLE_Authority )
|
||||
Captures, Assists, Grabs, Covers, Seals, FlagKills, DefKills,
|
||||
Frags, HeadShots, ShieldBelts, Amps, CountryPrefix;
|
||||
|
||||
// Toggle stats functions
|
||||
reliable if( Role == ROLE_Authority )
|
||||
ToggleStats, ShowStats;
|
||||
}
|
||||
|
||||
function PostBeginPlay()
|
||||
{
|
||||
local Actor A;
|
||||
|
||||
super.PostBeginPlay();
|
||||
|
||||
SetTimer( 0.5, True );
|
||||
}
|
||||
|
||||
function Timer()
|
||||
{
|
||||
local string temp;
|
||||
local PlayerPawn P;
|
||||
if( Owner == None )
|
||||
{
|
||||
SetTimer( 0.0, False );
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
if(bIpToCountry)
|
||||
{
|
||||
if(CountryPrefix == "")
|
||||
{
|
||||
if(Owner.Owner.IsA('PlayerPawn'))
|
||||
{
|
||||
P=PlayerPawn(Owner.Owner);
|
||||
if(NetConnection(P.Player) != None)
|
||||
{
|
||||
temp=P.GetPlayerNetworkAddress();
|
||||
temp=Left(temp, InStr(temp, ":"));
|
||||
temp=IpToCountry.GetItemName(temp);
|
||||
if(temp == "!Disabled") /* after this return, iptocountry won't resolve anything anyway */
|
||||
bIpToCountry=False;
|
||||
else if(Left(temp, 1) != "!") /* good response */
|
||||
{
|
||||
CountryPrefix=SelElem(temp, 5);
|
||||
if(CountryPrefix=="") /* the country is probably unknown(maybe LAN), so as the prefix */
|
||||
bIpToCountry=False;
|
||||
}
|
||||
}
|
||||
else
|
||||
bIpToCountry=False;
|
||||
}
|
||||
else
|
||||
bIpToCountry=False;
|
||||
}
|
||||
else
|
||||
bIpToCountry=False;
|
||||
}
|
||||
}
|
||||
|
||||
static final function string SelElem(string Str, int Elem)
|
||||
{
|
||||
local int pos;
|
||||
while(Elem-->1)
|
||||
Str=Mid(Str, InStr(Str,":")+1);
|
||||
pos=InStr(Str, ":");
|
||||
if(pos != -1)
|
||||
Str=Left(Str, pos);
|
||||
return Str;
|
||||
}
|
||||
|
||||
// Called on the server, executed on the client
|
||||
simulated function ToggleStats()
|
||||
{
|
||||
local PlayerPawn P;
|
||||
|
||||
if( Owner == None ) return;
|
||||
P = PlayerPawn( Owner.Owner );
|
||||
if( P == None ) return;
|
||||
|
||||
if( P.Scoring != None && !P.Scoring.IsA( 'SmartCTFScoreBoard' ) )
|
||||
{
|
||||
P.ClientMessage( "Problem loading the SmartCTF ScoreBoard..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
bViewingStats = !bViewingStats;
|
||||
IndicatorStartShow = Level.TimeSeconds;
|
||||
IndicatorVisibility = 255;
|
||||
P.bShowScores = True;
|
||||
}
|
||||
}
|
||||
|
||||
// Called on the client
|
||||
simulated function ShowStats(optional bool bHide)
|
||||
{
|
||||
local PlayerPawn P;
|
||||
|
||||
if( Owner == None ) return;
|
||||
P = PlayerPawn( Owner.Owner );
|
||||
if( P == None ) return;
|
||||
|
||||
if( P.Scoring != None && !P.Scoring.IsA( 'SmartCTFScoreBoard' ) )
|
||||
{
|
||||
P.ClientMessage( "Problem loading the SmartCTF ScoreBoard..." );
|
||||
}
|
||||
else
|
||||
{
|
||||
bViewingStats = True;
|
||||
if(!bHide) P.bShowScores = True;
|
||||
}
|
||||
}
|
||||
|
||||
function ClearStats()
|
||||
{
|
||||
Captures = 0;
|
||||
Assists = 0;
|
||||
Grabs = 0;
|
||||
Covers = 0;
|
||||
Seals = 0;
|
||||
DefKills = 0;
|
||||
FlagKills = 0;
|
||||
Frags = 0;
|
||||
HeadShots = 0;
|
||||
ShieldBelts = 0;
|
||||
Amps = 0;
|
||||
|
||||
FragSpree = 0;
|
||||
CoverSpree = 0;
|
||||
SealSpree = 0;
|
||||
SpawnKillSpree = 0;
|
||||
SpawnTime = 0;
|
||||
|
||||
LastKillTime = 0;
|
||||
MultiLevel = 0;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
||||
962
Sources/Classes/SmartCTFScoreBoard.uc
Normal file
962
Sources/Classes/SmartCTFScoreBoard.uc
Normal file
@@ -0,0 +1,962 @@
|
||||
class SmartCTFScoreBoard extends UnrealCTFScoreBoard;
|
||||
|
||||
#exec texture IMPORT NAME=faceless File=Textures\faceless.pcx GROUP=SmartCTF
|
||||
|
||||
var ScoreBoard NormalScoreBoard;
|
||||
var SmartCTFGameReplicationInfo SCTFGame;
|
||||
var SmartCTFPlayerReplicationInfo OwnerStats;
|
||||
|
||||
var int TryCount;
|
||||
var PlayerPawn PlayerOwner;
|
||||
|
||||
var string PtsText, FragsText, SepText, MoreText, HeaderText, HeaderText2;
|
||||
var int LastSortTime, MaxMeterWidth;
|
||||
var byte ColorChangeSpeed, RowColState;
|
||||
var Color White, Gray, DarkGray, Yellow, RedTeamColor, BlueTeamColor, RedHeaderColor, BlueHeaderColor, StatsColor, FooterColor, HeaderColor, TinyInfoColor, HeaderTinyInfoColor;
|
||||
var float StatsTextWidth, StatHeight, MeterHeight, NameHeight, ColumnHeight, StatBlockHeight;
|
||||
var float RedStartX, BlueStartX, ColumnWidth, StatWidth, StatsHorSpacing, ShadingSpacingX, HeaderShadingSpacingY, ColumnShadingSpacingY;
|
||||
var float StartY, StatLineHeight, StatBlockSpacing, StatIndent;
|
||||
var TournamentGameReplicationInfo pTGRI;
|
||||
var PlayerReplicationInfo pPRI;
|
||||
var Font StatFont, CapFont, FooterFont, GameEndedFont, PlayerNameFont, FragsFont, TinyInfoFont;
|
||||
var Font PtsFont22, PtsFont20, PtsFont18, PtsFont16, PtsFont14, PtsFont12;
|
||||
|
||||
var int MaxCaps, MaxAssists, MaxGrabs, MaxCovers, MaxSeals, MaxDefKills, MaxFlagKills, MaxFrags, MaxDeaths;
|
||||
var int TotShieldBelts, TotAmps;
|
||||
|
||||
var bool bSealsOrDefs;
|
||||
var bool bStarted;
|
||||
var bool bEndHandled;
|
||||
|
||||
struct FlagData {
|
||||
var string Prefix;
|
||||
var texture Tex;
|
||||
};
|
||||
var FlagData FD[32]; // there can be max 32 so max 32 different flags
|
||||
var int saveindex; // new loaded flags will be saved in FD[index]
|
||||
|
||||
function int GetFlagIndex(string Prefix)
|
||||
{
|
||||
local int i;
|
||||
for(i=0;i<32;i++)
|
||||
if(FD[i].Prefix == Prefix)
|
||||
return i;
|
||||
FD[saveindex].Prefix=Prefix;
|
||||
FD[saveindex].Tex=texture(DynamicLoadObject(SCTFGame.CountryFlagsPackage$"."$Prefix, class'Texture'));
|
||||
i=saveindex;
|
||||
saveindex = (saveindex+1) % 256;
|
||||
return i;
|
||||
}
|
||||
|
||||
function PostBeginPlay()
|
||||
{
|
||||
super.PostBeginPlay();
|
||||
|
||||
PlayerOwner = PlayerPawn( Owner );
|
||||
pTGRI = TournamentGameReplicationInfo( PlayerOwner.GameReplicationInfo );
|
||||
pPRI = PlayerOwner.PlayerReplicationInfo;
|
||||
LastSortTime = -100;
|
||||
|
||||
// Preload
|
||||
PtsFont22 = Font( DynamicLoadObject( "LadderFonts.UTLadder22", class'Font' ) );
|
||||
PtsFont20 = Font( DynamicLoadObject( "LadderFonts.UTLadder20", class'Font' ) );
|
||||
PtsFont18 = Font( DynamicLoadObject( "LadderFonts.UTLadder18", class'Font' ) );
|
||||
PtsFont16 = Font( DynamicLoadObject( "LadderFonts.UTLadder16", class'Font' ) );
|
||||
PtsFont14 = Font( DynamicLoadObject( "LadderFonts.UTLadder14", class'Font' ) );
|
||||
PtsFont12 = Font( DynamicLoadObject( "LadderFonts.UTLadder12", class'Font' ) );
|
||||
|
||||
SpawnNormalScoreBoard();
|
||||
if( NormalScoreBoard == None ) SetTimer( 1.0 , True );
|
||||
else
|
||||
{
|
||||
bStarted = True;
|
||||
SetTimer( 3.0, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to spawn a local instance of the original scoreboard class if it doesn't exist already.
|
||||
function SpawnNormalScoreBoard()
|
||||
{
|
||||
if( SCTFGame == None )
|
||||
{
|
||||
ForEach AllActors( class'SmartCTFGameReplicationInfo', SCTFGame ) break;
|
||||
}
|
||||
if( SCTFGame != None ) OwnerStats = SCTFGame.GetStats( PlayerOwner );
|
||||
|
||||
if( SCTFGame != None && SCTFGame.NormalScoreBoardClass == None )
|
||||
{
|
||||
Log( "Unable to identify original ScoreBoard type. Retrying in 1 second." , 'SmartCTF' );
|
||||
return;
|
||||
}
|
||||
|
||||
if( SCTFGame != None && SCTFGame.NormalScoreBoardClass == self.Class )
|
||||
{
|
||||
NormalScoreBoard = Spawn( class'UnrealCTFScoreBoard', PlayerOwner );
|
||||
Log( "Cannot use itself. Using the default CTF ScoreBoard instead." , 'SmartCTF' );
|
||||
return;
|
||||
}
|
||||
|
||||
if( SCTFGame != None && SCTFGame.NormalScoreBoardClass != None )
|
||||
{
|
||||
NormalScoreBoard = Spawn( SCTFGame.NormalScoreBoardClass, PlayerOwner );
|
||||
Log( "Determined and spawned original scoreboard as" @ NormalScoreBoard, 'SmartCTF' );
|
||||
}
|
||||
}
|
||||
|
||||
// In the case of the 'normal scoreboard' not being replicated properly, try every second to see if it has.
|
||||
function Timer()
|
||||
{
|
||||
if(!bStarted)
|
||||
{
|
||||
if( NormalScoreBoard == None )
|
||||
{
|
||||
TryCount++;
|
||||
SpawnNormalScoreBoard();
|
||||
}
|
||||
|
||||
if( NormalScoreBoard != None )
|
||||
{
|
||||
bStarted = True;
|
||||
SetTimer( 3.0, True );
|
||||
}
|
||||
else if( TryCount > 3 )
|
||||
{
|
||||
Log( "Given up. Using the default CTF ScoreBoard instead." , 'SmartCTF' );
|
||||
|
||||
if( NormalScoreBoard == None )
|
||||
{
|
||||
NormalScoreBoard = Spawn( class'UnrealCTFScoreBoard', PlayerOwner );
|
||||
Log( "Spawned as" @ NormalScoreBoard, 'SmartCTF' );
|
||||
}
|
||||
bStarted = True;
|
||||
SetTimer( 3.0, True );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bSealsOrDefs = !bSealsOrDefs;
|
||||
}
|
||||
}
|
||||
|
||||
function ShowScores( Canvas C )
|
||||
{
|
||||
if( SCTFGame == None || OwnerStats == None )
|
||||
{
|
||||
if( NormalScoreBoard != None ) NormalScoreBoard.ShowScores( C );
|
||||
else PlayerOwner.bShowScores = False;
|
||||
return;
|
||||
}
|
||||
|
||||
if(OwnerStats.bEndStats && !bEndHandled)
|
||||
{
|
||||
bEndHandled = True;
|
||||
bSealsOrDefs = True;
|
||||
SetTimer(10, true);
|
||||
}
|
||||
|
||||
if( OwnerStats.bViewingStats )
|
||||
SmartCTFShowScores( C );
|
||||
else
|
||||
{
|
||||
if( NormalScoreBoard == None ) SmartCTFShowScores( C );
|
||||
else NormalScoreBoard.ShowScores( C );
|
||||
}
|
||||
|
||||
if( OwnerStats.IndicatorVisibility > 0 ) ShowIndicator( C );
|
||||
}
|
||||
|
||||
function ShowIndicator( Canvas C )
|
||||
{
|
||||
local float BlockLen, LineHeight;
|
||||
|
||||
C.DrawColor.R = OwnerStats.IndicatorVisibility;
|
||||
C.DrawColor.G = OwnerStats.IndicatorVisibility;
|
||||
C.DrawColor.B = OwnerStats.IndicatorVisibility;
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.Font = C.SmallFont;
|
||||
C.StrLen( "Scoreboard:", BlockLen, LineHeight );
|
||||
C.SetPos( C.ClipX - BlockLen - 16, 16 );
|
||||
C.DrawText( "Scoreboard:" );
|
||||
C.SetPos( C.ClipX - BlockLen, 16 + LineHeight );
|
||||
C.DrawText( "Default" );
|
||||
C.SetPos( C.ClipX - BlockLen, 16 + 2 * LineHeight );
|
||||
C.DrawText( "SmartCTF" );
|
||||
if( OwnerStats.bViewingStats ) C.SetPos( C.ClipX - BlockLen - 16, 16 + 2 * LineHeight );
|
||||
else C.SetPos( C.ClipX - BlockLen - 16, 16 + LineHeight );
|
||||
C.DrawIcon( texture'UWindow.MenuTick', 1 );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
|
||||
if( Level.TimeSeconds - OwnerStats.IndicatorStartShow > 2 ) OwnerStats.IndicatorVisibility = 0;
|
||||
}
|
||||
|
||||
function SmartCTFShowScores( Canvas C )
|
||||
{
|
||||
local int ID, i, j, Time, AvgPing, AvgPL, TotSB, TotAmp;
|
||||
local float Eff;
|
||||
local int RedY, BlueY, X, Y;
|
||||
local float Nil, DummyX, DummyY, SizeX, SizeY, Buffer, Size;
|
||||
local byte LabelDrawn[2], Rendered[2];
|
||||
local Color TeamColor, TempColor;
|
||||
local string TempStr;
|
||||
local SmartCTFPlayerReplicationInfo PlayerStats, PlayerStats2;
|
||||
local int FlagShift; /* shifting elements to fit a flag */
|
||||
|
||||
if( Level.TimeSeconds - LastSortTime > 0.5 )
|
||||
{
|
||||
SortScores( 32 );
|
||||
RecountNumbers();
|
||||
InitStatBoardConstPos( C );
|
||||
CompressStatBoard( C );
|
||||
LastSortTime = Level.TimeSeconds;
|
||||
}
|
||||
|
||||
Y = int( StartY );
|
||||
RedY = Y;
|
||||
BlueY = Y;
|
||||
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
|
||||
// FOR EACH PLAYER DRAW INFO
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
if( Ordered[i] == None ) break;
|
||||
PlayerStats = SCTFGame.GetStatsByPRI( Ordered[i] );
|
||||
if( PlayerStats == None ) continue;
|
||||
|
||||
// Get the ID of the ith player
|
||||
ID = Ordered[i].PlayerID;
|
||||
|
||||
// set the pos depending on Team
|
||||
if( Ordered[i].Team == 0 )
|
||||
{
|
||||
X = RedStartX;
|
||||
Y = RedY;
|
||||
TeamColor = RedTeamColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
X = BlueStartX;
|
||||
Y = BlueY;
|
||||
TeamColor = BlueTeamColor;
|
||||
}
|
||||
C.DrawColor = TeamColor;
|
||||
|
||||
if( LabelDrawn[Ordered[i].Team] == 0 )
|
||||
{
|
||||
// DRAW THE Team SCORES with the cool Flag icons (masked because of black borders)
|
||||
|
||||
C.bNoSmooth = False;
|
||||
C.Font = PlayerNameFont;
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
if( Ordered[i].Team == 0 ) C.DrawColor = RedHeaderColor;
|
||||
else C.DrawColor = BlueHeaderColor;
|
||||
C.StrLen( PtsText, SizeX, SizeY );
|
||||
C.Style = ERenderStyle.STY_Modulated;
|
||||
C.SetPos( X - ShadingSpacingX, Y - HeaderShadingSpacingY );
|
||||
C.DrawRect( texture'shade', ColumnWidth + ( ShadingSpacingX * 2 ) , SizeY + ( HeaderShadingSpacingY * 2 ) );
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.SetPos( X - ShadingSpacingX, Y - HeaderShadingSpacingY );
|
||||
if( Ordered[i].Team == 0 ) C.DrawPattern( texture'redskin2', ColumnWidth + ( ShadingSpacingX * 2 ) , SizeY + ( HeaderShadingSpacingY * 2 ) , 1 );
|
||||
else C.DrawPattern( texture'blueskin2', ColumnWidth + ( ShadingSpacingX * 2 ) , SizeY + ( HeaderShadingSpacingY * 2 ) , 1 );
|
||||
|
||||
C.Style = ERenderStyle.STY_Modulated;
|
||||
C.SetPos( X - ShadingSpacingX, Y + SizeY + HeaderShadingSpacingY );
|
||||
C.DrawRect( texture'shade', ColumnWidth + ( ShadingSpacingX * 2 ) , ColumnHeight + ( ColumnShadingSpacingY * 2 ) );
|
||||
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.DrawColor = TeamColor;
|
||||
C.SetPos( X, Y - ( ( 32 - SizeY ) / 2 ) ); // Y - 4
|
||||
if( Ordered[i].Team == 0 ) C.DrawIcon( texture'I_TeamR', 0.5 );
|
||||
else C.DrawIcon( texture'I_TeamB', 0.5 );
|
||||
|
||||
C.Font = CapFont;
|
||||
C.StrLen( int( pTGRI.Teams[Ordered[i].Team].Score ), DummyX, DummyY );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
C.SetPos( X + StatIndent, Y - ( ( DummyY - SizeY ) / 2 ) );
|
||||
C.DrawText( int( pTGRI.Teams[Ordered[i].Team].Score ) );
|
||||
|
||||
//Draw the Frags/Pts text
|
||||
C.Font = PlayerNameFont;
|
||||
C.SetPos( X + ColumnWidth - SizeX, Y );
|
||||
C.DrawText( PtsText );
|
||||
C.Font = FragsFont;
|
||||
C.StrLen( FragsText $ SepText, Buffer, Nil );
|
||||
C.SetPos( X + ColumnWidth - SizeX - Buffer, Y );
|
||||
C.DrawText( FragsText $ SepText );
|
||||
|
||||
C.DrawColor = HeaderTinyInfoColor;
|
||||
C.Font = TinyInfoFont;
|
||||
C.StrLen( "TEST", Nil, DummyY );
|
||||
C.SetPos( X + StatIndent + DummyX + 2 * StatsHorSpacing, Y + ( SizeY - DummyY * 2 ) / 2 );
|
||||
Time = Max( 1, Level.TimeSeconds / 60 );
|
||||
AvgPing = 0;
|
||||
AvgPL = 0;
|
||||
TotSB = 0;
|
||||
TotAmp = 0;
|
||||
for( j = 0; j < 32; j++ )
|
||||
{
|
||||
if( Ordered[j] == None ) break;
|
||||
if( Ordered[j].Team == Ordered[i].Team )
|
||||
{
|
||||
PlayerStats2 = SCTFGame.GetStatsByPRI( Ordered[j] );
|
||||
if( PlayerStats2 == None ) continue;
|
||||
AvgPing += Ordered[j].Ping;
|
||||
AvgPL += Ordered[j].PacketLoss;
|
||||
TotSB += PlayerStats2.ShieldBelts;
|
||||
TotAmp += PlayerStats2.Amps;
|
||||
}
|
||||
}
|
||||
if( pTGRI.Teams[Ordered[i].Team].Size != 0 )
|
||||
{
|
||||
AvgPing = AvgPing / pTGRI.Teams[Ordered[i].Team].Size;
|
||||
AvgPL = AvgPL / pTGRI.Teams[Ordered[i].Team].Size;
|
||||
}
|
||||
if( TotShieldBelts == 0 ) TotSB = 0;
|
||||
else TotSB = Clamp( float( TotSB ) / float( TotShieldBelts ) * 100, 0, 100 );
|
||||
if( TotAmps == 0 ) TotAmp = 0;
|
||||
else TotAmp = Clamp( float( TotAmp ) / float( TotAmps ) * 100, 0, 100 );
|
||||
TempStr = "PING:" $ AvgPing $ " PL:" $ AvgPL $ "%";
|
||||
C.DrawText( TempStr );
|
||||
C.SetPos( X + StatIndent + DummyX + 2 * StatsHorSpacing, Y + ( SizeY - DummyY * 2 ) / 2 + DummyY );
|
||||
TempStr = "TM:" $ Time;
|
||||
if( TotSB != 0 ) TempStr = TempStr @ "SB:" $ TotSB $ "%";
|
||||
if( TotAmp != 0 ) TempStr = TempStr @ "AM:" $ TotAmp $ "%";
|
||||
C.DrawText( TempStr );
|
||||
|
||||
C.bNoSmooth = True;
|
||||
|
||||
Y += SizeY + HeaderShadingSpacingY + ColumnShadingSpacingY;
|
||||
LabelDrawn[Ordered[i].Team] = 1;
|
||||
}
|
||||
|
||||
C.Font = FooterFont;
|
||||
C.StrLen( "Test", Nil, DummyY );
|
||||
if( LabelDrawn[Ordered[i].Team] != 2 && ( Y + NameHeight + StatBlockHeight + StatBlockSpacing > C.ClipY - DummyY * 5 ) )
|
||||
{
|
||||
|
||||
C.DrawColor = TeamColor;
|
||||
C.StrLen( MoreText , Size, DummyY );
|
||||
if( Ordered[i].Team == 1 ) C.SetPos( X + ColumnWidth - Size, C.ClipY - DummyY * 5 );
|
||||
else C.SetPos( X, C.ClipY - DummyY * 5 );
|
||||
C.DrawText( "[" @ pTGRI.Teams[Ordered[i].Team].Size - Rendered[Ordered[i].Team] @ MoreText @ "]" );
|
||||
LabelDrawn[Ordered[i].Team] = 2; // "More" label also drawn
|
||||
}
|
||||
|
||||
else if( LabelDrawn[Ordered[i].Team] != 2 )
|
||||
{
|
||||
|
||||
// Draw the face
|
||||
if( Ordered[i].HasFlag == None )
|
||||
{
|
||||
C.bNoSmooth = False;
|
||||
C.DrawColor = White;
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.SetPos( X, Y );
|
||||
if( SCTFGame.bStatsDrawFaces && Ordered[i].TalkTexture != None ) C.DrawIcon( Ordered[i].TalkTexture, 0.5 );
|
||||
else C.DrawIcon( texture'faceless', 0.5 );
|
||||
C.SetPos( X, Y );
|
||||
C.DrawColor = DarkGray;
|
||||
C.DrawIcon( texture'IconSelection', 1 );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
C.bNoSmooth = True;
|
||||
}
|
||||
|
||||
// Draw the player name
|
||||
C.SetPos( X + StatIndent, Y );
|
||||
|
||||
C.Font = PlayerNameFont;
|
||||
if( Ordered[i].bAdmin ) C.DrawColor = White;
|
||||
else if( Ordered[i].PlayerID == pPRI.PlayerID ) C.DrawColor = Yellow;
|
||||
else C.DrawColor = TeamColor;
|
||||
TempColor = C.DrawColor;
|
||||
C.DrawText( Ordered[i].PlayerName );
|
||||
C.StrLen( Ordered[i].PlayerName, Size, Buffer );
|
||||
|
||||
C.DrawColor = TinyInfoColor;
|
||||
C.Font = TinyInfoFont;
|
||||
C.StrLen( "TEST", Buffer, DummyY );
|
||||
|
||||
// Draw Time, Eff, HS, SB, Amp
|
||||
C.SetPos( X + StatIndent + Size + StatsHorSpacing, Y + ( NameHeight - DummyY * 2 ) / 2 );
|
||||
TempStr = "";
|
||||
if( PlayerStats.HeadShots != 0 ) TempStr = TempStr $ "HS:" $ PlayerStats.HeadShots;
|
||||
if( PlayerStats.ShieldBelts != 0 ) TempStr = TempStr @ "SB:" $ PlayerStats.ShieldBelts;
|
||||
if( PlayerStats.Amps != 0 ) TempStr = TempStr @ "AM:" $ PlayerStats.Amps;
|
||||
if( Left( TempStr, 1 ) == " " ) TempStr = Mid( TempStr, 1 );
|
||||
C.DrawText( TempStr );
|
||||
Time = Max( 1, ( Level.TimeSeconds + pPRI.StartTime - Ordered[i].StartTime ) / 60 );
|
||||
if( PlayerStats.Frags + Ordered[i].Deaths == 0 ) Eff = 0;
|
||||
else Eff = ( PlayerStats.Frags / ( PlayerStats.Frags + Ordered[i].Deaths ) ) * 100;
|
||||
C.SetPos( X + StatIndent + Size + StatsHorSpacing, Y + ( NameHeight - DummyY * 2 ) / 2 + DummyY );
|
||||
C.DrawText( "TM:" $ Time $ " EFF:" $ Clamp( int( Eff ), 0, 100 ) $ "%" );
|
||||
|
||||
// Draw the country flag
|
||||
if(PlayerStats.CountryPrefix != "")
|
||||
{
|
||||
C.SetPos( X+8, Y + StatIndent);
|
||||
C.bNoSmooth = False;
|
||||
C.DrawColor = White;
|
||||
C.DrawIcon(FD[GetFlagIndex(PlayerStats.CountryPrefix)].Tex, 1.0);
|
||||
FlagShift=12;
|
||||
C.bNoSmooth = True;
|
||||
}
|
||||
else
|
||||
FlagShift=0;
|
||||
// Draw Bot or Ping/PL
|
||||
C.SetPos( X, Y + StatIndent + FlagShift);
|
||||
if( Ordered[i].bIsABot )
|
||||
{
|
||||
C.DrawText( "BOT" );
|
||||
if( Ordered[i].Team == pPRI.Team )
|
||||
{
|
||||
C.SetPos( X, Y + StatIndent + DummyY);
|
||||
C.DrawText( Left( string( BotReplicationInfo( Ordered[i] ).RealOrders ) , 3 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
C.DrawColor = HeaderTinyInfoColor;
|
||||
TempStr = "PI:" $ Ordered[i].Ping;
|
||||
if( Len( TempStr ) > 5 ) TempStr = "P:" $ Ordered[i].Ping;
|
||||
if( Len( TempStr ) > 5 ) TempStr = string( Ordered[i].Ping );
|
||||
C.DrawText( TempStr );
|
||||
C.SetPos( X, Y + StatIndent + DummyY + FlagShift);
|
||||
TempStr = "PL:" $ Ordered[i].PacketLoss $ "%";
|
||||
if( Len( TempStr ) > 5 ) TempStr = "L:" $ Ordered[i].PacketLoss $ "%";
|
||||
if( Len( TempStr ) > 5 ) TempStr = "L:" $ Ordered[i].PacketLoss;
|
||||
if( Len( TempStr ) > 5 ) TempStr = Ordered[i].PacketLoss $ "%";
|
||||
C.DrawText( TempStr );
|
||||
}
|
||||
|
||||
// Draw the Flag if he has Flag
|
||||
if( Ordered[i].HasFlag != None )
|
||||
{
|
||||
C.DrawColor = White;
|
||||
C.SetPos( X, Y );
|
||||
if( Ordered[i].HasFlag.IsA( 'GreenFlag' ) ) C.DrawIcon( texture'GreenFlag', 1 );
|
||||
else if( Ordered[i].HasFlag.IsA( 'YellowFlag' ) ) C.DrawIcon( texture'YellowFlag', 1 );
|
||||
else if( Ordered[i].Team == 0 ) C.DrawIcon( texture'BlueFlag', 1 );
|
||||
else C.DrawIcon( texture'RedFlag', 1 );
|
||||
} // End if he has Flag
|
||||
|
||||
C.Font = PlayerNameFont;
|
||||
C.DrawColor = TempColor;
|
||||
|
||||
// Draw Frag/Score
|
||||
C.StrLen( int( Ordered[i].Score ), Size, DummyY );
|
||||
C.SetPos( X + ColumnWidth - Size, Y );
|
||||
C.DrawText( int( Ordered[i].Score ) );
|
||||
|
||||
C.Font = FragsFont;
|
||||
C.StrLen( PlayerStats.Frags $ SepText, Buffer, SizeY );
|
||||
C.SetPos( X + ColumnWidth - Size - Buffer, Y );
|
||||
C.DrawText( PlayerStats.Frags $ SepText );
|
||||
|
||||
Y += NameHeight;
|
||||
|
||||
// Set the Font for the stat drawing
|
||||
C.Font = StatFont;
|
||||
|
||||
if( RowColState == 1 )
|
||||
{
|
||||
DrawStatType( C, X, Y, 1, 1, "Caps: ", PlayerStats.Captures, MaxCaps );
|
||||
DrawStatType( C, X, Y, 1, 2, "Assists: ", PlayerStats.Assists, MaxAssists );
|
||||
DrawStatType( C, X, Y, 1, 3, "Grabs: ", PlayerStats.Grabs, MaxGrabs );
|
||||
if(SCTFGame.bExtraStats)
|
||||
{
|
||||
if( bSealsOrDefs) {
|
||||
DrawStatType( C, X, Y, 2, 2, "DefKills: ", PlayerStats.DefKills, MaxDefKills );
|
||||
DrawStatType( C, X, Y, 2, 1, "Covers: ", PlayerStats.Covers, MaxCovers );
|
||||
}
|
||||
else {
|
||||
DrawStatType( C, X, Y, 2, 2, "Seals: ", PlayerStats.Seals, MaxSeals );
|
||||
DrawStatType( C, X, Y, 2, 1, "Deaths: ", Ordered[i].Deaths, MaxDeaths );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawStatType( C, X, Y, 2, 1, "Covers: ", PlayerStats.Covers, MaxCovers );
|
||||
if( MaxSeals > 0 ) DrawStatType( C, X, Y, 2, 2, "Seals: ", PlayerStats.Seals, MaxSeals );
|
||||
else DrawStatType( C, X, Y, 2, 2, "Deaths: ", Ordered[i].Deaths, MaxDeaths );
|
||||
}
|
||||
DrawStatType( C, X, Y, 2, 3, "FlagKls: ", PlayerStats.FlagKills, MaxFlagKills );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawStatType( C, X, Y, 1, 1, "Caps: ", PlayerStats.Captures, MaxCaps );
|
||||
DrawStatType( C, X, Y, 2, 1, "Grabs: ", PlayerStats.Grabs, MaxGrabs );
|
||||
|
||||
if(SCTFGame.bExtraStats)
|
||||
{
|
||||
if( bSealsOrDefs) {
|
||||
DrawStatType( C, X, Y, 2, 2, "DefKills: ", PlayerStats.DefKills, MaxDefKills );
|
||||
DrawStatType( C, X, Y, 1, 2, "Covers: ", PlayerStats.Covers, MaxCovers );
|
||||
}
|
||||
else {
|
||||
DrawStatType( C, X, Y, 2, 2, "Seals: ", PlayerStats.Seals, MaxSeals );
|
||||
DrawStatType( C, X, Y, 1, 2, "Deaths: ", Ordered[i].Deaths, MaxDeaths );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawStatType( C, X, Y, 1, 2, "Covers: ", PlayerStats.Covers, MaxCovers );
|
||||
if( MaxSeals > 0 ) DrawStatType( C, X, Y, 2, 2, "Seals: ", PlayerStats.Seals, MaxSeals );
|
||||
else DrawStatType( C, X, Y, 2, 2, "Deaths: ", Ordered[i].Deaths, MaxDeaths );
|
||||
}
|
||||
DrawStatType( C, X, Y, 3, 1, "Assists: ", PlayerStats.Assists, MaxAssists );
|
||||
DrawStatType( C, X, Y, 3, 2, "FlagKls: ", PlayerStats.FlagKills, MaxFlagKills );
|
||||
}
|
||||
|
||||
Y += StatBlockHeight + StatBlockSpacing;
|
||||
}
|
||||
|
||||
// Alter the RedY or BlueY and do next player
|
||||
if( Ordered[i].Team == 0 ) RedY = Y;
|
||||
else BlueY = Y;
|
||||
Rendered[Ordered[i].Team]++;
|
||||
|
||||
} //End of PRI for loop
|
||||
|
||||
DrawHeader( C );
|
||||
DrawFooters( C );
|
||||
}
|
||||
|
||||
function InitStatBoardConstPos( Canvas C )
|
||||
{
|
||||
local float Nil, LeftSpacingPercent, MidSpacingPercent, RightSpacingPercent;
|
||||
|
||||
CapFont = Font'LEDFont2'; //Font( DynamicLoadObject( "UWindowFonts.UTFont40", class'Font' ) );
|
||||
FooterFont = MyFonts.GetSmallestFont( C.ClipX );
|
||||
GameEndedFont = MyFonts.GetHugeFont( C.ClipX );
|
||||
PlayerNameFont = MyFonts.GetBigFont( C.ClipX );
|
||||
TinyInfoFont = C.SmallFont;
|
||||
|
||||
if( PlayerNameFont == PtsFont22 ) FragsFont = PtsFont18;
|
||||
else if( PlayerNameFont == PtsFont20 ) FragsFont = PtsFont18;
|
||||
else if( PlayerNameFont == PtsFont18 ) FragsFont = PtsFont14;
|
||||
else if( PlayerNameFont == PtsFont16 ) FragsFont = PtsFont12;
|
||||
else FragsFont = font'SmallFont';
|
||||
|
||||
C.Font = PlayerNameFont;
|
||||
C.StrLen( "Player", Nil, NameHeight );
|
||||
|
||||
StartY = ( 120.0 / 1024.0 ) * C.ClipY;
|
||||
ColorChangeSpeed = 100; // Influences how 'fast' the color changes from white to green. Higher = faster.
|
||||
|
||||
LeftSpacingPercent = 0.075;
|
||||
MidSpacingPercent = 0.15;
|
||||
RightSpacingPercent = 0.075;
|
||||
RedStartX = LeftSpacingPercent * C.ClipX;
|
||||
ColumnWidth = ( ( 1 - LeftSpacingPercent - MidSpacingPercent - RightSpacingPercent ) / 2 * C.ClipX );
|
||||
BlueStartX = RedStartX + ColumnWidth + ( MidSpacingPercent * C.ClipX );
|
||||
ShadingSpacingX = ( 10.0 / 1024.0 ) * C.ClipX;
|
||||
HeaderShadingSpacingY = ( 32 - NameHeight ) / 2 + ( ( 4.0 / 1024.0 ) * C.ClipX );
|
||||
ColumnShadingSpacingY = ( 10.0 / 1024.0 ) * C.ClipX;
|
||||
|
||||
StatsHorSpacing = ( 5.0 / 1024.0 ) * C.ClipX;
|
||||
StatIndent = ( 32 + StatsHorSpacing ); // For face + flag icons
|
||||
|
||||
InitStatBoardDynamicPos( C );
|
||||
}
|
||||
|
||||
function InitStatBoardDynamicPos( Canvas C , optional int Rows , optional int Cols , optional Font NewStatFont , optional float LineSpacing , optional float BlockSpacing )
|
||||
{
|
||||
if( Rows == 0 ) Rows = 3;
|
||||
if( Cols == 0 ) Cols = 2;
|
||||
if( LineSpacing == 0 ) LineSpacing = 0.9;
|
||||
if( BlockSpacing == 0 ) BlockSpacing = 1;
|
||||
|
||||
if( Rows == 2 && Cols == 3 ) RowColState = 1;
|
||||
else RowColState = 0;
|
||||
|
||||
StatWidth = ( ( ColumnWidth - StatIndent ) / Cols ) - ( StatsHorSpacing * ( Cols - 1 ) );
|
||||
|
||||
if( NewStatFont == None ) StatFont = MyFonts.GetSmallestFont( C.ClipX );
|
||||
else StatFont = NewStatFont;
|
||||
C.Font = StatFont;
|
||||
C.StrLen( "FlagKls: 00", StatsTextWidth, StatHeight );
|
||||
|
||||
MaxMeterWidth = StatWidth - StatsTextWidth - StatsHorSpacing;
|
||||
StatLineHeight = StatHeight * LineSpacing;
|
||||
MeterHeight = Max( 1, StatLineHeight * 0.3 );
|
||||
StatBlockSpacing = StatLineHeight * BlockSpacing;
|
||||
|
||||
StatBlockHeight = Rows * StatLineHeight;
|
||||
|
||||
if( pTGRI.Teams[0].Size > pTGRI.Teams[1].Size )
|
||||
ColumnHeight = pTGRI.Teams[0].Size * ( NameHeight + StatBlockHeight + StatBlockSpacing ) - StatBlockSpacing;
|
||||
else
|
||||
ColumnHeight = pTGRI.Teams[1].Size * ( NameHeight + StatBlockHeight + StatBlockSpacing ) - StatBlockSpacing;
|
||||
}
|
||||
|
||||
function CompressStatBoard( Canvas C , optional int Level )
|
||||
{
|
||||
local float EndY, Nil, DummyY;
|
||||
|
||||
C.Font = FooterFont;
|
||||
C.StrLen( "Test", Nil, DummyY );
|
||||
|
||||
EndY = StartY + ColumnHeight + ( ColumnShadingSpacingY * 2 ) + NameHeight + HeaderShadingSpacingY;
|
||||
if( EndY > C.ClipY - DummyY * 5 )
|
||||
{
|
||||
if( Level == 0 )
|
||||
{
|
||||
InitStatBoardDynamicPos( C, , , , 0.8 );
|
||||
}
|
||||
else if( Level == 1 )
|
||||
{
|
||||
InitStatBoardDynamicPos( C, 2, 3 );
|
||||
}
|
||||
else if( Level == 2 )
|
||||
{
|
||||
InitStatBoardDynamicPos( C, 2, 3, Font( DynamicLoadObject( "UWindowFonts.Tahoma10", class'Font' ) ) , 1.0 , 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We did all the compression we can do. Draw 'More' labels later.
|
||||
// First find the columnheight for the amount of players that fit on it.
|
||||
ColumnHeight = int( ( C.ClipY - ( EndY - ColumnHeight ) - DummyY * 5 + StatBlockSpacing ) / ( NameHeight + StatBlockHeight + StatBlockSpacing ) )
|
||||
* ( NameHeight + StatBlockHeight + StatBlockSpacing ) - StatBlockSpacing;
|
||||
return;
|
||||
}
|
||||
// Did some compression, see if we need more.
|
||||
CompressStatBoard( C , Level + 1 );
|
||||
}
|
||||
// No compression at all or no more compression needed.
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a specific stat
|
||||
* X, Y = Upper left corner of stats ( row,col: 1,1)
|
||||
*/
|
||||
function DrawStatType( Canvas C, int X, int Y, int Row, int Col, string Label, int Count, int Total )
|
||||
{
|
||||
local float Size, DummyY;
|
||||
local int ColorChange, M;
|
||||
|
||||
X += StatIndent + ( ( StatWidth + StatsHorSpacing ) * ( Col - 1 ) );
|
||||
Y += ( StatLineHeight * ( Row - 1 ) );
|
||||
|
||||
C.DrawColor = StatsColor;
|
||||
C.SetPos( X, Y );
|
||||
C.DrawText( Label );
|
||||
C.StrLen( Count, Size, DummyY );
|
||||
C.SetPos( X + StatsTextWidth - Size, Y );
|
||||
C.DrawText( Count ); //text
|
||||
if( Count > 0 )
|
||||
{
|
||||
ColorChange = ColorChangeSpeed * loge( Count );
|
||||
if( ColorChange > 255 ) ColorChange = 255;
|
||||
C.DrawColor.R = StatsColor.R - ColorChange;
|
||||
C.DrawColor.B = StatsColor.B - ColorChange;
|
||||
}
|
||||
M = GetMeterLength( Count, Total );
|
||||
C.SetPos( X + StatsTextWidth + StatsHorSpacing, Y + ( ( StatHeight - MeterHeight ) / 2 ) );
|
||||
C.DrawRect( texture'meter', M, MeterHeight ); //meter
|
||||
}
|
||||
|
||||
function DrawFooters( Canvas C )
|
||||
{
|
||||
local float DummyX, DummyY, Nil, X1, Y1;
|
||||
local string TextStr;
|
||||
local string TimeStr;
|
||||
local int Hours, Minutes, Seconds, i;
|
||||
local PlayerReplicationInfo PRI;
|
||||
local color specColor;
|
||||
local int baseX, baseY;
|
||||
|
||||
C.bCenter = True;
|
||||
C.Font = FooterFont;
|
||||
|
||||
// Display server info in bottom center
|
||||
C.DrawColor = FooterColor;
|
||||
C.StrLen( "Test", DummyX, DummyY );
|
||||
C.SetPos( 0, C.ClipY - DummyY );
|
||||
TextStr = "Playing" @ Level.Title @ "on" @ pTGRI.ServerName;
|
||||
if( SCTFGame.TickRate > 0 ) TextStr = TextStr @ "(TR:" @ SCTFGame.TickRate $ ")";
|
||||
C.DrawText( TextStr );
|
||||
|
||||
// Draw Time
|
||||
if( bTimeDown || ( PlayerOwner.GameReplicationInfo.RemainingTime > 0 ) )
|
||||
{
|
||||
bTimeDown = True;
|
||||
if( PlayerOwner.GameReplicationInfo.RemainingTime <= 0 )
|
||||
{
|
||||
TimeStr = RemainingTime $ "00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
Minutes = PlayerOwner.GameReplicationInfo.RemainingTime / 60;
|
||||
Seconds = PlayerOwner.GameReplicationInfo.RemainingTime % 60;
|
||||
TimeStr = RemainingTime $ TwoDigitString( Minutes ) $ ":" $ TwoDigitString( Seconds );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Seconds = PlayerOwner.GameReplicationInfo.ElapsedTime;
|
||||
Minutes = Seconds / 60;
|
||||
Hours = Minutes / 60;
|
||||
Seconds = Seconds - ( Minutes * 60 );
|
||||
Minutes = Minutes - ( Hours * 60 );
|
||||
TimeStr = ElapsedTime $ TwoDigitString( Hours ) $ ":" $ TwoDigitString( Minutes ) $ ":" $ TwoDigitString( Seconds );
|
||||
}
|
||||
|
||||
if(SCTFGame.bShowSpecs){
|
||||
for ( i=0; i<32; i++ )
|
||||
{
|
||||
if (PlayerPawn(Owner).GameReplicationInfo.PRIArray[i] != None)
|
||||
{
|
||||
PRI = PlayerPawn(Owner).GameReplicationInfo.PRIArray[i];
|
||||
if (PRI.bIsSpectator && !PRI.bWaitingPlayer && PRI.StartTime > 0)
|
||||
{
|
||||
if(HeaderText=="") HeaderText = pri.Playername; else HeaderText = HeaderText$", "$pri.Playername;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (HeaderText=="") HeaderText = "there is currently no one spectating this match."; else HeaderText = HeaderText$"."; // I'm sorry about this, it's really stupid
|
||||
} // but I'm to lazy rewrite it :P
|
||||
// Atleast it's working..
|
||||
C.SetPos( 0, C.ClipY - 2 * DummyY );
|
||||
C.DrawText( "Current Time:" @ GetTimeStr() @ "|" @ TimeStr );
|
||||
|
||||
// Draw Spectators
|
||||
C.StrLen( HeaderText, DummyX, Nil );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
C.SetPos( 0, C.ClipY - 5 * DummyY );
|
||||
|
||||
if(SCTFGame.bShowSpecs){
|
||||
specColor = SCTFGame.SpectatorColor;
|
||||
C.Font = MyFonts.GetSmallestFont(C.ClipX);
|
||||
C.DrawColor = specColor; // Added in 4E
|
||||
C.DrawText("Spectators:"@HeaderText);
|
||||
HeaderText=""; // This is declared as a global var, so we reset it to start with a clean slate.
|
||||
}else{
|
||||
C.DrawText( "" ); // Don't draw credits 2 times
|
||||
}
|
||||
|
||||
// Draw new-credits
|
||||
C.StrLen( HeaderText2, DummyX, DummyY );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
C.SetPos( 0, C.ClipY - 3 * DummyY );
|
||||
C.Font = MyFonts.GetSmallestFont(C.ClipX);
|
||||
C.DrawColor = Yellow;
|
||||
C.DrawText( HeaderText2 );
|
||||
|
||||
C.bCenter = False;
|
||||
}
|
||||
|
||||
function DrawHeader( Canvas C )
|
||||
{
|
||||
local float DummyX, DummyY;
|
||||
|
||||
if( pTGRI.GameEndedComments == "" ) return;
|
||||
|
||||
C.Font = GameEndedFont;
|
||||
C.StrLen( pTGRI.GameEndedComments, DummyX, DummyY );
|
||||
|
||||
C.DrawColor = DarkGray;
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.SetPos( C.ClipX / 2 - DummyX / 2 + 2, DummyY + 2 );
|
||||
C.DrawText( pTGRI.GameEndedComments );
|
||||
|
||||
C.DrawColor = HeaderColor;
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
C.SetPos( C.ClipX / 2 - DummyX / 2, DummyY );
|
||||
C.DrawText( pTGRI.GameEndedComments );
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns time and date in a string.
|
||||
*/
|
||||
function string GetTimeStr()
|
||||
{
|
||||
local string Mon, Day, Min;
|
||||
|
||||
Min = string( PlayerOwner.Level.Minute );
|
||||
if( int( Min ) < 10 ) Min = "0" $ Min;
|
||||
|
||||
switch( PlayerOwner.Level.month )
|
||||
{
|
||||
case 1: Mon = "Jan"; break;
|
||||
case 2: Mon = "Feb"; break;
|
||||
case 3: Mon = "Mar"; break;
|
||||
case 4: Mon = "Apr"; break;
|
||||
case 5: Mon = "May"; break;
|
||||
case 6: Mon = "Jun"; break;
|
||||
case 7: Mon = "Jul"; break;
|
||||
case 8: Mon = "Aug"; break;
|
||||
case 9: Mon = "Sep"; break;
|
||||
case 10: Mon = "Oct"; break;
|
||||
case 11: Mon = "Nov"; break;
|
||||
case 12: Mon = "Dec"; break;
|
||||
}
|
||||
|
||||
switch( PlayerOwner.Level.dayOfWeek )
|
||||
{
|
||||
case 0: Day = "Sunday"; break;
|
||||
case 1: Day = "Monday"; break;
|
||||
case 2: Day = "Tuesday"; break;
|
||||
case 3: Day = "Wednesday"; break;
|
||||
case 4: Day = "Thursday"; break;
|
||||
case 5: Day = "Friday"; break;
|
||||
case 6: Day = "Saturday"; break;
|
||||
}
|
||||
|
||||
return Day @ PlayerOwner.Level.Day @ Mon @ PlayerOwner.Level.Year $ "," @ PlayerOwner.Level.Hour $ ":" $ Min;
|
||||
}
|
||||
|
||||
/*
|
||||
* Length of a meter drawing for a given number A out of B total.
|
||||
*/
|
||||
function int GetMeterLength( int A, int B )
|
||||
{
|
||||
local int Result;
|
||||
|
||||
if( B == 0 ) return 0;
|
||||
Result = ( A * MaxMeterWidth ) / B;
|
||||
|
||||
if( Result > MaxMeterWidth ) return MaxMeterWidth;
|
||||
else return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort PlayerReplicationInfo's on score.
|
||||
*/
|
||||
function SortScores( int N )
|
||||
{
|
||||
local byte i, j;
|
||||
local bool bSorted;
|
||||
local SmartCTFPlayerReplicationInfo PlayerStats1, PlayerStats2;
|
||||
|
||||
// Copy PRI array except for spectators.
|
||||
j = 0;
|
||||
for( i = 0; i < N; i++ )
|
||||
{
|
||||
if( pTGRI.priArray[i] == None ) break;
|
||||
if( pTGRI.priArray[i].bIsSpectator && !pTGRI.priArray[i].bWaitingPlayer ) continue;
|
||||
Ordered[j] = pTGRI.priArray[i];
|
||||
j++;
|
||||
}
|
||||
// Clear the remaining entries.
|
||||
for( i = j; i < N; i++ )
|
||||
{
|
||||
Ordered[i] = None;
|
||||
}
|
||||
|
||||
for( i = 0; i < N; i++)
|
||||
{
|
||||
bSorted = True;
|
||||
for( j = 0; j < N - 1; j++)
|
||||
{
|
||||
if( Ordered[j] == None || Ordered[j+1] == None ) break;
|
||||
|
||||
if( Ordered[j].Score < Ordered[j+1].Score )
|
||||
{
|
||||
SwapOrdered( j, j + 1 );
|
||||
bSorted = False;
|
||||
}
|
||||
else if( Ordered[j].Score == Ordered[j+1].Score )
|
||||
{
|
||||
PlayerStats1 = SCTFGame.GetStatsByPRI( Ordered[j] );
|
||||
PlayerStats2 = SCTFGame.GetStatsByPRI( Ordered[j+1] );
|
||||
if( PlayerStats1 != None && PlayerStats2 != None )
|
||||
{
|
||||
if( PlayerStats1.Frags < PlayerStats2.Frags )
|
||||
{
|
||||
SwapOrdered( j, j + 1 );
|
||||
bSorted = False;
|
||||
}
|
||||
else if( PlayerStats1.Frags == PlayerStats2.Frags )
|
||||
{
|
||||
if( Ordered[j].Deaths > Ordered[j+1].Deaths )
|
||||
{
|
||||
SwapOrdered( j, j + 1 );
|
||||
bSorted = False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if( bSorted ) break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for sorting.
|
||||
*/
|
||||
function SwapOrdered( byte A, byte B )
|
||||
{
|
||||
local PlayerReplicationInfo Temp;
|
||||
Temp = Ordered[A];
|
||||
Ordered[A] = Ordered[B];
|
||||
Ordered[B] = Temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalculate the totals for displaying meters on the scoreboards.
|
||||
* This way it doesn't get calculated every tick.
|
||||
*/
|
||||
function RecountNumbers()
|
||||
{
|
||||
local byte ID, i;
|
||||
local SmartCTFPlayerReplicationInfo PlayerStats;
|
||||
|
||||
MaxCaps = 0;
|
||||
MaxAssists = 0;
|
||||
MaxGrabs = 0;
|
||||
MaxCovers = 0;
|
||||
MaxSeals = 0;
|
||||
MaxDefKills = 0;
|
||||
MaxFlagKills = 0;
|
||||
MaxFrags = 0;
|
||||
MaxDeaths = 0;
|
||||
TotShieldBelts = 0;
|
||||
TotAmps = 0;
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
if( Ordered[i] == None ) break;
|
||||
if( Ordered[i].bIsSpectator && !Ordered[i].bWaitingPlayer ) continue;
|
||||
|
||||
ID = Ordered[i].PlayerID;
|
||||
|
||||
PlayerStats = SCTFGame.GetStatsByPRI( Ordered[i] );
|
||||
if( PlayerStats != None )
|
||||
{
|
||||
if( PlayerStats.Captures > MaxCaps ) MaxCaps = PlayerStats.Captures;
|
||||
if( PlayerStats.Assists > MaxAssists ) MaxAssists = PlayerStats.Assists;
|
||||
if( PlayerStats.Grabs > MaxGrabs ) MaxGrabs = PlayerStats.Grabs;
|
||||
if( PlayerStats.Covers > MaxCovers ) MaxCovers = PlayerStats.Covers;
|
||||
if( PlayerStats.Seals > MaxSeals ) MaxSeals = PlayerStats.Seals;
|
||||
if( PlayerStats.DefKills > MaxDefKills ) MaxDefKills = PlayerStats.DefKills;
|
||||
if( PlayerStats.FlagKills > MaxFlagKills ) MaxFlagKills = PlayerStats.FlagKills;
|
||||
if( PlayerStats.Frags > MaxFrags ) MaxFrags = PlayerStats.Frags;
|
||||
TotShieldBelts += PlayerStats.ShieldBelts;
|
||||
TotAmps += PlayerStats.Amps;
|
||||
}
|
||||
if( Ordered[i].Deaths > MaxDeaths ) MaxDeaths = Ordered[i].Deaths;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
PtsText="Pts"
|
||||
FragsText="Frags"
|
||||
SepText=" / "
|
||||
MoreText="More..."
|
||||
HeaderText2="[ SmartCTF 4E | {PiN}Kev | {DnF2}SiNiSTeR | [es]Rush | adminthis & The_Cowboy & Sp0ngeb0b ]"
|
||||
White=(R=255,G=255,B=255)
|
||||
Gray=(R=128,G=128,B=128)
|
||||
DarkGray=(R=32,G=32,B=32)
|
||||
Yellow=(R=255,G=255)
|
||||
RedTeamColor=(R=255)
|
||||
BlueTeamColor=(G=128,B=255)
|
||||
RedHeaderColor=(R=64)
|
||||
BlueHeaderColor=(G=32,B=64)
|
||||
StatsColor=(R=255,G=255,B=255)
|
||||
FooterColor=(R=255,G=255,B=255)
|
||||
HeaderColor=(R=255,G=255)
|
||||
TinyInfoColor=(R=128,G=128,B=128)
|
||||
HeaderTinyInfoColor=(R=192,G=192,B=192)
|
||||
}
|
||||
16
Sources/Classes/SmartCTFServerActor.uc
Normal file
16
Sources/Classes/SmartCTFServerActor.uc
Normal file
@@ -0,0 +1,16 @@
|
||||
class SmartCTFServerActor expands Actor;
|
||||
|
||||
function PostBeginPlay()
|
||||
{
|
||||
if( CTFGame( Level.Game ) != None )
|
||||
{
|
||||
Log( "ServerActor, Spawning and adding Mutator...", 'SmartCTF' );
|
||||
Level.Game.BaseMutator.AddMutator( Level.Game.Spawn( class'SmartCTF' ) );
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bHidden=True
|
||||
}
|
||||
361
Sources/Classes/SmartCTFServerInfo.uc
Normal file
361
Sources/Classes/SmartCTFServerInfo.uc
Normal file
@@ -0,0 +1,361 @@
|
||||
class SmartCTFServerInfo expands ServerInfoCTF;
|
||||
|
||||
var SmartCTFGameReplicationInfo SCTFGame;
|
||||
var PlayerPawn PlayerOwner;
|
||||
var string MapNameText;
|
||||
var bool bFontUpdated;
|
||||
var float LastUpdateTime;
|
||||
var float HeaderHeight, CatHeight, TextHeight, SmallTextHeight, VSpacing, BorderSpacing, TotalHeight;
|
||||
var float StartY, Y, SideSpacing;
|
||||
var Color HeaderBlue, TextBlue, InfoWhite;
|
||||
|
||||
function PostBeginPlay()
|
||||
{
|
||||
if( SCTFGame == None )
|
||||
{
|
||||
ForEach AllActors( class'SmartCTFGameReplicationInfo', SCTFGame ) break;
|
||||
}
|
||||
|
||||
super.PostBeginPlay();
|
||||
}
|
||||
|
||||
function RenderInfo( Canvas C )
|
||||
{
|
||||
local float XL;
|
||||
local GameReplicationInfo GRI;
|
||||
|
||||
if( Level.TimeSeconds - LastUpdateTime > 0.5 ) bFontUpdated = False;
|
||||
if( !bFontUpdated )
|
||||
{
|
||||
C.Font = MyFonts.GetHugeFont( C.ClipX );
|
||||
C.StrLen( "Test", XL, HeaderHeight );
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.StrLen( "Test", XL, CatHeight );
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "Test", XL, TextHeight );
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "Test", XL, SmallTextHeight );
|
||||
CatHeight = CatHeight * 1.2;
|
||||
TextHeight = TextHeight * 1.2;
|
||||
SmallTextHeight = SmallTextHeight * 1.1;
|
||||
VSpacing = HeaderHeight * 0.8;
|
||||
BorderSpacing = VSpacing;
|
||||
TotalHeight = 1.5 * HeaderHeight + 2 * BorderSpacing + CatHeight * 3 + TextHeight * 6 + SmallTextHeight * 7 + VSpacing * 3;
|
||||
StartY = C.ClipY / 2 - TotalHeight / 2;
|
||||
SideSpacing = C.ClipX / 10;
|
||||
bFontUpdated = True;
|
||||
LastUpdateTime = Level.TimeSeconds;
|
||||
}
|
||||
|
||||
GRI = PlayerPawn(Owner).GameReplicationInfo;
|
||||
|
||||
DrawTitle( C );
|
||||
DrawContactInfo( C, GRI );
|
||||
DrawMOTD( C, GRI );
|
||||
DrawGameStats( C, GRI );
|
||||
DrawServerStats( C, GRI );
|
||||
DrawLeaderBoard( C, GRI );
|
||||
}
|
||||
|
||||
function DrawTitle( Canvas C )
|
||||
{
|
||||
Y = StartY;
|
||||
|
||||
C.Style = ERenderStyle.STY_Modulated;
|
||||
C.SetPos( SideSpacing - BorderSpacing, Y );
|
||||
C.DrawRect( texture'shade', C.ClipX - 2 * SideSpacing + 2 * BorderSpacing , TotalHeight );
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.DrawColor.R = 32;
|
||||
C.DrawColor.G = 32;
|
||||
C.DrawColor.B = 32;
|
||||
C.SetPos( SideSpacing - BorderSpacing, Y );
|
||||
C.DrawPattern( texture'newblue', C.ClipX - 2 * SideSpacing + 2 * BorderSpacing , 1.5 * HeaderHeight, 1.0 );
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
|
||||
C.Font = MyFonts.GetHugeFont( C.ClipX );
|
||||
C.DrawColor = HeaderBlue;
|
||||
|
||||
C.bCenter = True;
|
||||
C.SetPos( 0, Y + 0.25 * HeaderHeight );
|
||||
C.DrawText( ServerInfoText, True );
|
||||
C.bCenter = False;
|
||||
|
||||
Y += 1.5 * HeaderHeight + BorderSpacing;
|
||||
}
|
||||
|
||||
function DrawContactInfo( Canvas C, GameReplicationInfo GRI )
|
||||
{
|
||||
local float XL, YL, XL2, YL2;
|
||||
|
||||
C.DrawColor = HeaderBlue;
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL, YL );
|
||||
|
||||
C.SetPos( SideSpacing, Y );
|
||||
C.DrawText( ContactInfoText, True);
|
||||
|
||||
C.DrawColor = TextBlue;
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL2, YL2 );
|
||||
|
||||
C.SetPos( SideSpacing, Y + CatHeight );
|
||||
C.DrawText( NameText, True);
|
||||
|
||||
C.SetPos( SideSpacing, Y + CatHeight + TextHeight );
|
||||
C.DrawText( AdminText, True);
|
||||
|
||||
C.SetPos( SideSpacing, Y + CatHeight + 2 * TextHeight);
|
||||
C.DrawText( EMailText, True);
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
C.SetPos( SideSpacing + XL2 * 2, Y + CatHeight );
|
||||
C.DrawText( GRI.ServerName, True);
|
||||
|
||||
C.SetPos( SideSpacing + XL2 * 2, Y + CatHeight + TextHeight );
|
||||
if( GRI.AdminName != "" )
|
||||
C.DrawText( GRI.AdminName, True );
|
||||
else
|
||||
C.DrawText( UnknownText, True );
|
||||
|
||||
C.SetPos( SideSpacing + XL2 * 2, Y + CatHeight + 2 * TextHeight );
|
||||
if( GRI.AdminEmail != "" )
|
||||
C.DrawText( GRI.AdminEmail, True );
|
||||
else
|
||||
C.DrawText( UnknownText, True );
|
||||
}
|
||||
|
||||
function DrawMOTD( Canvas C, GameReplicationInfo GRI )
|
||||
{
|
||||
local float XL, YL, XL2, YL2;
|
||||
|
||||
C.DrawColor = HeaderBlue;
|
||||
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL, YL );
|
||||
|
||||
C.SetPos( SideSpacing * 6, Y );
|
||||
C.DrawText( MOTD, True );
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL2, YL2 );
|
||||
|
||||
C.StrLen( GRI.MOTDLine1, XL2, YL2 );
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight );
|
||||
C.DrawText( GRI.MOTDLine1, True );
|
||||
|
||||
C.StrLen( GRI.MOTDLine2, XL2, YL2 );
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight + TextHeight );
|
||||
C.DrawText( GRI.MOTDLine2, True );
|
||||
|
||||
C.StrLen( GRI.MOTDLine3, XL2, YL2 );
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight + 2 * TextHeight );
|
||||
C.DrawText( GRI.MOTDLine3, True );
|
||||
|
||||
C.StrLen( GRI.MOTDLine4, XL2, YL2 );
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight + 3 * TextHeight );
|
||||
C.DrawText( GRI.MOTDLine4, True );
|
||||
|
||||
Y += CatHeight + 4 * TextHeight + VSpacing;
|
||||
}
|
||||
|
||||
function DrawGameStats( Canvas C, GameReplicationInfo GRI )
|
||||
{
|
||||
local float XL, YL, XL2, YL2;
|
||||
local int i, NumBots;
|
||||
|
||||
C.DrawColor = HeaderBlue;
|
||||
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL, YL );
|
||||
|
||||
C.SetPos( SideSpacing, Y );
|
||||
C.DrawText( GameStatsText, True );
|
||||
|
||||
C.DrawColor = TextBlue;
|
||||
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL2, YL2 );
|
||||
|
||||
C.SetPos( SideSpacing, Y + CatHeight );
|
||||
C.DrawText( GameTypeText, True );
|
||||
|
||||
C.SetPos( SideSpacing, Y + CatHeight + TextHeight );
|
||||
C.DrawText( PlayersText, True );
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
|
||||
C.SetPos( SideSpacing * 2, Y + CatHeight );
|
||||
C.DrawText( "Smart Capture The Flag", True); // GRI.GameName
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
if( ( GRI.PRIArray[i] != None ) && ( GRI.PRIArray[i].bIsABot ) ) NumBots++;
|
||||
}
|
||||
C.SetPos( SideSpacing * 2, Y + CatHeight + TextHeight );
|
||||
C.DrawText( GRI.NumPlayers $ " [" $ NumBots @ BotText $ "]", True );
|
||||
}
|
||||
|
||||
function DrawServerStats( canvas C, GameReplicationInfo GRI )
|
||||
{
|
||||
local float XL, YL, XL2, YL2;
|
||||
local TournamentGameReplicationInfo TGRI;
|
||||
|
||||
C.DrawColor = HeaderBlue;
|
||||
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL, YL );
|
||||
|
||||
C.SetPos( SideSpacing * 6, Y );
|
||||
C.DrawText( ServerStatsText, True );
|
||||
|
||||
C.DrawColor = TextBlue;
|
||||
|
||||
C.Font = MyFonts.GetSmallFont( C.ClipX );
|
||||
C.StrLen( "TEMP", XL2, YL2 );
|
||||
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight );
|
||||
C.DrawText( GamesHostedText, True);
|
||||
|
||||
C.SetPos( SideSpacing * 6, Y + CatHeight + TextHeight );
|
||||
C.DrawText( FlagsCapturedText, True);
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
|
||||
TGRI = TournamentGameReplicationInfo( GRI );
|
||||
|
||||
C.SetPos( SideSpacing * 7.25, Y + CatHeight );
|
||||
C.DrawText( TGRI.TotalGames, True );
|
||||
|
||||
C.SetPos( SideSpacing * 7.25, Y + CatHeight + TextHeight );
|
||||
C.DrawText( TGRI.TotalFlags, True );
|
||||
|
||||
Y += CatHeight + 2 * TextHeight + VSpacing;
|
||||
}
|
||||
|
||||
function DrawLeaderBoard( Canvas C, GameReplicationInfo GRI )
|
||||
{
|
||||
local float YL;
|
||||
local int i;
|
||||
local SmartCTFEndStats EndStats;
|
||||
local string Title, What, Who, Where, When;
|
||||
|
||||
C.DrawColor = HeaderBlue;
|
||||
|
||||
YL = ( CatHeight + SmallTextHeight - 4 ) / 64;
|
||||
C.Font = MyFonts.GetBigFont( C.ClipX );
|
||||
C.SetPos( SideSpacing + 68 * YL, Y );
|
||||
C.DrawText( TopPlayersText, True );
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
C.Style = ERenderStyle.STY_Translucent;
|
||||
C.bNoSmooth = False;
|
||||
C.SetPos( SideSpacing, Y );
|
||||
C.DrawIcon( texture'UTMenu.TrophyCTF', YL );
|
||||
C.SetPos( SideSpacing, Y );
|
||||
|
||||
C.bNoSmooth = True;
|
||||
C.Style = ERenderStyle.STY_Normal;
|
||||
|
||||
C.Font = MyFonts.GetSmallestFont( C.ClipX );
|
||||
C.DrawColor = TextBlue;
|
||||
|
||||
C.SetPos( SideSpacing * 2.5, Y + CatHeight );
|
||||
C.DrawText( BestFPHText, True );
|
||||
|
||||
C.SetPos( SideSpacing * 3.75, Y + CatHeight );
|
||||
C.DrawText( BestNameText, True );
|
||||
|
||||
C.SetPos( SideSpacing * 5.75, Y + CatHeight );
|
||||
C.DrawText( MapNameText, True );
|
||||
|
||||
C.SetPos( SideSpacing * 7.5, Y + CatHeight );
|
||||
C.DrawText( BestRecordSetText, True );
|
||||
|
||||
C.DrawColor = InfoWhite;
|
||||
|
||||
if( SCTFGame != None ) EndStats = SCTFGame.EndStats;
|
||||
if( EndStats != None )
|
||||
{
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
Title = "Greatest Point 'Ho";
|
||||
What = EndStats.MostPoints.Count @ "points/h";
|
||||
Who = EndStats.MostPoints.PlayerName;
|
||||
Where = EndStats.MostPoints.MapName;
|
||||
When = EndStats.MostPoints.RecordDate;
|
||||
break;
|
||||
case 1:
|
||||
Title = "Biggest DM'er";
|
||||
What = EndStats.MostFrags.Count @ "frags/h";
|
||||
Who = EndStats.MostFrags.PlayerName;
|
||||
Where = EndStats.MostFrags.MapName;
|
||||
When = EndStats.MostFrags.RecordDate;
|
||||
break;
|
||||
case 2:
|
||||
Title = "Best Flagcapper";
|
||||
What = EndStats.MostCaps.Count @ "caps/h";
|
||||
Who = EndStats.MostCaps.PlayerName;
|
||||
Where = EndStats.MostCaps.MapName;
|
||||
When = EndStats.MostCaps.RecordDate;
|
||||
break;
|
||||
case 3:
|
||||
Title = "Best Flagkiller";
|
||||
What = EndStats.MostFlagkills.Count @ "flagk./h";
|
||||
Who = EndStats.MostFlagkills.PlayerName;
|
||||
Where = EndStats.MostFlagkills.MapName;
|
||||
When = EndStats.MostFlagkills.RecordDate;
|
||||
break;
|
||||
case 4:
|
||||
Title = "Most Cover";
|
||||
What = EndStats.MostCovers.Count @ "covers/h";
|
||||
Who = EndStats.MostCovers.PlayerName;
|
||||
Where = EndStats.MostCovers.MapName;
|
||||
When = EndStats.MostCovers.RecordDate;
|
||||
break;
|
||||
case 5:
|
||||
Title = "Hardcore Sniper";
|
||||
What = EndStats.MostHeadShots.Count @ "HS/h";
|
||||
Who = EndStats.MostHeadShots.PlayerName;
|
||||
Where = EndStats.MostHeadShots.MapName;
|
||||
When = EndStats.MostHeadShots.RecordDate;
|
||||
break;
|
||||
}
|
||||
if( What == "" ) What = "--";
|
||||
if( Who == "" ) Who = "--";
|
||||
if( Where == "" ) Where = "--";
|
||||
if( When == "" ) When = "--";
|
||||
if( Len( Where ) > 20 ) Where = Left( Where, 20 ) $ "..";
|
||||
if( Len( Who ) > 25 ) Who = Left( Who, 25 ) $ "..";
|
||||
|
||||
C.DrawColor = TextBlue;
|
||||
C.SetPos( SideSpacing, Y + CatHeight + ( ( i + 1 ) * SmallTextHeight ) );
|
||||
C.DrawText( Title, True );
|
||||
C.DrawColor = InfoWhite;
|
||||
C.SetPos( SideSpacing * 2.5, Y + CatHeight + ( ( i + 1 ) * SmallTextHeight ) );
|
||||
C.DrawText( What, True );
|
||||
C.SetPos( SideSpacing * 3.75, Y + CatHeight + ( ( i + 1 ) * SmallTextHeight ) );
|
||||
C.DrawText( Who, True );
|
||||
C.SetPos( SideSpacing * 5.75, Y + CatHeight + ( ( i + 1 ) * SmallTextHeight ) );
|
||||
C.DrawText( Where, True );
|
||||
C.SetPos( SideSpacing * 7.5, Y + CatHeight + ( ( i + 1 ) * SmallTextHeight ) );
|
||||
C.DrawText( When, True );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MapNameText="Where"
|
||||
HeaderBlue=(R=9,G=151,B=247)
|
||||
TextBlue=(G=128,B=255)
|
||||
InfoWhite=(R=255,G=255,B=255)
|
||||
TopPlayersText="SmartCTF Record Holders [Numbers per Hour]"
|
||||
BestNameText="Who"
|
||||
BestFPHText="What"
|
||||
BestRecordSetText="When"
|
||||
}
|
||||
314
Sources/Classes/SmartCTFSnowyScoreboard.uc
Normal file
314
Sources/Classes/SmartCTFSnowyScoreboard.uc
Normal file
@@ -0,0 +1,314 @@
|
||||
// SnowyScoreboard original from CTT. Thanks to Defrost!
|
||||
// Brought to SmartCTF by Sp0ngeb0b
|
||||
// spongebobut@yahoo.com
|
||||
class SmartCTFSnowyScoreboard extends SmartCTFScoreBoard;
|
||||
|
||||
#exec texture import name=snowFlake1 file="Textures\SnowFlake1.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake2 file="Textures\SnowFlake2.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake3 file="Textures\SnowFlake3.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake4 file="Textures\SnowFlake4.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake5 file="Textures\SnowFlake5.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake6 file="Textures\SnowFlake6.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake7 file="Textures\SnowFlake7.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake8 file="Textures\SnowFlake8.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake9 file="Textures\SnowFlake9.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake10 file="Textures\SnowFlake10.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake11 file="Textures\SnowFlake11.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake12 file="Textures\SnowFlake12.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake13 file="Textures\SnowFlake13.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake14 file="Textures\SnowFlake14.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake15 file="Textures\SnowFlake15.pcx" mips=off flags=2
|
||||
#exec texture import name=snowFlake16 file="Textures\SnowFlake16.pcx" mips=off flags=2
|
||||
//#exec texture import name=lights file="Textures\Lights2.pcx" mips=off flags=2
|
||||
#exec texture import name=santa file="Textures\santa2.pcx" mips=off flags=2
|
||||
#exec texture import name=present file="Textures\presents.pcx" mips=off flags=2
|
||||
|
||||
struct ParticleInfo { // Snow particle description struct.
|
||||
var int spriteNum; // The snow flake sprite to use.
|
||||
var float cx; // Horizontal offset.
|
||||
var float cy; // Vertical offset.
|
||||
var float ct; // Time offset.
|
||||
var float waveFreq; // Particle wave frequency.
|
||||
var float waveAmplitude; // Amplitude of the wave.
|
||||
var float dy; // Vertical base velocity.
|
||||
var float dx; // Horizontal base velocity.
|
||||
var color col; // Color of the particle.
|
||||
};
|
||||
|
||||
var color baseColor; // Base color of the snow flakes.
|
||||
var bool bSnowInitialized; // Whether the particles have been initialized.
|
||||
var Texture sprites[16]; // Snow flake sprites.
|
||||
var ParticleInfo particles[100]; // Current particles displayed.
|
||||
var float lastUpdateTime; // Last time the particles were rendered.
|
||||
|
||||
var float minDX; // Minimum horizontal base velocity.
|
||||
var float maxDX; // Maximum horizontal base velocity.
|
||||
var float minDY; // Minimum vertical base velocity.
|
||||
var float maxDY; // Maximum vertical base velocity.
|
||||
var float minWaveAmplitude; // Minimum wave amplitude.
|
||||
var float maxWaveAmplitude; // Maximum wave amplitude.
|
||||
|
||||
// Non scaled constants.
|
||||
const minWaveFreq = 0.25; // Minimum wave frequency.
|
||||
const maxWaveFreq = 1.0; // Maximum wave frequency.
|
||||
const minGlow = 0.40; // Minimum snow flake sprite glow.
|
||||
const maxGlow = 1.00; // Maximum snow flake sprite glow.
|
||||
|
||||
// Scaled constants (set for a resolution of 1280x1024 px).
|
||||
const scaleMinDX = -20.0;
|
||||
const scaleMaxDX = 20.0;
|
||||
const scaleMinDY = 100.0;
|
||||
const scaleMaxDY = 300.0;
|
||||
const scaleMinWaveAmplitude = 8;
|
||||
const scaleMaxWaveAmplitude = 22;
|
||||
const scaleWidth = 1280;
|
||||
const scaleHeight = 1024;
|
||||
|
||||
// Texture constante
|
||||
// const lightsTextureWidth = 32; // Width of the lights texture.
|
||||
// const lightsTextureHeight = 256; // Height of the lights texture.
|
||||
|
||||
const santaTextureWidth = 128; // Width of the santa texture.
|
||||
const santaTextureHeight = 128; // Height of the santa texture.
|
||||
|
||||
const presentTextureWidth = 128; // Width of the present texture.
|
||||
const presentTextureHeight = 128; // Height of the present texture.
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Renders the scoreboard.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
function showScores(Canvas c) {
|
||||
super.showScores(c);
|
||||
renderSnow(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Renders the scoreboard in small scale?
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
function showMiniScores(Canvas c) {
|
||||
super.showMiniScores(c);
|
||||
renderSnow(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Renders the snow particles. Also adds the XmasImages.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
simulated function renderSnow(Canvas c) {
|
||||
local int baseX, baseY;
|
||||
local int index;
|
||||
local Texture sprite;
|
||||
local float cx, cy;
|
||||
|
||||
// Update position of each particle.
|
||||
updateSnow(c);
|
||||
|
||||
// Draw each particle.
|
||||
c.style = ERenderStyle.STY_Translucent;
|
||||
for (index = 0; index < arrayCount(particles); index++) {
|
||||
// Set position.
|
||||
cx = particles[index].cx;
|
||||
cy = particles[index].cy;
|
||||
cx += sin(particles[index].ct * particles[index].waveFreq * 2 * pi) * particles[index].waveAmplitude;
|
||||
c.setPos(cx, cy);
|
||||
|
||||
// Draw particle sprite.
|
||||
c.drawColor = particles[index].col;
|
||||
sprite = sprites[particles[index].spriteNum];
|
||||
c.drawTile(sprite, sprite.uSize, sprite.vSize, 0, 0, sprite.uSize, sprite.vSize);
|
||||
}
|
||||
/* Draw Lights (Looked stupid, removed)
|
||||
baseX = 0;
|
||||
baseY = c.clipY / 2;
|
||||
|
||||
c.style = ERenderStyle.STY_Normal;
|
||||
c.drawColor = BaseColor;
|
||||
|
||||
c.setPos(baseX, baseY);
|
||||
c.drawTile(Texture'lights', lightsTextureWidth, lightsTextureHeight, 0.0, 0.0, lightsTextureWidth, lightsTextureHeight);*/
|
||||
|
||||
if (SCTFGame.bXmasImages) // whether to display the Sexy Xmas images! :D
|
||||
{
|
||||
// Draw Santa
|
||||
baseX = c.clipX - santaTextureWidth - 16;
|
||||
baseY = c.clipY - santaTextureHeight - 16;
|
||||
|
||||
c.style = ERenderStyle.STY_Normal;
|
||||
c.drawColor = BaseColor;
|
||||
|
||||
c.setPos(baseX, baseY);
|
||||
c.drawTile(Texture'santa', santaTextureWidth, santaTextureHeight, 0.0, 0.0, santaTextureWidth, santaTextureHeight);
|
||||
|
||||
// Draw presents
|
||||
baseX = 16;
|
||||
baseY = c.clipY - presentTextureHeight - 16;
|
||||
|
||||
c.style = ERenderStyle.STY_Normal;
|
||||
c.drawColor = BaseColor;
|
||||
|
||||
c.setPos(baseX, baseY);
|
||||
c.drawTile(Texture'present', presentTextureWidth, presentTextureHeight, 0.0, 0.0, presentTextureWidth, presentTextureHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Updates the positions of the snow particles.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
simulated function updateSnow(Canvas c) {
|
||||
local float deltaTime;
|
||||
local int index;
|
||||
|
||||
// Prepare for update.
|
||||
setupScalars(c);
|
||||
if (!bSnowInitialized) {
|
||||
initializeSnow(c);
|
||||
}
|
||||
deltaTime = fMin(0.5, level.timeSeconds - lastUpdateTime);
|
||||
|
||||
// Move each particle.
|
||||
for (index = 0; index < arrayCount(particles); index++) {
|
||||
particles[index].cx += particles[index].dx * deltaTime;
|
||||
particles[index].cy += particles[index].dy * deltaTime;
|
||||
particles[index].ct += deltaTime / level.timeDilation;
|
||||
|
||||
// Check if particle has left the screen.
|
||||
if (particles[index].cy > c.clipY) {
|
||||
// It has, reset particle.
|
||||
initializeParticle(index, c, true);
|
||||
}
|
||||
}
|
||||
lastUpdateTime = level.timeSeconds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Initializes all snow particles.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $ENSURE bSnowInitialized
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
simulated function initializeSnow(Canvas c) {
|
||||
local int index;
|
||||
bSnowInitialized = true;
|
||||
|
||||
// Initialize each particle.
|
||||
for (index = 0; index < arrayCount(particles); index++) {
|
||||
initializeParticle(index, c);
|
||||
}
|
||||
lastUpdateTime = level.timeSeconds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Initializes the specified particle.
|
||||
* $PARAM index The particle that is to be initialized.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $PARAM bReset Reset particle to the top of the screen.
|
||||
* $REQUIRE 0 <= index && index <= arrayCount(particles) && c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
simulated function initializeParticle(int index, Canvas c, optional bool bReset) {
|
||||
particles[index].spriteNum = rand(arrayCount(sprites));
|
||||
particles[index].cx = fRand() * c.clipX;
|
||||
if (bReset) {
|
||||
particles[index].cy = -sprites[particles[index].spriteNum].vSize;
|
||||
} else {
|
||||
particles[index].cy = fRand() * c.clipY;
|
||||
}
|
||||
particles[index].ct = 0.0;
|
||||
particles[index].dx = fRand() * (maxDX - minDX) + minDX;
|
||||
particles[index].dy = fRand() * (maxDY - minDY) + minDY;
|
||||
particles[index].waveFreq = fRand() * (maxWaveFreq - minWaveFreq) + minWaveFreq;
|
||||
particles[index].waveAmplitude = fRand() * (maxWaveAmplitude - minWaveAmplitude) + minWaveAmplitude;
|
||||
particles[index].waveFreq *= particles[index].dy / maxDY;
|
||||
particles[index].waveAmplitude *= particles[index].dy / maxDY;
|
||||
|
||||
if (level.month == 12 && level.day == 24 || level.month == 12 && level.day == 25 || level.month == 12 && level.day == 31 || level.month == 1 && level.day == 1) {
|
||||
particles[index].col.r = rand(256);
|
||||
particles[index].col.g = rand(256);
|
||||
particles[index].col.b = rand(256);
|
||||
} else {
|
||||
particles[index].col = baseColor * (fRand() * (maxGlow - minGlow) + minGlow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Computes the absolute values of the scaled settings.
|
||||
* $PARAM c The canvas on which the rendering should be performed.
|
||||
* $REQUIRE c != none
|
||||
* $OVERRIDE
|
||||
*
|
||||
**************************************************************************************************/
|
||||
simulated function setupScalars(Canvas c) {
|
||||
minDX = scaleMinDX / scaleWidth * c.clipX;
|
||||
maxDX = scaleMaxDX / scaleWidth * c.clipX;
|
||||
minDY = scaleMinDY / scaleHeight * c.clipY;
|
||||
maxDY = scaleMaxDY / scaleHeight * c.clipY;
|
||||
minWaveAmplitude = scaleMinWaveAmplitude / scaleWidth * c.clipX;
|
||||
maxWaveAmplitude = scaleMaxWaveAmplitude / scaleWidth * c.clipX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
*
|
||||
* $DESCRIPTION Default properties block.
|
||||
*
|
||||
**************************************************************************************************/
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BaseColor=(R=255,G=255,B=255)
|
||||
sprites(0)=Texture'SmartCTF_4E.snowFlake1'
|
||||
sprites(1)=Texture'SmartCTF_4E.snowFlake2'
|
||||
sprites(2)=Texture'SmartCTF_4E.snowFlake3'
|
||||
sprites(3)=Texture'SmartCTF_4E.snowFlake4'
|
||||
sprites(4)=Texture'SmartCTF_4E.snowFlake5'
|
||||
sprites(5)=Texture'SmartCTF_4E.snowFlake6'
|
||||
sprites(6)=Texture'SmartCTF_4E.snowFlake7'
|
||||
sprites(7)=Texture'SmartCTF_4E.snowFlake8'
|
||||
sprites(8)=Texture'SmartCTF_4E.snowFlake9'
|
||||
sprites(9)=Texture'SmartCTF_4E.snowFlake10'
|
||||
sprites(10)=Texture'SmartCTF_4E.snowFlake11'
|
||||
sprites(11)=Texture'SmartCTF_4E.snowFlake12'
|
||||
sprites(12)=Texture'SmartCTF_4E.snowFlake13'
|
||||
sprites(13)=Texture'SmartCTF_4E.snowFlake14'
|
||||
sprites(14)=Texture'SmartCTF_4E.snowFlake15'
|
||||
sprites(15)=Texture'SmartCTF_4E.snowFlake16'
|
||||
}
|
||||
37
Sources/Classes/SmartCTFSpawnNotifyPRI.uc
Normal file
37
Sources/Classes/SmartCTFSpawnNotifyPRI.uc
Normal file
@@ -0,0 +1,37 @@
|
||||
class SmartCTFSpawnNotifyPRI expands SpawnNotify;
|
||||
|
||||
var Actor IpToCountry;
|
||||
var bool bChecked;
|
||||
|
||||
simulated event Actor SpawnNotification( Actor A )
|
||||
{
|
||||
local Actor Search;
|
||||
local SmartCTFPlayerReplicationInfo RI;
|
||||
|
||||
if( A.Owner == None ) return A;
|
||||
if( !A.Owner.IsA( 'PlayerPawn' ) && !A.Owner.IsA( 'Bot' ) ) return A;
|
||||
if( !Pawn( A.Owner ).bIsPlayer ) return A;
|
||||
|
||||
if(!bChecked)
|
||||
{
|
||||
foreach Level.Game.AllActors(class'Actor', Search, 'IpToCountry')
|
||||
{
|
||||
IpToCountry=Search;
|
||||
break;
|
||||
}
|
||||
bChecked=True;
|
||||
}
|
||||
// Spawn SmartCTF PRI for this pawn on the server
|
||||
RI=Spawn( class'SmartCTFPlayerReplicationInfo', A );
|
||||
if(IpToCountry != None)
|
||||
{
|
||||
RI.IpToCountry=IpToCountry;
|
||||
RI.bIpToCountry=True;
|
||||
}
|
||||
return A;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ActorClass=Class'Engine.PlayerReplicationInfo'
|
||||
}
|
||||
18
Sources/Classes/SmartCTFSpreeMsg.uc
Normal file
18
Sources/Classes/SmartCTFSpreeMsg.uc
Normal file
@@ -0,0 +1,18 @@
|
||||
class SmartCTFSpreeMsg expands KillingSpreeMessage;
|
||||
|
||||
static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
if( RelatedPRI_1 != None )
|
||||
{
|
||||
if( Switch == 5 ) return default.SpreeNote[Switch] @ RelatedPRI_1.PlayerName $ "!";
|
||||
if( Switch == 6 ) return RelatedPRI_1.PlayerName @ class'TournamentPlayer'.default.SpreeNote[3];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
spreenote(5)="This is just TOO EASY for"
|
||||
SpreeSound(5)=Sound'Botpack.ChatSound.SpreeSound'
|
||||
SpreeSound(6)=Sound'Botpack.ChatSound.SpreeSound'
|
||||
}
|
||||
BIN
Sources/Textures/SnowFlake1.pcx
Normal file
BIN
Sources/Textures/SnowFlake1.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake10.pcx
Normal file
BIN
Sources/Textures/SnowFlake10.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake11.pcx
Normal file
BIN
Sources/Textures/SnowFlake11.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake12.pcx
Normal file
BIN
Sources/Textures/SnowFlake12.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake13.pcx
Normal file
BIN
Sources/Textures/SnowFlake13.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake14.pcx
Normal file
BIN
Sources/Textures/SnowFlake14.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake15.pcx
Normal file
BIN
Sources/Textures/SnowFlake15.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake16.pcx
Normal file
BIN
Sources/Textures/SnowFlake16.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake2.pcx
Normal file
BIN
Sources/Textures/SnowFlake2.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake3.pcx
Normal file
BIN
Sources/Textures/SnowFlake3.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake4.pcx
Normal file
BIN
Sources/Textures/SnowFlake4.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake5.pcx
Normal file
BIN
Sources/Textures/SnowFlake5.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake6.pcx
Normal file
BIN
Sources/Textures/SnowFlake6.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake7.pcx
Normal file
BIN
Sources/Textures/SnowFlake7.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake8.pcx
Normal file
BIN
Sources/Textures/SnowFlake8.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/SnowFlake9.pcx
Normal file
BIN
Sources/Textures/SnowFlake9.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/faceless.pcx
Normal file
BIN
Sources/Textures/faceless.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/meter.pcx
Normal file
BIN
Sources/Textures/meter.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/powered.pcx
Normal file
BIN
Sources/Textures/powered.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/presents.pcx
Normal file
BIN
Sources/Textures/presents.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/santa2.pcx
Normal file
BIN
Sources/Textures/santa2.pcx
Normal file
Binary file not shown.
BIN
Sources/Textures/shade.pcx
Normal file
BIN
Sources/Textures/shade.pcx
Normal file
Binary file not shown.
Reference in New Issue
Block a user