Actor >> Keypoint >> JBCamera
class JBCamera extends Keypoint
placeable;
#exec texture import file=Textures\JBCamera.pcx mips=off masked=on
replication
{
reliable if (Role == ROLE_Authority)
Caption, Overlay, Switching, bWidescreen, FieldOfView, MotionBlur;
reliable if (Role == ROLE_Authority)
bHasCamManager;
}
enum EOverlayStyle
{
OverlayStyle_ScaleDistort,
OverlayStyle_ScaleProportional,
OverlayStyle_Tile,
};
struct TInfoCaption
{
var() bool bBlinking;
var() Color Color;
var() string Font;
var() localized string Text;
var() float Position;
var Font FontObject;
};
struct TInfoOverlay
{
var() Material Material;
var() Color Color;
var() EOverlayStyle Style;
var Actor Actor;
};
struct TInfoSwitching
{
var() bool bAllowAuto;
var() bool bAllowManual;
var() bool bAllowTriggered;
var() bool bAllowTimed;
var() int CamOrder;
var() float Time;
var() editconst string Tag;
};
struct TInfoViewer
{
var PlayerController Controller;
var bool bManual;
var bool bBehindViewPrev;
var float FieldOfViewPrev;
var Actor ViewTargetPrev;
var float TimeToSwitch;
};
var(Events) name TagSwitch;
var() editinline JBCamController CamController;
var() TInfoCaption Caption;
var() TInfoOverlay Overlay;
var() TInfoSwitching Switching;
var() bool bWidescreen;
var() float FieldOfView;
var() byte MotionBlur;
var Class<JBCamController> ClassCamController;
var private JBCamManager CamManager;
var private bool bHasCamManager;
var private float TimeUpdateMovement;
var private bool bIsActiveLocal;
var private array<TInfoViewer> ListInfoViewer;
var private MotionBlur CameraEffectMotionBlur;
simulated event PostBeginPlay()
{
if (CamController == None)
CamController = new ClassCamController;
CamController.Camera = Self;
CamController.Init();
InitCameraArray();
}
function InitCameraArray()
{
local JBProbeEvent ProbeEventSwitch;
CamManager = Class'JBCamManager'.Static.SpawnFor(Self);
if (CamManager == None)
return;
if (TagSwitch != '' &&
TagSwitch != 'None') {
ProbeEventSwitch = Spawn(Class'JBProbeEvent', Self, TagSwitch);
ProbeEventSwitch.OnTrigger = TriggerSwitch;
}
bHasCamManager = True;
}
simulated event SetInitialState()
{
Super.SetInitialState();
if (Role == ROLE_Authority)
Disable('Tick');
}
event Trigger(Actor ActorOther, Pawn PawnInstigator)
{
if (PawnInstigator.Controller != None)
TriggerForController(ActorOther, PawnInstigator.Controller);
}
function TriggerForController(Actor ActorOther, Controller ControllerInstigator)
{
local JBCamera CameraActivate;
local JBTagPlayer TagPlayerInstigator;
if (Trigger(ActorOther) != None) {
if (!Level.Game.IsInState('MatchInProgress'))
return;
TagPlayerInstigator = Class'JBTagPlayer'.Static.FindFor(ControllerInstigator.PlayerReplicationInfo);
if (TagPlayerInstigator == None ||
(TagPlayerInstigator.IsInJail() && Class'JBBotSquadJail'.Static.IsPlayerFighting(ControllerInstigator)))
return;
}
if (CamManager == None) {
CameraActivate = Self;
}
else if (CamManager.FindCameraFirst() == Self) {
if (Switching.bAllowAuto)
CameraActivate = CamManager.FindCameraBest();
if (CameraActivate == None)
CameraActivate = Self;
}
if (CameraActivate != None)
CameraActivate.ActivateFor(ControllerInstigator);
}
event UnTrigger(Actor ActorOther, Pawn PawnInstigator)
{
DeactivateFor(PawnInstigator.Controller);
}
function TriggerSwitch(Actor ActorOther, Pawn PawnInstigator)
{
local JBCamera thisCamera;
foreach DynamicActors(Class'JBCamera', thisCamera, Tag)
if (thisCamera != Self &&
thisCamera.Switching.bAllowTriggered)
thisCamera.SwitchTo(Self);
}
function SwitchTo(JBCamera Camera, optional bool bOverrideManual)
{
local int iInfoViewer;
for (iInfoViewer = ListInfoViewer.Length - 1; iInfoViewer >= 0; iInfoViewer--)
if (bOverrideManual || !ListInfoViewer[iInfoViewer].bManual)
Camera.ActivateFor(ListInfoViewer[iInfoViewer].Controller);
}
function SwitchToPrev(Controller Controller, optional bool bManual)
{
local JBCamera CameraPrev;
if (CamManager == None)
return;
CameraPrev = CamManager.FindCameraPrev(Self);
CameraPrev.ActivateFor(Controller, bManual);
}
function SwitchToNext(Controller Controller, optional bool bManual)
{
local JBCamera CameraNext;
if (CamManager == None)
return;
CameraNext = CamManager.FindCameraNext(Self);
CameraNext.ActivateFor(Controller, bManual);
}
function AutoSwitchTimed(float TimeDelta)
{
local int iInfoViewer;
if (!Switching.bAllowTimed)
return;
for (iInfoViewer = ListInfoViewer.Length - 1; iInfoViewer >= 0; iInfoViewer--) {
ListInfoViewer[iInfoViewer].TimeToSwitch -= TimeDelta;
if (ListInfoViewer[iInfoViewer].TimeToSwitch <= 0.0 &&
!ListInfoViewer[iInfoViewer].bManual)
SwitchToNext(ListInfoViewer[iInfoViewer].Controller);
}
}
function AutoSwitchBest()
{
local JBCamera CameraBest;
if (!Switching.bAllowAuto || ListInfoViewer.Length == 0)
return;
CameraBest = CamManager.FindCameraBest();
if (CameraBest != None &&
CameraBest != Self)
SwitchTo(CameraBest);
}
function float RateCurrentView()
{
if (CamController == None)
return 0.0;
return CamController.RateCurrentView();
}
function bool HasViewers()
{
return ListInfoViewer.Length > 0;
}
function bool IsViewer(Controller Controller)
{
local int iInfoViewer;
if (PlayerController(Controller) == None)
return False;
for (iInfoViewer = 0; iInfoViewer < ListInfoViewer.Length; iInfoViewer++)
if (ListInfoViewer[iInfoViewer].Controller == Controller)
return True;
return False;
}
function bool IsViewerAllowed(Controller Controller)
{
local JBTagPlayer TagPlayer;
if (PlayerController(Controller) == None)
return False;
TagPlayer = class'JBTagPlayer'.static.FindFor(Controller.PlayerReplicationInfo);
if (TagPlayer != None &&
TagPlayer.GetJail() != None &&
TagPlayer.GetJail().IsReleaseActive(Controller.PlayerReplicationInfo.Team))
return False;
return True;
}
function ActivateFor(Controller Controller, optional bool bManual)
{
local int iInfoViewer;
local Actor ViewTargetPrev;
local PlayerController ControllerPlayer;
if (!IsViewerAllowed(Controller) || IsViewer(Controller))
return;
ControllerPlayer = PlayerController(Controller);
if (JBCamera(ControllerPlayer.ViewTarget) != None)
JBCamera(ControllerPlayer.ViewTarget).DeactivateFor(Controller);
if (!IsViewer(Controller)) {
ViewTargetPrev = ControllerPlayer.ViewTarget;
if ( ViewTargetPrev != Controller.Pawn &&
Pawn(ViewTargetPrev) != None &&
Pawn(ViewTargetPrev).Controller != None)
ViewTargetPrev = Pawn(ViewTargetPrev).Controller;
iInfoViewer = ListInfoViewer.Length;
ListInfoViewer.Insert(iInfoViewer, 1);
ListInfoViewer[iInfoViewer].Controller = ControllerPlayer;
ListInfoViewer[iInfoViewer].bManual = bManual;
ListInfoViewer[iInfoViewer].bBehindViewPrev = ControllerPlayer.bBehindView;
ListInfoViewer[iInfoViewer].FieldOfViewPrev = ControllerPlayer.FOVAngle;
ListInfoViewer[iInfoViewer].ViewTargetPrev = ViewTargetPrev;
ListInfoViewer[iInfoViewer].TimeToSwitch = Switching.Time;
if (CamManager != None && Switching.bAllowManual)
CamManager.AddInventoryCamera(Controller, Self);
}
if (ControllerPlayer.ViewTarget != Self) {
ControllerPlayer. SetViewTarget(Self);
ControllerPlayer.ClientSetViewTarget(Self);
}
if (ControllerPlayer == Level.GetLocalPlayerController() && !bIsActiveLocal)
ActivateForLocal();
Enable('Tick');
UpdateMovement();
}
function DeactivateFor(Controller Controller)
{
local int iInfoViewer;
local Actor ViewTargetPrev;
local PlayerController ControllerPlayer;
ControllerPlayer = PlayerController(Controller);
if (ControllerPlayer == None)
return;
for (iInfoViewer = 0; iInfoViewer < ListInfoViewer.Length; iInfoViewer++)
if (ListInfoViewer[iInfoViewer].Controller == Controller)
break;
if (iInfoViewer >= ListInfoViewer.Length)
return;
if (ControllerPlayer.ViewTarget == Self) {
ViewTargetPrev = Controller;
if (JBCamera(ListInfoViewer[iInfoViewer].ViewTargetPrev) == None &&
ListInfoViewer[iInfoViewer].ViewTargetPrev != None)
ViewTargetPrev = ListInfoViewer[iInfoViewer].ViewTargetPrev;
ControllerPlayer.SetViewTarget(ViewTargetPrev);
ControllerPlayer.SetFOVAngle (ListInfoViewer[iInfoViewer].FieldOfViewPrev);
ControllerPlayer.bBehindView = ListInfoViewer[iInfoViewer].bBehindViewPrev;
ControllerPlayer.ClientSetViewTarget(ControllerPlayer.ViewTarget);
ControllerPlayer.ClientSetBehindView(ControllerPlayer.bBehindView);
}
if (CamManager != None)
CamManager.RemoveInventoryCamera(Controller);
ListInfoViewer.Remove(iInfoViewer, 1);
if (ListInfoViewer.Length == 0) {
if (bIsActiveLocal)
DeactivateForLocal();
Disable('Tick');
}
}
function DeactivateForAll()
{
while (ListInfoViewer.Length > 0)
DeactivateFor(ListInfoViewer[0].Controller);
}
protected simulated function ActivateForLocal()
{
local JBCamera thisCamera;
local PlayerController ControllerPlayer;
foreach DynamicActors(Class'JBCamera', thisCamera)
if (thisCamera.bIsActiveLocal)
thisCamera.DeactivateForLocal();
ControllerPlayer = Level.GetLocalPlayerController();
if (JBInterfaceHud(ControllerPlayer.myHUD) != None)
JBInterfaceHud(ControllerPlayer.myHUD).bWidescreen = bWidescreen;
if (MotionBlur > 0) {
CameraEffectMotionBlur = MotionBlur(FindCameraEffect(Class'MotionBlur'));
CameraEffectMotionBlur.BlurAlpha = 255 - MotionBlur;
ControllerPlayer.AddCameraEffect(CameraEffectMotionBlur);
}
if (bHasCamManager && Switching.bAllowManual)
ControllerPlayer.ReceiveLocalizedMessage(Class'JBLocalMessageScreen', 510);
bIsActiveLocal = True;
UpdateLocal();
}
protected simulated function DeactivateForLocal()
{
local PlayerController ControllerPlayer;
local JBInterfaceHud JBInterfaceHud;
ControllerPlayer = Level.GetLocalPlayerController();
JBInterfaceHud = JBInterfaceHud(ControllerPlayer.myHUD);
if (JBInterfaceHud != None)
JBInterfaceHud.bWidescreen = False;
if (CameraEffectMotionBlur != None) {
RemoveCameraEffect(CameraEffectMotionBlur);
CameraEffectMotionBlur = None;
}
if (JBInterfaceHud != None)
JBInterfaceHud.ClearMessageByClass(Class'JBLocalMessageScreen', 510);
bIsActiveLocal = False;
}
protected simulated function UpdateLocal()
{
local PlayerController ControllerPlayer;
ControllerPlayer = Level.GetLocalPlayerController();
ControllerPlayer.bBehindView = False;
ControllerPlayer.FOVAngle = FieldOfView;
}
simulated function UpdateMovement()
{
local float TimeDelta;
if (CamController == None || TimeUpdateMovement == Level.TimeSeconds)
return;
if (TimeUpdateMovement > 0.0)
TimeDelta = Level.TimeSeconds - TimeUpdateMovement;
TimeUpdateMovement = Level.TimeSeconds;
CamController.UpdateMovement(TimeDelta);
}
simulated event Tick(float TimeDelta)
{
local bool bIsActiveLocalNew;
local int iInfoViewer;
local PlayerController ControllerPlayer;
if (Role == ROLE_Authority)
for (iInfoViewer = ListInfoViewer.Length - 1; iInfoViewer >= 0; iInfoViewer--) {
ControllerPlayer = ListInfoViewer[iInfoViewer].Controller;
if (ControllerPlayer == None)
ListInfoViewer.Remove(iInfoViewer, 1);
else if (ControllerPlayer.ViewTarget != Self)
DeactivateFor(ControllerPlayer);
else
ControllerPlayer.bBehindView = False;
}
if (Level.NetMode != NM_DedicatedServer) {
bIsActiveLocalNew = (Level.GetLocalPlayerController().ViewTarget == Self);
if (bIsActiveLocalNew != bIsActiveLocal)
if (bIsActiveLocalNew)
ActivateForLocal();
else
DeactivateForLocal();
if (bIsActiveLocal)
UpdateLocal();
}
if (Role == ROLE_Authority || bIsActiveLocal)
UpdateMovement();
if (CamManager != None) {
AutoSwitchTimed(TimeDelta);
AutoSwitchBest();
}
}
simulated function RenderOverlayMaterial(Canvas Canvas)
{
local float RatioStretchTotal;
local vector RatioStretch;
local vector SizeOverlay;
if (Overlay.Material == None)
return;
if (Texture(Overlay.Material) != None)
Texture(Overlay.Material).LODSet = LODSET_Interface;
Canvas.DrawColor = Overlay.Color;
switch (Overlay.Style) {
case OverlayStyle_ScaleDistort:
Canvas.SetPos(0, 0);
Canvas.DrawTile(Overlay.Material, Canvas.ClipX, Canvas.ClipY, 0, 0,
Overlay.Material.MaterialUSize(),
Overlay.Material.MaterialVSize());
break;
case OverlayStyle_ScaleProportional:
SizeOverlay.X = Overlay.Material.MaterialUSize();
SizeOverlay.Y = Overlay.Material.MaterialVSize();
RatioStretch.X = Canvas.ClipX / SizeOverlay.X;
RatioStretch.Y = Canvas.ClipY / SizeOverlay.Y;
RatioStretchTotal = FMax(RatioStretch.X, RatioStretch.Y);
SizeOverlay *= RatioStretchTotal;
Canvas.SetPos((Canvas.ClipX - SizeOverlay.X) / 2.0,
(Canvas.ClipY - SizeOverlay.Y) / 2.0);
Canvas.DrawTileScaled(Overlay.Material, RatioStretchTotal, RatioStretchTotal);
break;
case OverlayStyle_Tile:
Canvas.SetPos(0, 0);
Canvas.DrawTile(Overlay.Material, Canvas.ClipX, Canvas.ClipY, 0, 0, Canvas.ClipX, Canvas.ClipY);
break;
}
}
simulated function RenderOverlayCaption(Canvas Canvas)
{
local vector SizeCaption;
local vector LocationCaption;
if (Caption.Text == "")
return;
if (Caption.FontObject == None) {
Caption.FontObject = Font(DynamicLoadObject(Caption.Font, Class'Font'));
if (Caption.FontObject == None)
Caption.FontObject = Font'DefaultFont';
}
Canvas.Font = Caption.FontObject;
Canvas.TextSize(Caption.Text, SizeCaption.X, SizeCaption.Y);
LocationCaption.X = (Canvas.ClipX - SizeCaption.X) / 2.0;
LocationCaption.Y = Canvas.ClipY * Caption.Position - SizeCaption.Y / 2.0;
Canvas.DrawColor = Caption.Color;
if (Caption.bBlinking)
Canvas.DrawColor.A -= Canvas.DrawColor.A * (Level.TimeSeconds % 0.7) / 1.4;
Canvas.SetPos(LocationCaption.X, LocationCaption.Y);
Canvas.DrawText(Caption.Text);
}
simulated function RenderOverlays(Canvas Canvas)
{
if (Overlay.Actor != None)
Overlay.Actor.RenderOverlays(Canvas);
RenderOverlayMaterial(Canvas);
RenderOverlayCaption(Canvas);
}
event Destroyed()
{
DeactivateForAll();
}
simulated function CameraEffect FindCameraEffect(Class<CameraEffect> ClassCameraEffect)
{
local int iCameraEffect;
local PlayerController PlayerControllerLocal;
PlayerControllerLocal = Level.GetLocalPlayerController();
if (PlayerControllerLocal == None)
return None;
for (iCameraEffect = 0; iCameraEffect < PlayerControllerLocal.CameraEffects.Length; iCameraEffect++)
if (PlayerControllerLocal.CameraEffects[iCameraEffect] != None &&
PlayerControllerLocal.CameraEffects[iCameraEffect].Class == ClassCameraEffect)
return PlayerControllerLocal.CameraEffects[iCameraEffect];
return CameraEffect(Level.ObjectPool.AllocateObject(ClassCameraEffect));
}
simulated function RemoveCameraEffect(CameraEffect CameraEffect)
{
local int iCameraEffect;
local PlayerController PlayerControllerLocal;
PlayerControllerLocal = Level.GetLocalPlayerController();
if (PlayerControllerLocal == None)
return;
PlayerControllerLocal.RemoveCameraEffect(CameraEffect);
for (iCameraEffect = 0; iCameraEffect < PlayerControllerLocal.CameraEffects.Length; iCameraEffect++)
if (PlayerControllerLocal.CameraEffects[iCameraEffect] == CameraEffect)
return;
Level.ObjectPool.FreeObject(CameraEffect);
}
simulated function UpdatePrecacheMaterials()
{
Super.UpdatePrecacheMaterials();
Level.AddPrecacheMaterial(Overlay.Material);
}
defaultproperties
{
ClassCamController = Class'JBCamController';
bWidescreen = False;
MotionBlur = 0;
FieldOfView = 85.0;
Caption = (bBlinking=True,Color=(R=255,G=255,B=255,A=255),Font="UT2003Fonts.FontEurostile12",Position=0.8);
Overlay = (Color=(R=255,G=255,B=255,A=255),Style=OverlayStyle_ScaleProportional);
Switching = (bAllowManual=True,bAllowTriggered=True,Time=5.0,Tag="(set TagSwitch under Events instead)");
Texture = Texture'JBCamera';
RemoteRole = ROLE_SimulatedProxy;
bNoDelete = True;
bStatic = False;
bDirectional = True;
Velocity = (X=1.0);
}