# Diagonal Movement Blocking

## Recommended Posts

Has anyone come up with a way of blocking only diagonal movement? I'm currently working on a puzzle which would be quite easy to beat if diagonal (i.e. directly northeast, southeast etc.) movement was possible.

Any suggestions would be welcome.

EDIT: Direction confusion sorted out.

##### Share on other sites

First, note that the game's north direction is to the upper-right side of your computer screen, so, talking in terms of the direction markers at the corners of the game screen, do you blocking motion in the cardinal directions, N, S, E, and W, or do you mean blocking movement in the other four directions, NE, NW, SE, and SW?

Either way, I have some ideas, but the implementation would depend on what's in the puzzle. In the space occupied by the puzzle, are there any terrains or terrain scripts?

I have an idea, which I will try to implement, and we can see if it meets your needs.

Edit: Here's what I came up with. It may need some tinkering to make it fit for you/make it more foolproof.

Code:
` beginstate START_STATE;if(get_flag(A, == 1){		y = 0;		while (y< C ){			x = 0;			while(x< C ){				if(get_terrain(x,y) == D)					set_terrain(x,y,0);				x = x + 1;			}			y = y + 1;		}		if(get_terrain(char_loc_x(0),char_loc_y(0) - 1) == 0)			set_terrain(char_loc_x(0),char_loc_y(0) - 1,D);		if(get_terrain(char_loc_x(0),char_loc_y(0) + 1) == 0)			set_terrain(char_loc_x(0),char_loc_y(0) + 1,D);		if(get_terrain(char_loc_x(0) - 1,char_loc_y(0)) == 0)			set_terrain(char_loc_x(0) - 1,char_loc_y(0),D);		if(get_terrain(char_loc_x(0) + 1,char_loc_y(0)) == 0)			set_terrain(char_loc_x(0) + 1,char_loc_y(0),D);	}break; `
This is intended to be the START_STATE of the town. Obviously you can add anything else you want to the start state. I've written it with an A, B, C, and D. These are spot where you will need to fill in numbers. A,B is the coordinates of an SDF to switch the motion blocking on. C is the width of the town, 32, 48, or 64, and D is the number of a terrain to block the party with. I imagined the D terrain as probably being:

Code:
` begindefineterrain D;   import = 0;   te_full_move_block = 1;   te_can_look_at = 0; `
The blocking works by placing terrain D directly to the N, S, E, and W of the party's lead member, and moving the terrains every turn so that they don't get left all over the place. Some imporovements could involve finding the first living member of the party instead of character 0, and altering the loops so that only the area of the town containing the puzzle is affected.
##### Share on other sites

Sorry, you're right. I do mean NE, SE etc. Thinking about this problem for too long has caused me to lose track of the basics.

Anyway, here is the room in which I need the effect to take place (ignore the character sprite):

So much for the surprise when it's released...

The red blocks and the gravel floor all have the same terrain script, which is:

Code:
` beginterrainscript;variables;int mylocx,mylocy,charlocx,charlocy,diffx,diffy,newlocx,newlocy;body;beginstate INIT_STATE;	set_script_mode(2);	break;beginstate START_STATE;	if(terrain_in_this_spot() == 496){		mylocx = my_loc_x();		mylocy = my_loc_y();		charlocx = char_loc_x(char_who_activated_script());		charlocy = char_loc_y(char_who_activated_script());		diffx = mylocx - charlocx;		diffy = mylocy - charlocy;		newlocx = mylocx + diffx;		newlocy = mylocy + diffy;		}break;beginstate BLOCK_MOVE_STATE;	if((terrain_in_this_spot() == 496) && (get_terrain(newlocx,newlocy) == 495) && (char_on_loc(newlocx,newlocy) == -1) && (diffx + diffy != 2) && (diffx + diffy != -2) && (diffx + diffy != 0)){		print_str_color("The block moves!",2);		play_sound(-45);		set_terrain(newlocx,newlocy,496);		set_terrain(mylocx,mylocy,495);		force_instant_terrain_redraw();		}		else{			if(get_terrain(newlocx,newlocy) != 495){				play_sound(41);				print_str_color("The friction is too great.",2);				}			if(char_on_loc(newlocx,newlocy) != -1)				print_str_color("Someone is in the way.",2);			if((diffx + diffy == 2) || (diffx + diffy == -2) || (diffx + diffy == 0))				print_str_color("You can't push it diagonally.",2);			}break;beginstate STEP_INTO_SPOT_STATE;//Possibly something could be done here...break; `
How it works:

Terrain 495 uses the gravel graphic, terrain 496 uses the red blocks.

It first checks whether the terrain_in_this_spot is 496, and if so, looks at my_loc(x and y values) and character location, then finding the diff(erence), 'myloc - charloc'.

The new location of the block is simply the opposite side from which it is pushed,

'myloc + diff'.

Imagine a grid of 3x3 spaces, with the terrain script in the centre. It should check the location of the first character in the party every tick. I thought that it would be possible to check whether a character is crossing from say, the south to the east side of the grid and create your blocked terrain at the destination, then turning it off again at some point, like the beginning of the next tick. Unfortunately, the start state seems to want to run multiple times whenever I use a call in it to check the character location, so when I walked into the space, it went haywire. Since it got just a little complicated, I gave up on that method.

Your idea seems interesting, I'll try it out and hope that the start state runs once each tick...

EDIT: I have found a few flaws, apart from your misinterpretation over direction which is entirely my fault.

It relies on the fact that you will never traverse any terrain other than terrain 0. In response I'm changing it to also accommodate terrain 495.

##### Share on other sites

Seeing that what you are building depends on using terrains, I'm surprised that my idea works, but if it does, good! Like I said before, what I posted was just a simplistic version; I'm not surprised that it had to be adapted.

About the script having their states run several times a turn, the standard way to deal with this is use get_current_tick to find out the tick, and store it in a variable. Then, every time the state is run, check to see if the current tick is different from the stored previous tick. If they are the same, it is still the same turn, so have your script do nothing. If they are different, store the new value and do whatever it is you want to do once a turn.

A good example of this is creature scripts with custom abilities that they are only supposed to use once a turn. See the beginning of state 3 of t13kimzahn in The Za-Khazi Run for an example.

##### Share on other sites

After some tweaking it did work, but not before I had to create another new terrain specifically for terrain 495 to change into.

Hopefully when this comes out it will be one of the most puzzle orientated dungeons around. In fact, I might even do a mine cart ride if that isn't too cliched...

##### Share on other sites

You could use that script and then have the party in a boat. That will automatically limit them to the 4 cardinal directions, and I am sure you will be able to conjure up an explanation for pushing around blocks in a boat.

##### Share on other sites

I believe that BoA boats can move in 8 directions, BoE in 4.

##### Share on other sites

No, they can only move in the diagonal directions if it is clear all around. Check by moving down a very narrow river with a few right angle turns in it.

This would only work if you could have some blocking terrain, though.