kActor
kActor is an internal class that acts as an intermediary between scripts and an actor's native object. If an actor has a script object assigned, it will receive a handle to its associated kActor in its constructor.
Core
void Remove()
remove the actor from the game
bool IsStale()
returns true if the actor has been flagged for removal, and is no longer valid
void MarkPersistentBit( bool bUnmark )
bool IsPersistentMarked()
set and check the actor's persistent bit, respectively
the persistent bit only applies to actors placed in the map file – for actors spawned dynamically during gameplay, MarkPersistentBit()
does nothing, and IsPersistentMarked()
always returns false
for more information on the persistent bit, see ScriptObject::OnRestore()
int TID()
actor tag ID
kScriptObject@ ScriptObject()
returns a wrapper for the user script object this actor is associated with
kDictMem@ Definition()
provides access to actor's defs properties
int& Type()
actor type ID
this is the number after the actor's type name in defs/actors/, and enumerated in turokActorTypes
in scripts/common.txt
bool InstanceOf( kStr& className )
returns whether this actor's associated native object is an instance of className
, or a subclass thereof (this refers to kex-prefixed classes, not script classes)
kActor@ CastToActor()
kAI@ CastToAI()
returns non-null even if actor isn't an AI; validate with InstanceOf("kexAI")
if uncertain
int GameTicks()
how many ticks the actor has existed for
int16& Health()
actor's health
uint& Flags()
bit field of actor flags:
- AF_SOLID
- AF_DORMANT
- AF_SNAPTOFLOOR
- AF_WOUNDEDMORTALLY
- AF_CASTSHADOW
- AF_TRIGGERSTUFF
- AF_HIDDEN
-
AF_ACTIVATED
–
prevents actor from being triggered (by script, actor, or sector)
gets set automatically when the actor is triggered - AF_DISABLED – cleared when the actor is triggered
-
AF_ENTEREDAREAEVENT
–
set on the tick after the player enters an event area
cleared when the player leaves
untested for other actor types - AF_REMOVEONCOMPLETION
- AF_NOBLOOD
-
AF_AVOIDWATER
–
deletes the actor if it enters a water sector
initialized by "Avoid Water" in Spawn Flags 1 - AF_FLOATINWATERONDEATH
- AF_DEAD
-
AF_STATIONARY
–
AI stands in place
initialized by "Sniper" in Spawn Flags 1 - AF_ALIGNTOFLOOR
- AF_NODRAW
- AF_NONSHOOTABLE
- AF_FULLVOLUME
- AF_CANBETOUCHED
- AF_IGNORESOUNDEVENTS – animations will skip any sounds they would normally play
- AF_TRIGGERANIMATION
- AF_HOLDTRIGGERANIM
- AF_TRIGGERNAIMDELAY
- AF_STAYINWATER
- AF_ALWAYSACTIVE
- AF_COLLIDEDWITHWALL
- AF_INVINCIBLE – for the player, this is not affected by god mode, invincibility, or spiritual invincibilty
- AF_ALLOWTINYENEMYCHEAT
- AF_NOMOVEMENT
uint SpawnFlags1()
- 1 << 0–Solid
- 1 << 1–Projectile Attack 1
- 1 << 2–Leader
- 1 << 3–Snap To Floor
- 1 << 4–Explosion Death
- 1 << 5–Climb Walls
- 1 << 6–Projectile Attack 2
- 1 << 7–No Repeat Explosion
- 1 << 8–Die On Explosion
- 1 << 9–Flocker
- 1 << 13–Kamikaze
- 1 << 14–Avoid Players
- 1 << 15–Float In Water On Death
- 1 << 16–Teleport
- 1 << 17–Cast Shadow
- 1 << 18–Teleport Wait
- 1 << 19–Use Strong Attacks
- 1 << 20–Use Weak Attacks
- 1 << 21–Sniper
- 1 << 22–Melt On Death
- 1 << 23–Avoid Water
- 1 << 24–Flying
- 1 << 25–Teleport Avoid Water
- 1 << 26–Teleport Avoid Cliffs
- 1 << 27–Trigger Stuff
- 1 << 28–Cannot Cause A Fight
- 1 << 29–No Wall Collision
- 1 << 30–Screen Shake
- 1 << 31–Respawn Animation
uint SpawnFlags2()
- 1 << 0–Drop Item Mask 1
- 1 << 1–Drop Item Mask 2
- 1 << 2–Drop Item Mask 3
- 1 << 3–Drop Item Mask 4
- 1 << 4–Drop Item Mask 5
- 1 << 5–Drop Item Mask 6
- 1 << 6–Drop Item Mask 7
- 1 << 7–Drop Item Mask 8
- 1 << 8–Drop Item Mask 9
- 1 << 9–Drop Item Mask 10
- 1 << 10–Drop Item Mask 11
- 1 << 11–Drop Item Mask 12
- 1 << 12–Drop Item Mask 13
- 1 << 13–Drop Item Mask 14
- 1 << 14–Remove on Completion
- 1 << 15–No Blood
- 1 << 16–Hold Trigger Animation
- 1 << 17–Projectile Attack 3
- 1 << 18–Projectile Attack 4
- 1 << 19–Drop Item On Damage
- 1 << 20–No Automap Draw
- 1 << 21–Alternate Moves
- 1 << 24–Projectile Attack 5
- 1 << 25–Projectile Attack 6
- 1 << 26–Mortal Wound Impact
- 1 << 27–Stay In Water
- 1 << 30–Projectile Attack 7
- 1 << 31–Projectile Attack 8
uint SpawnFlags3()
- 1 << 1–Play Trigger Anim Once
- 1 << 2–Regenerate From Start
- 1 << 3–Walk In Straight Line
- 1 << 5–No Thinker
- 1 << 6–Avoid Players 2
- 1 << 7–No Violent Death
- 1 << 8–Projectile Attack 9
- 1 << 9–Projectile Attack 10
- 1 << 10–Make Spawn Anim Visible
- 1 << 11–No Draw On Camera
static bit fields corresponding to the tabs of the same names in the editor
some of these are used to initialize other properties when the actor is (re)spawned (e.g., the "Sniper" flag sets AF_STATIONARY
), while other are referenced directly (e.g., the item drop flags in TurokEnemy::DropItem()
)
int16 SpawnParams( int param )
static properties corresponding to the following editor fields:
- 0–Target TID
- 1–Trigger Anim (uint8)
- 2–Health (initial)
- 3–Max Regenerations
- 4–Attack Chance (uint8)
- 5–Texture (initial) (int8)
- 6–Params 2 (int8)
- 7–Params 1 (int8)
some classes use these in novel ways (e.g., movers use health and attack chance to control timing)
Display
kRenderModel@ RenderModel()
returns a handle to the actor's render model
int& ModelVariation()
which model variant to use (e.g., regular or cyborg variant of raptor)
kVec3& Scale()
model scale
kAnimState& AnimState()
returns a reference to the actor's anim state
float& AnimSpeed()
void RunFxEvent( kStr& effectName )
apply an actor effect, defined in actorfx/*.kafx
todo: link to actorfx reference
Movement
kVec3& Origin()
current location of the actor
actors are removed at a distance around 1996.9 * GAME_SCALE
from global origin
kVec3& PrevOrigin()
location of the actor before the last move
for objects in motion, this is the location from the previous tick – the value will get stale when the object comes to rest
kVec3& Movement()
almost the change in location during the last tick, but not quite
for the player, this will be the horizontal offset only, except when in the air or swimming
when swimming, the z component will reflect the attempted offset – it'll still be non-zero when swimming up at the surface or down at the floor
kVec3& Velocity()
attempted delta per tick
For the player, this will always be (0,0,0)
, except for the z component when in the air. When knocked back by a purlin, it'll also reflect the entire velocity imparted by the attack.
float& Gravity()
positive is down
only takes effect when in the air
float& StepHeight()
void MoveToPosition( float newX, float newY )
tries to move to the given global horizontal coordinates
will move up and down slopes, but will be stopped by any obstructions along the way
stores collision info in the global CModel
if anything was hit along the way
void SetPosition( kVec3& newLoc )
set location to an arbitrary point
if the actor gets stuck in an invalid spot (based on its clip flags), the game will try to find a reasonable place to move it back into bounds
kAngle& Yaw()
kAngle& Pitch()
kAngle& Roll()
orientation of the actor, applied in the order listed
for the player, this reflects where the player is looking
kQuat& Rotation()
orientation of the actor
for the player, this reflects where the player is looking
bool OnGround()
on the ground, on a climbable wall, or swimming along the ground underwater
bool InWater()
swimming underwater
int GetWaterLevel()
info related to water areas (excluding AAF_SHALLOWWATER
areas)
possible values are:
- WLT_INVALID – not in a water area
- WLT_OVER – in the air above water surface
- WLT_BETWEEN – walking in shallow water, or swimming above the surface
- WLT_UNDER – submerged
int AreaID()
int SectorIndex()
actor's area and sector, respectively
int GetSectorIndexAtLocation( kVec3& loc, uint clipFlags = 0 )
tries to find a sector that contains loc
from the actor's current location
clipFlags
is a bit field of clip flags to disable while traversing the nav mesh during the search:
- CF_CLIPEDGES
- CF_IGNOREBLOCKERS
- CF_DROPOFF
- CF_NOENTERWATER–allow entering water sectors
- CF_NOEXITWATER–allow exiting water sectors
- CF_NOCLIPSTATICS
- CF_NOCLIPACTORS
- CF_WALKWALLS
- CF_COLLIDEFLOORS
- CF_HITSCAN
- CF_ALLOWCLIMB
- CF_ALLOWCRAWL
- CF_NOSTEPDOWN
- CF_NOSLOPESTEP
- CF_COLLIDEHEIGHT
- CF_COLLIDECORPSES
- CF_NOEXITWALLS
- CF_NOCOLLIDEFUNC
- CF_NOFLOORADJUST
- CF_NOCEILINGADJUST
- CF_COLLIDEWATER
updates the global CModel
, presumably to indicate what, if anything, blocked the path from the actor's current location to loc
void SetSector( uint i )
float& Friction()
float& BounceDamp()
Collision
float& Radius()
float& Height()
collision volume dimensions
float& WallRadius()
float& FloorHeight()
initial global z-coordinate of the floor at the current location, as defined in the map file
modifying the reference value will not change the sector's height (see kWorld::ChangeSectorHeight()
), but will persist to subsequent calls to the function, allowing you to change what's considered the "initial" height
float GetFloorHeight()
current global z-coordinate of the floor at the current location
float& CeilingHeight()
float GetCeilingHeight()
global z-coordinate of the ceiling at the current location
CeilingHeight()
's value is only updated when the actor enters a new sector, making it coarse and imprecise
bool CheckPosition( kVec3& v )
bool CheckPosition( float f, float f )
float GetWaterHeight()
global z-coordinate of current area's water surface
int& ImpactType()
defines which onImpact sub-block effects use when colliding with this actor
possible values are:
- IT_DEFAULT
- IT_WATER
- IT_METAL
- IT_STONE
- IT_FLESH_HUMAN
- IT_FLESH_CREATURE
- IT_FLESH_UNDEAD
- IT_LAVA
- IT_SLIME
- IT_FORCEFIELD
uint& ClipFlags()
bit field of clipping flags:
- CF_CLIPEDGES
- CF_IGNOREBLOCKERS
- CF_DROPOFF
-
CF_NOENTERWATER
–
actor cannot enter
AAF_WATER
sectors, unless they also haveAAF_SHALLOWWATER
- CF_NOEXITWATER
- CF_NOCLIPSTATICS
- CF_NOCLIPACTORS
- CF_WALKWALLS
- CF_COLLIDEFLOORS
- CF_HITSCAN
- CF_ALLOWCLIMB
- CF_ALLOWCRAWL
- CF_NOSTEPDOWN
- CF_NOSLOPESTEP
- CF_COLLIDEHEIGHT
- CF_COLLIDECORPSES
- CF_NOEXITWALLS
- CF_NOCOLLIDEFUNC
- CF_NOFLOORADJUST
- CF_NOCEILINGADJUST
- CF_COLLIDEWATER
- 1 << 26–allow entering restricted sectors
- 1 << 29–use per-poly level collision, even if the setting is disabled
Sound
void PlaySound( kStr& path )
play a sound by file path
e.g., self.PlaySound( "sounds/shaders/pistol_shot.ksnd" );
void PlaySoundWithLookupID( int ID )
play a sound by ID number, as defined in defs/fileLookup.txt
void StopSound()
stop all sounds this actor is playing, looping or otherwise
void StopLoopingSounds()
stop only looping sounds this actor is playing
Spatial
kVec3 GetTransformedVector( kVec3& localOffset )
returns localOffset
converted to global coordinates based on actor's Scale()
, Origin()
, and orientation
for the player, this doesn't take view pitch into account; for other actors, it does take slope tilt into account
float GetTurnYaw( kVec3& v )
offset from current Yaw()
to face global point v
float GetAvoidanceAngle( kVec3& v, float f )
float DistanceToPoint( kVec3& v )
float DistanceToPoint( float x, float y, float z )
square of the distance from center of mass (origin + half height) to a global point
Targeting
void SetTarget( kActor@ a )
kActor@ GetTarget()
bool CanSee( kActor@ a, uint clipFlags = 0 )
bool CanSee( kPuppet@ a, uint clipFlags = 0 )
performs a raycast to a
, and stores the result in the global CModel
returns true if anything was hit between the two actors
clipFlags
is a bit field of clip flags to disable (e.g., "collide floors" means the ray should not collide with floors; i.e., the actor should see through floors):
- CF_CLIPEDGES–see through most level geometry?
- CF_IGNOREBLOCKERS–do not see through blocking sectors (closed doors)
- CF_DROPOFF–do not see across cliff sectors
- CF_NOENTERWATER–no effect?
- CF_NOEXITWATER
- CF_NOCLIPSTATICS–do not see through static meshes (trees, etc.)
- CF_NOCLIPACTORS–do not see through actors
- CF_WALKWALLS
- CF_COLLIDEFLOORS–see through floors
-
CF_HITSCAN–causes
kCModel::InterceptVector()
to be all over the place? - CF_ALLOWCLIMB
- CF_ALLOWCRAWL–no effect?
- CF_NOSTEPDOWN
- CF_NOSLOPESTEP
- CF_COLLIDEHEIGHT
- CF_COLLIDECORPSES–no effect?
- CF_NOEXITWALLS
- CF_NOCOLLIDEFUNC
- CF_NOFLOORADJUST
- CF_NOCEILINGADJUST
- CF_COLLIDEWATER–no effect?
void SetHeadTrackTarget( kActor@ a )
Other Methods
void SpawnProjectile( kStr& s, kVec3& v1, kVec3& v2, float f )
void SpawnFx( kStr& s, kVec3& v )
void SpawnFx( kStr& s, kVec3& v, kQuat& q )
void InflictGenericDamage( kActor@ instigator, int amount )
deal amount
of damage to this actor
instigator
will be passed on to ScriptObject::OnDamage()
/OnDeath()
void MeleeObject( kStr& damageType, kVec3& offset, float radius )
inflict damageType
on all actors within range of the given offset, according to the following math:
float range = (radius + 1) * 2 * GAME_SCALE;
kVec3 origin = self.GetTransformedVector( offset );
for every actor A in the general vicinity of origin
{
kVec3 v = A.Origin(); // actor's base
v.z += A.Height() * 0.5f; // center of mass
float dist = (v - origin).Unit() - A.Radius();
if ( dist <= range )
inflict damageType on A
}
damage types are defined in defs/damageInfo.txt
void InteractActorsAtPosition( kVec3& position, kStr& callbackFunc,
float arg1 = 0, float arg2 = 0, float arg3 = 0, float arg4 = 0 )
for every actor A
in the general vicinity of position
, call:
this.callbackFunc( A, arg1, arg2, arg3, arg4 );
the callback function should be defined in the user script (or a parent class) for the actor that called InteractActorsAtPosition()
, with the following type signature:
void( kActor@, const float, const float, const float, const float )
bool RandomDecision( int i )
probability of returning true is 1 / 2i
-1, except when i
is 0
, in which case the probability is nearly 0