Usage:
onwalltest npcx npcy width height testx testy
All parameters in pixels.
It will move the first NPC to npcx, npcy and make it go width*height pixels large. Then the other NPC checks the given point.
NPC Code:
//#CLIENTSIDE
if (created) {
x = 0;
y = 0;
}
if (playerchats) {
if (startswith(onwalltest, #c)) {
tokenize #c;
x = strtofloat(#t(1))/16;
y = strtofloat(#t(2))/16;
setshape 1, strtofloat(#t(3)), strtofloat(#t(4));
showpoly 0,{x,y,
x+strtofloat(#t(3))/16,y,
x+strtofloat(#t(3))/16,y+strtofloat(#t(4))/16,
x,y+strtofloat(#t(4))/16};
}
}
NPC Code:
//#CLIENTSIDE
if (created) {
x = 0.5;
y = 0;
}
if (playerchats) {
if (startswith(onwalltest, #c)) {
tokenize #c;
sleep 0.2;
if (onwall(strtofloat(#t(5))/16,strtofloat(#t(6))/16)) {
say2 ONWALL;
} else say2 NOT ON WALL;
}
}
I believe using it like onwalltest 1 1 15 15 0 0 (Making it fill a whole tile minus the top and most left line of pixels, and checking for the topleft pixel) proves that it is pixel exact.
And just for the sake of posting code, here is a simplified version of my movement script.
NPC Code:
//#CLIENTSIDE
if (created || timeout) {
disabledefmovement;
speed = 8; // Pixels to move in 0.05 secs
setarray wall, 6; // To store all the onwall checks around the player
for (d = 0; d < 4; d ++) if (keydown(d)) {
for (m=0; m < speed; m ++) {
// We need to check all around the player for sidemoving.
// Two tiles for three sides -> 6
for (i=0; i < 6; i++) {
wall = 0;
// Lots of pixelexact math stuff
// First, set up directions to check in
checkdir = (d-int(i/2)+1)%4;
checkdir2 = (checkdir+1)%4;
// Set the "centre" of the player, the very center, more than pixelexact
mx = this.x+23.5/16;
my = this.y+31.5/16;
// Modificators based on the direction
modx = vecx(checkdir2)*(15.5/16-i%2) + vecx(checkdir)*16.5/16;
mody = vecy(checkdir2)*(15.5/16-i%2) + vecy(checkdir)*16.5/16;
for (p=0; p < 2; p++) {
// Two points for each pixels (the corners which are close to the player)
pmodx = p*vecx(checkdir2)*15/16;
pmody = p*vecy(checkdir2)*15/16;
// Finally, the pixel we need to check
tx = mx+modx-pmodx;
ty = my+mody-pmody;
// If the test point is on a wall, save that
wall += onwall(tx,ty);
}
// If one test point is on a wall, this position is blocked
wall[i] = (wall > 0);
}
// Check if you need to move to the side instead of straigh forwards
if (!(1 in {wall[2],wall[3]})) mod = 0;
else if (!(1 in {wall[2],wall[0],wall[1]})) mod = 1;
else if (!(1 in {wall[3],wall[4],wall[5]})) mod = -1;
else mod = 20; // No movement allowed
if (mod in {-1,0,1}) {
// Figure out how to move
mx = vecx((d+mod)%4)*1/16;
my = vecy((d+mod)%4)*1/16;
playerx += mx;
playery += my;
// Stop movement, so you only move 2 pixels when sidemoving
if (mod!=0 && m>0) m = speed;
} else m = speed; // If completely blocked, we may as well stop checking
}
}
timeout = 0.05;
}
(Only to be used for educational purposes. If you really really have to use it or derived work on your PW, gimme credit at least.)