Page 1 of 1

Incoming and outgoing datalink

PostPosted: Sat Feb 18, 12 11:59 pm
by SimonDenton
So for ingoing and outgoing calls I have two different datalink displays; InCall and OutCall. Both have distinct sounds, alert icon etc. To do this I have my own triggers. Since both are pretty much the same, I'll show code for InCall.

First I have my function in the player class :
[spoiler]
Code: Select all
// ----------------------------------------------------------------------
// StartInCall()
//
// Locates and starts the DataLink passed in
// ----------------------------------------------------------------------

function Bool StartInCall(
   String datalinkName,
   Optional SummerInCallTrigger datalinkTrigger)
{
   local Conversation activeDataLink;
   local bool bDataLinkPlaySpawned;

   // Don't allow DataLinks to start if we're in PlayersOnly mode
   if ( Level.bPlayersOnly )
      return False;

   activeDataLink = GetActiveDataLink(datalinkName);

   if ( activeDataLink != None )
   {
      // Search to see if there's an active DataLinkPlay object
      // before creating one

      if ( dataLinkPlay == None )
      {
         datalinkPlay = Spawn(class'SummerInCallPlay');
         bDataLinkPlaySpawned = True;
      }

      // Call SetConversation(), which returns
      if (datalinkPlay.SetConversation(activeDataLink))
      {
         datalinkPlay.SetTrigger(datalinkTrigger);

         if (datalinkPlay.StartConversation(Self))
         {
            return True;
         }
         else
         {
            // Datalink must already be playing, or in queue
            if (bDataLinkPlaySpawned)
            {
               datalinkPlay.Destroy();
               datalinkPlay = None;
            }
            
            return False;
         }
      }
      else
      {
         // Datalink must already be playing, or in queue
         if (bDataLinkPlaySpawned)
         {
            datalinkPlay.Destroy();
            datalinkPlay = None;
         }
         return False;
      }
   }
   else
   {
      return False;
   }
}


Next I have an InCall Trigger:

//=============================================================================
// DataLinkTrigger.
//=============================================================================
class SummerInCallTrigger extends DataLinkTrigger;


// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
defaultproperties
{
checkFlagTimer=1.00
bTriggerOnceOnly=True
CollisionRadius=96.00
}
Code: Select all

[/spoiler]

Then I have SummerInCallPlay instead of DatalinkPlay:
[spoiler]
Code: Select all
//=============================================================================
// SummerInCallPlay
//=============================================================================
class SummerInCallPlay expands DataLinkPlay;



var SummerHUDInCallDisplay SummerHUDInCallDisplay;             // Window that displays the datalink


// ----------------------------------------------------------------------
// SetConversation()
//
// Sets the conversation to be played.  Returns True if successful
// ----------------------------------------------------------------------

function bool SetConversation( Conversation newCon )
{
   local bool bConSet;

   // If this is the first conversation, then
   // set the 'con' variable.

   bConSet = False;

   if ((con == None) && (SummerHUDInCallDisplay == None))
   {
      startCon = newCon;
      con      = newCon;
      bConSet  = True;
   }
   else
   {
      if (PushDataLink(newCon) && (SummerHUDInCallDisplay != None))
      {
         SummerHUDInCallDisplay.MessageQueued(True);
         bConSet = True;
      }
   }

   return bConSet;
}

// ----------------------------------------------------------------------
// SetTrigger()
// ----------------------------------------------------------------------

function SetTrigger(datalinkTrigger newDatalinkTrigger)
{
   SummerInCallTrigger = newDatalinkTrigger;
}

// ----------------------------------------------------------------------
// StartConversation()
//
// Starts a conversation. 
//
// 1.  Initializes the Windowing system
// 2.  Gets a pointer to the first Event
// 3.  Jumps into the 'PlayEvent' state
// ----------------------------------------------------------------------

function Bool StartConversation(DeusExPlayer newPlayer, optional Actor newInvokeActor, optional bool bForcePlay)
{
   local Actor tempActor;

   if ( Super.StartConversation(newPlayer, newInvokeActor, bForcePlay) == False )
      return False;

   // Create the DataLink display if necessary.  If it already exists,
   // then we're presently in a DataLink and need to queue this one up
   // for play after the current DataLink is finished.
   //
   // Don't play the DataLink if
   //
   // 1.  A First-person conversation is currently playing
   // 2.  Player is rooting around inside a computer
   //
   // In these cases we'll just queue it up instead

   if ( ( SummerHUDInCallDisplay == None ) &&
       ((player.conPlay == None) && (NetworkTerminal(rootWindow.GetTopWindow()) == None)))
   {
      lastSpeechTextLength = 0;
      bEndTransmission = False;
      eventTimer = 0;

      SummerHUDInCallDisplay = rootWindow.hud.CreateInfoLinkWindow();

      if ( dataLinkQueue[0] != None )
         SummerHUDInCallDisplay.MessageQueued(True);
   }
   else
   {
      return True;
   }

   // Grab the first event!
   currentEvent = con.eventList;

   // Create the history object.  Passing in True means
   // this is an InfoLink conversation.
   SetupHistory(GetDisplayName(con.GetFirstSpeakerDisplayName()), True);

   // Play a sound and wait a few seconds before starting
   SummerHUDInCallDisplay.ShowTextCursor(False);
   player.PlaySound(startSound, SLOT_None);
   bStartTransmission = True;
   SetTimer(blinkRate, True);
   return True;
}
   
// ----------------------------------------------------------------------
// TerminateConversation()
// ----------------------------------------------------------------------

function TerminateConversation(optional bool bContinueSpeech, optional bool bNoPlayedFlag)
{
   // Make sure sound is no longer playing
   player.StopSound(playingSoundId);

   // Save the DataLink history
   if ((history != None) && (player != None))
   {
      history.next = player.conHistory;
      player.conHistory = history;
      history = None;      // in case we get called more than once!!
   }

   SetTimer(blinkRate, True);

   if ((SummerHUDInCallDisplay != None) && (SummerHUDInCallDisplay.winName != None))
      SummerHUDInCallDisplay.winName.SetText(EndTransmission);

   bEndTransmission = True;

   // Notify the trigger that we've finished
   NotifyDatalinkTrigger();

   Super.TerminateConversation(bContinueSpeech, bNoPlayedFlag);
}

// ----------------------------------------------------------------------
// NotifyDatalinkTrigger()
// ----------------------------------------------------------------------

function NotifyDatalinkTrigger()
{
    if (datalinkTrigger != None)
      datalinkTrigger.DatalinkFinished();
}

// ----------------------------------------------------------------------
// AbortDataLink()
//
// Aborts the current datalink playing immediately
// ----------------------------------------------------------------------

function AbortDataLink()
{
   // Make sure there's no audio playing
   player.StopSound(playingSoundId);

   GotoState('');

   SetTimer(0.0, False);

   if (SummerHUDInCallDisplay != None)
   {
      rootWindow.hud.DestroyInfoLinkWindow();
      SummerHUDInCallDisplay = None;

      // Put the currently playing DataLink at the front of the queue,
      // but *only* if the bEndTransmission flag isn't set (which means
      // we're just waiting for the "END TRANSMISSION" pause at the end
      // of a DataLink).

      if (!bEndTransmission)
         InsertDataLink(con);   
   }

   con          = None;
   currentEvent = None;
   lastEvent    = None;
}

// ----------------------------------------------------------------------
// ResumeDataLinks()
//
// Resumes aborted and queued DataLinks
// ----------------------------------------------------------------------

function ResumeDataLinks()
{
   SetConversation(PopDataLink());

   if ( con != None )
   {
      StartConversation(player, invokeActor);
   }
   else
   {
      if (SummerHUDInCallDisplay != None)
      {
         rootWindow.hud.DestroyInfoLinkWindow();
         SummerHUDInCallDisplay = None;
      }
      player.datalinkPlay = None;
      Destroy();
   }
}



// ----------------------------------------------------------------------
// PushDataLink()
//
// Queues a DataLink for play after the current DataLink is complete.
// ----------------------------------------------------------------------

function bool PushDataLink( Conversation queueCon )
{
   local Int queueIndex;
   local Bool bPushed;

   bPushed = False;

   // If this is the currently playing datalink, don't requeue it
   //
   // We're using the startCon variable, as we want to check the
   // conversation that was -started initially-, as opposed to a
   // conversation that was -jumped into-.

   if ( queueCon == startCon )
      return bPushed;
      
   // Now push this conversation on the stack
   for( queueIndex=0; queueIndex<8; queueIndex++ )
   {
      // If this conversation is already in the queue,
      // don't queue it again
      if ( dataLinkQueue[queueIndex] == queueCon )
         break;

      if ( dataLinkQueue[queueIndex] == None )
      {
         dataLinkQueue[queueIndex] = queueCon;
         bPushed = True;
         break;
      }
   }

   return bPushed;
}

// ----------------------------------------------------------------------
// PopDataLink()
//
// Pops a DataLink conversation off the stack.  If there are no
// DataLinks available, returns None
// ----------------------------------------------------------------------

function Conversation PopDataLink()
{
   local Conversation conResult;
   local Int queueIndex;

   conResult = None;

   if ( dataLinkQueue[0] != None )
   {
      // Save a pointer to the first entry and move the
      // others down.
      conResult = dataLinkQueue[0];
   
      for( queueIndex=0; queueIndex<7> startDelay )
      {
         bStartTransmission = False;
         eventTimer = 0.0;
         SetTimer(0.0, False);

         SummerHUDInCallDisplay.ShowTextCursor(True);

         // Play this event!
         GotoState('PlayEvent');
      }
   }
   else if (bEndTransmission)
   {
      SummerHUDInCallDisplay.winName.Show(!SummerHUDInCallDisplay.winName.IsVisible());

      if ( eventTimer > endDelay )
      {
         SetTimer(0.0, False);
         bEndTransmission = False;
         rootWindow.hud.DestroyInfoLinkWindow();
         SummerHUDInCallDisplay = None;

         // Check to see if there's another DataLink to trigger
         if ( FireNextDataLink() == False )
         {
            player.datalinkPlay = None;
            Destroy();
         }
      }
   }
}




// ----------------------------------------------------------------------------
// All the unique Setup routines for each event type are located here
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------
// SetupEventSpeech()
//
// Display the speech and wait for feedback.
// ----------------------------------------------------------------------

function EEventAction SetupEventSpeech( ConEventSpeech event, out String nextLabel )
{
   local EEventAction nextAction;
   local ConEvent checkEvent;
   local String speech;

   // Keep track of the last speaker
   lastActor = event.speaker;

   // Display the first speech chunk.
   speech = event.conSpeech.speech;

   if (!bSilent)
   {
      // If we're continuing from the last speech, then we want to Append
      // and not Display the first chunk.
      if ( event.bContinued == True )
      {
         SummerHUDInCallDisplay.AppendText(speech);
      }
      else
      {
         // Clear the window, set the name of the currently speaking
         // actor and then start displaying the speech.

         SummerHUDInCallDisplay.ClearScreen();
         SummerHUDInCallDisplay.SetSpeaker(event.speakerName, GetDisplayName(event.speakerName));
         SummerHUDInCallDisplay.ShowPortrait();
         SummerHUDInCallDisplay.DisplayText(speech);

         lastSpeechTextLength = len(speech);
      }
   }

   // Save this event in the history
   AddHistoryEvent(GetDisplayName(event.speakerName), event.conSpeech );

   nextAction = EA_WaitForSpeech;
   nextLabel = "";
   return nextAction;
}


// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
defaultproperties
{
    startSound=Sound'SummerSound.UserInterface.InCall'
    blinkRate=0.50
    startDelay=1.50
    endDelay=1.00
    perCharDelay=0.03
    infoLinkNames(0)=(BindName="AlexJacobson",displayName="Alex Jacobson"),
    infoLinkNames(1)=(BindName="AnnaNavarre",displayName="Anna Navarre"),
    infoLinkNames(2)=(BindName="BobPage",displayName="Bob Page"),
    infoLinkNames(3)=(BindName="BobPageAug",displayName="Bob Page"),
    infoLinkNames(4)=(BindName="Daedalus",displayName="Daedalus"),
    infoLinkNames(5)=(BindName="GarySavage",displayName="Gary Savage"),
    infoLinkNames(6)=(BindName="GuntherHermann",displayName="Gunther Hermann"),
    infoLinkNames(7)=(BindName="Helios",displayName="Helios"),
    infoLinkNames(8)=(BindName="Icarus",displayName="Icarus"),
    infoLinkNames(9)=(BindName="JaimeReyes",displayName="Jaime Reyes"),
    infoLinkNames(10)=(BindName="Jock",displayName="Jock"),
    infoLinkNames(11)=(BindName="MorganEverett",displayName="Morgan Everett"),
    infoLinkNames(12)=(BindName="PaulDenton",displayName="Paul Denton"),
    infoLinkNames(13)=(BindName="SamCarter",displayName="Sam Carter"),
    infoLinkNames(14)=(BindName="StantonDowd",displayName="Stanton Dowd"),
    infoLinkNames(15)=(BindName="TracerTong",displayName="Tracer Tong"),
    infoLinkNames(16)=(BindName="WaltonSimons",displayName="Walton Simons"),
    EndTransmission="END OF CALL..."
    bHidden=True
}   
[/spoiler]

And lastly SummerHUDInCallDisplay, instead of datalink display:
[spoiler]
Code: Select all
//=============================================================================
// SummerHUDInCallDisplay
//=============================================================================
class SummerHUDInCallDisplay expands HUDInfoLinKDisplay;



// ----------------------------------------------------------------------
// ShowDatalinkIcon()
// ----------------------------------------------------------------------

function ShowDatalinkIcon(bool bShow)
{
   winPortrait.SetBackground(Texture'SummerInCallIcon');
   winPortrait.SetBackgroundStyle(DSTY_Masked);
}


// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
defaultproperties
{
    FontName=Font'DeusExUI.FontMenuHeaders_DS'
    fontText=Font'DeusExUI.FontFixedWidthSmall_DS'
    fontTextX=7
    fontTextY=10
    texBackgrounds(0)=Texture'DeusExUI.UserInterface.HUDInfolinkBackground_1'
    texBackgrounds(1)=Texture'DeusExUI.UserInterface.HUDInfolinkBackground_2'
    texBorders(0)=Texture'DeusExUI.UserInterface.HUDInfolinkBorder_1'
    texBorders(1)=Texture'DeusExUI.UserInterface.HUDInfolinkBorder_2'
    strQueued="Caller on hold..."
    IncomingTransmission="INCOMING CALL..."
}
[/spoiler]

I am getting a lot of problems including type mismatch on line 88 of incall play, bad or missing expression on line 50 etc. I am still new to coding, but I thought replacing datalink with in call and inheriting the datalink function would allow me to do both incoming and outgoing calls like in DX3.

Input would be appreciated :)

PostPosted: Sun Feb 19, 12 1:00 am
by Dae
We would be happy to help you on condition that you do your homework, narrow down the problem(s) and ask them as concisely and detailed as possible. If there are several problems/questions, make sure to separate them.

Not only that would raise your chances to awake interest of the visitors here, but also perhaps help you gain some experience in programming.

This is how programming help works here, this is how it works everywhere else.

PostPosted: Mon Feb 20, 12 12:53 pm
by SimonDenton
Thanks for the advice Dae :D

I am attempting to make two distink datalink types, incoming and outgoing. The same mechanics of datalink transmissions are preserved, the only difference is with the icons and starting sounds. To do this I need nice and simple triggers for both types of datalinks, player class functions for each, a datalink play of each and a hud display class. My problem is that simply replacing datalink with "Incall" and "Outcall" while extending the original Datalink functions is not getting me anywhere. I feel I need assistance to understand the logic behind it and face the endless type mismatch/bad expression errors.