304 lines
8.6 KiB
Ucode
304 lines
8.6 KiB
Ucode
// ====================================================================
|
|
// Class: Engine.InteractionMaster
|
|
//
|
|
// The InteractionMaster controls the entire interaction system. It's
|
|
// job is to take input and Pre/PostRender call and route them to individual
|
|
// Interactions and/or viewports.
|
|
//
|
|
// The stubs here in script are for just the GlobalInteracations as those
|
|
// are the only Interactions the IM routes directly too. A new stub is
|
|
// created in order to limit the number of C++ -> Uscript switches.
|
|
//
|
|
// (c) 2001, Epic Games, Inc. All Rights Reserved
|
|
// ====================================================================
|
|
|
|
class InteractionMaster extends Interactions
|
|
transient
|
|
Native;
|
|
|
|
var transient Client Client;
|
|
|
|
var transient const Interaction BaseMenu; // Holds a pointer to the base menu system
|
|
var transient const Interaction Console; // Holds the special Interaction that acts as the console
|
|
var transient array<Interaction> GlobalInteractions; // Holds a listing of all global Interactions
|
|
var transient bool bRequireRawJoystick;
|
|
|
|
native function Travel(string URL); // Setup a travel to a new map
|
|
|
|
// ====================================================================
|
|
// Control functions
|
|
// ====================================================================
|
|
|
|
event Interaction AddInteraction(string InteractionName, optional Player AttachTo) // Adds an Interaction
|
|
{
|
|
local Interaction NewInteraction;
|
|
local class<Interaction> NewInteractionClass;
|
|
|
|
NewInteractionClass = class<Interaction>(DynamicLoadObject(InteractionName, class'Class'));
|
|
|
|
if (NewInteractionClass!=None)
|
|
{
|
|
NewInteraction = new NewInteractionClass;
|
|
if (NewInteraction != None)
|
|
{
|
|
|
|
// Place the Interaction in the proper array
|
|
|
|
if (AttachTo != None) // Handle location Interactions
|
|
{
|
|
AttachTo.LocalInteractions.Length = AttachTo.LocalInteractions.Length + 1;
|
|
AttachTo.LocalInteractions[AttachTo.LocalInteractions.Length-1] = NewInteraction;
|
|
NewInteraction.ViewportOwner = AttachTo;
|
|
}
|
|
else // Handle Global Interactions
|
|
{
|
|
GlobalInteractions.Length = GlobalInteractions.Length + 1;
|
|
GlobalInteractions[GlobalInteractions.Length-1] = NewInteraction;
|
|
}
|
|
|
|
// Initialize the Interaction
|
|
|
|
NewInteraction.Initialize();
|
|
NewInteraction.Master = Self;
|
|
|
|
return NewInteraction;
|
|
|
|
}
|
|
else
|
|
Log("Could not create interaction ["$InteractionName$"]",'IMaster');
|
|
|
|
}
|
|
else
|
|
Log("Could not load interaction ["$InteractionName$"]",'IMaster');
|
|
|
|
return none;
|
|
|
|
} // AddInteraction
|
|
|
|
event RemoveInteraction(interaction RemoveMe) // Removes a Interaction
|
|
{
|
|
local int Index;
|
|
|
|
// Grab the array to work with
|
|
|
|
if (RemoveMe.ViewportOwner != None)
|
|
{
|
|
for (Index = 0; Index < RemoveMe.ViewPortOwner.LocalInteractions.Length; Index++)
|
|
{
|
|
if ( RemoveMe.ViewPortOwner.LocalInteractions[Index] == RemoveMe )
|
|
{
|
|
RemoveMe.ViewPortOwner.LocalInteractions.Remove(Index,1);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (Index = 0; Index < GlobalInteractions.Length; Index++)
|
|
{
|
|
if ( GlobalInteractions[Index] == RemoveMe )
|
|
{
|
|
GlobalInteractions.Remove(Index,1);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Find the Interaction to delete
|
|
|
|
Log("Could not remove interaction ["$RemoveMe$"] (Not Found)", 'IMaster');
|
|
|
|
} // RemoveInteraction
|
|
|
|
// ====================================================================
|
|
// SetFocusTo - This function will cause a window to adjust it's position
|
|
// in it's array so that it processes input first and displays last.
|
|
// ====================================================================
|
|
|
|
event SetFocusTo(Interaction Inter, optional Player ViewportOwner)
|
|
{
|
|
local array<Interaction> InteractionArray;
|
|
local Interaction temp;
|
|
local int i,iIndex;
|
|
|
|
|
|
if (ViewportOwner != none)
|
|
InteractionArray = ViewportOwner.LocalInteractions;
|
|
else
|
|
InteractionArray = GlobalInteractions;
|
|
|
|
if (InteractionArray.Length == 0)
|
|
{
|
|
Log("Attempt to SetFocus on an empty Array.",'IMaster');
|
|
return;
|
|
}
|
|
|
|
// Search for the Interaction
|
|
|
|
iIndex = -1;
|
|
for ( i=0; i<InteractionArray.Length; i++ )
|
|
{
|
|
if (InteractionArray[i] == Inter)
|
|
{
|
|
iIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Was it found?
|
|
|
|
if (iIndex<0)
|
|
{
|
|
log("Interaction "$Inter$" is not in "$ViewportOwner$".",'IMaster');
|
|
return;
|
|
}
|
|
else if (iIndex==0)
|
|
return; // Already has focus
|
|
|
|
|
|
// Move it to the top.
|
|
|
|
temp = InteractionArray[iIndex];
|
|
for ( i=0; i<iIndex; i++)
|
|
InteractionArray[i+1] = InteractionArray[i];
|
|
|
|
InteractionArray[0] = temp;
|
|
InteractionArray[0].bActive = true; // Give it Input
|
|
InteractionArray[0].bVisible = true; // Make it visible
|
|
|
|
} // SetFocusTo
|
|
|
|
// ====================================================================
|
|
// Input Functions
|
|
//
|
|
// The Process functions are here to limit the # of switches from C++ to Script.
|
|
// ====================================================================
|
|
|
|
event bool Process_KeyType( array<Interaction> InteractionArray, out EInputKey Key, optional string Unicode ) // Process a single key press
|
|
{
|
|
local int Index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=0; Index<InteractionArray.Length; Index++)
|
|
{
|
|
// Give each Interaction the chance to process the key event
|
|
|
|
if ( ( InteractionArray[Index].bActive ) && (!InteractionArray[Index].bNativeEvents) && ( InteractionArray[Index].KeyType(key,Unicode) ) )
|
|
return true; // and break the chain if processed
|
|
|
|
}
|
|
return false; // Keep processing
|
|
|
|
} // Process_KeyType
|
|
|
|
event bool Process_KeyEvent( array<Interaction> InteractionArray,
|
|
out EInputKey Key, out EInputAction Action, FLOAT Delta ) // Process the range of input events
|
|
{
|
|
local int Index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=0; Index<InteractionArray.Length; Index++)
|
|
{
|
|
// Give each Interaction the chance to process the key event
|
|
|
|
if ( ( InteractionArray[Index].bActive ) && (!InteractionArray[Index].bNativeEvents) && ( InteractionArray[Index].KeyEvent(Key, Action, Delta ) ) )
|
|
{
|
|
return true; // and break the chain if processed
|
|
}
|
|
|
|
}
|
|
return false;
|
|
|
|
} // Process_KeyEvent
|
|
|
|
// ====================================================================
|
|
// Render functions only occure on local interactions. The process
|
|
// the array in reverse order so that the objects that have focus
|
|
// are drawn last.
|
|
// ====================================================================
|
|
|
|
event Process_PreRender( array<Interaction> InteractionArray, canvas Canvas )
|
|
{
|
|
local int index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=InteractionArray.Length; Index>0; Index--) // Give each Interaction PreRender time
|
|
{
|
|
if ( (InteractionArray[Index-1].bVisible ) && (!InteractionArray[Index-1].bNativeEvents) )
|
|
InteractionArray[Index-1].PreRender(canvas);
|
|
}
|
|
|
|
} // Process_PreRender
|
|
|
|
event Process_PostRender( array<Interaction> InteractionArray, canvas Canvas )
|
|
{
|
|
local int index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=InteractionArray.Length; Index>0; Index--) // Give each Interaction PreRender time
|
|
{
|
|
if ( (InteractionArray[Index-1].bVisible ) && (!InteractionArray[Index-1].bNativeEvents) )
|
|
InteractionArray[Index-1].PostRender(canvas);
|
|
}
|
|
|
|
} // Process_PostRender
|
|
|
|
// ====================================================================
|
|
// Tick - Interactions can request access to be ticked.
|
|
// ====================================================================
|
|
|
|
event Process_Tick( array<Interaction> InteractionArray, float DeltaTime )
|
|
{
|
|
local int Index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=0; Index<InteractionArray.Length; Index++)
|
|
{
|
|
// Give each Interaction that requires it tick
|
|
if ( (InteractionArray[Index].bRequiresTick ) && (!InteractionArray[Index].bNativeEvents) )
|
|
InteractionArray[Index].Tick(DeltaTime);
|
|
}
|
|
|
|
}
|
|
|
|
// ====================================================================
|
|
// Message - The IM is responsible for sending Message events to all
|
|
// interactions.
|
|
// ====================================================================
|
|
|
|
event Process_Message( coerce string Msg, float MsgLife, array<Interaction> InteractionArray)
|
|
{
|
|
local int Index;
|
|
|
|
// Chain through the Interactions
|
|
|
|
for ( Index=0; Index<InteractionArray.Length; Index++)
|
|
{
|
|
// Give each Interaction the message
|
|
|
|
InteractionArray[Index].Message(Msg, MsgLife);
|
|
}
|
|
|
|
} // Message
|
|
|
|
|
|
event NotifyLevelChange(array<Interaction> InteractionArray)
|
|
{
|
|
local int Index;
|
|
|
|
for (Index=0;Index<InteractionArray.Length; Index++)
|
|
InteractionArray[Index].NotifyLevelChange();
|
|
}
|
|
|
|
|
|
defaultproperties
|
|
{
|
|
|
|
}
|