Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - bulka_tarta

#21
Ha, that was simple enough! It all works like a dream now :D

Thanks for the tips!

Oh, and sorry for being such a pain in the lower back :P
#22
Yes, it's all working!  :-D

I'm currently working out how how to add more message to the active chat though. So for example, I start the chat with couple of messages. Later, the player does x,y and z, and I want to add more messages to the chat to continue the dialogue. I'm also working on simple "yes" or "no" dialogue options - or in other words, if player clicks button "X", the chat will display "abc". If player clicks "Y", chat displays "123".

The thing is... If I simply do "Chat.Add" it clears all the messages and creates new ones. Same thing if I do "Chat.Prepare" and then "Chat.Advance".  I only want the chat to clear, and start a new one (with a different character), once I tell it to.

Anyway, I think I should be able to work something out.
#23
I think I need a little break, haha. I went over these lines so many times, I could no longer spot the difference.

I have set up the structs like they should be (well, hopefully) and everything works just fine!
Thank you!
#24
Yes, I just caught myself on that too!

When I try putting this stuff together I get an error though "Failed to save room room1.crm; details below
Clients.ash(-10): Error (line unknown): ';' expected (cannot define body of imported function)".

How can you have "line -10"? My .ash file for the script is below.

I set the identifier to #define MAX_CLIENTS 2 (just for testing).
Since I want this to be in a separate script, I did some searching and I figured that you need to set up a struct in header of the script.
Code: ags
//.ash file
#define MAX_CLIENTS 2

struct Client {
  String name;
  String address;
  int clientPhoto;
};

import Client clients[MAX_CLIENTS];
import function setupClients();


Code: ags

//.asc file
Client clients[MAX_CLIENTS];
int clientCount=0;

bool addClient(String name, String address)
{
  if(clientCount+1 >= MAX_CLIENTS)    // We've run out of array space, can't add any more
    return false;
  clients[clientCount].name = name;
  clients[clientCount].address = address;
 
  clientCount++;
}
 
void setupClients()
{
  addClient("John Smith", "Burger Street");
  addClient("Johnny Smith", "Ketchup is not down");
}



EDIT: I was missing ; at the end of "import bool addClient(String name, String address)" which gave the negative number in the error. I fixed that, however I get an error which I originally wanted to mention, before I got that "line -10". It says "Size of identifier does not match prototype" on the "void setupClients()" line. I can't figure out how, since I declare 2 max clients and add exactly that number of clients to set up...
#25
Awesome, thanks for the explanations!

In that case I will have a go at putting my arrays into structs.



Thanks again!
#26
Hey thanks,

So what would be a difference between having a struct like this:
Code: ags
 //Client Details
client[0].Name = "Smith John";
client[0].Photo = 28;
 
client[1].Name = "Bob the Builder";
client[1].Photo = 29;


and just set of arrays like this:
Code: ags
//Client Details
clientName[0] = "Smith John";
clientPhoto[0] = 28;
 
clientName[1] = "Bob the Builder";
clientPhoto[1] = 29;


For me (someone new to programming) it seems like it's achieving the same thing. Is there anything performance-related that I should be concerned about?

As for calling the function, I wasn't aware that you can do this, thanks!
#27
Hey, thanks for the replies everyone.

Structs are the way I wanted to go with, however I don't see (or understand?) the advantage of using them (at least in my scenario).

What I have set up at the moment is something similar to Khris' suggestion. I have a bunch of Arrays, however I don't call them in as a function like this:
Code: ags
 SetClient(0, "John Smith", 29, ...);
  SetClient(1, "Johnny Smithy", 30, ...);
  // ...


but I rather declare each array separately, and then call it at the game_start:
Code: ags

function ClientInfo()
{ 
//Client Details
clientName[0] = "Smith John";
clientPhoto[0] = 28;

clientName[1] = "Bob the Builder";
clientPhoto[1] = 29;

//etc...


This is because I have quite a lot of info to add for each of the characters, and having a function with all the info in one line would be really difficult to read and manage for me later on.

Originally I hoped that structs would allow my to do something like this:
Code: ags
Client[0]{
Name;
Photo;
Balance;
}

Client[1]{
Name;
Photo;
Balance;
}

//etc...

So basically with no need to name each variable with "[1], [2], [3]", but rather just state the number at the top of the struct. I looked at the manual and it seems like this isn't quite how the structs work and that you still need to call each variable separately (weapon[0], weapon[1] etc...), so I may just stick to what I have at the moment. As I mentioned, it would be much easier to add and edit info if I had a line by line structure.
#28
Ok... WOW. A huge thanks to Khris, this is incredible!

With my last post, I thought I am getting better at programming, and that maybe I will eventually get this to work, but I didn't expect someone to actually create a module like this!

I saw the module yesterday morning, and I wanted to check it out so bad I couldn't wait until I finish work. When I sat down and tried to get it to work... Let's just say I had some problems. I didn't want to say anything on the forums, as I was embarrassed that I can't even get a module to work (apparently I'm not getting better at programming at all :P).

Anyway, I got it to work in the end (witchcraft? luck?), and I'm planning to dissect it over the weekend, hopefully learning something in the process.

Huge thanks, once again! I'm going to dig in into AGS now and maybe make something cool one day!


EDIT:
Ekhem.. So I went to try and create a new room with the chat dialogue and all I get is just a button with standard graphic displaying. To test if I'm not missing anything, I copied and pasted the code from the room where I got it actually working, but it just doesn't like the new room (same code works in the first room).

Spoiler

Code: ags
int chatOne;
String me, ma;

function room_Load()
{
  player.y = 0;
  
  chatOne = Chat.Create(btnChat, eFontFont3, 41);
  
  me = "*Tom";
  ma = "Jerry";
  
  Chat.Prepare(chatOne, "12321321312321",me);
  Chat.Prepare(chatOne, "vgdcvbdfbvdfbfbdfbdfb", ma);
  Chat.Prepare(chatOne, "13213213213213213213", me);
  Chat.Prepare(chatOne, "fgdfgdfgdfgdfgdfgda", ma);
  Chat.Prepare(chatOne, "3423423", me);
}

function room_RepExec()
{
String lm, nm;
  if (IsTimerExpired(1)) {
    Chat.Advance(chatOne);
    lm = Chat.GetLastMessage(chatOne);
    nm = Chat.GetNextMessage(chatOne);
    if (nm != null) SetTimer(1, (GetGameSpeed() * (lm.Length + nm.Length)) / 20);
    else SetTimer(2, 80);
  }
}
[close]

I followed the module instructions, and I also followed the example room code. The above works like it should in one room, but it doesn't work at all in another. I don't get any error messages, the chat is just not displaying.
Also... When I tried copying the example room script into one of the rooms I get error: "Unable to create local script: Runtime error: unresolved import 'btnFirstChat'" - I made a GUI that includes a "btnFirstChat" button, so it shouldn't be causing a problem...

Anyway, I feel bad enough for taking Khris' time to do the module, so I will try and work out what the problem depends on - I got it working once, so I can do this again! <extremely determined>

EDIT2: This is really silly. Whenever I do a script in a new room, I did copy the code over, but I forgot to set up the right Events on the room properties - sorry about that!!!
#29
I'm getting defeated by this every day  :~(

That's what my latest efforts managed to produce:  (warning, contains flashing images) http://i.imgur.com/COIKvNW.gifv
Well, at least it made me laugh when I first saw that bug :P

Code: ags

DynamicSprite* msgDS;
String msgText[50];
int msgIndex;
int textIndex;
int chatY;

export msgDS;
export msgText;
export msgIndex;
export textIndex;
export chatY;

//setting up the text strings
//called in on game_start
function msgReady() {
  textIndex = 0;
  
  while (textIndex < 49){
    msgText[textIndex] = "123";
    textIndex ++;
 }
}

//if in repeatedly execute, it creates the abomination from the link above
//if in game_start just shows the AGS cup (default AGS image)
function msgChat(){
 msgIndex = 0;
 chatY = 0;
 
 msgDS = DynamicSprite.Create(System.ViewportWidth, System.ViewportHeight);

 DynamicSprite *windowSprite = DynamicSprite.CreateFromExistingSprite(msgDS.Graphic);
 windowSprite.Crop(10, chatY, 10, 10);
 gDynamic.BackgroundGraphic = windowSprite.Graphic;
 DrawingSurface *surface = msgDS.GetDrawingSurface();
 
 while (msgIndex < 49){
 surface.DrawStringWrapped(10, msgIndex *10, 100, Game.NormalFont, eAlignLeft, msgText[msgIndex]);
 msgIndex ++;
 }
 
 surface.Release();
 windowSprite.Delete();
}



I'm not sure what I'm doing wrong. I know Khris has mentioned setting up Array for the DynamiSprite (msgDS) but that complicates things even more for me. I once even crashed AGS completely (white screen when playing the game, Alt+F4 doesn't work - crazy stuff!). I'm going to keep trying with this, but meanwhile maybe someone has an idea of why it messes up so badly.


EDIT: the only way I manged to get it to work was by drawing all the messages at once (as previously) and simply placing another GUI on top. The GUI would basically look like the game's background, but it had a hole in the middle, where the text would show through. It's really a quick cheat, I'm not sure how bad it would be to actually use it like this.
#30
Thanks! I will check out the solution as soon as I can.

Regarding how it should look like, it would be kind of a merge between Mainlining chat (as on example earlier) and something like Papers, Please. Here's a quick mock up:

Messages would go from the bottom to top of the screen, but only a certain part in the middle (more or less) would be visible - just enough space to show about 3 messages. Ideally, the player should be able to scroll (like in Mainlining) to see the previous messages if needed.

If there's a new message, it would ideally push all the other ones up by one "block" (one message height).

What I have at the moment, is that the "visible message area" is actually going up with the GUI, and I need it to stay in the one place, while pushing the messages higher.


I'm not sure if that would change your current suggestion Khris, but I will give it a go tomorrow and see what I can do with it. Thanks! :)
#31
O...K...

I (somehow?!) managed to display all the messages on screen at the same time (well, at least ten of them for testing).
Code: ags

//called in on Game Start, global script
function msgChat(){
  msgIndex = 0;
  msgOn = 0;
 
  Test = DynamicSprite.Create(200, 500);
  Test.Crop(0, 0, 150, 50);               //can't work out these numbers, but works oO
  TestSurface = Test.GetDrawingSurface();
  gDynamic.BackgroundGraphic = Test.Graphic;

  while (msgOn < 49){
    msgText[msgOn] = "123";
    msgOn ++;
  }
}

//triggered by a button
function msgChatRelease(){
  if (dialogOn == false){
  TestSurface.DrawingColor = 14;
    while (chatCount < 49){
    TestSurface.DrawStringWrapped(10, chatCount * 20, 200, Game.NormalFont, eAlignLeft, msgText[chatCount]); 
    chatCount ++;
    }
  }

  dialogOn = true;
  
  if (dialogOn == true){
  TestSurface.Release();
  }
}


Above code does (almost!) all I needed. I get ten messages displayed when I hit the button in the scene. The crop works, so that I can display just the part that I'm actually interested in. Moving the GUI around... is not as simple as I thought it would be...

This...
Code: ags

if (gDynamic.Visible && gDynamic.Y > 0) gDynamic.Y -= 1;


Moves the entire GUI with all of the messages AND the crop. This means that it doesn't show "more messages" just moves the ones visible to the top of the screen. I need to find a way to lock the Cropped area or the Dynamic Sprite in place when the GUI is moving, or move the DynamicSprite without moving the GUI. Any idea how to approach this? In the manual I found "Resize (dynamic sprite)" and "Rotate (dynamic sprite)" - why is there no simply "Move (dynamic sprite)" ;(

EDIT: Just for clarification, I'm not thinking of doing a chat dialogue exactly as in the example in first post (full screen height). I need to crop just a small portion of the screen - I'm intending to make it look like a window on your desktop, so to speak.
#32
When I thought I get this, I get stuck again (you're dealing with first-time programmer here, sorry :P).

Code: ags

DynamicSprite* msgDS[50];   //changed 50 DrawingSurfaces into 50 DynamicSprites
DrawingSurface* msgSurface;
int msgOn;
String msgText[50];
int msgIndex;

export msgDS;
export msgSurface;
export msgOn;
export msgText;
export msgIndex;

function msgChat(){
  msgIndex = 0;
  
//sets up all of the DynamicSprites
//makes most sense to put it in Game Start, to set up the sprites inititally
  while (msgIndex < 49){     
  msgDS[msgIndex] = DynamicSprite.Create(100, 50);   
  gDynamic.BackgroundGraphic = msgDS[msgIndex].Graphic;  //Is this the problem? Can you have multiple DynamicSprites as one GUI background?
  
  msgOn = 0;
  msgText[msgOn] = "123";  //sets the reference for messages
  
  msgSurface = msgDS[msgIndex].GetDrawingSurface();     
  msgSurface.DrawingColor = 14;          
  msgSurface.DrawStringWrapped(0, msgOn * 20, 200, Game.NormalFont, eAlignLeft, msgText[msgOn]);
  msgIndex ++;
  msgOn ++;
  }
}

function msgChatRelease(){
  if (msgText[msgOn] != "123"){  //if the messaged is changed, release the message
  msgSurface.Release();
  }
}

//separate script, changes the messages, releases them
//triggered through clicking a button
function Dialog01(){
  msgText[0] = "Hii";
  msgText[1] = "I know where you live";
  msgText[2] = "Say goodbye to your fish";
  msgChatRelease();
}



With that code, I would imagine that the messages should display only once the button is clicked. However, all I get is one sprite constantly displayed as "123", which is weird, since I'm not releasing the sprite until I click the button. To my (still pretty limited) understanding, clicking the button should at least change the msgText of the displayed sprite.

Once I get to display all of the messages in correct manner (and once I'm able to edit them), everything should be pretty simple. I imagine the cropping function would be pretty easy to set up:
Code: ags
 msgDS[msgOn].Crop(int x, int y, int width, int height);
And moving the entire GUI shouldn't be a problem too.

EDIT: The only thing that comes to my mind, is that perhaps I can't assign so many different sprites as a one GUI background, and there should be some separate objects/buttons to assign the text to.

EDIT2: So I realized a bunch of things:
1) The "msgOn = 0;" and  "msgText[msgOn] = "123";" need to be outside the while loop, otherwise they both just keep setting themselves back to original values. I have now put them above the while loop, but it triggers error: "Null string referenced" on line 27. I'm not exactly sure how or why...
2) If the gDynamic.BackgroundGraphic is in while loop, it will just keep re-assigning the GUI background to the latest msgDS[].Graphic.
#33
Ok... So I had a little go on attempting to create what Khris suggested.

Code: AGS

DynamicSprite* msgDS;    
DrawingSurface* msgSurface[50];
int msgOn; //to turning on different messages 
String msgText[50];

export msgDS;
export msgSurface;
export msgOn;
export msgText;

//called in in Global Script, repeatedly_execute()
function msgChat(){
  msgDS = DynamicSprite.Create(250, 400);  //long Dynamic Sprite
  gDynamic.BackgroundGraphic = msgDS.Graphic; 
  
  if (msgOn == 1){
  msgSurface[0] = msgDS.GetDrawingSurface();     
  msgSurface[0].DrawingColor = 14;          
  msgSurface[0].DrawStringWrapped(0, 0, 200, Game.NormalFont, eAlignLeft, msgText[0]");
  msgSurface[0].Release();
  }
  
  if (msgOn == 2){
  msgSurface[1] = msgDS.GetDrawingSurface();     
  msgSurface[1].DrawingColor = 14;          
  msgSurface[1].DrawStringWrapped(0, 20, 200, Game.NormalFont, eAlignLeft, msgText[1]);
  msgSurface[1].Release();
  }
  
  if (msgOn == 3){
  msgSurface[2] = msgDS.GetDrawingSurface();     
  msgSurface[2].DrawingColor = 14;          
  msgSurface[2].DrawStringWrapped(0, 40, 200, Game.NormalFont, eAlignLeft, msgText[2]);
  msgSurface[2].Release();
  }
}

//In separate script, intended to be used as dialog editor
function Dialog01(){
  msgText[0] = "Hii";
  msgText[1] = "I know where you live";
  msgText[2] = "Say goodbye to your fish";
}

//Button on click to trigger dialogue
  Dialog01();     //changes the msgText strings
  msgOn = 1;      //supposed to trigger first msgText string
  Wait(40);       //supposed to wait before going to second line...
  msgOn = 2;


As you can see, I combined my previous approach, but with DynamicSprite instead. I do prefer the idea of this (no messing around with the GUI labels), but I still have some problems with the code.
1) Most importantly, it doesn't behave exactly as I would like. The Wait(); function doesn't do much - I was hoping that after button is clicked, I can change msgOn to 1, display first Surface, Wait, Change msgOn to 2, Display another line, etc (I would later add some tweening to get that nicer chat-look). For some reason, what happens instead is that the game waits after clicking the button, and goes straight to "msgOn 2" and skips first line altogether.
2) I understand that creating lots of "if" statements for each msgSurface is not the best way to go about it, but I have no idea how to get started with that "copy Dynamic Sprite" thing.

I do prefer using DynamicSprites over GUI with multiple labels, but I guess I have hit a brick wall at this stage. I will keep digging through the forums, but as usual, any help is greatly appreciated.

#34
Hey, thanks for the tips. I was trying to use GUI with bunch of labels and here's what I have so far:
Code: ags

String chatSay[100]; // I will probably never have 100 chat messages at once, but just in case...
bool messageOn[100];
export chatSay;
export messageOn;

//makes all labels invisible
// called in global script game_start() { 
function ChatInfo(){
  lblMessage1.Visible = false;
  lblMessage2.Visible = false;
  lblMessage3.Visible = false;
  lblMessage4.Visible = false;
  lblMessage5.Visible = false;

//defines all chatSay variables and messageOn bool
  chatSay[0] = "";
  chatSay[1] = "";
  chatSay[2] = "";
  chatSay[3] = "";
  chatSay[4] = "";

  messageOn[0] = false;
  messageOn[1] = false;
  messageOn[2] = false;
  messageOn[3] = false;
  messageOn[4] = false;
}

// setting up the chat labels
// called in global script repeatedly_execute()
function ChatLabels(){
  lblMessage1.Text = chatSay[0];
  lblMessage2.Text = chatSay[1];
  lblMessage3.Text = chatSay[2];
  lblMessage4.Text = chatSay[3];
  lblMessage5.Text = chatSay[4];
}

// not the best way, it will require a lot of If statements :/
// called in global script repeatedly_execute()
function ChatMessage(){
  if (messageOn[0] == true){
    gChatDialog.Visible = true;
    lblMessage1.Visible = true;
  }
  if (chatSay[1] != ""){
    gChatDialog.TweenY(0.2, 10, eEaseLinearTween, eNoBlockTween); // some tweening action to move the boxes around, currently just place holder info
    lblMessage2.Visible = true;
  }
   if (chatSay[2] != ""){
    gChatDialog.TweenY(0.2, 10, eEaseLinearTween, eNoBlockTween);
    lblMessage2.Visible = true;
  }
   if (chatSay[3] != ""){
    gChatDialog.TweenY(0.2, 10, eEaseLinearTween, eNoBlockTween);
    lblMessage3.Visible = true;
  } if (chatSay[4] != ""){
    gChatDialog.TweenY(0.2, 10, eEaseLinearTween, eNoBlockTween);
    lblMessage4.Visible = true;
  }
}

//separate script that would later serve as a dialogue editor
//triggered by pressing a button
function Dialog00(){
  messageOn[0] = true;
  chatSay[0] = "Hii";
  messageOn[1] = true;
  chatSay[1] = "Is this really you?!";
  messageOn[2] = true;
  chatSay[2] = "I know where you live";
  messageOn[3] = true;
  chatSay[3] = "Buahahah";
  messageOn[4] = true;
  chatSay[4] = "Say goodbye to your fish";
}


I have a good feeling (might be very misleading) that this would eventually get me what I wanted. I was also planning on substituting "messageOn" to a global int, that triggers later messages "(if chatCount == 1)lblMessage1.Visible = true; if (chatCount 2, message2 etc"). Before I do that, the current issue is that all of the labels display at the same time after triggering the dialogue. If I insert some "Wait" functions (between variables in "Dialog00()", or between the if statements in "ChatMessage()") all that happens is that after clicking the button (triggers dialogue) the game just waits a while, and later all the labels appear all at once. I realize it's some kind of problem of the order of how things are called, but I have no idea how to get it to wait a little between each label being visible.

Anyway, while I was working on this, I realized that there's a new post on the topic. I will look into the Khris' suggestion and read some more about DrawingSurface commands - I imagine his suggestion would be much more efficient, but I will have to see if I can grasp my head around it.
#35
Hi,

I'm not sure if this is not going to be too advanced for "Beginners Forum", but I'm a beginner (in AGS and programming!) so it felt appropriate to post it here.

I'm trying to get a custom dialogue to look like a chat box, like you could expect in Skype, Facebook Chat or similar.

Key points that I want it (eventually) to include:
- text stays on screen and it's scrollable
- possibility to divide messages into individual boxes (boxes/labels anything)
- possibility for (at least) two variations of the boxes to determine characters
- non-blocking - so perhaps some kind of a backgroundSay?

I tested out at least 3 different dialogue modules to try and get them to do what I wanted. I also spent all day browsing through various topics. Considering that I'm a total programming noob, it is highly possible that I have seen the answers somewhere on the forums, but have totally misunderstood it or I just didn't notice that it could be of use to me.

I have however, managed to put ttogether a very simple hack

Code: ags

//setting up the function
void MySay(this Character*, String text ,String text2, String text3) {
   
  lblSay2.Visible = false;
  lblSay2.SetPosition(7, 123);
  lblSay3.Visible = false;
  lblSay3.SetPosition(7, 123);
  
  lblSay1.Text = text;
  lblSay2.Text = text2;
  lblSay3.Text = text3;

  gDialog.Visible = true;  
  Wait(40);
  lblSay1.TweenPosition(0.2, 7, 100);
  
  lblSay2.Visible = true;
  Wait(40);
  lblSay1.TweenPosition(0.2, 7, 77, eEaseLinearTween , eNoBlockTween);
  lblSay2.TweenPosition(0.2, 7, 100);
  
  lblSay3.Visible = true;
  Wait(40);
  lblSay2.TweenPosition(0.2, 7, 100);
  
  Wait(40);
  gDialog.Visible = false;

// using MySay();
function cClient1_Talk()
{
  cClient1.MySay("Hi", "What's up", "Blah");
}


All of the above does pretty much what I wanted, but as you can imagine it is extremely limiting and very primitive. I wanted to be able to determine what each individual label (chat box) has to say, where the function would keep creating new labels for each phrase. I was thinking of using some sort of "[" in the text to determine where a new box would be created.


I understand that this may require extensive amount of work, but any kind of pointers would be much appreciated.


EDIT: I just remembered a good example of how it could work like:https://youtu.be/Kek4zO0OF_8?t=121
It's the chat-thing on the left. Player doesn't give any input, it's just triggered at certain points in the game.
I believe the game was made in Gamemaker, but would something similar be achievable in AGS at all?
(BTW the game is pretty damn cool, if you haven't played it already give it a go!)
#36
This works great! Thank you very much for your help!
I intend to add a few more arrays, but I imagine I can just simply add them in into the code.

#37
Hi,

I have a ListBox that I wanted to be in alphabetical order - and I have manged to find piece of code on these forums to help me achieve this. It works great! Well... almost - there's a little catch to it thought.

I have bunch of arrays that I want to display on GUI labels when a certain item in the ListBox is clicked on. The problem is that these arrays are meant to be connected with each other - so "0" goes with all other "0" variables, "1" with other "1" and so on. When I sort the items in ListBox, it only sorts the "clientName[]", but all the other labels use the same Index as they are written in.

Code: ags

// Creates list of clients in the lstDatabase
function ClientList() 
{
 ClientInfo(); // this function includes bunch of Arrays with required info
 
 int index = 0;
   while (index < maxClients) { // maxClients = total number of clients in database
     lstDatabase.AddItem(clientName[index]);
     index ++;
   }   
  lstDatabase.Sort(eOrderAscending, false); //Sorting function
}

// Replaces all GUI labels and buttons with client info
function ClientLabels()
{
  lblName.Text = clientName[lstDatabase.SelectedIndex];
  lblAddress.Text = clientAddress[lstDatabase.SelectedIndex];
  lblName2.Text = clientName[lstDatabase.SelectedIndex];
  lblAddress2.Text = clientAddress[lstDatabase.SelectedIndex];
  bPhoto.NormalGraphic = clientPhoto[lstDatabase.SelectedIndex];
  bPhoto2.NormalGraphic = clientPhoto[lstDatabase.SelectedIndex];
}


Sort ListBox Code:
Code: ags

void Sort(this ListBox*, eOrder order, bool caseSensitive) {
  
  int ic = this.ItemCount;
  if (ic < 2) return;
 
  int i, j, c;
  String temp;
  while (i < ic - 1) {
    j = i + 1;
    while (j < ic) {
      c = this.Items[i].CompareTo(this.Items[j], caseSensitive);
      if ((c < 0 && order == eOrderDescending) || (c > 0 && order == eOrderAscending)) {
        temp = this.Items[i];
        this.Items[i] = this.Items[j];
        this.Items[j] = temp;
      }
      j++;
    }
    i++;
  }
}


What all the code above does is that it leaves me with "clientName[]" sorted alphabetically in the ListBox, but the labels just follow the order in which they are written in. I'm not sure how to get the labels to "stay" with their associated variables. Any help would be greatly appreciated.
#38
Hi,

This is a bit tricky to explain so hopefully you can bare with me... I wanted to set up a computer screen, where the player can look through the "database of characters" to find required information.

What I was hoping of getting:
Character Name - Name of the character
Photo - Image of the character
Balance - How much money they have
Bunch of other stats (but I want to keep it short for now)

I wanted to display this info in a ListBox. You see a list of Names on the left, and the right side of the screen shows all the other information. Ideally, player would be then able to click on "More Info" to show a page with additional information. This means, that more than one Label would need to get the same data - for example, in the original List you see "name" and "photo". When you click on "More Info" you get another screen showing "name" and "photo" but also other bits.

I currently show this info with simply changing the string in each listbox.

Code: ags

if (lDatabase.SelectedIndex == 0){ 
    ClientID = 00;
lblName.Text = ClientName; // Here I just list all the labels that need to be changed
}


and in a another script I determine

Code: ags

if (ClientID == 00){
ClientName = "John Smith;
ClientPhoto = 29;
}


This saves me having to repeat the same info for each of the Labels, however I realized that all this does, is just change the text on each label, while I need each of this things to be a variable, that can be later modified.

Ideally, I wanted to be able to give an ID to each item in the Listbox. If you click on that item (name), it gets the information of that ID's variables and shows it on the right - Name, Photo, Balance.
The only way I can think of to achieve this, was to store all the info in separate functions. For example,

Code: ags

function ID00(){
ClientName = John Smith
ClientPhoto = 29
Balance = 200
}

function ID01(){
ClientName = Jonny Smithy
ClientPhoto = 30
Balance = 2
}

//etc


I'm still unsure of how I would be able to assign this info in the ListBox items thought, so a (bad?) alternative would be to create a separate button for each name in the list (custom list with lots of buttons?). You click on the button and it changes all the Labels on the right.
In other words, I guess it's like making an "inventory item" (which is not an actual inventory item) that has various stats - dmg, durability, lvl etc all of which can be changed in-game.

I've read in the manual about the Arrays, but I don't see how I can make them work - If I have an Array e.g. String Name[]; how can I determine what this Array "holds" (name, photo, balance)? Do I just make an Array for each info bit separate, and just make sure to keep the track of each number "on paper"?

I have searched the forums, but I can't find anything that I could successfully apply to my scenario. Any kind of help or a pointer in right direction would be greatly appreciated!



EDIT:
I just remembered why I wanted to use the different functions.
I was planning on creating a different function for each of the Items in the ListBox and later call these functions with
Code: ags
 if (lDatabase.SelectedIndex == 0){ 
function ID01();
}

That way I could store different variables for each of the Characters, but having so many functions seems like an overkill (I'm thinking of increasing the characters in the ListBox to 100 :P).
#39
Thanks to Cassiebsg and Crimson Wizard for the help!

I think that for what I need this should be ok, although my "Pixel Perfection OCD" may prove to be a bigger problem!

I'm just glad it's not something I have messed up in my project, because I have a tendency to do so ;)
#40
That's awesome!
Initially, I had some problems with the module, but I have managed to get it to work.

I found out that the part which changes the color of selected TextBox (THIS:)
Code: AGS

minlab.TextColor=color; 

Crashes the game. I commented it out for now, but it would be nice to have the selected TextBox to change color. I couldn't find anything on "minlab", I'm not sure if it's something that's now obsolete?


Ok, so that would be it for having multiple TextBoxes. However, I can't figure out a way to get the Parser to work for each TextBox. I want to check (function Button_OnClick) that if both TextBoxes have something specific in them.
Code: AGS

  gLoginScreen.Visible = false;
  Parser.ParseText(txtUsername.Text);
  Parser.ParseText(txtPassword.Text);
  String badword = Parser.SaidUnknownWord();
  if (badword != null){
    Display("Wrong cridentials");
    gLoginScreen.Visible = true;
  }
  Parser.ParseText(txtPassword.Text);
    if (badword != null){
    Display("Wrong cridentials");
    gLoginScreen.Visible = true;
  }  
    else if ((Parser.Said("codebank"))&&(Parser.Said("password"))){  // How to determine which Parser is which? 
    gBankOS.Visible = true; 
    } 


However, the above does not determine which Parser is which.
As for now, I simply checked if Textboxes have exactly the things I need the player to type in them, with a code like this:
Code: AGS

  gLoginScreen.Visible = false;
  if ((txtUsername.Text == "codebank") && (txtPassword.Text == "password")){
    gBankOS.Visible = true;
  }
  else {
    Display("Wrong Cridentials");
    gLoginScreen.Visible = true;
  } 


That piece of code does exactly what I want, which is to make another GUI visible if Username and Password are correct and if they are not (or are empty) to say that they are invalid. However, I'm not sure how would something like this work if I wanted to have more TextBoxes to be filled in at once. For example, if Player needs to fill in 5 TextBoxes (with correct info) to fill in a form on a computer. Having &&, &&, && doesn't seem very efficient and I was wondering if there would be a better way to approach this (perhaps with the Parser).


SMF spam blocked by CleanTalk