mersox
Active member
Hi guys, I've hit a wall. I'm looking to find a way to make the player change it's attack if he's surrounded by two enemies: one enemy in front and one behind. A good example is the double kick in Batletoads SNES.
I'm using as a base this script (which works), that detects a nearby enemy (only one enemy):
My logic was to modify it so that when one condition is met (enemy is behind of player), the script starts another search for an enemy on the opposite side of the player. If found, it changes the animation accordingly to a double attack (Ani2). If not, it switches to a back attack (Ani).
This is the script so far (it needs to be expanded to also detect a "flipped" version when player is facing the opposite direction, but that's not important now). This version makes the game close at startup. There's probably an obvious issue I'm not seeing.
Here's what the log says:
line 661 (counted with notepad) refers to an unrelated section of the player's file that normally has no issues. I don't know what's up with that.
The script is called by the player entity like this:
@cmd surroundattack "ANI_attackbackward" "ANI_attack4" -60 0 0 7
I'm at my wit's end...
I'm using as a base this script (which works), that detects a nearby enemy (only one enemy):
Code:
void finisher(void AniP, void Ani , int RxMin, int RxMax, int Ry, int Rz, int Type, int Flag)
{// Checks closest enemy's animation & range
// If it's accepted, change animation
// AniP : Enemy's animation
// Ani : Animation to change to
// RxMin : Minimum x range
// RxMax : Maximum x range
// Ry : y range
// Rz : z range
// Type : 0 = non targetted , 1 = for targetting, 2 = for grabbing
// Flag : 0 = facing direction not necessary , 1 = facing direction must be opposite
/*Originally smartbomb by
Damon Vaughn Caskey
07152008*/
void self = getlocalvar("self"); //Caller.
float x = getentityproperty(self, "x");
float y = getentityproperty(self, "a");
float z = getentityproperty(self, "z");
int dir = getentityproperty(self, "direction");
void vEntity; //Target entity placeholder.
int iEntity; //Entity enumeration holder.
int iType; //Entity type.
int iMax = openborvariant("count_entities"); //Entity count.
//Enumerate and loop through entity collection.
for(iEntity=0; iEntity<iMax; iEntity++){
vEntity = getentity(iEntity); //Get target entity from current loop.
iType = getentityproperty(vEntity, "type"); //Get target type.
//Enemy type?
if (iType == openborconstant("TYPE_ENEMY")){
float Tx = getentityproperty(vEntity, "x");
float Ty = getentityproperty(vEntity, "a");
float Tz = getentityproperty(vEntity, "z");
int Anti = getentityproperty(vEntity, "antigrab");
int Edir = getentityproperty(vEntity, "direction");
void EAnim = getentityproperty(vEntity, "animationID");
if(EAnim == openborconstant(AniP)){
float Disx = Tx - x;
float Disy = Ty - y;
float Disz = Tz - z;
if(Disz < 0){
Disz = -Disz;
}
if(Disy < 0){
Disy = -Disy;
}
if( Disx >= RxMin && Disx <= RxMax && Disz <= Rz && Disy <= Ry && dir == 1 ) // Target within range on right facing?
{
if(Type == 2){
if(((Flag == 1 && Edir == 0) || Flag == 0) && Anti < 10){
dasher(0,0,0);
setlocalvar("Target" + self, vEntity);
performattack(self, openborconstant(Ani));
}
} else {
if((Flag == 1 && Edir == 0) || Flag == 0){
if(Type == 1){
dasher(0,0,0);
setlocalvar("Target" + self, vEntity);
}
performattack(self, openborconstant(Ani));
}
}
} else if( Disx >= -RxMax && Disx <= -RxMin && Disz <= Rz && Disy <= Ry && dir == 0) // Target within range on left facing?
{
if(Type == 2){
if(((Flag == 1 && Edir == 1) || Flag == 0) && Anti < 10){
dasher(0,0,0);
setlocalvar("Target" + self, vEntity);
performattack(self, openborconstant(Ani));
}
} else {
if((Flag == 1 && Edir == 1) || Flag == 0){
if(Type == 1){
dasher(0,0,0);
setlocalvar("Target" + self, vEntity);
}
performattack(self, openborconstant(Ani));
}
}
}
}
}
}
}
My logic was to modify it so that when one condition is met (enemy is behind of player), the script starts another search for an enemy on the opposite side of the player. If found, it changes the animation accordingly to a double attack (Ani2). If not, it switches to a back attack (Ani).
This is the script so far (it needs to be expanded to also detect a "flipped" version when player is facing the opposite direction, but that's not important now). This version makes the game close at startup. There's probably an obvious issue I'm not seeing.
Code:
void surroundattack(void Ani, void Ani2, int RxMin, int RxMax, int Ry, int Rz)
{// Checks closest enemy's animation & range
// If it's accepted, change animation
// Ani : Animation to change to
// RxMin : Minimum x range
// RxMax : Maximum x range
// Ry : y range
// Rz : z range
/*Originally smartbomb by
Damon Vaughn Caskey
07152008*/
void self = getlocalvar("self"); //Caller.
float x = getentityproperty(self, "x");
float y = getentityproperty(self, "a");
float z = getentityproperty(self, "z");
int dir = getentityproperty(self, "direction");
void vEntity; //Target entity placeholder.
int iEntity; //Entity enumeration holder.
int iType; //Entity type.
void vEntity2; //Target entity placeholder (second count).
int iEntity2; //Entity enumeration holder (second count).
int iType2; //Entity type (second count).
int iMax = openborvariant("count_entities"); //Entity count.
//Enumerate and loop through entity collection.
for(iEntity=0; iEntity<iMax; iEntity++){
vEntity = getentity(iEntity); //Get target entity from current loop.
iType = getentityproperty(vEntity, "type"); //Get target type.
//Enemy type?
if (iType == openborconstant("TYPE_ENEMY")){
float Tx = getentityproperty(vEntity, "x");
float Ty = getentityproperty(vEntity, "a");
float Tz = getentityproperty(vEntity, "z");
{
float Disx = Tx - x;
float Disy = Ty - y;
float Disz = Tz - z;
if(Disz < 0){
Disz = -Disz;
}
if(Disy < 0){
Disy = -Disy;
}
if( Disx >= RxMin && Disx <= RxMax && Disz <= Rz && Disy <= Ry && dir == 1 ) // Enemy behind player when right facing?
{
//Enumerate and loop through entity collection.
for(iEntity2=0; iEntity2<iMax; iEntity2++){
vEntity2 = getentity(iEntity2); //Get target entity from current loop.
iType2 = getentityproperty(vEntity2, "type"); //Get target type.
//Enemy type?
if (iType2 == openborconstant("TYPE_ENEMY")){
float Tx2 = getentityproperty(vEntity2, "x");
float Ty2 = getentityproperty(vEntity2, "a");
float Tz2 = getentityproperty(vEntity2, "z");
{
float Disx2 = Tx2 - x;
float Disy2 = Ty2 - y;
float Disz2 = Tz2 - z;
if(Disz2 < 0){
Disz2 = -Disz2;
}
if(Disy2 < 0){
Disy2 = -Disy2;
}
if( Disx2 >= -RxMax && Disx2 <= -RxMin && Disz2 <= Rz && Disy2 <= Ry && dir == 1) // Enemy in front of player when right facing?
{
performattack(self, openborconstant(Ani2));
}
}
}
else {performattack(self, openborconstant(Ani));
}
}
}
}
}
}
Here's what the log says:
Script error: data/chars/daniel/daniel.txt, line 137: Unknown error '' (in production 'stmt_list')
^
********** An Error Occurred **********
* Shutting Down *
Fatal Error in load_cached_model, file: data/chars/daniel/daniel.txt, line 661, message: Error parsing function main of animation script in file '%s'!
Total Ram: 8482250752 Bytes ( 8089 MB )
Free Ram: 1427103744 Bytes ( 1360 MB )
Used Ram: 59858944 Bytes ( 57 MB )
Release level data...........
Done!
Release graphics data........ Done!
Release game data............
Release game data............ Done!
Release timer................ Done!
Release input hardware....... Done!
Release sound system......... Done!
Release FileCaching System... Done!
**************** Done *****************
Fatal Error in load_cached_model, file: data/chars/daniel/daniel.txt, line 661, message: Error parsing function main of animation script in file '%s'!
line 661 (counted with notepad) refers to an unrelated section of the player's file that normally has no issues. I don't know what's up with that.
The script is called by the player entity like this:
@cmd surroundattack "ANI_attackbackward" "ANI_attack4" -60 0 0 7
I'm at my wit's end...