I don't need to test my programs. I have an error-correcting modem.
Difference between revisions of "Unreal Wiki:Sandbox"
From Unreal Wiki, The Unreal Engine Documentation Site
Line 7: | Line 7: | ||
<uscript> | <uscript> | ||
+ | // Extended to add support for weapon idle animations | ||
+ | ////////////////////////////////////////////////////// | ||
+ | simulated state Active | ||
+ | { | ||
+ | simulated function BeginState(name PreviousStateName) | ||
+ | { | ||
+ | local int i; | ||
+ | |||
+ | // Cache a reference to the AI controller | ||
+ | if (Role == ROLE_Authority) | ||
+ | { | ||
+ | CacheAIController(); | ||
+ | } | ||
+ | |||
+ | if ( SendToIdleState() ) | ||
+ | { | ||
+ | if ( GetZoomedState() == ZST_Zoomed ) | ||
+ | { | ||
+ | PushState('Zoomed'); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | OnAnimEnd(none, 0.f, 0.f); | ||
+ | if ( UTBot(Instigator.Controller) != None ) | ||
+ | { | ||
+ | if ( PendingFire(0) ) | ||
+ | { | ||
+ | StillFiring(0); | ||
+ | } | ||
+ | else if ( PendingFire(1) ) | ||
+ | { | ||
+ | StillFiring(1); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Check to see if we need to go down | ||
+ | if( bWeaponPutDown ) | ||
+ | { | ||
+ | `LogInv("Weapon put down requested during transition, put it down now"); | ||
+ | PutDownWeapon(); | ||
+ | } | ||
+ | else if ( !HasAnyAmmo() ) | ||
+ | { | ||
+ | WeaponEmpty(); | ||
+ | } | ||
+ | else if ( bAutoFire ) | ||
+ | { | ||
+ | // if either of the fire modes are pending, perform them | ||
+ | for( i=0; i<GetPendingFireLength(); i++ ) | ||
+ | { | ||
+ | if ( PendingFire(i) ) | ||
+ | { | ||
+ | BeginFire(i); | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if (InvManager != none && InvManager.LastAttemptedSwitchToWeapon != none) | ||
+ | { | ||
+ | if (InvManager.LastAttemptedSwitchToWeapon != self) | ||
+ | { | ||
+ | InvManager.LastAttemptedSwitchToWeapon.ClientWeaponSet(true); | ||
+ | } | ||
+ | InvManager.LastAttemptedSwitchToWeapon = none; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Override BeginFire to verify that the pawn isn't busy (performing other blocking animations, etc.) as well | ||
+ | * as handle starting the prefire sequence if this weapon has a prefire animation. | ||
+ | */ | ||
+ | simulated function BeginFire(byte FireModeNum) | ||
+ | { | ||
+ | // verify that our owning pawn isn't busy before calling Super.BeginFire(), which is where PendingFire is set | ||
+ | if ( !IsFiringAllowed(FireModeNum) ) | ||
+ | { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // `log(`location @ `showvar(IsTimerActive(nameof(DelayedFire)),DelayedFire Active)); | ||
+ | |||
+ | // if this weapon uses a prefire animation | ||
+ | if ( FireModeNum < PrefireDelay.Length && PreFireDelay[FireModeNum] > 0 ) | ||
+ | { | ||
+ | PrefireCachedStartTrace = InstantFireStartTrace(); | ||
+ | if ( FireModeNum == 0 ) | ||
+ | { | ||
+ | // if there is already a timer for this, it means that the user is spamming the fire button | ||
+ | // and we are still performing the prefire sequence from the first time the user pressed the | ||
+ | // fire button | ||
+ | if ( IsTimerActive(nameof(DelayedFire)) ) | ||
+ | { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // do the actual firing of the weapon after the prefire sequence has been completed. | ||
+ | SetTimer(PreFireDelay[FireModeNum], false, nameof(DelayedFire)); | ||
+ | } | ||
+ | else if ( FireModeNum == 1 ) | ||
+ | { | ||
+ | // if there is already a timer for this, it means that the user is spamming the fire button | ||
+ | // and we are still performing the prefire sequence from the first time the user pressed the | ||
+ | // fire button | ||
+ | if ( IsTimerActive(nameof(DelayedAltFire)) ) | ||
+ | { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | // do the actual firing of the weapon after the prefire sequence has been completed. | ||
+ | SetTimer(PreFireDelay[FireModeNum], false, nameof(DelayedAltFire)); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | `log("Unhandled fire mode in" @ Name $ "." $ GetFuncName() @ "-" @ FireModeNum); | ||
+ | ScriptTrace(); | ||
+ | } | ||
+ | |||
+ | // ensure our weapon mode is custom so that CustomFire() is called right now. CustomFire() will do the prefire stuff | ||
+ | WeaponFireTypes[FireModeNum] = EWFT_Custom; | ||
+ | } | ||
+ | |||
+ | Super.BeginFire(FireModeNum); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Called when an animation ends. | ||
+ | * | ||
+ | * Always return to the weapon idle animation after our last played custom animation is finished, if it has one. | ||
+ | */ | ||
+ | simulated event OnAnimEnd( optional AnimNodeSequence SeqNode, optional float PlayedTime, optional float ExcessTime ) | ||
+ | { | ||
+ | // we do NOTHING, very much on purpose, so that UT will stop triggering our idle animation while we're in the middle | ||
+ | // of doing something else. | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Starts a random idle animation. | ||
+ | */ | ||
+ | simulated function PlayWeaponIdleAnim( optional bool bLocalOnly ) | ||
+ | { | ||
+ | Global.PlayWeaponIdleAnim(bLocalOnly); | ||
+ | } | ||
+ | |||
+ | |||
+ | /** | ||
+ | * Called when zooming starts. | ||
+ | * | ||
+ | * @param WeaponOwner value of Instigator.Controller, the player that is holding this weapon.w | ||
+ | */ | ||
+ | simulated function StartZoom(UTPlayerController WeaponOwner) | ||
+ | { | ||
+ | `wtrace_enter(Self,`showvar(WeaponOwner)); | ||
+ | |||
+ | // calling Global.StartZoom() will result in the PlayWeaponIdleAnimation() function being called. Since we are transitioning into | ||
+ | // a zoomed state, we want the idle animation that is played to be the one setup for the zoom mode. Therefore, PushState() prior | ||
+ | // to calling Global.StartZoom() so that Zoomed.PlayWeaponIdleAnim() is called rather than our version. | ||
+ | PushState('Zoomed'); | ||
+ | Global.StartZoom(WeaponOwner); | ||
+ | |||
+ | // and just to be on the safe side. | ||
+ | PlayWeaponIdleAnim(); | ||
+ | |||
+ | `wtrace_exit(Self); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | simulated state WeaponEquipping | ||
+ | { | ||
+ | /** | ||
+ | * Overridden to trigger our weapon equip animation and hide the carry attachment. | ||
+ | */ | ||
+ | simulated event BeginState(Name PreviousStateName) | ||
+ | { | ||
+ | Super.BeginState(PreviousStateName); | ||
+ | |||
+ | if ( !bDisplayAmmoAttachment ) | ||
+ | { | ||
+ | ToggleCarryAttachment(false); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | simulated state WeaponFiring | ||
+ | { | ||
+ | ignores SwitchAmmoTypes; | ||
+ | /** | ||
+ | * Timer event, call is set up in Weapon::TimeWeaponFiring(). | ||
+ | * The weapon is given a chance to evaluate if another shot should be fired. | ||
+ | * This event defines the weapon's rate of fire. | ||
+ | */ | ||
+ | simulated function RefireCheckTimer() | ||
+ | { | ||
+ | if ( IsTimerActive(nameof(DelayedFire)) || IsTimerActive(nameof(DelayedAltFire)) ) | ||
+ | { | ||
+ | return; | ||
+ | } | ||
+ | Super.RefireCheckTimer(); | ||
+ | } | ||
+ | |||
+ | simulated event BeginState(name PreviousStateName) | ||
+ | { | ||
+ | // this call will result in WeaponFired() being called, which spawns our effects. | ||
+ | // After returning from this function, the CheckRefire timer function will be active. | ||
+ | Super.BeginState(PreviousStateName); | ||
+ | } | ||
+ | |||
+ | simulated event EndState(name NextStateName) | ||
+ | { | ||
+ | local int Idx; | ||
+ | |||
+ | if ( NextStateName == 'Active' ) | ||
+ | { | ||
+ | for ( Idx = 0; Idx < GetPendingFireLength(); Idx++ ) | ||
+ | { | ||
+ | ClearPendingFire(Idx); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Super.EndState(NextStateName); | ||
+ | } | ||
+ | |||
+ | simulated function StartZoom(UTPlayerController WeaponOwner) | ||
+ | { | ||
+ | // don't allow the player to switch zooming modes while reloading | ||
+ | } | ||
+ | |||
+ | simulated function EndZoom(UTPlayerController WeaponOwner) | ||
+ | { | ||
+ | // don't allow the player to switch zooming modes while reloading | ||
+ | } | ||
+ | } | ||
+ | |||
/** Override BeginFire so that it will enter the firing state right away. */ | /** Override BeginFire so that it will enter the firing state right away. */ | ||
simulated function BeginFire(byte FireModeNum) | simulated function BeginFire(byte FireModeNum) |
Revision as of 16:28, 18 February 2012
Do not edit the area above the separator line, please.
Legacy:Actor Actor UE3:Actor (UT3) Project:Sandbox
// Extended to add support for weapon idle animations ////////////////////////////////////////////////////// simulated state Active { simulated function BeginState(name PreviousStateName) { local int i; // Cache a reference to the AI controller if (Role == ROLE_Authority) { CacheAIController(); } if ( SendToIdleState() ) { if ( GetZoomedState() == ZST_Zoomed ) { PushState('Zoomed'); } } OnAnimEnd(none, 0.f, 0.f); if ( UTBot(Instigator.Controller) != None ) { if ( PendingFire(0) ) { StillFiring(0); } else if ( PendingFire(1) ) { StillFiring(1); } } // Check to see if we need to go down if( bWeaponPutDown ) { `LogInv("Weapon put down requested during transition, put it down now"); PutDownWeapon(); } else if ( !HasAnyAmmo() ) { WeaponEmpty(); } else if ( bAutoFire ) { // if either of the fire modes are pending, perform them for( i=0; i<GetPendingFireLength(); i++ ) { if ( PendingFire(i) ) { BeginFire(i); break; } } } if (InvManager != none && InvManager.LastAttemptedSwitchToWeapon != none) { if (InvManager.LastAttemptedSwitchToWeapon != self) { InvManager.LastAttemptedSwitchToWeapon.ClientWeaponSet(true); } InvManager.LastAttemptedSwitchToWeapon = none; } } /** * Override BeginFire to verify that the pawn isn't busy (performing other blocking animations, etc.) as well * as handle starting the prefire sequence if this weapon has a prefire animation. */ simulated function BeginFire(byte FireModeNum) { // verify that our owning pawn isn't busy before calling Super.BeginFire(), which is where PendingFire is set if ( !IsFiringAllowed(FireModeNum) ) { return; } // `log(`location @ `showvar(IsTimerActive(nameof(DelayedFire)),DelayedFire Active)); // if this weapon uses a prefire animation if ( FireModeNum < PrefireDelay.Length && PreFireDelay[FireModeNum] > 0 ) { PrefireCachedStartTrace = InstantFireStartTrace(); if ( FireModeNum == 0 ) { // if there is already a timer for this, it means that the user is spamming the fire button // and we are still performing the prefire sequence from the first time the user pressed the // fire button if ( IsTimerActive(nameof(DelayedFire)) ) { return; } // do the actual firing of the weapon after the prefire sequence has been completed. SetTimer(PreFireDelay[FireModeNum], false, nameof(DelayedFire)); } else if ( FireModeNum == 1 ) { // if there is already a timer for this, it means that the user is spamming the fire button // and we are still performing the prefire sequence from the first time the user pressed the // fire button if ( IsTimerActive(nameof(DelayedAltFire)) ) { return; } // do the actual firing of the weapon after the prefire sequence has been completed. SetTimer(PreFireDelay[FireModeNum], false, nameof(DelayedAltFire)); } else { `log("Unhandled fire mode in" @ Name $ "." $ GetFuncName() @ "-" @ FireModeNum); ScriptTrace(); } // ensure our weapon mode is custom so that CustomFire() is called right now. CustomFire() will do the prefire stuff WeaponFireTypes[FireModeNum] = EWFT_Custom; } Super.BeginFire(FireModeNum); } /** * Called when an animation ends. * * Always return to the weapon idle animation after our last played custom animation is finished, if it has one. */ simulated event OnAnimEnd( optional AnimNodeSequence SeqNode, optional float PlayedTime, optional float ExcessTime ) { // we do NOTHING, very much on purpose, so that UT will stop triggering our idle animation while we're in the middle // of doing something else. } /** * Starts a random idle animation. */ simulated function PlayWeaponIdleAnim( optional bool bLocalOnly ) { Global.PlayWeaponIdleAnim(bLocalOnly); } /** * Called when zooming starts. * * @param WeaponOwner value of Instigator.Controller, the player that is holding this weapon.w */ simulated function StartZoom(UTPlayerController WeaponOwner) { `wtrace_enter(Self,`showvar(WeaponOwner)); // calling Global.StartZoom() will result in the PlayWeaponIdleAnimation() function being called. Since we are transitioning into // a zoomed state, we want the idle animation that is played to be the one setup for the zoom mode. Therefore, PushState() prior // to calling Global.StartZoom() so that Zoomed.PlayWeaponIdleAnim() is called rather than our version. PushState('Zoomed'); Global.StartZoom(WeaponOwner); // and just to be on the safe side. PlayWeaponIdleAnim(); `wtrace_exit(Self); } } simulated state WeaponEquipping { /** * Overridden to trigger our weapon equip animation and hide the carry attachment. */ simulated event BeginState(Name PreviousStateName) { Super.BeginState(PreviousStateName); if ( !bDisplayAmmoAttachment ) { ToggleCarryAttachment(false); } } } simulated state WeaponFiring { ignores SwitchAmmoTypes; /** * Timer event, call is set up in Weapon::TimeWeaponFiring(). * The weapon is given a chance to evaluate if another shot should be fired. * This event defines the weapon's rate of fire. */ simulated function RefireCheckTimer() { if ( IsTimerActive(nameof(DelayedFire)) || IsTimerActive(nameof(DelayedAltFire)) ) { return; } Super.RefireCheckTimer(); } simulated event BeginState(name PreviousStateName) { // this call will result in WeaponFired() being called, which spawns our effects. // After returning from this function, the CheckRefire timer function will be active. Super.BeginState(PreviousStateName); } simulated event EndState(name NextStateName) { local int Idx; if ( NextStateName == 'Active' ) { for ( Idx = 0; Idx < GetPendingFireLength(); Idx++ ) { ClearPendingFire(Idx); } } Super.EndState(NextStateName); } simulated function StartZoom(UTPlayerController WeaponOwner) { // don't allow the player to switch zooming modes while reloading } simulated function EndZoom(UTPlayerController WeaponOwner) { // don't allow the player to switch zooming modes while reloading } } /** Override BeginFire so that it will enter the firing state right away. */ simulated function BeginFire(byte FireModeNum) { // verify that our owning pawn isn't busy before calling Super.BeginFire(), which is where PendingFire is set if ( !IsFiringAllowed(FireModeNum) ) { return; } //`log(`location @ `showvar(IsTimerActive(nameof(DelayedFire)),DelayedFire Active)); Super.BeginFire(FireModeNum); } /** * For tracehit weapons with no prefire delay, handles firing the weapon. */ simulated function InstantFire() { //`log(`location); CustomFire(); PerformInstantFire(); } /** * For weapons using projectiles, which have no prefire delay - fires the weapon. */ simulated function Projectile ProjectileFire() { //`log(`location); CustomFire(); return Super.ProjectileFire(); } simulated function Delayed_CustomFire( byte FireModeNum ); /** * Called on a timer (set in BeginFire()), this is called only for weapons which have a prefire delay. */ simulated function DelayedFire() { DelayedWeaponFire(0); } /** * Called on a timer (set in BeginFire()), this is called only for weapons which have a prefire delay. */ simulated function DelayedAltFire() { DelayedWeaponFire(1); } simulated function DelayedWeaponFire( byte FireModeNum ) { //`log(`location); // restore our WeaponFireType, since we switched it to EWFT_Custom in BeginFire() WeaponFireTypes[FireModeNum] = default.WeaponFireTypes[FireModeNum]; if ( WeaponFireTypes[FireModeNum] == EWFT_InstantHit ) { // our own version of InstantFire() is only called for weapons that do not have a prefire // delay, so go directly to our parent class/state version PerformInstantFire(); } else if ( WeaponFireTypes[FireModeNum] == EWFT_Projectile ) { // our own version of ProjectileFire() is only called for weapons that do not have a prefire // delay, so go directly to our parent class/state version Super.ProjectileFire(); } else if ( WeaponFireTypes[FireModeNum] == EWFT_Custom ) { Delayed_CustomFire(FireModeNum); } PrefireCachedStartTrace = vect(0,0,0); } /** * Utility function to allow me to inject some debugging code prior to passing control to our parent classes. */ protected simulated function PerformInstantFire() { Super.InstantFire(); }
Testing UScript highlighter...
class X extends Y within Z implements(I) nottransient; `include(SomeFile.uci) var(Group) interp struct Type { var() bool bCorrect; var array<class<Actor> > ActorClasses; } VarName; reliable client function CheckType(optional class<Actor> ActorClass) { local int i; for (i = 0; i < VarName.ActorClasses.Length; ++i) { if (ActorClass == None || ClassIsChildOf(VarName.ActorClasses[i], ActorClass)) { VarName.ActorClasses[i].static.StaticSaveConfig(); continue; } VarName.ActorClasses.Remove(i--, 1); } VarName.bCorrect = True; } static function byte GetHash(int Value) { switch (Value) { case -1: return 0; case 0xCAFE: return 1 default: return (Value >= 0 && Value < 10) ? class'Hasher'.default.Hash[Value] : (Value & 0xff); } } defaultproperties { VarName.Empty VarName[0] = {( bCorrect = True, ActorClasses.Add(class'ReplicationInfo') )} }