Once again I'm having troubles with writing and reading simple ints from a dat file. My apologies for the last thread I created regarding a high score issue, a thread I'll come back to once I get the hang of this... :-\
Alright here's the code so far, in the room we start in:
// ROOM THAT THE INTRO STARTS IN
SetRestartPoint();
// if gamedata.dat is not present, create a new one with blank values
File *output = File.Open("gamedata.dat", eFileWrite);
if (output == null) {
gamerestartedwithcommentary = 0;
hasstartedcommentary = 0;
output.WriteInt(gamerestartedwithcommentary);
output.WriteInt(hasstartedcommentary);
}
output.Close();
// read back from gamedata.dat to find out if commentary mode is on
File *input = File.Open("gamedata.dat", eFileRead);
gamerestartedwithcommentary = input.ReadInt(); // THIS LINE'S THE TROUBLEMAKER (?)
input.Close();
// if commentary mode is on
if (gamerestartedwithcommentary == 1) {
gamerestartedwithcommentary = 0;
hasstartedcommentary = 1;
SetGlobalInt(240, 1);
File *output2 = File.Open("gamedata.dat", eFileWrite); // SEE QUESTION 2
output2.WriteInt(gamerestartedwithcommentary);
output2.Close();
}
SetFadeColor(255, 255, 255);
Wait(40);
StartCutscene(eSkipESCOnly);
Compiling leaves me with the message "Error: FileReadInt: File read back in wrong order". What is going on?
Second question: Why can't I use the code "File *output = ...." twice? It left me with an error message saying "Variable 'output' already defined". So I threw in a 2 behind it and it compiled. I can't wrap my head around this. Do you have to store each int in its own variable? Can anyone explain this or maybe direct me somewhere that makes it easy to understand?
Quote
Second question: Why can't I use the code "File *output = ...." twice? .. Do you have to store each int in its own variable? Can anyone explain this or maybe direct me somewhere that makes it easy to understand?
Is that
exactly how the code is in your script? Specifically, it's a single code block, not two seperate functions that you've just pasted together here?
I'm not sure what you mean by "
store each int in its own variable", but I think I can explain why you can't use the code twice.
File pointers, like ALL AGS pointers and variable types, need to have a unique name - by having
File *output twice, you're declaring two pointers with the same name. Just as you don't need to put
int gamerestartedwithcommentary everytime you want to use it (and if you did, it'd generate the same error, incidentally), you don't need
File * to use a previously declared pointer.
Basically, skip the pointer declaration from the second occurance, and you should be OK:
// ROOM THAT THE INTRO STARTS IN
SetRestartPoint();
// if gamedata.dat is not present, create a new one with blank values
File *output = File.Open("gamedata.dat", eFileWrite);
// ETC
if (gamerestartedwithcommentary == 1) {
gamerestartedwithcommentary = 0;
hasstartedcommentary = 1;
SetGlobalInt(240, 1);
output = File.Open("gamedata.dat", eFileWrite); // 'output' is already declared, so you don't need to declare it before use here
output.WriteInt(gamerestartedwithcommentary);
output.Close();
}
If you wanted to use a File pointer with the same name in another function, that'd need the
File declaration, but should compile OK. E.g.:
function DoSomething() {
File *output = File.Open("gamedata.dat", eFileWrite);
if (output == null) {
gamerestartedwithcommentary = 0;
hasstartedcommentary = 0;
output.WriteInt(gamerestartedwithcommentary);
output.WriteInt(hasstartedcommentary);
}
output.Close();
}
function DoOther() {
File *output = File.Open("gamedata.dat", eFileWrite);
output.WriteInt(gamerestartedwithcommentary);
output.Close();
}
For your first question: You seem to be using
if (output == null) to check if the file already exists. It doesn't work quite like that. I'm guessing the problem is that
output isn't null, so the
WriteInt code isn't run. (And if it was null, the code wouldn't run, because the file wouldn't have opened...) Then, when you use
ReadInt, the file is empty - which causes the error.
If you ARE trying to check if the file exists, try opening it in
eModeRead first - that WILL return null if it's not there. If you're not checking that, maybe you just meant
if (output != null)?
The code I posted is indeed one continuous piece of code and not copy / pasted from around the global script. Thanks for explainging the part about declaring pointers... but I'm still a little lost as you're about to find out. :o
I am absolutely trying to detect whether or not gamedata.dat does exist or not, in case there was any doubt. I made some changes to the code...
SetRestartPoint();
// if gamedata.dat is not present, create a new one with blank values
File *input = File.Open("gamedata.dat",eFileRead);
if (input == null) { // This should work when reading from the file?
input.Close();
File *output = File.Open("gamedata.dat", eFileWrite);
gamerestartedwithcommentary = 0;
hasstartedcommentary = 0;
output.WriteInt(gamerestartedwithcommentary);
output.WriteInt(hasstartedcommentary);
output.Close();
}
//input.Close(); // Can I successfully close a file twice in case the file does exist?
// read back from gamedata.dat if commentary mode is on
File.Open("gamedata.dat", eFileRead); // What's wrong with this part?
gamerestartedwithcommentary = input.ReadInt();
input.Close();
// if commentary mode is on
if (gamerestartedwithcommentary == 1) {
hasstartedcommentary = 1;
SetGlobalInt(240, 1);
File.Open("gamedata.dat", eFileWrite);
gamerestartedwithcommentary = 0;
output.WriteInt(gamerestartedwithcommentary); // Error message: Undefined token output
output.Close();
}
SetFadeColor(255, 255, 255);
Wait(40);
StartCutscene(eSkipESCOnly);
This again gives me an error message saying undefined token output (see comment in the margin inside the code), but I'm sure that's not the only problem you can spot...
Because you're declaring output in a condition (input == null), you can only use it in that condition - as soon as it hits the closing } the pointer is destroyed, just like any other variable. Perhaps I should've been clearer on that, sorry. As to what's wrong with:
File.Open("gamedata.dat", eFileRead);
Well, you don't have to DECLARE the pointer again, but you do still have to tell AGS which one to use... Try:
// ROOM THAT THE INTRO STARTS IN
SetRestartPoint();
// if gamedata.dat is not present, create a new one with blank values
File *output = File.Open("gamedata.dat", eFileRead);
if (output == null) { // Couldn't open - file probably doesn't exist
output = File.Open("gamedata.dat", eFileWrite); // Will create the file
gamerestartedwithcommentary = 0;
hasstartedcommentary = 0;
output.WriteInt(gamerestartedwithcommentary);
output.WriteInt(hasstartedcommentary);
}
output.Close(); // Will close it if already existed, or if it just had to be created.
// read back from gamedata.dat to find out if commentary mode is on
File *input = File.Open("gamedata.dat", eFileRead);
gamerestartedwithcommentary = input.ReadInt();
input.Close();
// if commentary mode is on
if (gamerestartedwithcommentary == 1) {
gamerestartedwithcommentary = 0;
hasstartedcommentary = 1;
SetGlobalInt(240, 1);
output = File.Open("gamedata.dat", eFileWrite);
output.WriteInt(gamerestartedwithcommentary);
output.Close();
}
SetFadeColor(255, 255, 255);
Wait(40);
StartCutscene(eSkipESCOnly);
Compiles fine, and seems to work without obvious errors, Whether it does exactly what you need it to, is another question.
Thank you Ashen! That did exactly what I wanted to do and then some. Is writing to dat files giving anyone else headaches or is it just me? :)