|
|
(8 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| Do not edit the area above the separator line, please. | | Do not edit the area above the separator line, please. |
| ---- | | ---- |
| [[Legacy:Actor]]
| | UIComp_DrawImage custom subclasses: |
| [[Actor]]
| | {{#dpl: |
| [[UE3:Actor (UT3)]]
| | |category=Subclasses of UIComp_DrawImage{{!}}Subclasses of UIComp_DrawImage (UE3)}{{!}}Subclasses of UIComp_DrawImage (UT3) |
| [[Project:Sandbox]]
| | |category=Custom classes{{!}}Custom UE3-specific classes{{!}}Custom UT3-specific classes |
| | | |namespace={{#if:UE3|{{!}}UE3}}{{!}}User |
| <uscript>
| | |format=,[[%PAGE%|%TITLE%]],, |
| // Extended to add support for weapon idle animations
| | |inlinetext=,  |
| //////////////////////////////////////////////////////
| | |shownamespace=false |
| simulated state Active
| | |replaceintitle=/ (?!\()/,_ |
| { | | |resultsheader=\n;Known custom subclasses:: |
| simulated function BeginState(name PreviousStateName)
| | |oneresultheader=\n;Known custom subclass:: |
| {
| | |noresultsheader=<nowiki></nowiki> |
| local int i;
| | |allowcachedresults=true |
| | | }} |
| // 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();
| |
| }
| |
| | |
| </uscript>
| |
| | |
| Testing UScript highlighter...
| |
| <uscript>
| |
| 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')
| |
| )}
| |
| } | |
| </uscript>
| |