06-04-2013, 07:40 PM
It's been such a long time that I updated this that the is_attacking function has changed entirely from the actual update I wanted to post.
So I will start off with the old hit_time function I wanted to post:
All this little thing does is estimate how long it will take a given object to reach a certain range around the character with it's current speed. -1 means the object either doesn't exist anymore or will not reach at all (not moving or not intersecting). This is very useful to determine the most imminent threat. For example a distant super arrow might still hit sooner than a closer slow blast, thus better try to dodge that and cope with the blast later. All those calculations are some simple yet ugly math that could and should be done better.
On to the new is_attacking function. This one has gotten a little ridiculous and even beyond the current dlls capabilities. But here it still is:
First of all it checks for the existence of given object o and whether it is the character itself.
Then it checks whether the character itself has a bdy, is not blinking(invulnerable) and whether the given object has an itr.
If that object has itrs that could hit our characters bdy it goes on to cycle through all of them to see if they are harmful and intersecting with a bdy. (yes this function will check whether it is technically already too late - but that's ok)
The harmful check is by far the longest obviously. First of all there are several itr kinds that aren't harmful at all.
The catching kind 1 inside walking frames is generally harmless. The picking kinds 2 and 7 are harmless. The super punch kind 6 is harmless. The healing kind 8 is harmless. The blocking kind 14 is harmless. And anything with effect 4 is also harmless. (maybe I should invert the kind part and only note down harmful kinds - but this way seemed better at first)
Then there are of course some more delicate situations such as burning or thrown characters (where the team does not matter) or weapons (where the itr kind 5 is always present but only activated by the character).
So I also check whether the object is either not on the same team, burning (state 18) or falling (state 12) and whether the object has a throwinjury attached (unkwn16[0]). So only burning objects, thrown falling characters or objects from another team are considered harmful. And last but not least: kind 5 itrs from weapons are only considered harmful if the holding characters (unkwn6) wpoint attacking is not 0. Yeah go figure that one line out.
Once a harmful itr is found it is double checked with every bdy of our character via yet another 3 functions: intersect(rectangeA, rectangleB), sBdy_rect(bdy_number, self.frame_number) and tItr_rect(bdy_number, target.frame_number). The last two of those get an array of the bdy and itr coordinates and the first one checks whether they overlap (in all 3 dimensions).
So this function truly checks whether an itr is about to hit or not. The problem currently is that multiple itrs or bdys with the same kind (mostly Henrys flute) will crash the game as they return the wrong kind after the first one.
I will keep trying to fully rebuild basic AI but I am not sure whether I can keep track of it here the way I started it as I've only recently discovered the use of a lot of built in variables that can help making it less deterministic which I have yet to understand. However if you want to view the fully working basic AI I had done last year you can download LF 1over2 as the boss from stage 2 uses it.
So I will start off with the old hit_time function I wanted to post:
C-Code:
float hit_time(int i){ //returns time till attack hits //diagonal range is awful - need to redo it //maybe also use a hit line function if(!is_object(i)){return -1;} float t=-1; float xt=t; float zt=t; float vx=dvx(i)-dvx(self.num); float vz=dvz(i)-dvz(self.num); if(vx!=0){xt=abs((abs(xdistance(self.num,i))-80)/vx);}else{xt=0;} if(vz!=0){zt=abs((abs(zdistance(self.num,i))-15)/vz);}else{zt=0;} if(xt>zt){t=xt;}else{t=zt;} int x=target.x+t*vx; int z=target.z+t*vz; if(range(0,80+abs(dvx(i)),abs(xdistance(self.num,i)))&&range(0,15+abs(dvz(i)),abs(zdistance(self.num,i)))){t=0;} else if(abs(self.x-x)>abs(xdistance(self.num,i))||abs(self.z-z)>abs(zdistance(self.num,i))||!range(0,80,abs(self.x-x))||!range(0,15,abs(self.z-z))){t=-1;} else if(vx==0&&vz==0){t=-1;} return t; } |
On to the new is_attacking function. This one has gotten a little ridiculous and even beyond the current dlls capabilities. But here it still is:
C-Code:
bool is_attacking(int o){ //true if an itr of o overlaps with a self.bdy if(loadTarget(o)!=-1&&o!=self.num){ if(self.data.frames[self.frame].bdy_count>0&&self.blink==0&&target.data.frames[target.frame].itr_count>0){ for(int i = 0; i < target.data.frames[target.frame].itr_count; ++i){ if((target.team!=self.team||target.state==18||target.state==12)&& (self.state!=12||target.data.frames[target.frame].itrs[i].fall>=60)&& target.data.frames[target.frame].itrs[i].kind!=1&& target.data.frames[target.frame].itrs[i].kind!=2&& (game.objects[o].unkwn16[0]!=0|| target.data.frames[target.frame].itrs[i].kind!=4)&& (game.objects[game.objects[o].unkwn6].data.frames[game.objects[game.objects[o].unkwn6].frame1].wpoint.attacking!=0|| target.data.frames[target.frame].itrs[i].kind!=5)&& target.data.frames[target.frame].itrs[i].kind!=6&& target.data.frames[target.frame].itrs[i].kind!=7&& target.data.frames[target.frame].itrs[i].kind!=8&& target.data.frames[target.frame].itrs[i].kind!=14&& target.data.frames[target.frame].itrs[i].effect!=4){ for(int j = 0; j < self.data.frames[self.frame].bdy_count; ++j){ if(intersect(sBdy_rect(j,self.frame),tItr_rect(i,target.frame)))return true; } } } } } return false; } |
Then it checks whether the character itself has a bdy, is not blinking(invulnerable) and whether the given object has an itr.
If that object has itrs that could hit our characters bdy it goes on to cycle through all of them to see if they are harmful and intersecting with a bdy. (yes this function will check whether it is technically already too late - but that's ok)
The harmful check is by far the longest obviously. First of all there are several itr kinds that aren't harmful at all.
The catching kind 1 inside walking frames is generally harmless. The picking kinds 2 and 7 are harmless. The super punch kind 6 is harmless. The healing kind 8 is harmless. The blocking kind 14 is harmless. And anything with effect 4 is also harmless. (maybe I should invert the kind part and only note down harmful kinds - but this way seemed better at first)
Then there are of course some more delicate situations such as burning or thrown characters (where the team does not matter) or weapons (where the itr kind 5 is always present but only activated by the character).
So I also check whether the object is either not on the same team, burning (state 18) or falling (state 12) and whether the object has a throwinjury attached (unkwn16[0]). So only burning objects, thrown falling characters or objects from another team are considered harmful. And last but not least: kind 5 itrs from weapons are only considered harmful if the holding characters (unkwn6) wpoint attacking is not 0. Yeah go figure that one line out.
Once a harmful itr is found it is double checked with every bdy of our character via yet another 3 functions: intersect(rectangeA, rectangleB), sBdy_rect(bdy_number, self.frame_number) and tItr_rect(bdy_number, target.frame_number). The last two of those get an array of the bdy and itr coordinates and the first one checks whether they overlap (in all 3 dimensions).
So this function truly checks whether an itr is about to hit or not. The problem currently is that multiple itrs or bdys with the same kind (mostly Henrys flute) will crash the game as they return the wrong kind after the first one.
I will keep trying to fully rebuild basic AI but I am not sure whether I can keep track of it here the way I started it as I've only recently discovered the use of a lot of built in variables that can help making it less deterministic which I have yet to understand. However if you want to view the fully working basic AI I had done last year you can download LF 1over2 as the boss from stage 2 uses it.
favorite dcing techniques: wpoint | double key inputs | holding back | alternate basic moves