1078 lines
31 KiB
Ucode
1078 lines
31 KiB
Ucode
// custom HUD supporting KFO
|
|
class HideHUD extends HUD_StoryMode;
|
|
|
|
|
|
#exec obj load file="KFMapEndTextures.utx"
|
|
#exec obj load file="2K4Menus.utx"
|
|
|
|
#exec TEXTURE IMPORT FILE="Textures\AllyHealthBackdrop_D.tga" NAME="AllyHealthBackdrop_D" GROUP="Extra" MIPS=0 MASKED=1
|
|
#exec TEXTURE IMPORT FILE="Textures\AllyHealthBar_D.tga" NAME="AllyHealthBar_D" GROUP="Extra" MIPS=0 MASKED=1
|
|
|
|
// =============================================================================
|
|
// defined in HUD
|
|
// var() PlayerController PlayerOwner;
|
|
// var() Pawn PawnOwner;
|
|
// var() PlayerReplicationInfo PawnOwnerPRI;
|
|
// var() Console PlayerConsole;
|
|
|
|
// defined in HUDKillingFloor
|
|
// var KFPlayerReplicationInfo KFPRI;
|
|
// var KFGameReplicationInfo KFGRI;
|
|
|
|
// message struct
|
|
struct MsgStruct
|
|
{
|
|
var string Msg;
|
|
var int count;
|
|
var float time;
|
|
};
|
|
var transient array<MsgStruct> MsgArray;
|
|
|
|
|
|
var transient float OldDilation,CurrentBW,DesiredBW,NextLevelTimer,LevelProgressBar,VisualProgressBar;
|
|
var bool bUseBloom,bUseMotionBlur,bDisplayingProgress;
|
|
var transient bool bFadeBW;
|
|
|
|
|
|
// Miscellaneous arrays.
|
|
// Used for kill icons.
|
|
struct KillIconSetting
|
|
{
|
|
var string ZedName;
|
|
var int ZedPriority;
|
|
var string IconTexture;
|
|
};
|
|
var KillIconSetting KillIconList[128];
|
|
|
|
struct ZedCounter
|
|
{
|
|
var string ZedName;
|
|
var int ZedPriority;
|
|
var int NumKills;
|
|
var Material ZedIcon;
|
|
};
|
|
// Used to store kill data.
|
|
var array<ZedCounter> ZedsKilled;
|
|
|
|
|
|
struct ScoreSprite
|
|
{
|
|
var string ScoreText; // Drawn text
|
|
var float X, Y; // 2D location
|
|
var float SpeedX, SpeedY; // 2D speed
|
|
var float UpTime; // How long this sprite has been around for.
|
|
var float FadeTime; // How long this sprite will last.
|
|
};
|
|
var array<ScoreSprite> ScoreList; // Holds a list of current score popups.
|
|
|
|
|
|
var string HealthBarPerkList[16];
|
|
const MAXPLAYERS=16;
|
|
var Font TinyFont;
|
|
|
|
// Materials for the health bars.
|
|
var Material AllyMaterial, AllyMaterialBackdrop;
|
|
// Used to create the effect when an ally has low health.
|
|
var float BlinkCounter;
|
|
var float BlinkCounterDir;
|
|
|
|
|
|
simulated function DrawHudPassA(Canvas C)
|
|
{
|
|
super.DrawHudPassA(C);
|
|
|
|
DrawAllyData(C);
|
|
}
|
|
|
|
|
|
final private function string GetHealthBarPerk(int Index)
|
|
{
|
|
return HealthBarPerkList[Index];
|
|
}
|
|
|
|
|
|
final private function bool InOrder(PlayerReplicationInfo P1, PlayerReplicationInfo P2)
|
|
{
|
|
if (P1.bOnlySpectator )
|
|
{
|
|
if (P2.bOnlySpectator)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
else if (P2.bOnlySpectator)
|
|
return true;
|
|
|
|
if (P1.Score < P2.Score)
|
|
return false;
|
|
|
|
if (P1.Score == P2.Score)
|
|
{
|
|
if (P1.Deaths > P2.Deaths)
|
|
return false;
|
|
if ( (P1.Deaths == P2.Deaths) && (PlayerController(P2.Owner) != None) && (Viewport(PlayerController(P2.Owner).Player) != None) )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
final private function SortPRIArray()
|
|
{
|
|
local int i,j;
|
|
local PlayerReplicationInfo tmp;
|
|
|
|
for (i = 0; i < KFGRI.PRIArray.Length-1; i++)
|
|
{
|
|
for (j = i + 1; j < KFGRI.PRIArray.Length; j++)
|
|
{
|
|
if (!InOrder(KFGRI.PRIArray[i], KFGRI.PRIArray[j]))
|
|
{
|
|
tmp = KFGRI.PRIArray[i];
|
|
KFGRI.PRIArray[i] = KFGRI.PRIArray[j];
|
|
KFGRI.PRIArray[j] = tmp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// KFGRI - Game Replication Info
|
|
// KFPRI - Player Replication Info
|
|
final private function function DrawAllyData(Canvas C)
|
|
{
|
|
local KFPlayerReplicationInfo PRI;
|
|
local array<KFPlayerReplicationInfo> TeamPRIArray;
|
|
|
|
local float AllyBarHeight, AllyBarLength;
|
|
local float AllyBarScaleX, AllyBarScaleY;
|
|
local float TempX, TempY;
|
|
|
|
local int i, PlayerCount;
|
|
local int BlinkColour;
|
|
local int BackdropBlinkColour;
|
|
local float BlinkRate;
|
|
|
|
local string PlayerName;
|
|
local float YL, XL;
|
|
|
|
// If we're missing either of these or are showing the scoreboard, leave the function.
|
|
if (KFGRI == None || KFPRI == None || bShowScoreBoard || GetHealthBarPerk(0) == "None")
|
|
return;
|
|
|
|
// If the list is empty, all perks will display this.
|
|
if(GetHealthBarPerk(0) != "")
|
|
{
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
// Reached an end point without breaking out of the for loop, leave the function.
|
|
if(GetHealthBarPerk(i) == "")
|
|
return;
|
|
|
|
// The class matches
|
|
if(KFPRI.ClientVeteranSkill == class<KFVeterancyTypes>(DynamicLoadObject(GetHealthBarPerk(i), Class'Class')))
|
|
break;
|
|
|
|
// We looped through all of the possible perks, leave the function.
|
|
if(i == 15)
|
|
return;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < KFGRI.PRIArray.Length; i++)
|
|
{
|
|
PRI = KFPlayerReplicationInfo(KFGRI.PRIArray[i]);
|
|
|
|
if(!PRI.bOnlySpectator)
|
|
{
|
|
// Do not include this player - or any dead players.
|
|
if(PRI == KFPRI || PRI.PlayerHealth <= 0)
|
|
continue;
|
|
|
|
PlayerCount++;
|
|
TeamPRIArray[TeamPRIArray.Length] = PRI;
|
|
}
|
|
}
|
|
|
|
if(PlayerCount == 0)
|
|
return;
|
|
|
|
SortPRIArray();
|
|
|
|
// Leave in this max players clamp.
|
|
PlayerCount = Min(PlayerCount, MAXPLAYERS);
|
|
|
|
// All bars together should be equal to 1/4 of the height.
|
|
AllyBarHeight = (C.SizeY * 0.15) / 8.f;
|
|
AllyBarLength = AllyBarHeight * 10.f;
|
|
|
|
// Get scales.
|
|
AllyBarScaleX = AllyBarLength/AllyMaterial.MaterialUSize();
|
|
AllyBarScaleY = AllyBarHeight/AllyMaterial.MaterialVSize();
|
|
|
|
TempY = C.SizeY * 0.5 - (AllyBarHeight * PlayerCount * 0.5f);
|
|
TempX = -(C.SizeX * 0.005);
|
|
|
|
if(TinyFont == None)
|
|
TinyFont = Font(DynamicLoadObject("Engine.DefaultFont", Class'Font'));
|
|
C.Font = TinyFont;
|
|
|
|
for(i = 0; i < PlayerCount ; i++)
|
|
{
|
|
if(TeamPRIArray[i] == None)
|
|
return;
|
|
|
|
if(TeamPRIArray[i].PlayerHealth > 50)
|
|
BlinkColour = 255;
|
|
else
|
|
{
|
|
// 50: 255
|
|
// 0: 0
|
|
BlinkColour = int((float(Clamp(TeamPRIArray[i].PlayerHealth, 0, 50)) / 50.f) * 255.f);
|
|
|
|
if(TeamPRIArray[i].PlayerHealth < 25)
|
|
{
|
|
BlinkRate = BlinkCounter * 2.f;
|
|
|
|
if(BlinkRate > 1.f)
|
|
BlinkRate -= 1.f;
|
|
}
|
|
else
|
|
BlinkRate = BlinkCounter;
|
|
|
|
BlinkColour = int(FClamp(float(BlinkColour) + (255.f - float(BlinkColour)) * BlinkRate,0.f,255.f));
|
|
}
|
|
|
|
BackdropBlinkColour = int(FClamp((float(BlinkColour)/255.f) * 64.f,0.f,255.f));
|
|
|
|
C.SetDrawColor(64, BackdropBlinkColour, BackdropBlinkColour, (KFHUDAlpha*0.85f));
|
|
|
|
C.SetPos(TempX, TempY);
|
|
C.DrawTileScaled(AllyMaterialBackdrop,AllyBarScaleX,AllyBarScaleY);
|
|
|
|
C.SetDrawColor(255, BlinkColour, BlinkColour, (KFHUDAlpha*0.5f));
|
|
|
|
C.SetPos(TempX - (AllyBarLength * 0.95f * float(100 - Clamp(TeamPRIArray[i].PlayerHealth, 0, 100)) / 100.f), TempY);
|
|
C.DrawTileScaled(AllyMaterial,AllyBarScaleX,AllyBarScaleY);
|
|
|
|
C.SetDrawColor(0, 0, 0, KFHUDAlpha);
|
|
|
|
PlayerName = TeamPRIArray[i].PlayerName;
|
|
|
|
if(Len(PlayerName) > 16)
|
|
PlayerName = Left(PlayerName,16);
|
|
|
|
C.Strlen(PlayerName, XL, YL);
|
|
|
|
C.SetPos(TempX + AllyBarLength * 0.95f - XL, TempY + AllyBarHeight * 0.5f - YL * 0.5f);
|
|
C.DrawText(PlayerName);
|
|
|
|
TempY -= AllyBarHeight;
|
|
}
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// Zed Kill Counter
|
|
// =============================================================================
|
|
|
|
// SkeletonHUD
|
|
function UpdateKillMessage(Object OptionalObject, PlayerReplicationInfo RelatedPRI_1)
|
|
{
|
|
local class<Monster> MClass;
|
|
|
|
// If the RelatedPRI doesn't exist, then it's the current player.
|
|
// If the RelatedPRI does exist, make sure it's equal to the player.
|
|
if (OptionalObject != none && (RelatedPRI_1 == none || KFPlayerReplicationInfo(RelatedPRI_1) == KFPRI))
|
|
{
|
|
MClass = class<Monster>(OptionalObject);
|
|
|
|
ProcessNewKill(MClass.default.MenuName);
|
|
// ProcessNewScore(MClass.Default.ScoringValue);
|
|
}
|
|
|
|
super(HUDKillingFloor).UpdateKillMessage(OptionalObject, RelatedPRI_1);
|
|
}
|
|
|
|
|
|
simulated function ProcessNewKill(String EnemyName)
|
|
{
|
|
local ZedCounter NewZedEntry;
|
|
local int i, NewIndex; // j
|
|
|
|
for(i = 0; i < ZedsKilled.Length; i++)
|
|
{
|
|
if(ZedsKilled[i].ZedName == EnemyName)
|
|
{
|
|
ZedsKilled[i].NumKills++;
|
|
SortZedArray();
|
|
return;
|
|
}
|
|
|
|
// If this new zed is an event version, handle this accordingly.
|
|
// else if(bCompactZedNames &&
|
|
// (InStr(EnemyName, ZedsKilled[i].ZedName) > -1 || InStr(ZedsKilled[i].ZedName, EnemyName) > -1))
|
|
// {
|
|
// // Set the zed name to the smaller of the two.
|
|
// if(Len(EnemyName) < Len(ZedsKilled[i].ZedName))
|
|
// {
|
|
// for(j = i + 1; j < ZedsKilled.Length; j++)
|
|
// {
|
|
// if(InStr(ZedsKilled[j].ZedName, EnemyName) > - 1)
|
|
// {
|
|
// ZedsKilled[i].NumKills += ZedsKilled[j].NumKills;
|
|
// ZedsKilled.Remove(j,1);
|
|
// }
|
|
// }
|
|
|
|
// ZedsKilled[i].ZedName = EnemyName;
|
|
// ZedsKilled[i].ZedIcon = Texture(DynamicLoadObject(GetZedTexture(EnemyName), Class'Texture', true));
|
|
// }
|
|
|
|
// ZedsKilled[i].NumKills++;
|
|
// SortZedArray();
|
|
// return;
|
|
// }
|
|
}
|
|
|
|
NewZedEntry.ZedName = EnemyName;
|
|
NewZedEntry.NumKills = 1;
|
|
NewZedEntry.ZedPriority = GetZedPriority(EnemyName);
|
|
|
|
NewIndex = ZedsKilled.Length;
|
|
ZedsKilled[NewIndex] = NewZedEntry;
|
|
|
|
// if(GetZedTexture(EnemyName) == "")
|
|
// ZedsKilled[NewIndex].ZedIcon = PerkStarIcons[0];
|
|
// else
|
|
ZedsKilled[NewIndex].ZedIcon = Texture(DynamicLoadObject(GetZedTexture(EnemyName), Class'Texture', true));
|
|
|
|
SortZedArray();
|
|
}
|
|
|
|
|
|
simulated function int GetZedPriority(string MonsterName)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0; i < 128; i++)
|
|
{
|
|
if(KillIconList[i].ZedName == "")
|
|
return 0;
|
|
|
|
if(MonsterName == KillIconList[i].ZedName)
|
|
return KillIconList[i].ZedPriority;
|
|
|
|
// if(bCompactZedNames
|
|
// && InStr(MonsterName, KillIconList[i].ZedName) > -1
|
|
// && Len(MonsterName) > Len(KillIconList[i].ZedName))
|
|
// {
|
|
// return KillIconList[i].ZedPriority;
|
|
// }
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Pulls the zed texture reference at a specific index from the replicated array.
|
|
simulated function string GetZedTexture(string MonsterName)
|
|
{
|
|
local int i;
|
|
|
|
for(i = 0; i < 128; i++)
|
|
{
|
|
if(KillIconList[i].ZedName == "")
|
|
break;
|
|
|
|
if(MonsterName == KillIconList[i].ZedName)
|
|
return KillIconList[i].IconTexture;
|
|
|
|
|
|
// if(bCompactZedNames
|
|
// && InStr(MonsterName, KillIconList[i].ZedName) > -1
|
|
// && Len(MonsterName) > Len(KillIconList[i].ZedName))
|
|
// {
|
|
// return KillIconList[i].IconTexture;
|
|
// }
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
|
|
// Sorts Zeds by weight and then name.
|
|
simulated function SortZedArray()
|
|
{
|
|
local int i,j;
|
|
local ZedCounter SwitchZed;
|
|
|
|
for (i = 0; i < ZedsKilled.Length - 1; i++)
|
|
{
|
|
for (j = i + 1; j < ZedsKilled.Length; j++)
|
|
{
|
|
if (ZedsKilled[i].ZedPriority > ZedsKilled[j].ZedPriority)
|
|
{
|
|
SwitchZed = ZedsKilled[i];
|
|
ZedsKilled[i] = ZedsKilled[j];
|
|
ZedsKilled[j] = SwitchZed;
|
|
}
|
|
|
|
else if (ZedsKilled[i].ZedPriority == ZedsKilled[j].ZedPriority)
|
|
{
|
|
if (Caps(ZedsKilled[i].ZedName) < Caps(ZedsKilled[j].ZedName))
|
|
{
|
|
SwitchZed = ZedsKilled[i];
|
|
ZedsKilled[i] = ZedsKilled[j];
|
|
ZedsKilled[j] = SwitchZed;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// INVENTORY
|
|
// =============================================================================
|
|
|
|
// ServerPerks.SRHUDKillingFloor
|
|
simulated function PostBeginPlay()
|
|
{
|
|
local Font MyFont;
|
|
|
|
Super(HudBase).PostBeginPlay();
|
|
SetHUDAlpha();
|
|
|
|
foreach DynamicActors(class'KFSPLevelInfo', KFLevelRule)
|
|
break;
|
|
|
|
Hint_45_Time = 9999999;
|
|
|
|
MyFont = LoadWaitingFont(0);
|
|
MyFont = LoadWaitingFont(1);
|
|
|
|
// NOTE!!! SHUT ME LATER!!!
|
|
bUseBloom = bool(ConsoleCommand("get ini:Engine.Engine.ViewportManager Bloom"));
|
|
bUseMotionBlur = class'KFHumanPawn'.Default.bUseBlurEffect;
|
|
|
|
CacheDialogueActors();
|
|
CacheObjectives();
|
|
}
|
|
|
|
|
|
// Only do this if objective mode is enabled.
|
|
// ServerPerks.SRHUDKillingFloor
|
|
simulated function DrawStoryHUDInfo(Canvas C)
|
|
{
|
|
if (KF_StoryGRI(Level.GRI) != none)
|
|
super.DrawStoryHUDInfo(C);
|
|
}
|
|
|
|
|
|
// Only do this if objective mode is enabled.
|
|
// ServerPerks.SRHUDKillingFloor
|
|
simulated function DrawKFHUDTextElements(Canvas Canvas)
|
|
{
|
|
if (KF_StoryGRI(Level.GRI) == none)
|
|
super(HudKillingFloor).DrawKFHUDTextElements(Canvas);
|
|
}
|
|
|
|
|
|
// ServerPerks.SRHUDKillingFloor
|
|
simulated function DrawEndGameHUD(Canvas C, bool bVictory)
|
|
{
|
|
local float Scalar;
|
|
local Shader M;
|
|
|
|
if (SGRI != none)
|
|
{
|
|
super.DrawEndGameHUD(C, bVictory);
|
|
return;
|
|
}
|
|
C.DrawColor.A = 255;
|
|
C.DrawColor.R = 255;
|
|
C.DrawColor.G = 255;
|
|
C.DrawColor.B = 255;
|
|
Scalar = FClamp(C.ClipY, 320, 1024);
|
|
C.CurX = C.ClipX / 2 - Scalar / 2;
|
|
C.CurY = C.ClipY / 2 - Scalar / 2;
|
|
C.Style = ERenderStyle.STY_Alpha;
|
|
|
|
if (bVictory)
|
|
M = Shader'KFMapEndTextures.VictoryShader';
|
|
else
|
|
M = Shader'KFMapEndTextures.DefeatShader';
|
|
|
|
C.DrawTile(M, Scalar, Scalar, 0, 0, 1024, 1024);
|
|
|
|
if (bShowScoreBoard && ScoreBoard != none)
|
|
ScoreBoard.DrawScoreboard(C);
|
|
}
|
|
|
|
|
|
// fix accessed none spam, add scrolling through entire list
|
|
// ServerPerks.SRHUDKillingFloor
|
|
function DrawInventory(Canvas C)
|
|
{
|
|
local Inventory CurInv;
|
|
local int i, Categorized[5], Num[5], X, Y, TempX, TempY, TempWidth, TempHeight, TempBorder, StartY;
|
|
|
|
if (PawnOwner == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (bInventoryFadingIn)
|
|
{
|
|
if (Level.TimeSeconds < InventoryFadeStartTime + InventoryFadeTime)
|
|
{
|
|
C.SetDrawColor(255, 255, 255, byte(((Level.TimeSeconds - InventoryFadeStartTime) / InventoryFadeTime) * 255.0));
|
|
}
|
|
else
|
|
{
|
|
bInventoryFadingIn = false;
|
|
C.SetDrawColor(255, 255, 255, 255);
|
|
}
|
|
}
|
|
else if (bInventoryFadingOut)
|
|
{
|
|
if (Level.TimeSeconds < InventoryFadeStartTime + InventoryFadeTime)
|
|
{
|
|
C.SetDrawColor(255, 255, 255, byte((1.0 - ((Level.TimeSeconds - InventoryFadeStartTime) / InventoryFadeTime)) * 255.0));
|
|
}
|
|
else
|
|
{
|
|
bInventoryFadingOut = false;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
C.SetDrawColor(255, 255, 255, 255);
|
|
}
|
|
|
|
TempX = InventoryX * C.ClipX;
|
|
TempY = InventoryY * C.ClipY;
|
|
TempWidth = InventoryBoxWidth * C.ClipX;
|
|
TempHeight = InventoryBoxHeight * C.ClipX;
|
|
TempBorder = BorderSize * C.ClipX;
|
|
C.Font = GetFontSizeIndex(C, -3);
|
|
SelectedInventoryCategory = -1;
|
|
|
|
// First count the weapons
|
|
for (CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory)
|
|
{
|
|
// Don't allow non-categorized or Grenades
|
|
if (CurInv.InventoryGroup > 0 && CurInv.InventoryGroup <= ArrayCount(Categorized) && KFWeapon(CurInv) != None)
|
|
{
|
|
if (CurInv == SelectedInventory) // Make sure index is in sync (could have desynced)
|
|
{
|
|
SelectedInventoryCategory = CurInv.InventoryGroup-1;
|
|
SelectedInventoryIndex = Categorized[SelectedInventoryCategory];
|
|
}
|
|
++Categorized[CurInv.InventoryGroup-1];
|
|
}
|
|
}
|
|
|
|
// Check if current selected weapon goes off screen.
|
|
if (SelectedInventoryCategory!=-1 && (TempY+Categorized[SelectedInventoryCategory]*TempHeight)>=C.ClipY )
|
|
{
|
|
// Adjust offset based on current selected weapon.
|
|
Y = SelectedInventoryIndex*TempHeight;
|
|
X = (C.ClipY-TempY)/2;
|
|
if( Y>X )
|
|
StartY = X-Y;
|
|
}
|
|
|
|
// Now draw weapons.
|
|
for ( CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory )
|
|
{
|
|
// Don't allow non-categorized or Grenades
|
|
if ( CurInv.InventoryGroup>0 && CurInv.InventoryGroup<=ArrayCount(Categorized) && KFWeapon(CurInv)!=None )
|
|
{
|
|
i = CurInv.InventoryGroup - 1;
|
|
X = TempX+(TempWidth*i);
|
|
Y = TempY+(Num[i]*TempHeight);
|
|
if( i==SelectedInventoryCategory )
|
|
Y+=StartY;
|
|
|
|
// Draw this item's Background
|
|
C.SetPos(X, Y);
|
|
if ( CurInv==SelectedInventory )
|
|
C.DrawTileStretched(SelectedInventoryBackgroundTexture, TempWidth, TempHeight);
|
|
else C.DrawTileStretched(InventoryBackgroundTexture, TempWidth, TempHeight);
|
|
|
|
// Draw the Weapon's Icon over the Background
|
|
C.SetPos(X + TempBorder, Y + TempBorder);
|
|
DrawSelectionIcon(C,CurInv==SelectedInventory,KFWeapon(CurInv),TempWidth - (2.0 * TempBorder),TempHeight - (2.0 * TempBorder));
|
|
++Num[i];
|
|
}
|
|
}
|
|
|
|
// Draw empty categories boxes.
|
|
for ( i=0; i<ArrayCount(Categorized); i++ )
|
|
{
|
|
if ( Categorized[i]==0 )
|
|
{
|
|
C.SetPos(TempX+(TempWidth*i), TempY);
|
|
C.DrawTileStretched(InventoryBackgroundTexture, TempWidth, TempHeight * 0.25);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// weapon name in icon
|
|
// ServerPerks.SRHUDKillingFloor
|
|
final function DrawSelectionIcon(Canvas C, bool bSelected, KFWeapon I, float Width, float Height)
|
|
{
|
|
local float RX,RY;
|
|
local Material M;
|
|
|
|
if (bSelected)
|
|
M = I.SelectedHudImage;
|
|
else
|
|
M = I.HudImage;
|
|
|
|
if (M != None)
|
|
{
|
|
RX = C.CurX;
|
|
RY = C.CurY;
|
|
C.DrawTile(M, Width, Height, 0, 0, 256, 192);
|
|
if( !bSelected )
|
|
return;
|
|
C.CurX = RX;
|
|
C.CurY = RY;
|
|
}
|
|
|
|
if( !bSelected )
|
|
{
|
|
C.DrawColor.G = 128;
|
|
C.DrawColor.B = 128;
|
|
}
|
|
RX = C.ClipX;
|
|
RY = C.ClipY;
|
|
C.OrgX = C.CurX;
|
|
C.CurX = 0;
|
|
C.ClipX = Width;
|
|
C.ClipY = C.CurY+Height;
|
|
C.DrawText(I.ItemName,false);
|
|
C.OrgX = 0;
|
|
C.ClipX = RX;
|
|
C.ClipY = RY;
|
|
if( !bSelected )
|
|
{
|
|
C.DrawColor.G = 255;
|
|
C.DrawColor.B = 255;
|
|
}
|
|
}
|
|
|
|
|
|
// Muuuuch better weapon scrolling
|
|
// ServerPerks.SRHUDKillingFloor
|
|
function PrevWeapon()
|
|
{
|
|
local Inventory CurInv;
|
|
local int Categorized[5], Num;
|
|
// local byte Tries;
|
|
|
|
if ( PawnOwner==none || PawnOwner.Inventory==None || !ShowInventory() )
|
|
return;
|
|
|
|
// while( ++Tries<3 )
|
|
// {
|
|
SelectedInventoryCategory = -1;
|
|
SelectedInventoryIndex = 0;
|
|
|
|
// First pass, gather weapon counts.
|
|
for ( CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory )
|
|
{
|
|
// Don't allow non-categorized or Grenades
|
|
if ( CurInv.InventoryGroup>0 && CurInv.InventoryGroup<=ArrayCount(Categorized) && KFWeapon(CurInv)!=None )
|
|
{
|
|
if ( CurInv==SelectedInventory )
|
|
{
|
|
SelectedInventoryCategory = CurInv.InventoryGroup - 1;
|
|
SelectedInventoryIndex = Categorized[SelectedInventoryCategory];
|
|
}
|
|
++Num;
|
|
++Categorized[CurInv.InventoryGroup - 1];
|
|
}
|
|
}
|
|
|
|
if( Num<=1 )
|
|
return; // Prevent runaway loop.
|
|
|
|
// Now check for suitable prev index.
|
|
// Find next available category.
|
|
if( SelectedInventoryIndex==0 )
|
|
{
|
|
while( true )
|
|
{
|
|
if( --SelectedInventoryCategory<0 )
|
|
SelectedInventoryCategory = ArrayCount(Categorized)-1;
|
|
|
|
if( Categorized[SelectedInventoryCategory]>0 )
|
|
break;
|
|
}
|
|
SelectedInventoryIndex = Categorized[SelectedInventoryCategory]-1;
|
|
}
|
|
else --SelectedInventoryIndex; // Simply go to previous index.
|
|
|
|
// Second pass, find our desired item.
|
|
Num = 0;
|
|
for ( CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory )
|
|
{
|
|
if ( CurInv.InventoryGroup==(SelectedInventoryCategory+1) && KFWeapon(CurInv)!=None && (Num++)==SelectedInventoryIndex )
|
|
{
|
|
SelectedInventory = CurInv;
|
|
break;
|
|
}
|
|
}
|
|
// if( PawnOwner.Weapon!=SelectedInventory ) // Make sure not reselecting current weapon.
|
|
// break;
|
|
// }
|
|
}
|
|
|
|
|
|
// Muuuuch better weapon scrolling
|
|
// ServerPerks.SRHUDKillingFloor
|
|
function NextWeapon()
|
|
{
|
|
local Inventory CurInv;
|
|
local int Categorized[5], Num;
|
|
// local byte Tries;
|
|
|
|
if ( PawnOwner==none || PawnOwner.Inventory==None || !ShowInventory() )
|
|
return;
|
|
|
|
// while( ++Tries<3 )
|
|
// {
|
|
SelectedInventoryCategory = -1;
|
|
SelectedInventoryIndex = 0;
|
|
|
|
// First pass, gather weapon counts.
|
|
for ( CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory )
|
|
{
|
|
// Don't allow non-categorized or Grenades
|
|
if ( CurInv.InventoryGroup>0 && CurInv.InventoryGroup<=ArrayCount(Categorized) && KFWeapon(CurInv)!=None )
|
|
{
|
|
if ( CurInv==SelectedInventory )
|
|
{
|
|
SelectedInventoryCategory = CurInv.InventoryGroup - 1;
|
|
SelectedInventoryIndex = Categorized[SelectedInventoryCategory];
|
|
}
|
|
++Num;
|
|
++Categorized[CurInv.InventoryGroup - 1];
|
|
}
|
|
}
|
|
|
|
if( Num<=1 )
|
|
return; // Prevent runaway loop.
|
|
|
|
// Now check for suitable next index.
|
|
// Find next available category.
|
|
if( SelectedInventoryCategory==-1 || SelectedInventoryIndex==(Categorized[SelectedInventoryCategory]-1) )
|
|
{
|
|
while( true )
|
|
{
|
|
if( ++SelectedInventoryCategory>=ArrayCount(Categorized) )
|
|
SelectedInventoryCategory = 0;
|
|
|
|
if( Categorized[SelectedInventoryCategory]>0 )
|
|
break;
|
|
}
|
|
SelectedInventoryIndex = 0;
|
|
}
|
|
else ++SelectedInventoryIndex; // Simply go to next index.
|
|
|
|
// Second pass, find our desired item.
|
|
Num = 0;
|
|
for ( CurInv = PawnOwner.Inventory; CurInv != none; CurInv = CurInv.Inventory )
|
|
{
|
|
if ( CurInv.InventoryGroup==(SelectedInventoryCategory+1) && KFWeapon(CurInv)!=None && (Num++)==SelectedInventoryIndex )
|
|
{
|
|
SelectedInventory = CurInv;
|
|
break;
|
|
}
|
|
}
|
|
// if( PawnOwner.Weapon!=SelectedInventory ) // Make sure not reselecting current weapon.
|
|
// break;
|
|
// }
|
|
}
|
|
|
|
|
|
// fuckup fix
|
|
// ServerPerks.SRHUDKillingFloor
|
|
function HideInventory()
|
|
{
|
|
if (bDisplayInventory)
|
|
super.HideInventory();
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// DISABLE SOME OVERLAYS
|
|
// =============================================================================
|
|
// TO DO CHECK!!! DrawCinematicHUD()
|
|
simulated function PreBeginPlay()
|
|
{
|
|
super.PreBeginPlay();
|
|
|
|
// remove film grain effect
|
|
SpectatorOverlay = none;
|
|
default.SpectatorOverlay = none;
|
|
// remove shitty sepia effect
|
|
VisionOverlay = none;
|
|
default.VisionOverlay = none;
|
|
log("HIDEHUD SpectatorOverlay none");
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// HIDE PORTRAITS WHEN SOMEONE CHATS
|
|
// =============================================================================
|
|
|
|
function DisplayTraderPortrait()
|
|
{
|
|
// switch for portraits
|
|
if (!class'Settings'.default.bHidePortraits)
|
|
super.DisplayTraderPortrait();
|
|
}
|
|
|
|
|
|
function DisplayPortrait(PlayerReplicationInfo PRI)
|
|
{
|
|
// switch for portraits
|
|
if (!class'Settings'.default.bHidePortraits)
|
|
super.DisplayPortrait(PRI);
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// fix for <'Pawn' is none> spam in logs... scrn (c)
|
|
// =============================================================================
|
|
|
|
function DrawDoorHealthBars(Canvas C)
|
|
{
|
|
// log spam fix
|
|
if (PlayerOwner.pawn != none)
|
|
super.DrawDoorHealthBars(c);
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// Hide health, vest bars while we are in iron sights
|
|
// =============================================================================
|
|
function DrawPlayerInfo(Canvas C, Pawn P, float ScreenLocX, float ScreenLocY)
|
|
{
|
|
local float XL, YL, TempX, TempY, TempSize;
|
|
local string PlayerName;
|
|
local float Dist, OffsetX;
|
|
local byte BeaconAlpha;
|
|
local float OldZ;
|
|
local Material TempMaterial, TempStarMaterial;
|
|
local int i, TempLevel;
|
|
// ADDITION!!! prevent shit tons of typecasting
|
|
local KFPlayerReplicationInfo loc_KFPRI;
|
|
|
|
if (KFPlayerReplicationInfo(P.PlayerReplicationInfo) == none || KFPRI == none || KFPRI.bViewingMatineeCinematic)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// ADDITION!!!
|
|
loc_KFPRI = KFPlayerReplicationInfo(P.PlayerReplicationInfo);
|
|
|
|
Dist = vsize(P.Location - PlayerOwner.CalcViewLocation);
|
|
Dist -= HealthBarFullVisDist;
|
|
Dist = FClamp(Dist, 0, HealthBarCutoffDist-HealthBarFullVisDist);
|
|
Dist = Dist / (HealthBarCutoffDist - HealthBarFullVisDist);
|
|
BeaconAlpha = byte((1.f - Dist) * 255.f);
|
|
|
|
if (BeaconAlpha == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
OldZ = C.Z;
|
|
C.Z = 1.0;
|
|
C.Style = ERenderStyle.STY_Alpha;
|
|
C.SetDrawColor(255, 255, 255, BeaconAlpha);
|
|
C.Font = GetConsoleFont(C);
|
|
PlayerName = Left(P.PlayerReplicationInfo.PlayerName, 16);
|
|
C.StrLen(PlayerName, XL, YL);
|
|
C.SetPos(ScreenLocX - (XL * 0.5), ScreenLocY - (YL * 0.75));
|
|
C.DrawTextClipped(PlayerName);
|
|
|
|
// ADDITION!!! Hide health, vest bars, perk icons while we are in iron sights
|
|
if (PawnOwner != none && PawnOwner.weapon != none && KFWeapon(PawnOwner.weapon).bAimingRifle)
|
|
{
|
|
C.Z = OldZ;
|
|
return;
|
|
}
|
|
|
|
BarLength = FMin(default.BarLength * (float(C.SizeX) / 1024.f),default.BarLength);
|
|
BarHeight = FMin(default.BarHeight * (float(C.SizeX) / 1024.f),default.BarHeight);
|
|
|
|
OffsetX = (36.f * VeterancyMatScaleFactor * 0.6) - (HealthIconSize + 2.0);
|
|
|
|
if (loc_KFPRI.ClientVeteranSkill != none && loc_KFPRI.ClientVeteranSkill.default.OnHUDIcon != none)
|
|
{
|
|
if (loc_KFPRI.ClientVeteranSkillLevel > 5)
|
|
{
|
|
TempMaterial = loc_KFPRI.ClientVeteranSkill.default.OnHUDGoldIcon;
|
|
TempStarMaterial = VetStarGoldMaterial;
|
|
TempLevel = loc_KFPRI.ClientVeteranSkillLevel - 5;
|
|
}
|
|
else
|
|
{
|
|
TempMaterial = loc_KFPRI.ClientVeteranSkill.default.OnHUDIcon;
|
|
TempStarMaterial = VetStarMaterial;
|
|
TempLevel = loc_KFPRI.ClientVeteranSkillLevel;
|
|
}
|
|
|
|
TempSize = FMin((36 * VeterancyMatScaleFactor ) * (float(C.SizeX) / 1024.f),36 * VeterancyMatScaleFactor) ;
|
|
VetStarSize = FMin(default.VetStarSize * (float(C.SizeX) / 1024.f),default.VetStarSize);
|
|
TempX = ScreenLocX + ((BarLength + HealthIconSize) * 0.5) - (TempSize * 0.25) - OffsetX;
|
|
TempY = ScreenLocY - YL - (TempSize * 0.75);
|
|
|
|
C.SetPos(TempX, TempY);
|
|
C.DrawTile(TempMaterial, TempSize, TempSize, 0, 0, TempMaterial.MaterialUSize(), TempMaterial.MaterialVSize());
|
|
|
|
TempX += (TempSize - (VetStarSize * 0.75));
|
|
TempY += (TempSize - (VetStarSize * 1.5));
|
|
|
|
for (i = 0; i < TempLevel; i++)
|
|
{
|
|
C.SetPos(TempX, TempY);
|
|
C.DrawTile(TempStarMaterial, VetStarSize * 0.7, VetStarSize * 0.7, 0, 0, TempStarMaterial.MaterialUSize(), TempStarMaterial.MaterialVSize());
|
|
|
|
TempY -= VetStarSize * 0.7;
|
|
}
|
|
}
|
|
|
|
// Health
|
|
if (P.Health > 0)
|
|
DrawKFBar(C, ScreenLocX - OffsetX, (ScreenLocY - YL) - 0.4 * BarHeight, FClamp(P.Health / P.HealthMax, 0, 1), BeaconAlpha);
|
|
|
|
// Armor
|
|
if (P.ShieldStrength > 0)
|
|
DrawKFBar(C, ScreenLocX - OffsetX, (ScreenLocY - YL) - 1.5 * BarHeight, FClamp(P.ShieldStrength / 100.f, 0, 1), BeaconAlpha, true);
|
|
|
|
C.Z = OldZ;
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
// W I P !!!
|
|
// try to make message spam protection
|
|
// =============================================================================
|
|
|
|
// kfo support
|
|
simulated function Message(PlayerReplicationInfo PRI, coerce string Msg, name MsgType)
|
|
{
|
|
local Class<LocalMessage> LocalMessageClass;
|
|
|
|
if ( PRI != None && MsgType == 'Say' || MsgType == 'TeamSay' )
|
|
{
|
|
DisplayPortrait(PRI);
|
|
}
|
|
|
|
switch( MsgType )
|
|
{
|
|
case 'Trader':
|
|
Msg = TraderString$":" @ Msg;
|
|
LocalMessageClass = class'SayMessagePlus';
|
|
PRI = None;
|
|
break;
|
|
case 'Voice':
|
|
case 'Say':
|
|
if ( PRI == None )
|
|
return;
|
|
Msg = PRI.PlayerName $ ": " $ Msg;
|
|
LocalMessageClass = class'SayMessagePlus';
|
|
break;
|
|
case 'TeamSay':
|
|
if ( PRI == None )
|
|
return;
|
|
Msg = PRI.PlayerName $ " (" $ PRI.GetLocationName() $ "): " $ Msg;
|
|
LocalMessageClass = class'TeamSayMessagePlus';
|
|
break;
|
|
case 'CriticalEvent':
|
|
LocalMessageClass = class'KFCriticalEventPlus';
|
|
LocalizedMessage(LocalMessageClass, 0, None, None, None, Msg);
|
|
return;
|
|
case 'DeathMessage':
|
|
LocalMessageClass = class'xDeathMessage';
|
|
break;
|
|
case 'Msg_CashReward':
|
|
LocalMessageClass = class'Msg_CashReward';
|
|
break;
|
|
default:
|
|
LocalMessageClass = class'StringMessagePlus';
|
|
break;
|
|
}
|
|
AddTextMessage(Msg, LocalMessageClass, PRI);
|
|
}
|
|
|
|
|
|
// do not show filtered messages in HUD
|
|
function AddTextMessage(string Msg, class<LocalMessage> MessageClass, PlayerReplicationInfo PRI)
|
|
{
|
|
local int i;
|
|
|
|
// log("HIDEHUD: AddTextMessage called. Message is " $ Msg);
|
|
if (class'Settings'.static.bIsWordBanned(Msg) || PRI == none || len(Msg) == 0)
|
|
return;
|
|
|
|
// convert cyrilic into barbaric
|
|
Msg = class'o_CyrillicEncodeUtilities'.static.EnCodeStringHide(Msg);
|
|
|
|
if (bMessageBeep && MessageClass.Default.bBeep)
|
|
PlayerOwner.PlayBeepSound();
|
|
|
|
for (i = 0; i < ConsoleMessageCount; i++)
|
|
{
|
|
if (TextMessages[i].Text == "")
|
|
break;
|
|
}
|
|
|
|
if (i == ConsoleMessageCount)
|
|
{
|
|
for (i = 0; i < ConsoleMessageCount - 1; i++)
|
|
TextMessages[i] = TextMessages[i + 1];
|
|
}
|
|
|
|
TextMessages[i].Text = Msg;
|
|
TextMessages[i].MessageLife = Level.TimeSeconds + MessageClass.default.LifeTime;
|
|
TextMessages[i].TextColor = MessageClass.static.GetConsoleColor(PRI);
|
|
|
|
// PRI fix
|
|
if (MessageClass == class'SayMessagePlus' || MessageClass == class'TeamSayMessagePlus')
|
|
TextMessages[i].PRI = PRI;
|
|
else
|
|
TextMessages[i].PRI = None;
|
|
}
|
|
|
|
|
|
// =============================================================================
|
|
|
|
defaultproperties
|
|
{
|
|
KillIconList(0)=(ZedName="Clot",ZedPriority=7,iconTexture="KFZED_FX_T.Screen.Low_Zed_Head")
|
|
KillIconList(1)=(ZedName="Crawler",ZedPriority=9,iconTexture="KFZED_FX_T.Screen.Low_Zed_Head")
|
|
KillIconList(2)=(ZedName="Gorefast",ZedPriority=6,iconTexture="KFZED_FX_T.Screen.Low_Zed_Head")
|
|
KillIconList(3)=(ZedName="Stalker",ZedPriority=8,iconTexture="KFZED_FX_T.Screen.Low_Zed_Head")
|
|
KillIconList(4)=(ZedName="Bloat",ZedPriority=5,iconTexture="KFZED_FX_T.Screen.Mid_Zed_Head")
|
|
KillIconList(5)=(ZedName="Siren",ZedPriority=4,iconTexture="KFZED_FX_T.Screen.Mid_Zed_Head")
|
|
KillIconList(6)=(ZedName="Husk",ZedPriority=3,iconTexture="KFZED_FX_T.Screen.Mid_Zed_Head")
|
|
KillIconList(7)=(ZedName="Flesh Pound",ZedPriority=1,iconTexture="KFZED_FX_T.Screen.Strong_Zed_Head")
|
|
KillIconList(8)=(ZedName="Scrake",ZedPriority=2,iconTexture="KFZED_FX_T.Screen.Strong_Zed_Head")
|
|
KillIconList(9)=(ZedName="Patriarch",iconTexture="KFZED_FX_T.Screen.Boss_Zed_Head")
|
|
HealthBarPerkList(0)="KFMod.KFVetFieldMedic"
|
|
AllyMaterial=Texture'HideMut.Extra.AllyHealthBar_D'
|
|
AllyMaterialBackdrop=Texture'HideMut.Extra.AllyHealthBackdrop_D'
|
|
}
|