home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Level Design
/
GLDesign.bin
/
Software
/
UnrealEngine2Runtime
/
UE2Runtime-22262001_Demo.exe
/
Gameplay
/
Classes
/
ScriptedController.uc
< prev
next >
Wrap
Text File
|
2003-12-11
|
10KB
|
438 lines
// ScriptedController
// AI controller which is controlling the pawn through a scripted sequence specified by
// an AIScript
class ScriptedController extends AIController;
var controller PendingController; // controller which will get this pawn after scripted sequence is complete
var int ActionNum;
var int AnimsRemaining;
var ScriptedSequence SequenceScript;
var LatentScriptedAction CurrentAction;
var Action_PLAYANIM CurrentAnimation;
var bool bBroken;
var bool bShootTarget;
var bool bShootSpray;
var bool bPendingShoot;
var bool bFakeShot; // FIXME - this is currently a hack
var bool bUseScriptFacing;
var bool bPendingDoubleJump;
var bool bFineWeaponControl;
var Actor ScriptedFocus;
var PlayerController MyPlayerController;
var int NumShots;
var name FiringMode;
var int IterationCounter;
var int IterationSectionStart;
function bool WeaponFireAgain(float RefireRate, bool bFinishedFire)
{
return false;
}
event NotifyJumpApex()
{
local actor HitActor;
local vector HitNormal,HitLocation, HalfHeight,Start;
// double jump
if ( bPendingDoubleJump )
{
Pawn.bWantsToCrouch = false;
Pawn.DoDoubleJump(false);
bPendingDoubleJump = false;
}
else if ( bJumpOverWall )
{
// double jump if haven't cleared obstacle
Pawn.Acceleration = Destination - Pawn.Location;
Pawn.Acceleration.Z = 0;
HalfHeight = Pawn.GetCollisionExtent();
HalfHeight.Z *= 0.5;
Start = Pawn.Location - Pawn.CollisionHeight * vect(0,0,0.5);
HitActor = Pawn.Trace(HitLocation, HitNormal, Start + 8 * Normal(Pawn.Acceleration), Start, true,HalfHeight);
if ( HitActor != None )
{
Pawn.bWantsToCrouch = false;
Pawn.DoDoubleJump(false);
}
}
}
function TakeControlOf(Pawn aPawn)
{
if ( Pawn != aPawn )
{
aPawn.PossessedBy(self);
Pawn = aPawn;
}
GotoState('Scripting');
}
function SetEnemyReaction(int AlertnessLevel);
function DestroyPawn()
{
if ( Pawn != None )
Pawn.Destroy();
Destroy();
}
function Pawn GetMyPlayer()
{
if ( (MyPlayerController == None) || (MyPlayerController.Pawn == None) )
ForEach DynamicActors(class'PlayerController',MyPlayerController)
if ( MyPlayerController.Pawn != None )
break;
if ( MyPlayerController == None )
return None;
return MyPlayerController.Pawn;
}
function Pawn GetInstigator()
{
if ( Pawn != None )
return Pawn;
return Instigator;
}
function Actor GetSoundSource()
{
if ( Pawn != None )
return Pawn;
return SequenceScript;
}
function bool CheckIfNearPlayer(float Distance)
{
local Pawn MyPlayer;
MyPlayer = GetMyPlayer();
return ( (MyPlayer != None) && (VSize(Pawn.Location - MyPlayer.Location) < Distance+CollisionRadius+MyPlayer.CollisionRadius ) && Pawn.PlayerCanSeeMe() );
}
function ClearScript()
{
ActionNum = 0;
CurrentAction = None;
CurrentAnimation = None;
ScriptedFocus = None;
Pawn.SetWalking(false);
Pawn.ShouldCrouch(false);
}
function SetNewScript(ScriptedSequence NewScript)
{
MyScript = NewScript;
SequenceScript = NewScript;
Focus = None;
ClearScript();
SetEnemyReaction(3);
SequenceScript.SetActions(self);
}
function ClearAnimation()
{
AnimsRemaining = 0;
bControlAnimations = false;
CurrentAnimation = None;
Pawn.PlayWaiting();
}
function int SetFireYaw(int FireYaw)
{
FireYaw = FireYaw & 65535;
if ( (Abs(FireYaw - (Rotation.Yaw & 65535)) > 8192)
&& (Abs(FireYaw - (Rotation.Yaw & 65535)) < 57343) )
{
if ( FireYaw ClockwiseFrom Rotation.Yaw )
FireYaw = Rotation.Yaw + 8192;
else
FireYaw = Rotation.Yaw - 8192;
}
return FireYaw;
}
function rotator AdjustAim(Ammunition FiredAmmunition, vector projStart, int AimError)
{
local rotator LookDir;
// make sure bot has a valid target
if ( Target == None )
Target = ScriptedFocus;
if ( Target == None )
{
Target = Enemy;
if ( Target == None )
{
bFire = 0;
bAltFire = 0;
return Pawn.Rotation;
}
}
LookDir = rotator(Target.Location - projStart);
LookDir.Yaw = SetFireYaw(LookDir.Yaw);
return LookDir;
}
function LeaveScripting();
state Scripting
{
function DisplayDebug(Canvas Canvas, out float YL, out float YPos)
{
Super.DisplayDebug(Canvas,YL,YPos);
Canvas.DrawText("AIScript "$SequenceScript$" ActionNum "$ActionNum, false);
YPos += YL;
Canvas.SetPos(4,YPos);
CurrentAction.DisplayDebug(Canvas,YL,YPos);
}
/* UnPossess()
scripted sequence is over - return control to PendingController
*/
function UnPossess()
{
Pawn.UnPossessed();
if ( (Pawn != None) && (PendingController != None) )
{
PendingController.bStasis = false;
PendingController.Possess(Pawn);
}
Pawn = None;
Destroy();
}
function LeaveScripting()
{
UnPossess();
}
function InitForNextAction()
{
SequenceScript.SetActions(self);
if ( CurrentAction == None )
{
LeaveScripting();
return;
}
MyScript = SequenceScript;
if ( CurrentAnimation == None )
ClearAnimation();
}
function Trigger( actor Other, pawn EventInstigator )
{
if ( CurrentAction.CompleteWhenTriggered() )
CompleteAction();
}
function Timer()
{
if ( CurrentAction.WaitForPlayer() && CheckIfNearPlayer(CurrentAction.GetDistance()) )
CompleteAction();
else if ( CurrentAction.CompleteWhenTimer() )
CompleteAction();
}
function AnimEnd(int Channel)
{
if ( CurrentAction.CompleteOnAnim(Channel) )
{
CompleteAction();
return;
}
if ( Channel == 0 )
{
if ( (CurrentAnimation == None) || !CurrentAnimation.PawnPlayBaseAnim(self,false) )
ClearAnimation();
}
else
{
// FIXME - support for CurrentAnimation play on other channels
Pawn.AnimEnd(Channel);
}
}
function CompleteAction()
{
ActionNum++;
GotoState('Scripting','Begin');
}
function SetMoveTarget()
{
local Actor NextMoveTarget;
Focus = ScriptedFocus;
NextMoveTarget = CurrentAction.GetMoveTargetFor(self);
if ( NextMoveTarget == None )
{
GotoState('Broken');
return;
}
if ( Focus == None )
Focus = NextMoveTarget;
MoveTarget = NextMoveTarget;
if ( !ActorReachable(MoveTarget) )
{
MoveTarget = FindPathToward(MoveTarget,false);
if ( Movetarget == None )
{
AbortScript();
return;
}
if ( Focus == NextMoveTarget )
Focus = MoveTarget;
}
}
function AbortScript()
{
LeaveScripting();
}
/* WeaponFireAgain()
Notification from weapon when it is ready to fire (either just finished firing,
or just finished coming up/reloading).
Returns true if weapon should fire.
If it returns false, can optionally set up a weapon change
*/
function bool WeaponFireAgain(float RefireRate, bool bFinishedFire)
{
if ( Pawn.bIgnorePlayFiring )
{
Pawn.bIgnorePlayFiring = false;
return false;
}
if ( NumShots < 0 )
{
bShootTarget = false;
bShootSpray = false;
StopFiring();
return false;
}
if ( bShootTarget && (ScriptedFocus != None) && !ScriptedFocus.bDeleteMe )
{
Target = ScriptedFocus;
if ( (!bShootSpray && ((Pawn.Weapon.RefireRate() < 0.99) && !Pawn.Weapon.CanAttack(Target)))
|| !Pawn.Weapon.BotFire(bFinishedFire,FiringMode) )
{
Enable('Tick'); //FIXME - use multiple timer for this instead
bPendingShoot = true;
return false;
}
if ( NumShots > 0 )
{
NumShots--;
if ( NumShots == 0 )
NumShots = -1;
}
return true;
}
StopFiring();
return false;
}
function Tick(float DeltaTime)
{
if ( bPendingShoot )
{
bPendingShoot = false;
MayShootTarget();
}
if ( !bPendingShoot
&& ((CurrentAction == None) || !CurrentAction.StillTicking(self,DeltaTime)) )
disable('Tick');
}
function MayShootAtEnemy();
function MayShootTarget()
{
WeaponFireAgain(0,false);
}
function EndState()
{
bUseScriptFacing = true;
bFakeShot = false;
}
Begin:
InitforNextAction();
if ( bBroken )
GotoState('Broken');
if ( CurrentAction.TickedAction() )
enable('Tick');
if ( !bFineWeaponControl )
{
if ( !bShootTarget )
{
bFire = 0;
bAltFire = 0;
}
else
{
Pawn.Weapon.RateSelf();
if ( bShootSpray )
MayShootTarget();
}
}
if ( CurrentAction.MoveToGoal() )
{
Pawn.SetMovementPhysics();
WaitForLanding();
KeepMoving:
SetMoveTarget();
MayShootTarget();
MoveToward(MoveTarget, Focus,,,Pawn.bIsWalking);
if ( (MoveTarget != CurrentAction.GetMoveTargetFor(self))
|| !Pawn.ReachedDestination(CurrentAction.GetMoveTargetFor(self)) )
Goto('KeepMoving');
CompleteAction();
}
else if ( CurrentAction.TurnToGoal() )
{
Pawn.SetMovementPhysics();
Focus = CurrentAction.GetMoveTargetFor(self);
if ( Focus == None )
FocalPoint = Pawn.Location + 1000 * vector(SequenceScript.Rotation);
FinishRotation();
CompleteAction();
}
else
{
//Pawn.SetPhysics(PHYS_RootMotion);
Pawn.Acceleration = vect(0,0,0);
Focus = ScriptedFocus;
if ( !bUseScriptFacing )
FocalPoint = Pawn.Location + 1000 * vector(Pawn.Rotation);
else if ( Focus == None )
{
MayShootAtEnemy();
FocalPoint = Pawn.Location + 1000 * vector(SequenceScript.Rotation);
}
FinishRotation();
MayShootTarget();
}
}
// Broken scripted sequence - for debugging
State Broken
{
Begin:
warn(Pawn$" Scripted Sequence BROKEN "$SequenceScript$" ACTION "$CurrentAction);
Pawn.bPhysicsAnimUpdate = false;
Pawn.StopAnimating();
if ( GetMyPlayer() != None )
PlayerController(GetMyPlayer().Controller).SetViewTarget(Pawn);
}
defaultproperties
{
bUseScriptFacing=true
IterationSectionStart=-1
}