I love the smell of UnrealEd crashing in the morning. – tarquin

Difference between revisions of "Unreal Wiki:Sandbox"

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search
m
 
(7 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=,&#32;
//////////////////////////////////////////////////////
+
|shownamespace=false
simulated state Active
+
|replaceintitle=/ (?!\()/,_
{
+
|resultsheader=\n;Known custom subclasses&#58;:
simulated function BeginState(name PreviousStateName)
+
|oneresultheader=\n;Known custom subclass&#58;:
{
+
|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);
+
 
+
}
+
 
+
 
+
/**
+
* This function is only called if our weapon has a prefire delay.  CustomFire() is called to start the weapon's animations and
+
* play the firing sound.  Meanwhile, a timer is ticking away (started by BeginFire()) for either DelayedFire() or DelayedAltFire()
+
* which, when executed, takes care of actually consuming the ammo and applying dmg to the target.
+
*/
+
simulated function CustomFire()
+
{
+
local int i;
+
local float FireRateScale;
+
local DepthPawn DP;
+
local float FireAnimRate;                                  // scaled by owner's remaining stamina.
+
 
+
//`log(`location @ `showvar(FireInterval[i]) @ `showvar(IsTimerActive(nameof(DelayedFire)),TimedFireActive));
+
//ScriptTrace();
+
DP = GetDP(true);
+
 
+
// do nothing here - this means that our weapon had a prefire delay and the actual
+
// firing will be handled in DelayedFire/DelayedAltFire
+
 
+
// or weapons w/o prefire delay play their anims at speed 0!  (ie. not at all!)
+
FireAnimRate = 1.0f;
+
FireRateScale = GetScaledFireSpeed();
+
 
+
if ( bReqStamina )
+
{
+
// Change the animation playback speed.
+
FireAnimRate = FClamp(FireRateScale,0.5,2.0);
+
 
+
// Change the min. time between refires.
+
for ( i = 0; i < FireInterval.Length; i++ )
+
{
+
FireInterval[i] = FClamp(
+
default.FireInterval[i] * (1.0f / FireRateScale),
+
default.FireInterval[i]*0.5,
+
default.FireInterval[i]*2
+
);
+
}
+
 
+
// Change the delay between the initial fire call and when damage is done.
+
PreFireDelay[CurrentFireMode] = FClamp(
+
default.PreFireDelay[CurrentFireMode] * (1.0f / FireRateScale),
+
default.PreFireDelay[CurrentFireMode] * 0.5,
+
default.PreFireDelay[CurrentFireMode] * 2
+
);
+
DP.WeaponStamina = Max(DP.WeaponStamina - StamCon, 0);
+
}
+
 
+
PlayPrefire(FireAnimRate);
+
 
+
/*
+
`log("FireAnim Playback rate is : "@FireAnimRate);
+
`log("Fire Interval is : "@Fireinterval[0]);
+
`log("Owner stamina is : "@P.SprintStamina);
+
*/
+
 
+
LastFireTime = WorldInfo.TimeSeconds;
+
}
+
 
+
/**
+
* Begins the weapon's prefire animation and sound.
+
*
+
* @param AnimRate scales the speed of the animation
+
*/
+
simulated function PlayPrefire( float AnimRate )
+
{
+
//`log(`location);
+
// Sharks need their fire anims blended to the fullbody slot -- probably need to move this to PlayFireEffects
+
if ( WorldInfo.NetMode != NM_DedicatedServer )
+
{
+
<snip a bunch of code that calls custom functions for running game-specific animations>
+
PlayPreFiringSound();
+
ShakeView();
+
}
+
 
+
}
+
 
+
/**
+
* 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>
+

Latest revision as of 01:55, 9 August 2015

Do not edit the area above the separator line, please.


UIComp_DrawImage custom subclasses: