⌂ YolkfolkThe Dizzy Fansite
Community discussion

Table leg puzzle

Started by AndyG on 23 May 2014 • 9,556 views

21 posts
#55351
So I've been working with DizzyAge all week, working through the video tutorial and the online book. It's all exciting and I've learned a lot. I'm a little stuck now trying to create a puzzle where you remove a table leg to change the horizontal tabletop to diagonal and walk up it. I have the graphics (a whole day learning Photoshop :surprise: ) and thought it would be a simple case of putting both tabletops in the map and disabling first one then the other. (Actually, the diagonal is in two parts, with only the uppermost being a block). So,
1. How can I set this event upon picking up the table leg? I only know about triggering events on dropping items.
2. Should the tabletop be static or dynamic? If static, it can't be disabled; if dynamic, it can't function as a block.

And any coding help would be much appreciated!! Thanks for reading :smile:
👍 0
#81206

Hi Andy,

Welcome to Yolkfolk. :smile:

It sounds like the bit you're missing is how to use the DRAW property. The DISABLE property doesn't do anything to static brushes, instead you have to set B_DRAW to zero to make the table disappear and B_DRAW to 3 to make it appear. You also have to use the command: GameCommand(CMD_REFRESH); to update the map every time you change static brushes.

(BTW, B_DRAW = 1 shows just the graphics, B_DRAW = 2 no graphics, just the interactions with the player.)

I'd also put a label in the code so the update only happens the first time you pick the leg up. This probably won't matter for this puzzle, from what you've told me, but it might come in handy later on. In my first game, there was a bit where an item appeared when you picked up a brick in front of it. What I didn't notice was that it reappeared every time you picked the brick up.

So the sort of thing you'll want to do is:

func PickupObject_100()
{
item = ObjFind(100);
if(ObjGet(item,O_STATUS)==0)
{
ObjSet(item,O_STATUS,1);
tab1 = BrushFind(200);
BrushSet(tab1,B_DRAW,0);
tab2 = BrushFind(201);
BrushSet(tab2,B_DRAW,3);
GameCommand(CMD_REFRESH);
}

DoPickupObject(item);
}
👍 0
#81208
Wow, thanks a lot! I wanted to wait until I'd got it working before I replied, then it turned out to be a simple cut and paste :smile: I just added another (tab3) since the diagonal table is in two parts, and of course set their DRAW to zero in the map editor. Lesson learned! I feel I might be jumping in at the deep end with new puzzles like this so I'll take a day to work through the tutorials again. Thanks again, I'm so glad the community is active after so many years :teethy:
👍 0
#81209
The way I tried to remember coding stuff like this was an Object is Dynamic and Brush is Static.
So you can delete Objects but you Draw Brush's. lol
👍 0
#81211

Thanks Meph!

Well, after working through the guide again I think I understand a little better and I'm now trying to implement a puzzle where you eat a cake upon dropping it (a la the whiskey in FWD) and find a nail file inside (three guesses where the room is set!). Believe it or not, I think I've done the hard part:

func DropObject_1001()
{
	item = ObjFind(1001);
	Message0(0,0, "YOU FIND THE CAKE TOOnTEMPTING AND EAT IT!");
	MessagePop();

	PlayerEmotion(9);
	WaitFrames(40);
	PlayerEmotion(0);
	Message0(0,0, "OH?  WHAT'S THIS?");
	MessagePop();

	DoDropObject(item);
	ObjSet(item,O_DISABLE,1);
	
	idx = ObjFind(1003);	
	ObjSet(idx,O_DISABLE,0);
}

Or maybe not so hard... I was proud of it anyway! It's probably too convoluted but works just fine :smile: . The problem I'm having is setting the nail file to the player's coordinates when it's enabled. I've tried messing about with y=PlayerGet(P_Y) etc, even within its own function. Then I tried substituting the cake for the file by changing its id, but then I wouldn't know how to assign it a graphic.

Again, I realise I'm jumping in at the deep end even with having read the book, so thanks for your patience!

👍 0
#81217

It doesn't matter how convuluted your coding is as long as it works Andy.

The 'normal' way to make items appear where Dizzy is standing is the method you mention (you can understand it better by looking at the 'DoDropObject' section of the action.gs file). However, you can also just add the file to your inventory as you don't need to consider a 'full' inventory as you have just dropped the cake. In this case just substitute the last line of the code with 'InventoryAdd(idx)' ...just make sure the 'file' is not disabled, is classed as an item and is on the map (preferably in an unaccessible room).

Alternatively, some people use a special function that they've added to the util.gs file that switches inventory items.

func ReplaceInventoryItem(old, new) // old is id of what is in inventory, new is what to replace it with)
{
idx = ObjFind(old);
InventorySub(idx);
idx = ObjFind(new);
InventoryAdd(idx);
}
👍 0
#81218
Excellent, thanks a lot! For some reason I'd been assuming the item had to be in the same room and so had to be disabled. And I love how simple that is - like DizzyAge in general, all the hard work is already done and it's just a case of finding the right coding. The eating animation I found, perfect example. I thought that would be many lines of clever coding :smile:
(One exception might be having to set items to idx rather than just being able to access them outright, this is confusing me but I'm sure there's a good reason for it.)
👍 0
#81229

It's more for convenience than 'you must do it this way!' as:

ObjSet(ObjFind(1000), O_DISABLE, 0);

is exactly the same as:

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

So, if you are making a lot of things happen at the same time when actioning an object (or using an item) you can just use the first bit of code to identify and modify each subsequent object in turn rather than continually switching the idx.

When 'using' an object you put idx in brackets and then use idx to identify the item being used as that is how the engine works in the 'UseObject' function, but once the 'item' is identified just identify the things that need to happen directly.

Also, think of 'idx' in the same way that you used 'item' in your cake/file coding; it's just an identifier and if you need to identify a lot of different objects in the same function you can just as easily start the function with a whole list of identifiers. Here's an example of having to ensure that three separate actions have occurred before something will happen:

func ActionObject_999()
{
ida = ObjFind(1000);
idb = ObjFind(1001);
idc = ObjFind(1002);
if (ObjGet(ida, O_STATUS) == 1
&& ObjGet(idb, O_STATUS) == 1
&& ObjGet(idc, O_STATUS) == 1)
{
ObjSet(ObjFind(1003), O_DISABLE, 0);
ObjSet(ObjFind(999), O_DISABLE, 1);
return;
}
else
{
Message1 (5,2, ""Nothing happened"");
MessagePop();
}
}

One final tip. If you are moving a visible object to somewhere else in the same room then you have to give it an identifier as you have to use the command ObjPresent(idx) (or whatever identifier you're using) to make it visible, otherwise it will only be visible when you next re-enter that room.

👍 0
#81241
Thanks a lot, that's been very useful. I suspected that idx meant "identity of x" and that x could be substituted. Like my old BASIC programming, LET a=10. I didn't have cause to test this out but I'm sure this will come in handy. I'm also glad to have an "AND" feature (IF you have all this item AND it's your third time to talk to him, etc): again, I hoped this would be the case and it wouldn't be too difficult. && is easy :smile: .

BTW, I downloaded your Spellbound Dizzy remake hoping to learn how to do the TID style scrolls of text, since Peter Teal went and passworded his games. The way you've done it will work just as well though, so thanks again :smile: . When Dizzy Met Daisy made me laugh, and I love the graphic style.
👍 0
#81251
I've also just realised I went the long way about my exit window. When you use the nail file, rather than simply change the status of the actionobject, I disabled it and enabled another. Oh well, as you say, as long as it works.

I also just spent over an hour trying to work out how to make a flappy bird, haha. That's another thing added to my repertoire :smile: . It's getting really addictive! If I wasn't married I doubt I'd get any sleep at all.
👍 0
#81252
Just worry when you start dreaming about coding puzzles {yolkfolk}:eek:
👍 0
#81337
Or when you groggily wake up and think 'that's a really good idea for a puzzle' then half an hour later can't remember what on earth it was...
👍 1
#81347

Could anyone help me with a similar one? This is driving me just absolutely mad. (I also checked other fan games scripts to make sure I'm doing it right, and I swear I am!) I've set an invisible collider near the ground to trigger a character talking to you. This works fine. I've set a narrower, taller static block (draw 2) to stop you jumping. Now, after the dialogue I want to erase this static block with a

idx = BrushFind(6008);
		BrushSet(idx,B_DRAW,0);

Simple, right? But it won't work. I've even tested it by setting the draw to 3 in the editor: the brush does disappear from view after the dialogue, but the mat remains. It's so far the only time that I'm convinced it must be broken! I'm actually going to work around this by just deleting it and making the dialogue collider wider, because it's not really important if you do jump and end up quite far away -- but for future reference, I'd like to know what the problem was if anyone knows?

Thanks as ever :smile:

👍 0
#81348
Did you remember to use GameCommand(CMD_REFRESH); ?
👍 0
#81349
Wow that was quick! And no, you're right {dizzy}:dizsmile: . I don't think this would ever have occurred to me, especially since the DRAW property was changing when I tested it, as in becoming invisible. I guess the refresh just changes the material. Thanks a lot!!
👍 0
#81351
I guess that's how it works. My rule is, if you change a brush put a refresh at the end of the function. And if in doubt, put it in anyway - it doesn't hurt. :teethy:
👍 0
#81352

No, the refresh command for static brushes only takes account of the changes, so to disable an invisible blocker you just need to change the material to 0 then refresh. If this is going to happen a lot in your game then you might as well just add a new function to the util.gs file:

func Makeair(static)
{
idx = BrushFind(static);
BrushSet(idx, B_MATERIAL, 0);
GameCommand (CMD_REFRESH);
}

Then just replace 'static' with the id of the brush to disable it at any time you've done what you need to do as part of the relevant function in the game.gs file

Makeair(1000);

👍 0
#81362
Ooh this is scary venturing outside the game and gamedef files, haha. I knew I would have to eventually, from having a look at your Spellbound Dizzy remake and seeing the added file for the mine cart, which is similar to something I want to try later. Also, Message2 seems to be the same colour as Message0 by default, so I'll have to play with the dialog file at some point. It's fun to experiment, I think I'm just scared of accidentally changing something important that I don't understand.
👍 0
#81364
Just check out the Message.gs file and look for func Message0 (x,y text). The first of the colours mentioned is for the text colour and the second for the border colour. You can have as many different coloured messages as you like, as long as there is a new function for each of them, ie Message1, Message2 etc. If the 'border' tile '3 dialog' is white then change it to whatever colour you fancy. If it's a set colour, ie brown wood, then just leave the border as white.

When I started playing around with some of the files, I added my bits without 'tabs' so that it would be easier to delete it if the game engine acted silly. Mind you, your first question was about using 'drop object' for the cake no matter where you were, whereas I have always messed around with the action file for doing a global drop ...so I've learnt something new. Thanks.

The util.gs file is handy for dumping functions that you use on the odd occasion ...and much easier to find it if it's not working rather than ploughing through pages of the game.gs file.
👍 0
#81366
Thanks a lot for that :smile: I thought it looked easy enough, but wow that's even simpler. I think I'll start with the util file when I start adding bubbles at various points. As I'm learning, I can see I've taken the long way quite a few times where something simpler would have done (case in point, constant idx=, often 4 or 5 times within a function, because I thought I had to) -- but I won't change it if it works.

I just finished making a falling apple :smile: it's triggered by a collision and plays an animation on hitting the floor. It took me about 3 hours of mostly trial and error - I can't tell you how many times I wanted to ask for help! And how many times I changed some code that would have worked perfectly well if only I'd remembered to save either the map or the file! But it's a good feeling when you can work it out for yourself. Next on the agenda: a snapping crocodile!
👍 0