Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Future Improvements (https://forums.graalonline.com/forums/forumdisplay.php?f=10)
-   -   testnpc (https://forums.graalonline.com/forums/showthread.php?t=63484)

jake13jake 01-16-2006 01:09 PM

testnpc
 
In my attempts to expand my custom movement system that I plan to use on Classic, I have made functions to detect players on x,y,w,h (though it depends on how reliable testplayer(x,y) is) and tiletypes on x,y,w,h... however, because players have a constant width and height, and round to the nearest 0.5, coordinate, they're easy to detect.

However, I have come to certain a point. I want to be able to test for NPCs using the x,y,w,h method. There, is, however, no way in the current scripting language to script this efficiently. NPCs can have any x and y value (clientside), and any width and height value (clientside). They round to the nearest 16th (well, 16ths is all that matters for the movement system anyways). In order to make the testing precise for NPCs, you would have to check every pixel of the defined area to test for it. I wouldn't do that.
However, onwall2 IS able to test NPCs, though I wouldn't know how.

perhaps an onNPC(x,y,w,h) function could be made?

ZeLpH_MyStiK 01-16-2006 04:42 PM

You just said onwall2 is able to test NPCs, so why don't you go find out about it? =\
or you can testnpc(x,y) , although i'm not sure whether it'll detect setshape changes.

ApothiX 01-16-2006 05:27 PM

Quote:

Originally Posted by jake13jake
In my attempts to expand my custom movement system that I plan to use on Classic, I have made functions to detect players on x,y,w,h (though it depends on how reliable testplayer(x,y) is) and tiletypes on x,y,w,h... however, because players have a constant width and height, and round to the nearest 0.5, coordinate, they're easy to detect.

However, I have come to certain a point. I want to be able to test for NPCs using the x,y,w,h method. There, is, however, no way in the current scripting language to script this efficiently. NPCs can have any x and y value (clientside), and any width and height value (clientside). They round to the nearest 16th (well, 16ths is all that matters for the movement system anyways). In order to make the testing precise for NPCs, you would have to check every pixel of the defined area to test for it. I wouldn't do that.
However, onwall2 IS able to test NPCs, though I wouldn't know how.

perhaps an onNPC(x,y,w,h) function could be made?

Make the function yourself using getnearestnpcs() ..

I seriously think you need to stop making suggestion threads about stuff that is easy to script, and if it was a part of the language you would probably be the only person who would use it.

jake13jake 01-16-2006 09:44 PM

Quote:

Originally Posted by ApothiX
Make the function yourself using getnearestnpcs() ..

I seriously think you need to stop making suggestion threads about stuff that is easy to script, and if it was a part of the language you would probably be the only person who would use it.

This isn't so easy as you think, that's the problem. I could do testnpc(x,y)... but only with a 1/16th check... which I wouldn't really advise to anyone making a custom movement system. True, if I used getnearestnpcs(), I could check the ranges given by this.x,y,width,height... wouldn't be quite so good though. It especially bothers me that I don't know how near getnearestnpcs() detects NPCs. I would want to avoid using it in anything but a damage system.

I might be the only person who uses it, but is your problem how well I would use it? I make functions that I think everyone should use. If this was easy to script, or didn't make sense with common functionality, I wouldn't have suggested it. I don't see what your problem is. You know, I'm sorry that I want to make the game more enjoyable and unique for players. Hey, I'd even let anyone use my movement system once it's done... That includes you. In fact it should be the envy of all movement systems

EDIT: owait, there is a getareanpcs function I could use.

jake13jake 01-17-2006 02:26 AM

Gripes, how in the world do I get the getareanpcs(x,y,w,h) function to work. To my knowledge it loads indexes? Yet, when I try to set a var to it, it doesn't give any value... did it change in gs2? Oh wait, doesn't it only work serverside? This means more work! Now I'll have to cycle through all the NPCs in the level. :( which may or may not be faster than cycling through every pixel.

Well, as I expected.. slow as hell to cycle through the npcs index and slow as hell to cycle at 1/16th pixel. Also, it's bad luck that my assumptions on player coord passing rounded to the nearest 1/2 were wrong. That means that I'd need an onPlayer(x,y,w,h) function in addition to an onNPC(x,y,w,h) function. Other functions mentioned are serverside only, and movement systems are, of course, scripted clientside. Something like getareaplayers() and getareanpcs() clientside would suffice, but onPlayer() and onNPC() would be the most useful in my case.

It would be possible to do an onPlayerOrNPC() using onwall and !onTiles (the function I made)... but would be just as difficult to separate the two.

ApothiX 01-17-2006 03:47 PM

PHP Code:

function onNPC(checkxcheckycheckwcheckh) {
  
temp.npclist getnearestnpcs(checkx,checky);

  for(
temp.npclisttemp.npc) {
    if(
temp.npc.x in |checkx,checkx+checkw| && test.npc.y in |checky,checky+checkh|) {
      return 
true;
    }
  }

  return 
false;


Whatever, I just scripted that in the thirty seconds that I've been sitting here staring at this thread. If it doesn't work, oh well, but that sounds like what you're trying to do. If you want to modify it to return the indexes or whatever, go ahead.

napo_p2p 01-17-2006 11:59 PM

Quote:

Originally Posted by ApothiX
PHP Code:

function onNPC(checkxcheckycheckwcheckh) {
  
temp.npclist getnearestnpcs(checkx,checky);

  for(
temp.npclisttemp.npc) {
    if(
temp.npc.x in |checkx,checkx+checkw| && test.npc.y in |checky,checky+checkh|) {
      return 
true;
    }
  }

  return 
false;



I think you have the for loop 'backwards' (switch temp.npc and temp.npclist) :p. And test.npc.y should be temp.npc.y. Not bad for 30 seconds though >_<. Other than that, it looks like it'll do what he wants.

jake13jake 01-18-2006 02:47 AM

1. getnearestnpcs() doesn't exist.
2. getareanpcs() doesn't exist clientside.

3. The following works... however... lags, would be the same for the player.
PHP Code:

function onNPC(tx,ty,w,h) {
  for (
i=0i<npcs.size(); i++)
    if (
npcs[i].width>&& npcs[i].height>0)
      if (
overlaps(tx,ty,w,h,npcs[i].x,npcs[i].y,npcs[i].width,npcs[i].height))
        return 
1;
  return 
0;


Now, if the array was a bit smaller, it wouldn't be so much of a lag problem. Thus, if 1 and/or 2 were available clientside, I wouldn't be having this problem. It's not such a problem on inside levels, but it's a HUGE problem on gmaps.

Oh, by the way, it's a bit less simple to check for the overlapping of an NPC onto the area being checked.
PHP Code:

function overlaps(x1,y1,w1,h1,x2,y2,w2,h2) {
  if (
x1 in |x2,x2+w2> && y1 in |y2,y2+h2>)       return 1;
  if (
x1+w1 in <x2,x2+w2> && y1 in |y2,y2+h2>)    return 1;
  if (
x1+w1 in <x2,x2+w2> && y1+h1 in <y2,y2+h2>) return 1;
  if (
x1 in |x2,x2+w2> && y1+h1 in <y2,y2+h2>)    return 1;
  if (
x2 in |x1,x1+w1> && y2 in |y1,y1+h1>)       return 1;
  if (
x2+w2 in <x1,x1+w1> && y2 in |y1,y1+h1>)    return 1;
  if (
x2+w2 in <x1,x1+w1> && y2+h2 in <y1,y1+h1>) return 1;
  if (
x2 in |x1,x1+w1> && y2+h2 in <y1,y1+h1>)    return 1;
  return 
0;


Unfortunately, the in operator has only so much functionality. I wish I could get rid of the last four lines at the least, but there's always the possibility of the first rectangle completely enclosing the second rectangle.

Yen 01-18-2006 02:52 AM

Shouldn't you use 'else' in the 'overlaps' function??

jake13jake 01-18-2006 03:12 AM

Quote:

Originally Posted by Yen
Shouldn't you use 'else' in the 'overlaps' function??

Well, the last 4 you could combine to the first four, but only using an else if... other than that, they're checking four different coordinates on two different rectangles. Only case you could make to use else if is

if (first coordinate in first rectangle in second rectangle's range)
else if (first coordinate in second rectangle in first rectangle's range)

if (second coordinate in first rectangle in second rectangle's range)
else if (second coordinate in second rectangle in first rectangle's range)

or wait... yea you could... but I don't think it's quite necessary in a return bool function.

Yen 01-18-2006 03:17 AM

Sorry, I'm being retarded. I totally forgot that return stops the block. x-x

jake13jake 01-18-2006 04:45 AM

Quote:

Originally Posted by Yen
Sorry, I'm being retarded. I totally forgot that return stops the block. x-x

I did it anyway tho.
So... yea, having trouble even with adding conditionals. although they're definitely not as reliable.

UGH... Just one giant optimization problem that seems to have no ends. Classic's most popular level, standing, loads 160 NPCs. I haven't counted how many have a setshape (probably a majority of them). Changing the conditions is the only thing that makes it lag less, yet, you the only truly reliable conditions I can come up with are: npcs.size > 0, npcs[i].width>0 && npcs[i].height>0.

It is a LOT easier to optimize the players check, since they have a constant width and height.

Okay, list of problems with not having a built-in onNPC() function so far.
1. To limit the range of checking for NPCs (the most obvious means of optimizing) means to limit the size of setshapes. (Which I'm trying anyway)
2. Can't check to see if an NPC uses dontblock(). Would have to add to every NPC that has dontblock() a variable this.dontblock=1; or blockagain(); this.dontblock=0;


All times are GMT +2. The time now is 05:27 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.