YolkfolkThe Dizzy Fansite 0 logged in0 playing
Community discussion

Scripting problem

Started by gavlaa on 7 May 2009 • 16,207 views

43 posts
#54444
I'm having a bit of a problem with the following code:

func ActionObject_2000()
{
idx = OpenDialogInventory();
if(idx!=-1) UseObject(idx);
}

func UseObject_2000( idx )
{
if(ObjGet(idx,O_ID)==1000);
{
Message0(5,4,"YOU USE THE KEY");
Message0(6,3,"AND THE DOORnCREAKS OPEN");
MessagePop();

InventorySub(idx);

idx = ObjFind(2000);
ObjSet(idx,O_DISABLE,1);

idx = BrushFind(2001);
BrushSet(idx,B_DRAW,0);
GameCommand(CMD_REFRESH);
}
else
{
DropObject(idx);
}
}

I know it works, having seen it demonstrated on the video tutorials, provided by Jamie.

What am I doing wrong?
👍 0
#65018
there doesn't seem to be anything wrong with the actual code. therefore it's more likely to be something you haven't changed in the map.

is the game throwing up an error when you first load it, or when you're playing the game? if the latter, when exactly is it throwing up the error? Or is it simply that it isn't working?

it could be a number of things, however i'd suggest that you ensure that object 2000 (the one you action) is set as a Dynamic brush, with the ID as 2000 (obviously!) and the 'class' set to 'action'

If you could provide more details about it, i should be able to help further.
👍 0
#65025
I should have really provided more details, so here they are:

The Door trigger has been set with an ID of 2000. .Iv'e double checked this, as well as making sure it's set as dynamic, and all seems to be as it should.

The error messge that is being thrown up is:

PARSER, 0, 0, "parse error"
DataScriptsgame.gs : 174

This refers to the following piece of highlighted code:

func ActionObject_2000()
{
idx = OpenDialogInventory();
if(idx!=-1) UseObject(idx);
}

func UseObject_2000( idx )
{
if(ObjGet(idx,O_ID)==1000);
{
Message0(5,4,"YOU USE THE KEY");
Message0(6,3,"AND THE DOORnCREAKS OPEN");
MessagePop();

InventorySub(idx);

idx = ObjFind(2000);
ObjSet(idx,O_DISABLE,1);

idx = BrushFind(2001);
BrushSet(idx,B_DRAW,0);
GameCommand(CMD_REFRESH);
}
else
{
DropObject(idx);
}
}

Hope this helps. If you need any other information, then just let me know.

Thanks
👍 0
#65026
i always have


return; after GameCommand(CMD_REFRESH);
👍 0
#65027

OHHHHH i've got it!

i've highlighted in red a bit of code you shouldn't have in there:

func ActionObject_2000()
{
	idx = OpenDialogInventory();
	if(idx!=-1) UseObject(idx);
}

func UseObject_2000( idx )
{
	if(ObjGet(idx,O_ID)==1000)<strong>[color="Red"];</strong>
	{
		Message0(5,4,"YOU USE THE KEY");
		Message0(6,3,"AND THE DOORnCREAKS OPEN");
		MessagePop();

		InventorySub(idx);

		idx = ObjFind(2000);
		ObjSet(idx,O_DISABLE,1);

		idx = BrushFind(2001);
		BrushSet(idx,B_DRAW,0);
		GameCommand(CMD_REFRESH);
	}
	else
	{
		DropObject(idx);
	}
}

that is all it is. you don't use the semi-colon ( ; ) after 'if' statements. if you use anything, you use the { and } brackets to enclose code within that 'if' statement. however if you've only got ONE bit of code after it, then you can do away with the { and } brackets, which is why you see the following code on line 4:

if(idx!=-1) UseObject(idx);

this is an 'if' statement with ONE bit of code after it, which can look confusing as it doesn't have the { and } brackets encasing that one bit of code. If we were to go the long way around it, then it would look like this:

	if(idx!=-1)
	{
		UseObject(idx);
	}

but because it only has one bit of code there, we don't really need the two brackets, so they can be removed, which saves two lines of code. you could of course also have it as follows:

if(idx!=-1) { UseObject(idx); }

which would also work fine too.

so if you remove that erronous semi-colon, you should find it works fine. :smile:

Please let me know if any of this has confused you!

👍 0
#65028
if the error is pointing to an 'else' statement, then the chances are that the problem is the previous 'if' statement.

also, meph, you don't need to use the 'return;' statement if the code won't clash with the code that follows, if that makes any sense!
👍 0
#65056
Thanks for that. Thats solved my problem. I hate getting these errors, but I guess thats how you learn.

How you produce some of your games considering the time and work is admirable. I have a new found respect.
👍 0
#65058
my first game was an absolute nightmare to do. i got so many many errors it was unreal. I didn't have a clue how to fix most of them, so i used to keep a backup of the last error-free version, in case i couldn't fix the latest error! most of the times i did actually fix errors was purely down to luck, and i remember at least twice i did something and it removed the error, but i had no idea at all why it had fixed the error!

i've said before i almost gave up on it, and there reallly were a few points i just didn't think i'd ever get it to work.

by the time i'd finished it, i had at least learned some of the stuff that was causing all the errors. the game was a very simple one, coding-wise, and you really do have to start off there otherwise there is a high chance you'll just confuse yourself!

even now, it's only about half the time that a piece of coding will do exactly what i want it to do first time. I'll usually have to go back and change it a bit to factor for something i didn't think about, or to remove an error. What changes isn't that you get a lot less errors (although you do get less and less the more you code), it's that you realise sooner what's caused the error, and are able to fix it quicker.

having said that, it may be just me that still gets errors! :tongue:
👍 0
#65064
Ive managed to code one puzzle amazingly similar to the first example you did, didnt last long though by the next one lol, I get the same error message, number 205, ive tried checking it all through with the code from your tutorial but I cant spot what is causing the error. Was doing similar to that Denzil example you did.


func ActionObject_2003()
{
idx = ObjFind(2003);
if(ObjGet(idx,0_STATUS)==0)
{
Message1(5,4, "MESSAGE HERE");
Message2(6,5, "MESSAGE HERE");
MessagePop();
ObjSet(idx,0_STATUS,1);
return;
}
if(ObjGet(idx,O_STATUS)==1)
{
idx = OpenDialogInventory();
if(idx!=-1) UseObject(idx);
}
}

func UseObject_2003( idx )
{
if(ObjGet(idx,O_ID)==1001)
{
Message0(5,4, "MESSAGE HERE");
Message2(6,5, "MESSAGE HERE");
MessagePop();

InventorySub(idx);

idx = ObjFind(2003);
ObjSet(idx,O_CLASS,0);

idx = ObjFind(1002);
ObjSet(idx,O_DISABLE,0);


}
else
{
DropObject(idx);
}

}
👍 0
#65065
might be this...during the Actionobject half you have the Status bit but you haven't got the ObjFind

idx = ObjFind(2003);
if(ObjGet(idx,0_STATUS)==1)

Might not be the problem but thats how I've coded mine.
try it.
👍 0
#65067

no it's not that at all, as you already have the 'objfind' code before the first 'if' statement, therefore it remembers the value when looking at the second 'if' statement.

what it is though, is that on the fourth line, when typing the following code:

if(ObjGet(idx,0_STATUS)==0)

you've used a 0 (the number) instead of a O (the letter) in O_STATUS, so it should therefore be:

if(ObjGet(idx,O_STATUS)==0)

if you check, you will probably find that it is around line 205 in the code, which is the error 'number' you had (it's actually the approximate line number of the problem).

you've also done the same thing on line 9:

ObjSet(idx,0_STATUS,1);

 

👍 0
#65071
Thanks, solved that now but getting a load of different error messeges when testing the puzzle now {yolkfolk}:scratch:
👍 0
#65073
well there are no more problems with that code, I just tested it. it's possibly a map problem
👍 0
#65074
hmmm can't see anything else in the code that's wrong. did you change anything else at the same time?

also, ensure that you have a dynamic object with ID 1002 in the map, as if you don't have, the game will try to find it when you use object 1001 (as asked to in the code), and if it can't find it in the map, will throw up an error.
👍 0
#65075
The error starts as soon as I action/talk to character ID 2003, set as class action & type dynamic.

Item 1002 is in the map, as disabled & set as item & dynamic, (to be enabled after item 1001 is given to character).

Item 1001 is ok & can be picked up.

As you say the code looks as it should from the tutorial example so I dunno why, maybe ive inadvertedly affected summat.


EDITS

Resolved, all working now, thanks for the earlier help though.
👍 0
#65108
Can someone help me? I'm trying to use the door code, provided by Jamie in his tutorials, and adapt it. I want to be able to get Dizzy to pick up a chest and then drop it onto a trigger, which will then change the properties of the chest to block. I also want the chest to be fixed in place, so that it can no longer be removed. I have tried a number of times to adapt this myself, but it just wont seem to work. {yolkfolk}:scratch:

This is the the door code:

func ActionObject_2001()
{
idx = OpenDialogInventory();
if(idx!=-1) { UseObject(idx); }
}

func UseObject_2001( idx )
{
if(ObjGet(idx,O_ID)==1000)
{
Message0(5,4,"YOU USE THE KEYnIN THE LOCK!");
Message0(6,3,"AND THE DOORnCREAKS OPEN!");
MessagePop();

InventorySub(idx);

idx = ObjFind(2001);
ObjSet(idx,O_DISABLE,1);

idx = BrushFind(2002);
BrushSet(idx,B_DRAW,0);
GameCommand(CMD_REFRESH);

}
else
{
DropObject(idx);
}
}
👍 0
#65109

you can't change a dynamic object to give it a 'block' property. It's only Static Brushes that can have the 'block' property.

what you want to do though, can be done a different way. What you do is, when you drop the chest down onto the trigger, you remove the chest from the inventory, but you also have a Static Brush (another chest) in the map, either next to or in front of the trigger. this Static Brush will have Material property of Block, and a Draw property of None, so that it's invisible. When you use the chest item on the trigger, you then code it to make the chest static brush have a draw property of Img+Mat so that it is visible. It's virtually the same as the door code, but you make the block item (the chest in this case) visible instead of invisible.

in the following example, ID 2001 is the trigger, 2002 in the chest static brush(which needs to have a Draw property of 0 in the map), and ID 1000 is the chest item:

// chest code
func ActionObject_2001()
{
	idx = OpenDialogInventory();
	if(idx!=-1) { UseObject(idx); }
}

func UseObject_2001( idx )
{
	if(ObjGet(idx,O_ID)==1000)
	{
		Message0(5,4,"YOU DROP THE CHESTnON THE FLOOR");
		Message0(6,3,"BUT IT'S TOO HEAVYnTO PICK UP AGAIN!");
		MessagePop();

		InventorySub(idx);

		idx = ObjFind(2001);
		ObjSet(idx,O_DISABLE,1);

		idx = BrushFind(2002);
		BrushSet(idx,B_DRAW,3);
		GameCommand(CMD_REFRESH);

	}
	else
	{
		DropObject(idx);
	}
}

if you compare this to the door code, you'll see that it's almost exactly the same. the only difference is the messages, and the Draw property of brush 2002 set to 3 (draw img+mat) in the chest code instead of 0 (draw none) in the door code:

// door code
func ActionObject_2001()
{
	idx = OpenDialogInventory();
	if(idx!=-1) { UseObject(idx); }
}

func UseObject_2001( idx )
{
	if(ObjGet(idx,O_ID)==1000)
	{
		Message0(5,4,"YOU USE THE KEYnIN THE LOCK!");
		Message0(6,3,"AND THE DOORnCREAKS OPEN!");
		MessagePop();

		InventorySub(idx);

		idx = ObjFind(2001);
		ObjSet(idx,O_DISABLE,1);

		idx = BrushFind(2002);
		BrushSet(idx,B_DRAW,0);
		GameCommand(CMD_REFRESH);

	}
	else
	{
		DropObject(idx);
	}
}
👍 0
#65111
I've noticed in your examples Jamie that in your 'UseObject' functions you put the line

if(ObjGet(idx,O_ID)==1000)

idx is already set the inventorys ID in 'UseObject()' within action.gs therefore I always use

if(idx==1000)

knocks a bit off the file size of game.gs not to mention the extra typing
👍 0
#65113
idx is the index of the object not it's ID.
if(idx==1000)
is totally different from
if(ObjGet(idx,O_ID)==1000)
If you edit the map, the index of an object/brush may change, but not it's ID property.
👍 0
#65115

I'll try to explain in as simple terms as i can where the idx originates from, and how it is used.

the idx originates in the following bit of coding, when it is used to store which item the player selected from the inventory:

idx = OpenDialogInventory();

the important thing to remember about this is that idx is NOT storing the ID property of the item, it is instead storing the game maps internal number for the item (every static brush and dynamic object in the map have a unique 'game map number'),

the next line then calls the UseObject function (in a different script file), with idx being passed on into that function, and then that function passes it on further to the UseObject_2001( idx ) function. this is then used in the following bit of code:

if(ObjGet(idx,O_ID)==1000)

what the ObjGet(idx,O_ID) bit of the above code does, is take the 'game map number' of the item (idx), and uses it to get that items ID property, which it then checks to see if it is equal to 1000.

if you used 'if(idx==1000)' instead, it would be checking if the game map number was equal to 1000. As you can't set the game map number (it is assigned by the map editor, and changes every time you alter the map), it is very unlikely to be 1000 (it could be 463, 18363, 9364 or anything really), and the code won't work as intended

what you're thinking of Andy, is where (in action.gs), the UseObject function sets variable 'id' as the item ID (for that function only), however it still calls UseObject_2001( idx ) and passes on variable idx that was passed to it.

I hope this is clear enough :smile:

👍 0