Page 1 of 2

This is bugging me.

Posted: Sat Oct 23, 2010 7:16 pm
by delta
I can't figure out function MaterialDensityRead( x, y, w, h ).

in the dizzyage book this muction has the following 'explanation':

Read materials densities found in a specified rectangle, in the material map.
The densities of the found materials are returned on the coresponding bits.
Ex: if only materials with void (0) and block (2) densities are found, the result will be 5 (binary 101).


Now forgive me if I'm being stupid here, but why, if it only found materials with void (0) and block (2) densities, would that produce a result of 5??

I simply don't understand the logic there. Could someone enlighten me?

I'm sure there was a post somewhere a few years ago explaining this (possibly by macon), but I'm buggered if I can find it.

Posted: Sat Oct 23, 2010 7:31 pm
by delta
I'm having the same problem with MaterialRead( x, y, w, h ) too, which is the one I'm likely to actually use.

Posted: Sat Oct 23, 2010 7:41 pm
by delta
another issue is that i'm using the following code (checked whenever he walks):

Code: Select all

	//find player position
	px = PlayerGet(P_ X) ;
	py = PlayerGet(P_Y);

	//set box corner coords
	boxx = px+8;
	boxy = py-14;
	boxw = px+10;
	boxh = py+6;

	boxa = MaterialRead(boxx,boxy,boxw,boxh);
println("box a");
println(boxx,boxy,boxw,boxh);
println(boxa);
This should in theory print the material type of whatever is to the right of him. Instead it prints '1' everywhere, no matter what he's stood next to. :v2_dizzy_confused2:

Posted: Sat Oct 23, 2010 7:47 pm
by xelanoimis
Well, the idea is to be able to find what materials are inside a given rectangle. And since there can be more than one, and since it's faster to return a single integer value than a table) I chose to return this info on bits.

I could've set it to test for a single density and tell if it is or not found inside the rectangle, but then you'd have to call it for every density you need to test. And that wouldn't be so fast.

So, each bit in the returned integer number correspond to a density value. Bit 0 is for void (0) and so on. If a bit is set than the corresponding density was found. If it's not, then no material with the corresponding density is inside the rectangle.

In the given example, if void (0) and block (2) densities were found, their bits were set so this mean ..0000101 which has the decimal value of 5. In fact correctly is "hard" not "block". "Hard" is the density (defined by MATD_HARD with value 2) and "block" is the material which the script template define it by MAT_BLOCK with value 7) and it has nothing to do with the ReadDensities function.

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5

You can use bit operators to test it:

Code: Select all

ret = MaterialDensityRead( x, y, w, h )
if( ( ret & (1 < < MATD_HARD) ) != 0 ) ... there's some hard blocker there ...
// 1 < < MATD_HARD has the binary value 100 and the decimal value 4
// no space between < < of course

Hope it was clear.

Posted: Sat Oct 23, 2010 7:51 pm
by delta
I *kinda* get that, but that still doesn't explain why it's returning '1' all the time.

All I want to do is get it to check if there is just 'air' material in that rectangle, and no other material such as my 'climb' material (10), which has a 'void' density too, which is why I need to use MaterialRead.

Posted: Sat Oct 23, 2010 7:52 pm
by xelanoimis
In the second issue, 1 means it found void material (bit 1 set)
The box should be given as x, y, w, h, not x1,y1,x2,y2. Perhaps that is the thing.
These functions should work because they are used in the custom walk implemented in script. And that works.

Posted: Sat Oct 23, 2010 7:55 pm
by xelanoimis
Both functions work the same (on bits). One is for densities and one for materials.

You can use the second for testing for air only, but the test should be like this:
mask_air = (1 < < MAT_AIR);
if( ( ret & (~mask_air) ) != 0 ) ... then there are other materials ...
the ~ operator inverse all bits, so the test is for all other but bit 1

Posted: Sat Oct 23, 2010 7:57 pm
by delta
xelanoimis wrote:The box should be given as x, y, w, h, not x1,y1,x2,y2. Perhaps that is the thing.
oh! oops. Having said that, I've fixed it, and it's still only returning '1'.

Posted: Sat Oct 23, 2010 8:00 pm
by delta
xelanoimis wrote: mask_air = (1 < < MAT_AIR);
if( ( ret & (~mask_air) ) != 0 )
where would I put that, and how would I test in a specific rectangle? This is my current code:

Code: Select all

	//find player position
	px = PlayerGet(P_ X) ;
	py = PlayerGet(P_Y);

	//set box corner coords
	boxx = px+8;
	boxy = py-14;

	boxa = MaterialRead(boxx,boxy,2,16);
println("box a");
println(boxx,boxy);
println(boxa);

	//set box corner coords
	boxx = px-10;
	boxy = py-14;

	boxb = MaterialRead(boxx,boxy,2,16);
println("box b");
println(boxx,boxy);
println(boxb);

	if(boxa==1&&boxb==1) return 1;
	else return 0;
'boxa' and 'boxb' print as '1' the whole time. even when the rectangle is in front of block material or my 'climb' material. very odd.

Posted: Sat Oct 23, 2010 8:03 pm
by xelanoimis
are you sure there are other materials there? Use the debug material view (F4) and try a larger box. If still a mystery, try it on the default template example, and if still a mystery, send it to me and I'll have a look by tomorrow evening.