Help with pointers for a dialogue system [SOLVED]

Started by newwaveburritos, Mon 15/08/2022 01:57:29

Previous topic - Next topic

newwaveburritos

Okay, I've got an idea for an icon based dialogue system which I wish to use in addition to the standard Monkey Island-esque dialogue system of the BASS template.  That is, inside of a regular dialogue when you choose an option that will exit the dialogue and enter this new phase of dialogue which will be the player asking about a character.  You'll scroll through the various icons until you find the character you want and then click it.  It looks like this:



In this instance we're talking to the Robot about the Mummy.  So, we have here two pieces of information we need to pass on.  Who we're talking to, and who we're talking about.  I was thinking it would be best to have a big switch case so that it's all in the same place and I can see everything and read everything and add the dialogue or instruction easily in one organized place.  But before we get that far let me show you the scrolling GUI where we choose the character icon because I know we're going to have to use that to pass on the character's icon the player chooses.  It's the same button, I'm just going through the views in order to animate it.

Code: ags

function ScrollLeft()
{
  BackgroundGraphic--;
  if (BackgroundGraphic==-1){
    BackgroundGraphic=7;
  }
    switch (BackgroundGraphic)
    {
      case 0:
        
        btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock); //cDracula
       
        break;
      
        
      case 1:
      
        btnCharacterChoice.Animate(43, 0, 5, eRepeat, eNoBlock); //cFrank
        break;
      
      case 2:
      
        btnCharacterChoice.Animate(44, 0, 5, eRepeat, eNoBlock);  //cMummy
        break;
      
      case 3:
      
        btnCharacterChoice.Animate(45, 0, 5, eRepeat, eNoBlock); //cPhantom
        break;
      
      case 4:
      
        btnCharacterChoice.Animate(46, 0, 5, eRepeat, eNoBlock);  //cWolfie
        break;
      
      case 5:
      
        btnCharacterChoice.Animate(78, 0, 5, eRepeat, eNoBlock);  //cYoko
        break;
      
      case 6:
      
        btnCharacterChoice.Animate(79, 0, 5, eRepeat, eNoBlock);  //cRobot
        break;
      
      case 7:
       
        btnCharacterChoice.Animate(41, 0, 5, eRepeat, eNoBlock);  //cAlien
        break;
      
      case 8:
      BackgroundGraphic=0;
      break;
    }
}


function ScrollRight()
{
  BackgroundGraphic++;
  if (BackgroundGraphic==8){
    BackgroundGraphic=0;
  }
    switch (BackgroundGraphic)
    {
      case 0:
        
        btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock);
        
        break;
      
      case 1:
      
        btnCharacterChoice.Animate(43, 0, 5, eRepeat, eNoBlock);
       
        break;
      
      case 2:
      
        btnCharacterChoice.Animate(44, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 3:
      
        btnCharacterChoice.Animate(45, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 4:
      
        btnCharacterChoice.Animate(46, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 5:
      
        btnCharacterChoice.Animate(78, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 6:
      
        btnCharacterChoice.Animate(79, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 7:
        
        btnCharacterChoice.Animate(41, 0, 5, eRepeat, eNoBlock);
        break;
    
    }
}


That's all well and good and works fine, it just doesn't do anything right now. The function to open the GUI is where I start to get lost.  I think it should look something like this:

Code: ags

Character* thisIsWho;
function openCharacterGUI(Character* whoImTalkingTo)
{
  gCharacters.X=player.x-20;
  gCharacters.Y=player.y-90;
  btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock);  //starts the animation since we have to start it before we can open it
  thisIsWho = whoImTalkingTo;
  gCharacters.Visible = true;  //this is the name of the GUI open in the screenshot.
}


What I think this does is pass along the pointer of who I'm talking to and I'll call this inside each character's dialogue.  That is, when I click from dRobot00 I'll call:

Code: ags

openCharacterGUI(cRobot);


Then I have the big switch case.

Code: ags

function talkToChar(Character* talkAbout)
{
  
  switch(talkAbout)
  {
   case cAlien:
      switch(thisIsWho) //this is who I'm talking to
      {
        case cAlien:
        //talking to Frankenstein about the Alien
        break;
        case cDracula:
        player.Say("Tell me about Dracula.");
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        player.Say("Tell me about The Alien!");
        break;
      }
    break;
    
   case cDracula:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Dracula about the Alien
        player.Say("Tell me about Dracula!");
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cFrank:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Frankenstein about the Alien
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cMummy:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Mummy about the Alien
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cPhantom:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Phantom about the Alien
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cWolfie:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Wolfie about the Alien
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cYoko:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to BrunchLadies about the Alien
        break;
        case cDracula:
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
    
    case cRobot:
      switch(thisIsWho)
      {
        case cAlien:
        //talking to Robot about the Alien
        break;
        case cDracula:
        cRobot.Say("Dracula!");
        break;
        case cFrank:
        break;
        case cMummy:
        break;
        case cPhantom:
        break;
        case cWolfie:
        break;
        case cYoko:
        break;
        case cRobot:
        break;
      }
    break;
  }    
}


So, what I think is I should have a similar function to the one that opens the GUI to close it that tells the switch case who the player clicked on.  And actually, I think maybe I don't want a function at all there or maybe one that returns something?  That's where it all falls apart for me but the theory of that switch case being a shelf to put answers on is really appealing to me. 

Well, thanks everybody!

EDIT: I think I have the comments on my switch case backwards.

eri0o

I am a bit unsure on what is working and what is not working...

In any case, a little trick I use in AGS is to create inventory items not just for inventory items, but for other things, like conversation topics, and then have dummy characters for the different inventory categories, then it's just changing to who the inventory is wired to, using an extra button for that, and then using an inventory item or asking about something, is all through inventory handling.

newwaveburritos

I think the part that isn't working is this:

Code: ags

function openCharacterGUI(Character* thisIsWho)
{
  gCharacters.X=player.x-20;
  gCharacters.Y=player.y-90;
  btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock);  //starts the animation
  thisIsWho = WhoAmITalkingTo;
  gCharacters.Visible = true;
}


When I put
Code: ags
openCharacterGUI(cRobot);
at the appropriate place in the dialog it doesn't work.  Nothing happens.  When I put
Code: ags
WhoAmITalkingTo=cRobot;
above the function it does.  WhoAmITalkingTo is a global characater variable as is WhoAmITalkingAbout.

eri0o

In openCharacterGUI(Character* thisIsWho) you have reversed how assigning to a variable works, it's right assigns to left of the equal sign, not the reverse - if I understood what you are trying to achieve.

newwaveburritos

Oh, yes, I think you're right.  When I swap those two and it works as intended.  I think this whole mess is working now like I envisioned it.  Thanks a million!

newwaveburritos

Okay, one thing I failed to account for is that it doesn't make sense to have a whole list of characters available to you at game start since you haven't met anybody yet so it makes sense to populate the thing as you meet the characters.  I think that I'll have to do this with the scrolling system.  The characters get added to a set which is how I am tracking who you have met.  BackgroundGraphic is just an int so you could feasibly change that int based on the number of entries in the set CharactersMet but I feel like there's a better option here that I'm just not thinking of.

Here's the scrolling code:

Code: ags


function ScrollLeft()
{
  BackgroundGraphic--;
  if (BackgroundGraphic==-1){
    BackgroundGraphic=7;
  }
    switch (BackgroundGraphic)
    {
      case 0:
        
        btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock);
       
        break;
      
      case 1:
      
        btnCharacterChoice.Animate(43, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 2:
      
        btnCharacterChoice.Animate(44, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 3:
      
        btnCharacterChoice.Animate(45, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 4:
      
        btnCharacterChoice.Animate(46, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 5:
      
        btnCharacterChoice.Animate(78, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 6:
      
        btnCharacterChoice.Animate(79, 0, 5, eRepeat, eNoBlock);
        break;
      
      case 7:
       
        btnCharacterChoice.Animate(41, 0, 5, eRepeat, eNoBlock);
        break;
      
    }
}


function ScrollRight()
{
  BackgroundGraphic++;
  if (BackgroundGraphic==8){
    BackgroundGraphic=0;
  }
    switch (BackgroundGraphic)
    {
      case 0:
        
        btnCharacterChoice.Animate(42, 0, 5, eRepeat, eNoBlock);
        labelWhoAmITalkingAbout.Text=String.Format("Dracula!");
        WhoAmITalkingAbout=cDracula;
        break;
      
      case 1:
      
        btnCharacterChoice.Animate(43, 0, 5, eRepeat, eNoBlock);
       WhoAmITalkingAbout=cFrank;
        break;
      
      case 2:
      
        btnCharacterChoice.Animate(44, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cMummy;
        break;
      
      case 3:
      
        btnCharacterChoice.Animate(45, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cPhantom;
        break;
      
      case 4:
      
        btnCharacterChoice.Animate(46, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cWolfie;
        break;
      
      case 5:
      
        btnCharacterChoice.Animate(78, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cYoko;
        break;
      
      case 6:
      
        btnCharacterChoice.Animate(79, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cRobot;
        break;
      
      case 7:
        
        btnCharacterChoice.Animate(41, 0, 5, eRepeat, eNoBlock);
        WhoAmITalkingAbout=cAlien;
        break;
    
    }
}


newwaveburritos

I've made a little progress.  I think what I'm looking for is something along the lines of:

Code: ags

BackgroundGraphic=CharactersMet.ItemCount;
    BackgroundGraphic++;
    if (BackgroundGraphic==CharactersMet.ItemCount){
      BackgroundGraphic=0;
    }


This will make it so that the background image of the button has the right number of options but I'm having trouble wrapping my head around how to set each of those to the proper character since you could meet them in any order, essentially.  I'm halfway tempted just to make the intro a big monster party so you meet everyone at once!

Code: ags

if (CharactersMet.Contains("Dracula")){
//enable Dracula's button etc. etc.
}
[code]

newwaveburritos

#7
Okay, with a LOT of help from timiddolphin this problem can be marked as solved.  For anybody following along now or in the future here is the code that makes the scrolling work.  This is predicated on the other code higher so it may not work for you out of the box but it can certainly be taken as an example.  I think everything that makes it work is in the thread here, though.

Code: ags

int buttonGraph[16];  //this is the number of total characters +1, by the way.

function initButtonGraph()
{
  //runs in game-start,  sets every slot in the array to 0.
  for (int i = 0; i < Game.CharacterCount; i++)
  {
    buttonGraph[i] = 0;
  }
}

function setFirstButtonGraphIndex(int theGraphic)
{
  for (int i = 0; i < 15; i++)
  {
    if(buttonGraph[i] == 0)
    {
      buttonGraph[i] = theGraphic; //sets the first 0 it finds to the graphic you put into this function
      return;
    }
  }
}

int scrollPosition = 0;

int findMaxScrollPosition()
{
  for (int i = 15; i > -1; i--)
  {
    if(buttonGraph[i] != 0)
    {
      return i;
    }
  }
  return 0;
}

function ScrollLeft()
{
  if(scrollPosition == 0)
  {
    scrollPosition = findMaxScrollPosition();
  } else {
    scrollPosition--;
  }
  btnCharacterChoice.Animate(buttonGraph[scrollPosition], 0, 5, eRepeat, eNoBlock);
}

function ScrollRight()
{
  if(scrollPosition == findMaxScrollPosition())
  {
    scrollPosition = 0;
  } else {
    scrollPosition++;
  }
  btnCharacterChoice.Animate(buttonGraph[scrollPosition], 0, 5, eRepeat, eNoBlock);
}



//===========================================


function game_start()
{
  initButtonGraph();
  setFirstButtonGraphIndex(42);  //you'll probably want to call these as you click on a character wherever your clicks are handled.
  setFirstButtonGraphIndex(43);
  setFirstButtonGraphIndex(44);
}

SMF spam blocked by CleanTalk