ascottk on 30/9/2009 at 21:11
I went UT2003's native functions and events and found a whole lot that works with T3:
New actor functs & events:
Code:
/**************************************
Added variables and functions based on UT2003 - ascottk
**************************************/
native(233) final function Error( coerce string S );
native(532) final function bool PlayerCanSeeMe();
native(256) final latent function Sleep( float Seconds );
// Collision.
native(262) final function SetCollision( optional bool NewColActors, optional bool NewBlockActors, optional bool NewBlockPlayers );
native(283) final function bool SetCollisionSize( float NewRadius, float NewHeight );
// Movement.
native(266) final function bool Move( vector Delta );
native(267) final function bool SetLocation( vector NewLocation );
native(299) final function bool SetRotation( rotator NewRotation );
native(3969) final function bool MoveSmooth( vector Delta );
native(3971) final function AutonomousPhysics(float DeltaSeconds);
// Relations.
native(298) final function SetBase( actor NewBase, optional vector NewFloor );
native(272) final function SetOwner( actor NewOwner );
//=========================================================================
// Engine notification functions.
//
// Major notifications.
//
event Destroyed();
event GainedChild( Actor Other );
event LostChild( Actor Other );
event Tick( float DeltaTime );
event PostNetReceive(); // jij
//
// Triggers.
//
event Trigger( Actor Other, Pawn EventInstigator );
event UnTrigger( Actor Other, Pawn EventInstigator );
event BeginEvent();
event EndEvent();
//
// Physics & world interaction.
//
event Timer();
event HitWall( vector HitNormal, actor HitWall );
event Falling();
event Landed( vector HitNormal );
event ZoneChange( ZoneInfo NewZone );
event PhysicsVolumeChange( PhysicsVolume NewVolume );
event Touch( Actor Other );
event PostTouch( Actor Other ); // called for PendingTouch actor after physics completes
event UnTouch( Actor Other );
event Bump( Actor Other );
event BaseChange();
event Attach( Actor Other );
event Detach( Actor Other );
event Actor SpecialHandling(Pawn Other);
event bool EncroachingOn( actor Other );
event EncroachedBy( actor Other );
event FinishedInterpolation()
{
bInterpolating = false;
}
event EndedRotation(); // called when rotation completes
event UsedBy( Pawn user ); // called if this Actor was touching a Pawn who pressed Use
//
// Damage and kills.
//
event KilledBy( pawn EventInstigator );
//event TakeDamage( int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType);
event TakeDamage( int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum);
//
// Spawn an actor. Returns an actor of the specified class, not
// of class Actor (this is hardcoded in the compiler). Returns None
// if the actor could not be spawned (either the actor wouldn't fit in
// the specified location, or the actor list is full).
// Defaults to spawning at the spawner's location.
//
native(278) final function actor Spawn
(
class<actor> SpawnClass,
optional actor SpawnOwner,
optional name SpawnTag,
optional vector SpawnLocation,
optional rotator SpawnRotation
);
//=============================================================================
// Timing.
// Causes Timer() events every NewTimerRate seconds.
native(280) final function SetTimer( float NewTimerRate, bool bLoop );
//
// Destroy this actor. Returns true if destroyed, false if indestructable.
// Destruction is latent. It occurs at the end of the tick.
//
native(279) final function bool Destroy();
//=============================================================================
// Regular engine functions.
// Level state.
event BeginPlay();
//=============================================================================
// Iterator functions.
// Iterator functions for dealing with sets of actors.
/* AllActors() - avoid using AllActors() too often as it iterates through the whole actor list and is therefore slow
*/
native(304) final iterator function AllActors ( class<actor> BaseClass, out actor Actor, optional name MatchTag );
/* DynamicActors() only iterates through the non-static actors on the list (still relatively slow, bu
much better than AllActors). This should be used in most cases and replaces AllActors in most of
Epic's game code.
*/
native(313) final iterator function DynamicActors ( class<actor> BaseClass, out actor Actor, optional name MatchTag );
/* ChildActors() returns all actors owned by this actor. Slow like AllActors()
*/
native(305) final iterator function ChildActors ( class<actor> BaseClass, out actor Actor );
/* BasedActors() returns all actors based on the current actor (slow, like AllActors)
*/
native(306) final iterator function BasedActors ( class<actor> BaseClass, out actor Actor );
/* TouchingActors() returns all actors touching the current actor (fast)
*/
native(307) final iterator function TouchingActors( class<actor> BaseClass, out actor Actor );
/* TraceActors() return all actors along a traced line. Reasonably fast (like any trace)
*/
native(309) final iterator function TraceActors ( class<actor> BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent );
/* RadiusActors() returns all actors within a give radius. Slow like AllActors(). Use CollidingActors() or VisibleCollidingActors() instead if desired actor types are visible
(not bHidden) and in the collision hash (bCollideActors is true)
*/
native(310) final iterator function RadiusActors ( class<actor> BaseClass, out actor Actor, float Radius, optional vector Loc );
/* VisibleActors() returns all visible actors within a radius. Slow like AllActors(). Use VisibleCollidingActors() instead if desired actor types are
in the collision hash (bCollideActors is true)
*/
native(311) final iterator function VisibleActors ( class<actor> BaseClass, out actor Actor, optional float Radius, optional vector Loc );
/* VisibleCollidingActors() returns visible (not bHidden) colliding (bCollideActors==true) actors within a certain radius.
Much faster than AllActors() since it uses the collision hash
*/
native(312) final iterator function VisibleCollidingActors ( class<actor> BaseClass, out actor Actor, float Radius, optional vector Loc, optional bool bIgnoreHidden );
/* CollidingActors() returns colliding (bCollideActors==true) actors within a certain radius.
Much faster than AllActors() for reasonably small radii since it uses the collision hash
*/
native(321) final iterator function CollidingActors ( class<actor> BaseClass, out actor Actor, float Radius, optional vector Loc );
//=============================================================================
// Color functions
native(549) static final operator(20) color - ( color A, color B );
native(550) static final operator(16) color * ( float A, color B );
native(551) static final operator(20) color + ( color A, color B );
native(552) static final operator(16) color * ( color A, float B );
//
// Called immediately before gameplay begins.
//
event PreBeginPlay()
{
// Handle autodestruction if desired.
if( !bGameRelevant )
Destroy();
}
// Called immediately after gameplay begins.
//
event PostBeginPlay();
// Called after PostBeginPlay.
//
simulated event SetInitialState()
{
bScriptInitialized = true;
if( InitialState!='' )
GotoState( InitialState );
else
GotoState( 'Auto' );
}
/*
Trigger an event
*/
event TriggerEvent( Name EventName, Actor Other, Pawn EventInstigator )
{
local Actor A;
if ( EventName == '' )
return;
ForEach DynamicActors( class 'Actor', A, EventName )
A.Trigger(Other, EventInstigator);
}
/*
Untrigger an event
*/
function UntriggerEvent( Name EventName, Actor Other, Pawn EventInstigator )
{
local Actor A;
if ( EventName == '' )
return;
ForEach DynamicActors( class 'Actor', A, EventName )
A.Untrigger(Other, EventInstigator);
}
function bool IsInVolume(Volume aVolume)
{
local Volume V;
ForEach TouchingActors(class'Volume',V)
if ( V == aVolume )
return true;
return false;
}
/*function bool IsInPain()
{
local PhysicsVolume V;
ForEach TouchingActors(class'PhysicsVolume',V)
if ( V.bPainCausing && (V.DamagePerSec > 0) )
return true;
return false;
}*/
/*function PlayTeleportEffect(bool bOut, bool bSound);
function bool CanSplash()
{
return false;
}*/
function vector GetCollisionExtent()
{
local vector Extent;
Extent = CollisionRadius * vect(1,1,0);
Extent.Z = CollisionHeight;
return Extent;
}
simulated function bool EffectIsRelevant(vector SpawnLocation)
{
local PlayerController P;
local bool bResult;
if ( (Instigator != None) && Instigator.IsHumanControlled() )
bResult = true;
else if ( SpawnLocation == Location )
bResult = ( Level.TimeSeconds - LastRenderTime < 3 );
else if ( (Instigator != None) && (Level.TimeSeconds - Instigator.LastRenderTime < 3) )
bResult = true;
else
{
P = Level.GetLocalPlayerController();
if ( P == None )
bResult = false;
else
bResult = ( (Vector(P.Rotation) Dot (SpawnLocation - P.ViewTarget.Location)) > 0.0 );
}
return bResult;
}
And using these functions are:
Volume:
Code:
//=============================================================================
// Volume: a bounding volume
// touch() and untouch() notifications to the volume as actors enter or leave it
// enteredvolume() and leftvolume() notifications when center of actor enters the volume
// pawns with bIsPlayer==true cause playerenteredvolume notifications instead of actorenteredvolume()
// This is a built-in Unreal class and it shouldn't be modified.
//=============================================================================
class Volume extends Brush
native;
var() localized string LocationName;
var inherited(173) vector RenderColor;
var inherited(174) string RenderName;
enum EVolumeType
{
VOLUME_BASIC,
VOLUME_PHYSICS,
VOLUME_LADDER,
VOLUME_AI,
VOLUME_TAG,
VOLUME_AMBIENT_LIGHT,
VOLUME_T3WATER,
VOLUME_SHALLOW_WATER,
VOLUME_DEATH_WATER
};
struct VolumeStimPing
{
var() StimulusAmount Amount "The stimulus and amount we are applying per ping";
};
struct VolumePinger
{
var() bool Inactive "Is this pinger inactive";
var() array<VolumeStimPing> Stim "The stimulus info";
var() float Frequency "How often to apply this stim in seconds. You should not go below 0.25 or so.";
};
var inherited(175) EVolumeType VolumeType;
var(Stimulus) inherited(907) VolumePinger VolumePingInfo "Every second a volume pulse of the stim specefied is emitted";
struct TeleportStruct
{
var() string TeleportName "This is the teleporter's name. It will be used to link other teleporters to it.";
var() string TeleportDestination "This the TeleportName of the destination teleporter.";
var() string TeleportMap "This the Map name to teleport to. Leave blank if destination teleporter is in the current map.";
var() bool PromptForTeleport "When TRUE, a dialog box will appear prompting the player if they want to enter the teleport.";
var() bool UsePlayerOrientation "When TRUE, the player will keep his orientation during the teleport.";
var() string TeleportDisplayName "This is a localized string table entry that lists the name of the destination the *player* will see when asked if they want to teleport.";
var() string FirstVisitGlobalVar "The global variable name; if this global var is false, it means it's the first time we've visited the dest map and will play a voice-over.";
};
var(Teleport) inherited(1245) TeleportStruct TeleportInfo "Information used if you want to make this volume a teleporter.";
var() inherited(1125) bool Enabled "Indicates whether this volume is currently enabled (this applies to AI-related volumes, such as context and tagged volumes AND water volumes).";
var(AI) inherited(1790) bool bEditorOnlyVolume "If true, this volume will not be monitored for game events like other volumes -- primarily intended for the NavMeshSubtractionVolume.";
var() Box CachedWorldBBox;
var Actor AssociatedActor; // this actor gets touch() and untouch notifications as the volume is entered or left
var() name AssociatedActorTag; // Used by L.D. to specify tag of associated actor
var() int LocationPriority;
//var() edfindable decorationlist DecoList; // A list of decorations to be spawned inside the volume when the level starts
function bool Encompasses(Actor Other); // returns true if center of actor is within volume
//native function bool Encompasses(Actor Other); // returns true if center of actor is within volume
function PostBeginPlay()
{
Super.PostBeginPlay();
if ( AssociatedActorTag != '' )
ForEach AllActors(class'Actor',AssociatedActor, AssociatedActorTag)
break;
if ( AssociatedActor != None )
{
GotoState('AssociatedTouch');
InitialState = GetStateName();
}
}
State AssociatedTouch
{
event touch( Actor Other )
{
AssociatedActor.touch(Other);
}
event untouch( Actor Other )
{
AssociatedActor.untouch(Other);
}
function BeginState()
{
local Actor A;
ForEach TouchingActors(class'Actor', A)
Touch(A);
}
}
classproperties
{
ClassPlaceableStatus=FALSE
}
defaultproperties
{
LocationName="unspecified"
RenderColor=(X=0.200000,Y=0.200000,Z=0.200000)
RenderName="VOLUME"
VolumeType=VOLUME_BASIC
Enabled=True
bEditorOnlyVolume=False
CollisionFlags=(bCollideActors=True)
bNotTickable=False
}
And PhysicsVolume:
Code:
//=============================================================================
// PhysicsVolume: a bounding volume which affects actor physics
// This is a built-in Unreal class and it shouldn't be modified.
//=============================================================================
class PhysicsVolume extends Volume
native
nativereplication;
var() vector ViewFlash, ViewFog;
var() vector Gravity;
// Distance Fog
var(VolumeFog) bool bDistanceFog; // There is distance fog in this physicsvolume.
var(VolumeFog) color DistanceFogColor;
var(VolumeFog) float DistanceFogStart;
var(VolumeFog) float DistanceFogEnd;
var() bool bPainCausing; // Zone causes pain.
var() vector ZoneVelocity;
var() float GroundFriction;
var() float TerminalVelocity;
var() float DamagePerSec;
//var() class<DamageType> DamageType;
var() int Priority; // determines which PhysicsVolume takes precedence if they overlap
//var() sound EntrySound; //only if waterzone
//var() sound ExitSound; // only if waterzone
var() class<actor> EntryActor; // e.g. a splash (only if water zone)
var() class<actor> ExitActor; // e.g. a splash (only if water zone)
var() float FluidFriction;
var() bool bDestructive; // Destroys most actors which enter it.
var() bool bNoInventory;
var() bool bMoveProjectiles;// this velocity zone should impart velocity to projectiles and effects
var() bool bBounceVelocity; // this velocity zone should bounce actors that land in it
var() bool bNeutralZone; // Players can't take damage in this zone.
var() bool bWaterVolume;
var Info PainTimer;
// Karma . . . er . . . Havok
var(Physics) float LinearDrag; // Extra damping applied to Karma actors in this volume.
var(Physics) float AngularDrag;
var(Movement) float Buoyancy; // How buoyant Karma things are in this volume (if bWaterVolume true). Multiplied by Actors KarmaParams->KBuoyancy.
var PhysicsVolume NextPhysicsVolume;
simulated function PostBeginPlay()
{
// here for compatibility
Super.PostBeginPlay();
}
/* Called when an actor in this PhysicsVolume changes its physics mode
*/
event PhysicsChangedFor(Actor Other);
event ActorEnteredVolume(Actor Other);
event ActorLeavingVolume(Actor Other);
event PawnEnteredVolume(Pawn Other)
{
if ( Other.IsPlayerPawn() )
TriggerEvent(Event,self, Other);
}
event PawnLeavingVolume(Pawn Other)
{
if ( Other.IsPlayerPawn() )
UntriggerEvent(Event,self, Other);
}
/*
TimerPop
damage touched actors if pain causing.
since PhysicsVolume is static, this function is actually called by a volumetimer
*/
function TimerPop(VolumeTimer T)
{
local actor A;
local bool bFound;
/*if ( T == PainTimer )
{
if ( !bPainCausing )
{
PainTimer.Destroy();
return;
}
ForEach TouchingActors(class'Actor', A)
if ( A.bCanBeDamaged && !A.bStatic )
{
CausePainTo(A);
bFound = true;
}
if ( !bFound )
PainTimer.Destroy();
}*/
}
/*function Trigger( actor Other, pawn EventInstigator )
{
// turn zone damage on and off
if (DamagePerSec != 0)
{
bPainCausing = !bPainCausing;
if ( bPainCausing && (PainTimer == None) )
PainTimer = spawn(class'VolumeTimer', self);
}
}*/
event touch(Actor Other)
{
local Pawn P;
local bool bFoundPawn;
Super.Touch(Other);
if ( Other == None )
return;
if ( bNoInventory && (Other.Owner == None) )
{
Other.Lifetime = 1.5;
return;
}
/*if ( bMoveProjectiles && (ZoneVelocity != vect(0,0,0)) )
{
if ( Other.Physics == PHYS_Projectile )
Other.Velocity += ZoneVelocity;
else if ( (Other.Physics == PHYS_None) )
{
//Other.SetPhysics(PHYS_Projectile);
Other.Velocity += ZoneVelocity;
}
}*/
/*if ( bPainCausing )
{
if ( Other.bDestroyInPainVolume )
{
Other.Destroy();
return;
}
if ( Other.bCanBeDamaged && !Other.bStatic )
{
CausePainTo(Other);
if ( PainTimer == None )
PainTimer = Spawn(class'VolumeTimer', self);
else if ( Pawn(Other) != None )
{
ForEach TouchingActors(class'Pawn', P)
if ( (P != Other) && P.bCanBeDamaged )
{
bFoundPawn = true;
break;
}
if ( !bFoundPawn )
PainTimer.SetTimer(1.0,true);
}
}
}
if ( bWaterVolume && Other.CanSplash() )
PlayEntrySplash(Other);*/
}
/*function PlayEntrySplash(Actor Other)
{
local float SplashSize;
local actor splash;
splashSize = FClamp(0.00003 * Other.Mass * (250 - 0.5 * FMax(-600,Other.Velocity.Z)), 0.1, 1.0 );
if( EntrySound != None )
{
PlaySound(EntrySound, SLOT_Interact, splashSize);
if ( Other.Instigator != None )
MakeNoise(SplashSize);
}
if( EntryActor != None )
{
splash = Spawn(EntryActor);
if ( splash != None )
splash.SetDrawScale(splashSize);
}
}*/
/*event untouch(Actor Other)
{
if ( bWaterVolume && Other.CanSplash() )
PlayExitSplash(Other);
}*/
/*function PlayExitSplash(Actor Other)
{
local float SplashSize;
local actor splash;
splashSize = FClamp(0.003 * Other.Mass, 0.1, 1.0 );
if( ExitSound != None )
PlaySound(ExitSound, SLOT_Interact, splashSize);
if( ExitActor != None )
{
splash = Spawn(ExitActor);
if ( splash != None )
splash.SetDrawScale(splashSize);
}
}*/
/*function CausePainTo(Actor Other)
{
local float depth;
local Pawn P;
// FIXMEZONE figure out depth of actor, and base pain on that!!!
depth = 1;
P = Pawn(Other);
if ( DamagePerSec > 0 )
{
if ( Region.Zone.bSoftKillZ && (Other.Physics != PHYS_Walking) )
return;
Other.TakeDamage(int(DamagePerSec * depth), None, Location, vect(0,0,0), DamageType);
if ( (P != None) && (P.Controller != None) )
P.Controller.PawnIsInPain(self);
}
else
{
if ( (P != None) && (P.Health < P.Default.Health) )
P.Health = Min(P.Default.Health, P.Health - depth * DamagePerSec);
}
}*/
classproperties
{
ClassPlaceableStatus=FALSE
}
defaultproperties
{
RenderColor=(Z=1.000000)
RenderName="PHYSICS VOLUME"
VolumeType=VOLUME_PHYSICS
}
And Pawn (additions):
Code:
//***************************************
// Interface to Pawn's Controller
// return true if controlled by a Player (AI or human)
simulated function bool IsPlayerPawn()
{
return ( (Controller != None) && Controller.bIsPlayer );
}
// return true if was controlled by a Player (AI or human)
simulated function bool WasPlayerPawn()
{
return false;
}
// return true if controlled by a real live human
simulated function bool IsHumanControlled()
{
return ( PlayerController(Controller) != None );
}
// return true if controlled by local (not network) player
simulated function bool IsLocallyControlled()
{
if ( Level.NetMode == NM_Standalone )
return true;
if ( Controller == None )
return false;
if ( PlayerController(Controller) == None )
return true;
return ( Viewport(PlayerController(Controller).Player) != None );
}
Unfortunately the physics volume does do anything yet as you can see I commented out a bunch of code (mostly dealing with damage & I don't know how T3 handles damage or sound).
I tested the new engine package on a raw non-editor install & there didn't seem to be an side effects. But I found some native functions and events we could use :thumb: