Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Gepard on Sun 25/12/2016 18:15:31

Title: Can a function change Strings in the game?
Post by: Gepard on Sun 25/12/2016 18:15:31
Hello,

I have various dungeons that player can explore and find loot in them. For example, he ventures deep into the dungeon, opens a door and finds a treasure chest. When he clicks the treasure chest an inventory window shows up with a single item, that was added to the inventory when he opened the door or clicked on the chest. I have this code for this:

Code (ags) Select
if (eventPlace1.IndexOf("gold")==-1) {
place1.AddInventory(iGold);
eventPlace1 = eventPlace1.Append ("gold");
}


This is to ensure the item will only be added once. And it is working, but the problem is, my script is getting pretty heavy. I was thinking if I could use a function that would fit these lines into one. I don't know if you can make a function that would refer to a String already in the game like you do with characters or inventory items. I tried but the game said "Invalid use of pointer".

Thanks for any help.
Title: Re: Can a function change Strings in the game?
Post by: Crimson Wizard on Sun 25/12/2016 20:20:21
Quote from: Gepard on Sun 25/12/2016 18:15:31I don't know if you can make a function that would refer to a String already in the game like you do with characters or inventory items. I tried but the game said "Invalid use of pointer".

Yes it is possible:
Code (ags) Select

function DoSomethingWithString(String myString)
{
   Display(myString);
}

String ThisFunctionReturnsString()
{
   return "some string";
}
Title: Re: Can a function change Strings in the game?
Post by: Gepard on Sun 25/12/2016 21:12:33
I'm sorry, I don't understand. I have a String defined in Global variables. Now I want it to change when player click on a GUI button. But when he clicks the button, it can always be different String that changes, depending on "where" the player is right now. How do I do this? I mean, what to put under button click code and what in the function?
Title: Re: Can a function change Strings in the game?
Post by: Khris on Sun 25/12/2016 21:38:28
Using strings like that to store game states is a *really* (REALLY) bad idea. But this thread isn't about that, so here's the answer you're looking for (I guess):

Header:
import String eventPlace[10];
import void PrepareChest(int which, String item);


Main Script
String eventPlace[10];

void PrepareChest(int which, InventoryItem *item) {
  if (eventPlace[which].IndexOf(item.Name) > -1) return; // do nothing
  eventPlace[which] = eventPlace[which].Append(item.Name);
  character[which + 10].AddInventory(item);
}


The code assumes that character #10 is used in conjunction with eventPlace[0], character #11 in conjunction with eventPlace[1], and so on, up until character #19 and eventPlace[9]. That's a total of ten chests.

You'd use it like this:  PrepareChest(1, iGold);The text is pulled from the inventory name.


A proper system involves
a) a struct for a chest, and setting up as many instances as you need using an array
b) assigning each chest index to a room
c) preparing a single chest inventory based on which chest is in the room
d) storing chest status in the instance data

Example:
// header
struct Chest {
  int inv[50];
  bool locked;
};  // edit: added semi-colon

// main
Chest chest[50];
  // in game_start
  chest[0].inv[iGold.ID] = 1;
  chest[0].inv[iSword.ID] = 1;

Edit: added semi-colon to struct def
Title: Re: Can a function change Strings in the game?
Post by: Snarky on Sun 25/12/2016 22:30:04
Quote from: Khris on Sun 25/12/2016 21:38:28
Using strings like that to store game states is a *really* (REALLY) bad idea. But this thread isn't about that

Maybe it should be. Gepard was using the same approach in another thread (http://www.adventuregamestudio.co.uk/forums/index.php?topic=54280.0), and it's really a very poor way to solve these tasks. (Just wait until you have both "ham" and "hammer" as items in the game, for example...)

To keep track of inventory items, use an array of inventory items (or simply a Character inventory), or perhaps a set of boolean flags, not some weird string concatenation of all their names. Try to avoid relying on custom text properties for game logic (use structs or arrays in the code instead), but if you must, convert it from a string to some more appropriate data type immediately upon reading it.
Title: Re: Can a function change Strings in the game?
Post by: Crimson Wizard on Sun 25/12/2016 22:35:32
To be honest, I did not really think about what Gepard was using the string for, but now when I give this more attention, maybe it is better to simply use Game.DoOnceOnly function? Because it does exactly what Gepard is trying to do with the string: remembers that some action was already done.
Title: Re: Can a function change Strings in the game?
Post by: Gepard on Mon 26/12/2016 09:11:59
Thank you, everyone, for your ideas.

In my game I have many places, that player can explore. While exploring, he can encounter three kinds of puzzles, enemies or items. For each place I have a String assigned and this String changes everytime a player solves a puzzle, defeats an enemy or finds an item. So for example if he enters a place where there is an enemy and the String does not contain the word "enemy1", a fight will start. If he defeats the enemy, than word "enemy1" will be added to that place's String (the same can be done with loot, I just append "chest1" and puzzles, I just add "relicpuzzle"). Not every place has the same type of puzzles, numbers of enemies, items etc. Also it is very easy to reset the place from the start and make all the puzzles, items and enemies alive again, I just set the String to "". I will definitely use the Game.DoOnceOnly feature, and will also look at structs as I haven't use them so far.

Edit: Also, I only have one room in the game (not counting the main menu).
Edit2: I searched the forums and the internet, but I couldn't find any tutorial on structs in AGS. I tried to declare them in my game, but with no luck. Can anyone tell me if there is a complex tutorial for beginners on how to use them. How and where to declare them, how to get and set their values? Thank you.
Title: Re: Can a function change Strings in the game?
Post by: dayowlron on Mon 26/12/2016 19:49:02
First off I want to say I would probably use arrays for controlling what you are asking for. But I basically wanted to reply because if you have an "enemy10" then you do the IndexOf for "enemy1" it will return true even though enemy1 was not in there. To fix that you can add a comma after the words and look for that comma in your querys.

if (eventPlace1.IndexOf("enemy1,")==-1) {
**code for encountering an enemy
eventPlace1 = eventPlace1.Append ("enemy1,");
}
Title: Re: Can a function change Strings in the game?
Post by: Khris on Tue 27/12/2016 19:05:41
Did you try the example code I used?
Put line 8 at the top of your script, the other lines in game_start. It should compile fine.
Title: Re: Can a function change Strings in the game? [SOLVED]
Post by: Gepard on Wed 28/12/2016 19:26:33
Thank you all for help. I'm trying to implement as much as possible to the system I already have. You guys are a great help! Much appreciated!
Title: Re: Can a function change Strings in the game?
Post by: Snarky on Wed 28/12/2016 21:55:24
Quote from: Gepard on Mon 26/12/2016 09:11:59
Edit2: I searched the forums and the internet, but I couldn't find any tutorial on structs in AGS. I tried to declare them in my game, but with no luck. Can anyone tell me if there is a complex tutorial for beginners on how to use them. How and where to declare them, how to get and set their values? Thank you.

There's a quick introduction to structs in the built-in AGS Manual, under "Scripting | Script language keywords", though it doesn't describe how to add functions to structs. Structs are usually declared in script headers, you can also refer to the "Scripting | Multiple Scripts" section.

I am sure there is a much better way to solve your task, but first there's one part I don't understand about your current solution: you say that "Not every place has the same type of puzzles, numbers of enemies, items etc.", but I don't see where you define that â€" the string only keeps track of what has been "used up" already. I'm also not clear on what defines the order in which things happen: if a place has two enemies, enemy1 and enemy2, what makes it so that enemy1 is the one you encounter the first time and enemy2 the second time? Or is that random somehow?
Title: Re: Can a function change Strings in the game?
Post by: Gepard on Thu 29/12/2016 12:43:22
Well a single place consist of multiple "rooms". These are not actual rooms, just levels, that are set using integer whenever player enters a room. So I just decide which level is the Enemy1 going to be in and when player fights it and win, the entString for that place will have "enemy1" appended to it. And I define the enemy when the place is opened. I use function for that.
Title: Re: Can a function change Strings in the game?
Post by: Snarky on Thu 29/12/2016 21:22:16
So somewhere you have a big function that says something like this?

Code (ags) Select
// Player enters "room"
function enterRoom(int roomLevel)
{
  if(roomlevel == 1)
  {
    if(room1String.IndexOf("enemy1") == -1)
    {
      doFight("enemy1");
      room1String = room1String.Append("enemy1");
    }
    else if(room1String.IndexOf("enemy2) == -1)
    {
      doFight("enemy2");
      room1String = room1String.Append("enemy2");
    }
    // etc.
  }
  else if(roomlevel == 2)
  {
    // Similar to roomlevel 1
  }
  // etc.
}