> To the creator of Firetrucks: is it okay if I implement the code in these scripts into Firetrucks? Also would I have your permission to use Firetrucks in my mod(s)?
> RPG_Camera
Code: Select all
//=============================================================================
// RPG_Camera.
// Operates independently now
// There should only be one camera
//=============================================================================
class RPG_Camera expands Pawn;
//Some dummy Camera values that might be coded at a later date
enum ECamMode
{
CM_Fixed, //Fixed camera, useful for putting the camera at a certain spot
CM_TrackFixedXY, //Track player and rotate instead of moving
CM_Track, //Track player
CM_EventInterpolation, //Interpolate a path (one of these days...)
CM_Unused1,
CM_Unused2,
CM_Unused3,
CM_Unused4
};
//The visible properties are kept here to allow map save/loading as well as letting the mapper
//specify the initial camera mode without using a trigger
var() ECamMode CameraMode;
var PlayerPawn LocalPlayer;
var() float CamDistance;
var float TargetDistance;
//These already exist, putting these here for informative purposes
//var (Movement) rotator DesiredRotation;
//var (Movement) rotator RotationRate;
//Disabling some superclass functions
function ClientDying(name DamageType, vector HitLocation);
function ClientGameEnded();
function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType);
function Died(pawn Killer, name damageType, vector HitLocation);
event FellOutOfWorld();
//The () makes it appear as a selectable InitialState
state() Camera
{
//This event is called by the player when viewing this actor in first person view
event Tick( float DeltaTime )
{
local vector NewLoc;
local int OldPitch;
if ( LocalPlayer == none )
return;
switch CameraMode
{
case CM_Fixed:
break;
case CM_TrackFixedXY:
OldPitch = DesiredRotation.Pitch; //Conserve DesiredRotation's pitch
DesiredRotation = rotator( LocalPlayer.Location - Location); //Aim at local player
DesiredRotation.Pitch = OldPitch; //Restore pitch
NewLoc = Location; //Conserve location, but alter Z if necessar... useful for spiral stairs!
NewLoc.Z = LocalPlayer.Location.Z - vector(DesiredRotation).Z * VSize(Location - LocalPlayer.Location);
SetLocation( NewLoc );
break;
case CM_Track:
if ( TargetDistance < CamDistance ) //Interpolate camera distance in a very arbitrary way
CamDistance = fMax( CamDistance - LocalPlayer.GroundSpeed * 0.5 * DeltaTime, TargetDistance);
else if ( TargetDistance > CamDistance )
CamDistance = fMin( CamDistance + LocalPlayer.GroundSpeed * 0.5 * DeltaTime, TargetDistance);
NewLoc = LocalPlayer.Location - vector(DesiredRotation) * CamDistance;
SetLocation( NewLoc);
break;
default:
break;
}
}
Begin:
//Loop if no player
if ( LocalPlayer == none && !FindLocalPlayer() )
{
Sleep(0.0);
Goto('Begin');
}
SetPhysics( PHYS_Flying);
CheckViewTarget:
LocalPlayer.ViewTarget = self;
LocalPlayer.bBehindView = false;
}
//Unrealscript functions always have a return value, said value is zero'd before function call.
//Meaning, if we return nothing, the function still return False
function bool FindLocalPlayer()
{
local PlayerPawn P;
ForEach AllActors (class'PlayerPawn', P)
if ( ViewPort(P.Player) != none )
{
LocalPlayer = P;
return true;
}
}
event PostBeginPlay()
{
Super.PostBeginPlay();
//The rotation the mapper uses will be the initial rotation
DesiredRotation = Rotation;
ViewRotation = Rotation;
TargetDistance = CamDistance;
}
> RPG_CameraSwitcher
Code: Select all
//=============================================================================
// RPG_CameraSwitcher.
//
// Extra notes:
// Cannot be destroyed
// Operates on both server and client instances
//=============================================================================
class RPG_CameraSwitcher expands Triggers;
var RPG_Camera ActiveCamera;
enum ECamMode
{
CM_Fixed,
CM_TrackFixedXY,
CM_Track,
CM_EventInterpolation,
CM_Unused1,
CM_Unused2,
CM_Unused3,
CM_Unused4
};
var() ECamMode NewCameraMode;
var(Events) bool bOnlyLocalTrigger; //Event is only triggered on the local machine
//var(Events) name Event; //Left here for informative purposes, works like a normal trigger
var() bool bTriggerOnceOnly;
var() bool bSmoothTransition;
var() float NewDistance;
var() float SmoothFactor; //To be described later
var() rotator NewOrientation;
var() vector FixedCamPos; //For fixed or X,Y track mode, if Zero, use camera's current
function Touch( Actor Other)
{
local Actor A;
//This is the local player
if ( PlayerPawn(Other) != none && ViewPort(PlayerPawn(Other).Player) != none )
{
//Trigger additional event if there's one
if ( !bOnlyLocalTrigger )
TriggerEvent( Event, self, Pawn(Other) );
if ( HasActiveCamera() )
{
if ( NewCameraMode <= CM_TrackFixedXY && FixedCamPos != vect(0,0,0) ) //Move the camera if Fixed or TrackXY
ActiveCamera.SetLocation( FixedCamPos);
ActiveCamera.CameraMode = ECamMode(NewCameraMode);
ActiveCamera.TargetDistance = NewDistance; //Linear distance interpolation
ActiveCamera.DesiredRotation = NewOrientation; //Linear rotation interpolation (layer 1) towards this orientation
if ( !bSmoothTransition )
{
ActiveCamera.SetRotation( ActiveCamera.DesiredRotation);
ActiveCamera.ViewRotation = ActiveCamera.DesiredRotation;
ActiveCamera.CamDistance = NewDistance;
}
if ( bOnlyLocalTrigger )
TriggerEvent( Event, self, Pawn(Other) );
if ( bTriggerOnceOnly )
SetCollision( false);
ActiveCamera.Tick( 0.0); //Force immediate camera update
}
}
}
//Sanity check and camera finder
function bool HasActiveCamera()
{
if ( ActiveCamera != none )
return true;
//No camera, find it
ForEach AllActors (class'RPG_Camera', ActiveCamera)
return true;
}
SPECIAL THANKS TO UT99.ORG USER HIGOR FOR BASICALLY WRITING THESE TWO SCRIPTS PLUS TWO OTHERS FOR ME TO STUDY.
RPG_Camera is an offset actor of any playerpawn (only appearing for individual local machines so each player pawn can have their own camera), it being where the player sees from. RPG_CameraSwitcher is intended to send signals to RPG_Camera, depending on whether or not the player is touching it (it is now a trigger. RPG_CameraHook actors change the state of RPG_Camera to make it either stay at a location and track the player, follow the player, or being fixed in one area). Do not intersect the RPG_CameraSwitcher collision radii as I don't think that they will function properly.