KF2-Server-Extension/ServerExt/Classes/ExtPlayerController.uc

1244 lines
32 KiB
Ucode
Raw Normal View History

2017-10-20 02:00:49 +00:00
Class ExtPlayerController extends KFPlayerController;
var localized string GotItemText;
var localized string KilledHimselfWith;
var localized string WasBurnedToDeath;
var localized string WasBlownIntoPeaces;
var localized string HadSuddenHeartAttack;
var localized string WasKilledBy;
var localized string WasIncineratedBy;
var localized string WasBlownUpBy;
var localized string ConnectionError;
var localized string Disconnecting;
var localized string NowViewingFrom;
var localized string ViewingFromOwnCamera;
2017-10-20 02:00:49 +00:00
struct FAdminCmdType
{
var string Cmd,Info;
};
enum EDmgMsgType
{
DMG_PawnDamage,
DMG_EXP,
DMG_Heal,
};
var string ServerMOTD,PendingMOTD;
var ExtPerkManager ActivePerkManager;
var class<KFGUI_Page> MidGameMenuClass;
var class<Ext_PerkBase> PendingPerkClass;
var private transient rotator OldViewRot;
var private transient float LastMisfireTime,LastFireTime,MisfireTimer;
var private transient byte MisfireCount,MisrateCounter;
var transient float NextSpectateChange,NextCommTime;
var array<FAdminCmdType> AdminCommands;
var transient byte DropCount;
var transient Object UserAPI;
var transient SoundCue BonusMusic;
var transient Object BonusFX;
// Stats
var transient byte TransitListNum;
var transient int TransitIndex;
// Dramatic end-game camera.
var transient vector EndGameCamFocusPos[2],CalcViewLocation;
var transient rotator EndGameCamRot,CalcViewRotation;
var transient float EndGameCamTimer,LastPlayerCalcView;
var transient bool bEndGameCamFocus;
var globalconfig bool bShowFPLegs,bHideNameBeacons,bHideKillMsg,bHideDamageMsg,bHideNumberMsg,bNoMonsterPlayer,bNoScreenShake,bRenderModes,bUseKF2DeathMessages,bUseKF2KillMessages;
var globalconfig int SelectedEmoteIndex;
var bool bMOTDReceived,bNamePlateShown,bNamePlateHidden,bClientHideKillMsg,bClientHideDamageMsg,bClientHideNumbers,bNoDamageTracking,bClientNoZed,bSetPerk;
struct SavedSkins
{
var int ID;
var class<KFWeaponDefinition> WepDef;
};
var globalconfig array<SavedSkins> SavedWeaponSkins;
2017-10-20 02:00:49 +00:00
replication
{
// Things the server should send to the client.
2020-11-28 20:04:55 +00:00
if (bNetDirty)
2017-10-20 02:00:49 +00:00
MidGameMenuClass,ActivePerkManager;
}
simulated function PostBeginPlay()
{
Super.PostBeginPlay();
2020-11-28 20:12:58 +00:00
if (WorldInfo.NetMode!=NM_Client && ActivePerkManager==None)
2017-10-20 02:00:49 +00:00
{
ActivePerkManager = Spawn(class'ExtPerkManager',Self);
ActivePerkManager.PlayerOwner = Self;
ActivePerkManager.PRIOwner = ExtPlayerReplicationInfo(PlayerReplicationInfo);
2020-11-28 20:12:58 +00:00
if (ActivePerkManager.PRIOwner!=None)
2017-10-20 02:00:49 +00:00
ActivePerkManager.PRIOwner.PerkManager = ActivePerkManager;
SetTimer(0.1,true,'CheckPerk');
}
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
simulated function Destroyed()
{
2020-11-28 20:12:58 +00:00
if (ActivePerkManager!=None)
2017-10-20 02:00:49 +00:00
ActivePerkManager.PreNotifyPlayerLeave();
Super.Destroyed();
2020-11-28 20:12:58 +00:00
if (ActivePerkManager!=None)
2017-10-20 02:00:49 +00:00
ActivePerkManager.Destroy();
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
function CheckPerk()
{
2020-11-28 20:12:58 +00:00
if (CurrentPerk!=ActivePerkManager)
2017-10-20 02:00:49 +00:00
{
CurrentPerk = ActivePerkManager;
2020-11-28 20:12:58 +00:00
if (KFPlayerReplicationInfo(PlayerReplicationInfo)!=None)
2017-10-20 02:00:49 +00:00
{
KFPlayerReplicationInfo(PlayerReplicationInfo).NetPerkIndex = 0;
2021-02-08 22:30:48 +00:00
KFPlayerReplicationInfo(PlayerReplicationInfo).CurrentPerkClass = ActivePerkManager.CurrentPerk.BasePerk;
2017-10-20 02:00:49 +00:00
}
}
}
2020-11-28 20:04:55 +00:00
reliable client function AddAdminCmd(string S)
2017-10-20 02:00:49 +00:00
{
local int i,j;
j = InStr(S,":");
i = AdminCommands.Length;
AdminCommands.Length = i+1;
2020-11-28 20:12:58 +00:00
if (j==-1)
2017-10-20 02:00:49 +00:00
{
AdminCommands[i].Cmd = S;
AdminCommands[i].Info = S;
}
else
{
AdminCommands[i].Cmd = Left(S,j);
AdminCommands[i].Info = Mid(S,j+1);
}
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
reliable client function ClientSetHUD(class<HUD> newHUDType)
{
Super.ClientSetHUD(newHUDType);
SendServerSettings();
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientSetBonus(SoundCue C, Object FX)
2017-10-20 02:00:49 +00:00
{
BonusMusic = C;
BonusFX = FX;
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
simulated final function SendServerSettings()
{
2020-11-28 20:12:58 +00:00
if (LocalPlayer(Player)!=None)
2017-10-20 02:00:49 +00:00
ServerSetSettings(bHideKillMsg,bHideDamageMsg,bHideNumberMsg,bNoMonsterPlayer);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable server function ServerSetSettings(bool bHideKill, bool bHideDmg, bool bHideNum, bool bNoZ)
2017-10-20 02:00:49 +00:00
{
bClientHideKillMsg = bHideKill;
bClientHideDamageMsg = bHideDmg;
bClientHideNumbers = bHideNum;
bNoDamageTracking = (bHideDmg && bHideNum);
bClientNoZed = bNoZ;
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
unreliable server function NotifyFixed(byte Mode)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Mode==1 && (Pawn==None || (WorldInfo.TimeSeconds-Pawn.SpawnTime)<5.f))
2017-10-20 02:00:49 +00:00
return;
OnClientFixed(Self,Mode);
2020-11-28 20:12:58 +00:00
if (Default.bRenderModes && ExtPlayerReplicationInfo(PlayerReplicationInfo)!=None)
2017-10-20 02:00:49 +00:00
ExtPlayerReplicationInfo(PlayerReplicationInfo).SetFixedData(Mode);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
delegate OnClientFixed(ExtPlayerController PC, byte Mode);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable client event ReceiveLocalizedMessage(class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Message!=class'KFLocalMessage_PlayerKills' && (Message!=class'KFLocalMessage_Game' || (Switch!=KMT_Suicide && Switch!=KMT_Killed)))
2017-10-20 02:00:49 +00:00
Super.ReceiveLocalizedMessage(Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject);
}
2020-11-28 20:04:55 +00:00
function AddZedKill(class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller)
2017-10-20 02:00:49 +00:00
{
// Stats.
2020-11-28 20:12:58 +00:00
if (ActivePerkManager!=None)
2017-10-20 02:00:49 +00:00
{
ActivePerkManager.TotalKills++;
ActivePerkManager.PRIOwner.RepKills++;
}
}
2020-11-28 20:04:55 +00:00
unreliable client function ClientPlayCameraShake(CameraShake Shake, optional float Scale=1.f, optional bool bTryForceFeedback, optional ECameraAnimPlaySpace PlaySpace=CAPS_CameraLocal, optional rotator UserPlaySpaceRot)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (!bNoScreenShake)
2017-10-20 02:00:49 +00:00
Super.ClientPlayCameraShake(Shake,Scale,bTryForceFeedback,PlaySpace,UserPlaySpaceRot);
}
2020-11-28 20:04:55 +00:00
exec final function AwardXP(int XP, optional byte Mode)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (WorldInfo.NetMode!=NM_Client && ActivePerkManager!=None)
2017-10-20 02:00:49 +00:00
ActivePerkManager.EarnedEXP(XP,Mode);
}
/** Perk xp stat */
function OnPlayerXPAdded(INT XP, class<KFPerk> PerkClass)
{
AwardXP(XP);
}
2020-11-28 20:04:55 +00:00
function AddSmallRadiusKill(byte Difficulty, class<KFPerk> PerkClass)
2017-10-20 02:00:49 +00:00
{
AwardXP(class'KFPerk_Berserker'.static.GetSmallRadiusKillXP(Difficulty));
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
function AddWeldPoints(int PointsWelded)
2017-10-20 02:00:49 +00:00
{
AwardXP(PointsWelded,1);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
function AddHealPoints(int PointsHealed)
2017-10-20 02:00:49 +00:00
{
AwardXP(PointsHealed,2);
}
2020-11-28 20:04:55 +00:00
function AddShotsHit(int AddedHits)
2017-10-20 02:00:49 +00:00
{
local KFWeapon W;
local float T;
Super.AddShotsHit(AddedHits);
W = KFWeapon(Pawn.Weapon);
2020-11-28 20:12:58 +00:00
if (W==None)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (LastMisfireTime>WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (++MisfireCount>15 && (WorldInfo.TimeSeconds-MisfireTimer)>10.f)
2017-10-20 02:00:49 +00:00
NotifyFixed(8);
LastMisfireTime = WorldInfo.TimeSeconds+2.f;
return;
}
MisfireCount = 0;
LastMisfireTime = WorldInfo.TimeSeconds+2.f;
MisfireTimer = WorldInfo.TimeSeconds;
return;
}
2020-11-28 20:12:58 +00:00
if (!W.HasAmmo(W.CurrentFireMode))
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (LastMisfireTime>WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (++MisfireCount>15 && (WorldInfo.TimeSeconds-MisfireTimer)>10.f)
2017-10-20 02:00:49 +00:00
NotifyFixed(16);
LastMisfireTime = WorldInfo.TimeSeconds+2.f;
return;
}
MisfireCount = 0;
LastMisfireTime = WorldInfo.TimeSeconds+2.f;
MisfireTimer = WorldInfo.TimeSeconds;
return;
}
T = W.GetFireInterval(W.CurrentFireMode);
ActivePerkManager.ModifyRateOfFire(T,W);
2020-11-28 20:12:58 +00:00
if ((WorldInfo.TimeSeconds-LastFireTime)<(T*0.5) || !W.IsFiring())
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if ((WorldInfo.TimeSeconds-LastFireTime)>4.f)
2017-10-20 02:00:49 +00:00
MisrateCounter = 0;
LastFireTime = WorldInfo.TimeSeconds;
2020-11-28 20:12:58 +00:00
if (MisrateCounter<5)
2017-10-20 02:00:49 +00:00
{
++MisrateCounter;
return;
}
2020-11-28 20:12:58 +00:00
if (LastMisfireTime>WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (++MisfireCount>15 && (WorldInfo.TimeSeconds-MisfireTimer)>10.f)
2017-10-20 02:00:49 +00:00
NotifyFixed(2);
LastMisfireTime = WorldInfo.TimeSeconds+1.f;
return;
}
MisfireCount = 0;
LastMisfireTime = WorldInfo.TimeSeconds+1.f;
MisfireTimer = WorldInfo.TimeSeconds;
}
else MisrateCounter = 0;
}
// Message of the day.
2020-11-28 20:04:55 +00:00
Delegate OnSetMOTD(ExtPlayerController PC, string S);
reliable client function ReceiveServerMOTD(string S, bool bFinal)
2017-10-20 02:00:49 +00:00
{
ServerMOTD $= S;
bMOTDReceived = bFinal;
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable server function ServerSetMOTD(string S, bool bFinal)
2017-10-20 02:00:49 +00:00
{
PendingMOTD $= S;
2020-11-28 20:12:58 +00:00
if (bFinal && PendingMOTD!="")
2017-10-20 02:00:49 +00:00
{
OnSetMOTD(Self,PendingMOTD);
PendingMOTD = "";
}
}
// TESTING:
2020-11-28 20:04:55 +00:00
reliable server function ServerItemDropGet(string Item)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (DropCount>5 || Len(Item)>100)
2017-10-20 02:00:49 +00:00
return;
++DropCount;
WorldInfo.Game.Broadcast(Self,PlayerReplicationInfo.GetHumanReadableName()@GotItemText@Item);
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:04:55 +00:00
reliable client function ReceiveLevelUp(Ext_PerkBase Perk, int NewLevel)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Perk!=None)
2017-10-20 02:00:49 +00:00
MyGFxHUD.LevelUpNotificationWidget.ShowAchievementNotification(class'KFGFxWidget_LevelUpNotification'.Default.LevelUpString, Perk.PerkName, class'KFGFxWidget_LevelUpNotification'.Default.TierUnlockedString, Perk.GetPerkIconPath(NewLevel), false, NewLevel);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ReceiveKillMessage(class<Pawn> Victim, optional bool bGlobal, optional PlayerReplicationInfo KillerPRI)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (bHideKillMsg || (bGlobal && KillerPRI==None))
2017-10-20 02:00:49 +00:00
return;
2020-11-28 20:12:58 +00:00
if (bUseKF2KillMessages)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (MyGFxHUD != none)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:04:55 +00:00
ExtMoviePlayer_HUD(MyGFxHUD).ShowKillMessageX((bGlobal ? KillerPRI : None), None, ,false, Victim);
2017-10-20 02:00:49 +00:00
}
}
2020-11-28 20:12:58 +00:00
else if (KFExtendedHUD(myHUD)!=None && Victim!=None)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).AddKillMessage(Victim,1,KillerPRI,byte(bGlobal));
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
unreliable client function ReceiveDamageMessage(class<Pawn> Victim, int Damage)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (!bHideDamageMsg && KFExtendedHUD(myHUD)!=None && Victim!=None)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).AddKillMessage(Victim,Damage,None,2);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
unreliable client function ClientNumberMsg(int Count, vector Pos, EDmgMsgType Type)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (!bHideNumberMsg && KFExtendedHUD(myHUD)!=None)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).AddNumberMsg(Count,Pos,Type);
}
2020-11-28 20:04:55 +00:00
reliable client event TeamMessage(PlayerReplicationInfo PRI, coerce string S, name Type, optional float MsgLifeTime )
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
//if (((Type == 'Say') || (Type == 'TeamSay')) && (PRI != None))
2020-11-28 20:04:55 +00:00
// SpeakTTS(S, PRI); <- KF built without TTS...
2017-10-20 02:00:49 +00:00
// since this is on the client, we can assume that if Player exists, it is a LocalPlayer
2020-11-28 20:12:58 +00:00
if (Player!=None)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (((Type == 'Say') || (Type == 'TeamSay')) && (PRI != None))
2017-10-20 02:00:49 +00:00
S = PRI.GetHumanReadableName()$": "$S;
2020-11-28 20:04:55 +00:00
LocalPlayer(Player).ViewportClient.ViewportConsole.OutputText("("$Type$") "$S);
2017-10-20 02:00:49 +00:00
}
if (MyGFxManager != none && MyGFxManager.PartyWidget != none)
2020-11-28 19:53:57 +00:00
{
2020-11-28 20:12:58 +00:00
if (!MyGFxManager.PartyWidget.ReceiveMessage(S)) //Fails if message is for updating perks in a steam lobby
2020-11-28 19:53:57 +00:00
return;
}
2017-10-20 02:00:49 +00:00
2020-11-28 20:12:58 +00:00
if (MyGFxHUD != none)
2020-11-28 19:53:57 +00:00
{
2020-11-28 20:12:58 +00:00
switch (Type)
2017-10-20 02:00:49 +00:00
{
case 'Log':
break; // Console only message.
case 'Music':
MyGFxHUD.MusicNotification.ShowSongInfo(S);
break;
case 'Event':
MyGFxHUD.HudChatBox.AddChatMessage(S, class 'KFLocalMessage'.default.DefaultColor);
break;
case 'DeathMessage':
//MyGFxHUD.HudChatBox.AddChatMessage(S, "FF0000"); // Console message only.
break;
case 'Say':
case 'TeamSay':
2020-11-28 20:12:58 +00:00
if (ExtPlayerReplicationInfo(PRI)!=None && ExtPlayerReplicationInfo(PRI).ShowAdminName())
2017-10-20 02:00:49 +00:00
MyGFxHUD.HudChatBox.AddChatMessage("("$ExtPlayerReplicationInfo(PRI).GetAdminNameAbr()$")"$S, ExtPlayerReplicationInfo(PRI).GetAdminColor());
2020-11-28 19:53:57 +00:00
else MyGFxHUD.HudChatBox.AddChatMessage(S, "64FE2E");
2017-10-20 02:00:49 +00:00
break;
case 'Priority':
MyGFxHUD.HudChatBox.AddChatMessage(S, class 'KFLocalMessage'.default.PriorityColor);
break;
case 'CriticalEvent':
PopScreenMsg(S); // HIGH|Low|Time
break;
case 'LowCriticalEvent':
MyGFxHUD.ShowNonCriticalMessage(S);
break;
default:
MyGFxHUD.HudChatBox.AddChatMessage(class'KFLocalMessage'.default.SystemString@S, class 'KFLocalMessage'.default.EventColor);
}
}
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
final function PopScreenMsg(string S)
2017-10-20 02:00:49 +00:00
{
local int i;
local string L;
local float T;
T = 4.f;
// Get lower part.
i = InStr(S,"|");
2020-11-28 20:12:58 +00:00
if (i!=-1)
2017-10-20 02:00:49 +00:00
{
L = Mid(S,i+1);
S = Left(S,i);
// Get time.
i = InStr(L,"|");
2020-11-28 20:12:58 +00:00
if (i!=-1)
2017-10-20 02:00:49 +00:00
{
T = float(Mid(L,i+1));
L = Left(L,i);
}
}
MyGFxHUD.DisplayPriorityMessage(S,L,T);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientKillMessage(class<DamageType> DamType, PlayerReplicationInfo Victim, PlayerReplicationInfo KillerPRI, optional class<Pawn> KillerPawn)
2017-10-20 02:00:49 +00:00
{
local string Msg,S;
local bool bFF;
2020-11-28 20:12:58 +00:00
if (Player==None || Victim==None)
2017-10-20 02:00:49 +00:00
return;
2020-11-28 20:12:58 +00:00
if (bUseKF2DeathMessages && MyGFxHUD!=None)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Victim==KillerPRI || (KillerPRI==None && KillerPawn==None)) // Suicide
2020-11-28 20:04:55 +00:00
ExtMoviePlayer_HUD(MyGFxHUD).ShowKillMessageX(None, Victim, ,true);
else ExtMoviePlayer_HUD(MyGFxHUD).ShowKillMessageX(KillerPRI, Victim, ,true, KillerPawn);
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:12:58 +00:00
if (Victim==KillerPRI || (KillerPRI==None && KillerPawn==None)) // Suicide
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Victim.GetTeamNum()==0)
2017-10-20 02:00:49 +00:00
{
Msg = ParseSuicideMsg(Chr(6)$"O"$Victim.GetHumanReadableName(),DamType);
class'KFMusicStingerHelper'.static.PlayPlayerDiedStinger(Self);
}
else Msg = ParseSuicideMsg(Chr(6)$"K"$Victim.GetHumanReadableName(),DamType);
}
else
{
2020-11-28 20:12:58 +00:00
if (KillerPRI!=None && Victim.Team!=None && Victim.Team==KillerPRI.Team) // Team-kill
2017-10-20 02:00:49 +00:00
{
bFF = true;
S = KillerPRI.GetHumanReadableName();
class'KFMusicStingerHelper'.static.PlayTeammateDeathStinger(Self);
}
else // Killed by monster.
{
bFF = false;
2020-11-28 20:12:58 +00:00
if (KillerPRI!=None)
2017-10-20 02:00:49 +00:00
{
S = KillerPRI.GetHumanReadableName();
}
else
{
S = class'KFExtendedHUD'.Static.GetNameOf(KillerPawn);
2020-11-28 20:12:58 +00:00
if (class<KFPawn_Monster>(KillerPawn)!=None && class<KFPawn_Monster>(KillerPawn).Default.MinSpawnSquadSizeType==EST_Boss) // Boss type.
2017-10-20 02:00:49 +00:00
S = "the "$S;
else S = class'KFExtendedHUD'.Static.GetNameArticle(S)@S;
}
class'KFMusicStingerHelper'.static.PlayZedKillHumanStinger(Self);
}
Msg = ParseKillMsg(Victim.GetHumanReadableName(),S,bFF,DamType);
}
S = Class'KFExtendedHUD'.Static.StripMsgColors(Msg);
2020-11-28 20:12:58 +00:00
if (!bUseKF2DeathMessages)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).AddDeathMessage(Msg,S);
ClientMessage(S,'DeathMessage');
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientZedKillMessage(class<DamageType> DamType, string Victim, optional PlayerReplicationInfo KillerPRI, optional class<Pawn> KillerPawn, optional bool bFFKill)
2017-10-20 02:00:49 +00:00
{
local string Msg,S;
2020-11-28 20:12:58 +00:00
if (Player==None)
2017-10-20 02:00:49 +00:00
return;
2020-11-28 20:12:58 +00:00
if (bUseKF2DeathMessages && MyGFxHUD!=None)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (KillerPRI==None && KillerPawn==None) // Suicide
2020-11-28 20:04:55 +00:00
ExtMoviePlayer_HUD(MyGFxHUD).ShowKillMessageX(None, None, Victim, true);
else ExtMoviePlayer_HUD(MyGFxHUD).ShowKillMessageX(KillerPRI, None, Victim, true, KillerPawn);
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:12:58 +00:00
if (KillerPRI==None && KillerPawn==None) // Suicide
2017-10-20 02:00:49 +00:00
{
Msg = ParseSuicideMsg(Chr(6)$"O"$Victim,DamType);
}
else
{
2020-11-28 20:12:58 +00:00
if (KillerPRI!=None) // Team-kill
2017-10-20 02:00:49 +00:00
{
S = KillerPRI.GetHumanReadableName();
}
else // Killed by monster.
{
S = class'KFExtendedHUD'.Static.GetNameOf(KillerPawn);
2020-11-28 20:12:58 +00:00
if (class<KFPawn_Monster>(KillerPawn)!=None && class<KFPawn_Monster>(KillerPawn).Default.MinSpawnSquadSizeType==EST_Boss) // Boss type.
2017-10-20 02:00:49 +00:00
S = "the "$S;
else S = class'KFExtendedHUD'.Static.GetNameArticle(S)@S;
}
Msg = ParseKillMsg(Victim,S,bFFKill,DamType);
}
S = Class'KFExtendedHUD'.Static.StripMsgColors(Msg);
2020-11-28 20:12:58 +00:00
if (!bUseKF2DeathMessages)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).AddDeathMessage(Msg,S);
ClientMessage(S,'DeathMessage');
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated final function string ParseSuicideMsg(string Victim, class<DamageType> DamType)
2017-10-20 02:00:49 +00:00
{
local string S;
S = string(DamType.Name);
2020-11-28 20:12:58 +00:00
if (Left(S,15)~="KFDT_Ballistic_")
2017-10-20 02:00:49 +00:00
{
S = Mid(S,15); // Weapon name.
return Victim$Chr(6)$"M"@KilledHimselfWith@S;
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:12:58 +00:00
else if (class<KFDT_Fire>(DamType)!=None)
return Victim$Chr(6)$"M"@WasBurnedToDeath;
2020-11-28 20:12:58 +00:00
else if (class<KFDT_Explosive>(DamType)!=None)
return Victim$Chr(6)$"M"@WasBlownIntoPeaces;
return Victim$Chr(6)$"M"@HadSuddenHeartAttack;
2017-10-20 02:00:49 +00:00
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated final function string ParseKillMsg(string Victim, string Killer, bool bFF, class<DamageType> DamType)
2017-10-20 02:00:49 +00:00
{
local string T,S;
T = (bFF ? "O" : "K");
S = string(DamType.Name);
2020-11-28 20:12:58 +00:00
if (Left(S,15)~="KFDT_Ballistic_")
2017-10-20 02:00:49 +00:00
{
S = Mid(S,15); // Weapon name.
return Chr(6)$"O"$Victim$Chr(6)$"M"@WasKilledBy@Chr(6)$T$Killer$Chr(6)$"M's "$S;
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:12:58 +00:00
else if (class<KFDT_Fire>(DamType)!=None)
return Chr(6)$"O"$Victim$Chr(6)$"M"@WasIncineratedBy@Chr(6)$T$Killer;
2020-11-28 20:12:58 +00:00
else if (class<KFDT_Explosive>(DamType)!=None)
return Chr(6)$"O"$Victim$Chr(6)$"M"@WasBlownUpBy@Chr(6)$T$Killer;
return Chr(6)$"O"$Victim$Chr(6)$"M"@WasKilledBy@Chr(6)$T$Killer;
2017-10-20 02:00:49 +00:00
}
2020-11-28 20:04:55 +00:00
reliable server function ServerCamera(name NewMode)
2017-10-20 02:00:49 +00:00
{
// <- REMOVED CAMERA LOGGING (PlayerController)
2020-11-28 20:04:55 +00:00
if (NewMode == '1st')
2020-11-28 19:53:57 +00:00
NewMode = 'FirstPerson';
2020-11-28 20:04:55 +00:00
else if (NewMode == '3rd')
2020-11-28 19:53:57 +00:00
NewMode = 'ThirdPerson';
2020-11-28 20:04:55 +00:00
SetCameraMode(NewMode);
2017-10-20 02:00:49 +00:00
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
exec function Camera(name NewMode)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:04:55 +00:00
ServerCamera(PlayerCamera.CameraStyle=='FirstPerson' ? 'ThirdPerson' : 'FirstPerson');
2017-10-20 02:00:49 +00:00
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated final function ToggleFPBody(bool bEnable)
2017-10-20 02:00:49 +00:00
{
bShowFPLegs = bEnable;
Class'ExtPlayerController'.Default.bShowFPLegs = bEnable;
2020-11-28 20:12:58 +00:00
if (ExtHumanPawn(Pawn)!=None)
2017-10-20 02:00:49 +00:00
ExtHumanPawn(Pawn).UpdateFPLegs();
}
2020-11-28 20:04:55 +00:00
/*exec function KickBan(string S)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (WorldInfo.Game!=None)
2017-10-20 02:00:49 +00:00
WorldInfo.Game.KickBan(S);
}*/
2020-11-28 20:04:55 +00:00
exec function Kick(string S)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (WorldInfo.Game!=None)
2017-10-20 02:00:49 +00:00
WorldInfo.Game.Kick(S);
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
reliable server function SkipLobby();
2020-11-28 20:04:55 +00:00
Delegate OnChangePerk(ExtPlayerController PC, class<Ext_PerkBase> NewPerk);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function SwitchToPerk(class<Ext_PerkBase> PerkClass)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (PerkClass!=None)
2017-10-20 02:00:49 +00:00
OnChangePerk(Self,PerkClass);
}
2020-11-28 20:04:55 +00:00
Delegate OnBoughtStats(ExtPlayerController PC, class<Ext_PerkBase> PerkClass, int iStat, int Amount);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function BuyPerkStat(class<Ext_PerkBase> PerkClass, int iStat, int Amount)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (PerkClass!=None && Amount>0 && iStat>=0)
2017-10-20 02:00:49 +00:00
OnBoughtStats(Self,PerkClass,iStat,Amount);
}
2020-11-28 20:04:55 +00:00
Delegate OnBoughtTrait(ExtPlayerController PC, class<Ext_PerkBase> PerkClass, class<Ext_TraitBase> Trait);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function BoughtTrait(class<Ext_PerkBase> PerkClass, class<Ext_TraitBase> Trait)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (PerkClass!=None && Trait!=None)
2017-10-20 02:00:49 +00:00
OnBoughtTrait(Self,PerkClass,Trait);
}
2020-11-28 20:04:55 +00:00
Delegate OnPerkReset(ExtPlayerController PC, class<Ext_PerkBase> PerkClass, bool bPrestige);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function ServerResetPerk(class<Ext_PerkBase> PerkClass, bool bPrestige)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (PerkClass!=None)
2017-10-20 02:00:49 +00:00
OnPerkReset(Self,PerkClass,bPrestige);
}
2020-11-28 20:04:55 +00:00
Delegate OnAdminHandle(ExtPlayerController PC, int PlayerID, int Action);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function AdminRPGHandle(int PlayerID, int Action)
2017-10-20 02:00:49 +00:00
{
OnAdminHandle(Self,PlayerID,Action);
}
2020-11-28 20:04:55 +00:00
simulated reliable client event bool ShowConnectionProgressPopup(EProgressMessageType ProgressType, string ProgressTitle, string ProgressDescription, bool SuppressPasswordRetry = false)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
switch (ProgressType)
2017-10-20 02:00:49 +00:00
{
2020-11-28 19:53:57 +00:00
case PMT_ConnectionFailure :
case PMT_PeerConnectionFailure :
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).NotifyLevelChange();
KFExtendedHUD(myHUD).ShowProgressMsg(ConnectionError@ProgressTitle$"|"$ProgressDescription$"|"$Disconnecting,true);
2017-10-20 02:00:49 +00:00
return true;
2020-11-28 19:53:57 +00:00
case PMT_DownloadProgress :
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).NotifyLevelChange();
case PMT_AdminMessage :
KFExtendedHUD(myHUD).ShowProgressMsg(ProgressTitle$"|"$ProgressDescription);
return true;
}
return false;
}
simulated function CancelConnection()
{
2020-11-28 20:12:58 +00:00
if (KFExtendedHUD(myHUD)!=None)
2017-10-20 02:00:49 +00:00
KFExtendedHUD(myHUD).CancelConnection();
else class'Engine'.Static.GetEngine().GameViewport.ConsoleCommand("Disconnect");
}
2020-01-09 11:05:13 +00:00
function NotifyLevelUp(class<KFPerk> PerkClass, byte PerkLevel, byte NewPrestigeLevel);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
function ShowBossNameplate(KFInterface_MonsterBoss KFBoss, optional string PlayerName)
{
2020-11-28 20:12:58 +00:00
if (!bNamePlateShown) // Dont make multiple bosses pop this up multiple times.
2017-10-20 02:00:49 +00:00
{
bNamePlateShown = true;
Super.ShowBossNameplate(KFBoss,PlayerName);
SetTimer(8,false,'HideBossNameplate'); // MAKE sure it goes hidden.
}
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
function HideBossNameplate()
{
2020-11-28 20:12:58 +00:00
if (!bNamePlateHidden)
2017-10-20 02:00:49 +00:00
{
bNamePlateHidden = false;
Super.HideBossNameplate();
ClearTimer('HideBossNameplate');
2020-11-28 20:12:58 +00:00
if (MyGFxHUD!=None)
2017-10-20 02:00:49 +00:00
MyGFxHUD.MusicNotification.SetVisible(true);
}
}
2020-11-28 20:04:55 +00:00
function UpdateRotation(float DeltaTime)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (OldViewRot!=Rotation && Pawn!=None && Pawn.IsAliveAndWell())
2017-10-20 02:00:49 +00:00
NotifyFixed(1);
Super.UpdateRotation(DeltaTime);
OldViewRot = Rotation;
}
2020-11-28 20:04:55 +00:00
reliable server function ServerGetUnloadInfo(byte CallID, class<Ext_PerkBase> PerkClass, bool bUnload)
2017-10-20 02:00:49 +00:00
{
OnRequestUnload(Self,CallID,PerkClass,bUnload);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
delegate OnRequestUnload(ExtPlayerController PC, byte CallID, class<Ext_PerkBase> PerkClass, bool bUnload);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientGotUnloadInfo(byte CallID, byte Code, optional int DataA, optional int DataB)
2017-10-20 02:00:49 +00:00
{
OnClientGetResponse(CallID,Code,DataA,DataB);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
delegate OnClientGetResponse(byte CallID, byte Code, int DataA, int DataB);
function DefClientResponse(byte CallID, byte Code, int DataA, int DataB);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientUsedAmmo(Ext_T_SupplierInteract S)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (Pawn!=None && S!=None)
2017-10-20 02:00:49 +00:00
S.UsedOnClient(Pawn);
}
unreliable server function ServerNextSpectateMode()
{
local Pawn HumanViewTarget;
2020-11-28 20:12:58 +00:00
if (!IsSpectating())
2017-10-20 02:00:49 +00:00
return;
// switch to roaming if human viewtarget is dead
2020-11-28 20:12:58 +00:00
if (CurrentSpectateMode != SMODE_Roaming)
2017-10-20 02:00:49 +00:00
{
HumanViewTarget = Pawn(ViewTarget);
2020-11-28 20:12:58 +00:00
if (HumanViewTarget == none || !HumanViewTarget.IsAliveAndWell())
2017-10-20 02:00:49 +00:00
{
SpectateRoaming();
return;
}
}
2020-11-28 20:04:55 +00:00
switch (CurrentSpectateMode)
2017-10-20 02:00:49 +00:00
{
case SMODE_PawnFreeCam:
2020-11-28 20:04:55 +00:00
SpectatePlayer(SMODE_PawnThirdPerson);
2017-10-20 02:00:49 +00:00
break;
case SMODE_PawnThirdPerson:
2020-11-28 20:04:55 +00:00
SpectatePlayer(SMODE_PawnFirstPerson);
2017-10-20 02:00:49 +00:00
break;
case SMODE_PawnFirstPerson:
case SMODE_Roaming:
2020-11-28 20:04:55 +00:00
SpectatePlayer(SMODE_PawnFreeCam);
2017-10-20 02:00:49 +00:00
break;
}
}
function ViewAPlayer(int dir)
{
local PlayerReplicationInfo PRI;
PRI = GetNextViewablePlayer(dir);
2020-11-28 20:04:55 +00:00
if (PRI!=None)
2017-10-20 02:00:49 +00:00
{
SetViewTarget(PRI);
ClientMessage(NowViewingFrom@PRI.GetHumanReadableName());
2017-10-20 02:00:49 +00:00
}
}
2020-11-28 20:04:55 +00:00
exec function ViewPlayerID(int ID)
2017-10-20 02:00:49 +00:00
{
ServerViewPlayerID(ID);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable server function ServerViewPlayerID(int ID)
2017-10-20 02:00:49 +00:00
{
local PlayerReplicationInfo PRI;
2020-11-28 20:12:58 +00:00
if (!IsSpectating())
2017-10-20 02:00:49 +00:00
return;
// Find matching player by ID
foreach WorldInfo.GRI.PRIArray(PRI)
{
2020-11-28 20:04:55 +00:00
if (PRI.PlayerID==ID)
2017-10-20 02:00:49 +00:00
break;
}
2020-11-28 20:12:58 +00:00
if (PRI==None || PRI.PlayerID!=ID || Controller(PRI.Owner)==None || Controller(PRI.Owner).Pawn==None || !WorldInfo.Game.CanSpectate(self, PRI))
2017-10-20 02:00:49 +00:00
return;
SetViewTarget(PRI);
ClientMessage(NowViewingFrom@PRI.GetHumanReadableName());
2020-11-28 20:12:58 +00:00
if (CurrentSpectateMode==SMODE_Roaming)
2020-11-28 20:04:55 +00:00
SpectatePlayer(SMODE_PawnFreeCam);
2017-10-20 02:00:49 +00:00
}
reliable server function SpectateRoaming()
{
local Pawn P;
P = Pawn(ViewTarget);
ClientMessage(ViewingFromOwnCamera);
2017-10-20 02:00:49 +00:00
Super.SpectateRoaming();
2020-11-28 20:12:58 +00:00
if (P!=None)
2017-10-20 02:00:49 +00:00
{
SetLocation(P.Location);
SetRotation(P.GetViewRotation());
ClientSetLocation(Location,Rotation);
}
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientSetLocation(vector NewLocation, rotator NewRotation)
2017-10-20 02:00:49 +00:00
{
SetLocation(NewLocation);
Super.ClientSetLocation(NewLocation,NewRotation);
}
unreliable server function ServerPlayLevelUpDialog()
{
2020-11-28 20:12:58 +00:00
if (NextCommTime<WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
NextCommTime = WorldInfo.TimeSeconds+2.f;
Super.ServerPlayLevelUpDialog();
}
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
unreliable server function ServerPlayVoiceCommsDialog(int CommsIndex)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (NextCommTime<WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
NextCommTime = WorldInfo.TimeSeconds+2.f;
Super.ServerPlayVoiceCommsDialog(CommsIndex);
}
}
// The player wants to fire.
// Setup bFire/bAltFire so that Auto-Fire trait will work.
2020-11-28 20:04:55 +00:00
exec function StartFire(optional byte FireModeNum)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (FireModeNum==0)
2017-10-20 02:00:49 +00:00
bFire = 1;
2020-11-28 20:12:58 +00:00
else if (FireModeNum==1)
2017-10-20 02:00:49 +00:00
bAltFire = 1;
Super.StartFire(FireModeNum);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
exec function StopFire(optional byte FireModeNum)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (FireModeNum==0)
2017-10-20 02:00:49 +00:00
bFire = 0;
2020-11-28 20:12:58 +00:00
else if (FireModeNum==1)
2017-10-20 02:00:49 +00:00
bAltFire = 0;
Super.StopFire(FireModeNum);
}
state Spectating
{
function BeginState(Name PreviousStateName)
{
Super.BeginState(PreviousStateName);
bCollideWorld = false;
}
function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot)
{
Acceleration = Normal(NewAccel) * SpectatorCameraSpeed;
Velocity = Acceleration;
2020-11-28 20:04:55 +00:00
MoveSmooth(Acceleration * DeltaTime);
2017-10-20 02:00:49 +00:00
}
function PlayerMove(float DeltaTime)
{
local vector X,Y,Z;
local rotator OldRotation;
OldRotation = Rotation;
GetAxes(Rotation,X,Y,Z);
Acceleration = (Normal(PlayerInput.aForward*X + PlayerInput.aStrafe*Y + PlayerInput.aUp*vect(0,0,1)) - bDuck*vect(0,0,1))*100.f;
UpdateRotation(DeltaTime);
if (Role < ROLE_Authority) // then save this move and replicate it
{
ReplicateMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0));
// only done for clients, as LastActiveTime only affects idle kicking
2020-11-28 20:12:58 +00:00
if ((!IsZero(Acceleration) || OldRotation != Rotation) && LastUpdateSpectatorActiveTime<WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
{
LastUpdateSpectatorActiveTime = WorldInfo.TimeSeconds+UpdateSpectatorActiveInterval;
ServerSetSpectatorActive();
}
}
else
{
ProcessMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0));
}
}
exec function SpectateNextPlayer()
{
SpectateRoaming();
}
exec function SpectatePreviousPlayer()
{
ServerViewNextPlayer();
2020-11-28 20:12:58 +00:00
if (Role == ROLE_Authority)
2017-10-20 02:00:49 +00:00
{
NotifyChangeSpectateViewTarget();
}
}
unreliable server function ServerViewNextPlayer()
{
2020-11-28 20:12:58 +00:00
if (CurrentSpectateMode==SMODE_Roaming)
2017-10-20 02:00:49 +00:00
{
CurrentSpectateMode = SMODE_PawnFreeCam;
SetCameraMode('FreeCam');
}
Global.ServerViewNextPlayer();
}
2020-11-28 20:04:55 +00:00
reliable client function ClientSetCameraMode(name NewCamMode)
2017-10-20 02:00:49 +00:00
{
Global.ClientSetCameraMode(NewCamMode);
2020-11-28 20:12:58 +00:00
if (NewCamMode=='FirstPerson' && ViewTarget==Self && MyGFxHUD!=None)
2017-10-20 02:00:49 +00:00
MyGFxHUD.SpectatorInfoWidget.SetSpectatedKFPRI(None); // Possibly went to first person, hide player info.
}
}
// Feign death:
2020-11-28 20:04:55 +00:00
function EnterRagdollMode(bool bEnable)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (bEnable)
2017-10-20 02:00:49 +00:00
GoToState('RagdollMove');
2020-11-28 20:12:58 +00:00
else if (Pawn==None)
2017-10-20 02:00:49 +00:00
GotoState('Dead');
2020-11-28 20:04:55 +00:00
else if (Pawn.PhysicsVolume.bWaterVolume)
2017-10-20 02:00:49 +00:00
GotoState(Pawn.WaterMovementState);
else GotoState(Pawn.LandMovementState);
}
// Optional dramatic end-game camera!
2020-11-28 20:04:55 +00:00
simulated function EndGameCamFocus(vector Pos)
2017-10-20 02:00:49 +00:00
{
local vector CamPos;
local rotator CamRot;
GetPlayerViewPoint(CamPos,CamRot);
bEndGameCamFocus = true;
EndGameCamFocusPos[0] = Pos;
EndGameCamFocusPos[1] = CamPos;
EndGameCamRot = CamRot;
EndGameCamTimer = WorldInfo.RealTimeSeconds;
2020-11-28 20:12:58 +00:00
if (LocalPlayer(Player)==None)
2017-10-20 02:00:49 +00:00
ClientFocusView(Pos);
2020-11-28 20:12:58 +00:00
else if (KFPawn(ViewTarget)!=None)
2017-10-20 02:00:49 +00:00
KFPawn(ViewTarget).SetMeshVisibility(true);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
reliable client function ClientFocusView(vector Pos)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (WorldInfo.NetMode==NM_Client)
2017-10-20 02:00:49 +00:00
EndGameCamFocus(Pos);
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
final function bool CalcEndGameCam()
{
local float T,RT;
local vector HL,HN;
2020-11-28 20:12:58 +00:00
if (LastPlayerCalcView==WorldInfo.TimeSeconds)
2017-10-20 02:00:49 +00:00
return true;
T = WorldInfo.RealTimeSeconds-EndGameCamTimer;
2020-11-28 20:12:58 +00:00
if (T>=20.f) // Finished view.
2017-10-20 02:00:49 +00:00
{
bEndGameCamFocus = false;
2020-11-28 20:12:58 +00:00
if (LocalPlayer(Player)!=None && KFPawn(ViewTarget)!=None)
2017-10-20 02:00:49 +00:00
KFPawn(ViewTarget).SetMeshVisibility(!Global.UsingFirstPersonCamera());
return false;
}
// Setup other cache params.
LastPlayerCalcView = WorldInfo.TimeSeconds;
CalcViewLocation.Z = 1.f;
RT = WorldInfo.RealTimeSeconds;
2020-11-28 20:12:58 +00:00
if (T<4.f)
2017-10-20 02:00:49 +00:00
RT += (4.f-T);
CalcViewLocation.X = Sin(RT*0.08f);
CalcViewLocation.Y = Cos(RT*0.08f);
CalcViewLocation = EndGameCamFocusPos[0] + Normal(CalcViewLocation)*350.f;
2020-11-28 20:12:58 +00:00
if (Trace(HL,HN,CalcViewLocation,EndGameCamFocusPos[0],false,vect(16,16,16))!=None)
2017-10-20 02:00:49 +00:00
CalcViewLocation = HL;
CalcViewRotation = rotator(EndGameCamFocusPos[0]-CalcViewLocation);
2020-11-28 20:12:58 +00:00
if (T<4.f && LocalPlayer(Player)!=None) // Zoom in to epic death.
2017-10-20 02:00:49 +00:00
{
T*=0.25;
CalcViewLocation = CalcViewLocation*T + EndGameCamFocusPos[1]*(1.f-T);
CalcViewRotation = RLerp(EndGameCamRot,CalcViewRotation,T,true);
}
return true;
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (bEndGameCamFocus && CalcEndGameCam())
2017-10-20 02:00:49 +00:00
{
out_Location = CalcViewLocation;
out_Rotation = CalcViewRotation;
return;
}
Super.GetPlayerViewPoint(out_Location,out_Rotation);
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
exec function DebugRenderMode()
{
2020-11-28 20:12:58 +00:00
if (WorldInfo.NetMode!=NM_Client)
2017-10-20 02:00:49 +00:00
{
bRenderModes = !bRenderModes;
SaveConfig();
ClientMessage(bRenderModes);
}
}
// Stats traffic.
2020-11-28 20:04:55 +00:00
reliable server function ServerRequestStats(byte ListNum)
2017-10-20 02:00:49 +00:00
{
2020-11-28 20:12:58 +00:00
if (ListNum<3)
2017-10-20 02:00:49 +00:00
{
TransitListNum = ListNum;
TransitIndex = 0;
SetTimer(0.001,true,'SendNextList');
}
}
2020-11-28 21:54:57 +00:00
2017-10-20 02:00:49 +00:00
function SendNextList()
{
2020-11-28 20:12:58 +00:00
if (!OnClientGetStat(Self,TransitListNum,TransitIndex++))
2017-10-20 02:00:49 +00:00
{
ClientGetStat(TransitListNum,true);
ClearTimer('SendNextList');
}
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated reliable client function ClientGetStat(byte ListNum, bool bFinal, optional string N, optional UniqueNetId ID, optional int V)
2017-10-20 02:00:49 +00:00
{
OnClientReceiveStat(ListNum,bFinal,N,ID,V);
}
2020-11-28 20:04:55 +00:00
Delegate OnClientReceiveStat(byte ListNum, bool bFinal, string N, UniqueNetId ID, int V);
Delegate bool OnClientGetStat(ExtPlayerController PC, byte ListNum, int StatIndex);
2017-10-20 02:00:49 +00:00
2020-11-28 20:04:55 +00:00
reliable server function ChangeSpectateMode(bool bSpectator)
2017-10-20 02:00:49 +00:00
{
OnSpectateChange(Self,bSpectator);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
simulated reliable client function ClientSpectateMode(bool bSpectator)
2017-10-20 02:00:49 +00:00
{
UpdateURL("SpectatorOnly",(bSpectator ? "1" : "0"),false);
}
2020-11-28 21:54:57 +00:00
2020-11-28 20:04:55 +00:00
Delegate OnSpectateChange(ExtPlayerController PC, bool bSpectator);
2017-10-20 02:00:49 +00:00
state RagdollMove extends PlayerWalking
{
Ignores NotifyPhysicsVolumeChange,ServerCamera,ResetCameraMode;
event BeginState(Name PreviousStateName)
{
FOVAngle = DesiredFOV;
2020-11-28 20:12:58 +00:00
if (WorldInfo.NetMode!=NM_Client)
2017-10-20 02:00:49 +00:00
SetCameraMode('ThirdPerson');
}
event EndState(Name NewState)
{
FOVAngle = DesiredFOV;
2020-11-28 20:12:58 +00:00
if (Pawn!=none && NewState!='Dead')
2017-10-20 02:00:49 +00:00
Global.SetCameraMode('FirstPerson');
}
2020-11-28 20:04:55 +00:00
function PlayerMove(float DeltaTime)
2017-10-20 02:00:49 +00:00
{
local rotator OldRotation;
2020-11-28 20:12:58 +00:00
if (Pawn == None)
2017-10-20 02:00:49 +00:00
GotoState('Dead');
else
{
// Update rotation.
OldRotation = Rotation;
2020-11-28 20:04:55 +00:00
UpdateRotation(DeltaTime);
2017-10-20 02:00:49 +00:00
bDoubleJump = false;
bPressedJump = false;
2020-11-28 20:12:58 +00:00
if (Role < ROLE_Authority) // then save this move and replicate it
2017-10-20 02:00:49 +00:00
ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, OldRotation - Rotation);
else ProcessMove(DeltaTime, vect(0,0,0), DCLICK_None, OldRotation - Rotation);
}
}
2020-11-28 20:04:55 +00:00
simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
2017-10-20 02:00:49 +00:00
{
local Actor TheViewTarget;
local vector HL,HN,EndOffset;
2020-11-28 20:12:58 +00:00
if (bEndGameCamFocus && CalcEndGameCam())
2017-10-20 02:00:49 +00:00
{
out_Location = CalcViewLocation;
out_Rotation = CalcViewRotation;
return;
}
2020-11-28 20:12:58 +00:00
if (Global.UsingFirstPersonCamera())
2017-10-20 02:00:49 +00:00
Global.GetPlayerViewPoint(out_Location,out_Rotation);
else
{
out_Rotation = Rotation;
TheViewTarget = GetViewTarget();
2020-11-28 20:12:58 +00:00
if (TheViewTarget==None)
2017-10-20 02:00:49 +00:00
TheViewTarget = Self;
out_Location = TheViewTarget.Location;
EndOffset = out_Location-vector(Rotation)*250.f;
2020-11-28 20:12:58 +00:00
if (TheViewTarget.Trace(HL,HN,EndOffset,out_Location,false,vect(16,16,16))!=None)
2017-10-20 02:00:49 +00:00
out_Location = HL;
else out_Location = EndOffset;
}
}
}
state PlayerWalking
{
ignores SeePlayer, HearNoise, Bump;
2020-11-28 20:04:55 +00:00
function PlayerMove(float DeltaTime)
2017-10-20 02:00:49 +00:00
{
local vector X,Y,Z, NewAccel;
local eDoubleClickDir DoubleClickMove;
local rotator OldRotation;
local bool bSaveJump;
2020-11-28 20:12:58 +00:00
if (Pawn == None)
2017-10-20 02:00:49 +00:00
{
GotoState('Dead');
}
else
{
GetAxes(Pawn.Rotation,X,Y,Z);
2020-11-28 20:12:58 +00:00
if (VSZombie(Pawn)!=None)
2017-10-20 02:00:49 +00:00
VSZombie(Pawn).ModifyPlayerInput(Self,DeltaTime);
// Update acceleration.
NewAccel = PlayerInput.aForward*X + PlayerInput.aStrafe*Y;
NewAccel.Z = 0;
NewAccel = Pawn.AccelRate * Normal(NewAccel);
if (IsLocalPlayerController())
{
AdjustPlayerWalkingMoveAccel(NewAccel);
}
2020-11-28 20:04:55 +00:00
DoubleClickMove = PlayerInput.CheckForDoubleClickMove(DeltaTime/WorldInfo.TimeDilation);
2017-10-20 02:00:49 +00:00
// Update rotation.
OldRotation = Rotation;
2020-11-28 20:04:55 +00:00
UpdateRotation(DeltaTime);
2017-10-20 02:00:49 +00:00
bDoubleJump = false;
2020-11-28 20:12:58 +00:00
if (bPressedJump && Pawn.CannotJumpNow())
2017-10-20 02:00:49 +00:00
{
bSaveJump = true;
bPressedJump = false;
}
else
{
bSaveJump = false;
}
2020-11-28 20:12:58 +00:00
if (Role < ROLE_Authority) // then save this move and replicate it
2017-10-20 02:00:49 +00:00
{
ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
}
else
{
ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation);
}
bPressedJump = bSaveJump;
}
}
}
state Dead
{
event BeginState(Name PreviousStateName)
{
local KFPlayerInput KFPI;
2020-11-28 20:04:55 +00:00
SetTimer(5.f, false, nameof(StartSpectate));
if ((Pawn != None) && (Pawn.Controller == self))
2017-10-20 02:00:49 +00:00
Pawn.Controller = None;
Pawn = None;
FOVAngle = DesiredFOV;
Enemy = None;
bPressedJump = false;
FindGoodView();
CleanOutSavedMoves();
2020-11-28 20:12:58 +00:00
if (KFPawn(ViewTarget)!=none)
2017-10-20 02:00:49 +00:00
{
KFPawn(ViewTarget).SetMeshVisibility(true);
}
2020-11-28 19:53:57 +00:00
// Deactivate any post process effects when we die
2017-10-20 02:00:49 +00:00
ResetGameplayPostProcessFX();
2020-11-28 20:12:58 +00:00
if (CurrentPerk != none)
2017-10-20 02:00:49 +00:00
CurrentPerk.PlayerDied();
KFPI = KFPlayerInput(PlayerInput);
2020-11-28 20:12:58 +00:00
if (KFPI != none)
2017-10-20 02:00:49 +00:00
KFPI.HideVoiceComms();
2020-11-28 20:12:58 +00:00
if (MyGFxManager != none)
2017-10-20 02:00:49 +00:00
MyGFxManager.CloseMenus();
2020-11-28 20:12:58 +00:00
if (MyGFxHUD != none)
2017-10-20 02:00:49 +00:00
MyGFxHUD.ClearBuffIcons();
}
2020-11-28 20:04:55 +00:00
simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
2017-10-20 02:00:49 +00:00
{
local Actor TheViewTarget;
local vector HL,HN,EndOffset;
2020-11-28 20:12:58 +00:00
if (bEndGameCamFocus && CalcEndGameCam())
2017-10-20 02:00:49 +00:00
{
out_Location = CalcViewLocation;
out_Rotation = CalcViewRotation;
return;
}
out_Rotation = Rotation;
TheViewTarget = GetViewTarget();
2020-11-28 20:12:58 +00:00
if (TheViewTarget==None)
2017-10-20 02:00:49 +00:00
TheViewTarget = Self;
out_Location = TheViewTarget.Location;
EndOffset = out_Location-vector(Rotation)*400.f;
2020-11-28 20:12:58 +00:00
if (TheViewTarget.Trace(HL,HN,EndOffset,out_Location,false,vect(16,16,16))!=None)
2017-10-20 02:00:49 +00:00
out_Location = HL;
else out_Location = EndOffset;
}
}
2020-01-09 11:05:13 +00:00
exec function RequestSwitchTeam()
{
2020-11-28 19:53:57 +00:00
ConsoleCommand("disconnect");
2020-01-09 11:05:13 +00:00
}
exec function SwitchTeam()
{
2020-11-28 19:53:57 +00:00
ConsoleCommand("disconnect");
2020-01-09 11:05:13 +00:00
}
2017-10-20 02:00:49 +00:00
defaultproperties
{
InputClass=Class'ExtPlayerInput'
PurchaseHelperClass=class'ExtAutoPurchaseHelper'
bIgnoreEncroachers=true
SpectatorCameraSpeed=900
MidGameMenuClass=class'UI_MidGameMenu'
PerkList.Empty()
PerkList.Add((PerkClass=Class'ExtPerkManager'))
NVG_DOF_FocalDistance=3800.0
NVG_DOF_SharpRadius=2500.0
NVG_DOF_FocalRadius=3500.0
NVG_DOF_MaxNearBlurSize=0.25
}