Double Dragon Reloaded Alternate

Complete Double Dragon Reloaded alternate - Updated version! 5.1.1

No permission to download
Project is completed.
So Rash from Battletoad will be a playable character?
I'm curious to see what this ninja is worth: is it possible to display his sprites?
 
  • Like
Reactions: L K
So Rash from Battletoad will be a playable character?
I'm curious to see what this ninja is worth: is it possible to display his sprites?
Yeah, I'm not doing ALL the toads. Just him. The idea is to represent ALL the in-universe DD stuff. Battletoads IS a part of it BUT beyond Rash as a playable character, that's about as much as I want to include from that part of the "Double Dragon" Tradewest universe. Even then, it will be more as a BONUS DLC sorta thing. The last of the NEW player characters I am introducing. The other one I'm including is a playable version of Jeff, as he was always the Boba Fett of this series.

So Rash from Battletoad will be a playable character?
I'm curious to see what this ninja is worth: is it possible to display his sprites?
I will hit you up on DM. Sound good?
 
literally, at the end of that script (that is attached above) I added the code from the script used by the sailor moon demo

That's the mistake. You are supposed to copy the script file which is PinoDodge.c from Sailor Moon to your game, to data/scripts folder.
Then declare that script in the same way as Pino, which is like this:

ondoattackscript data/scripts/pinododge.c

in enemy's header text.
 
That's the mistake. You are supposed to copy the script file which is PinoDodge.c from Sailor Moon to your game, to data/scripts folder.
Then declare that script in the same way as Pino, which is like this:

ondoattackscript data/scripts/pinododge.c

in enemy's header text.
BUT the problem with that is "ondoattackscript" is already being used. :(

If you look at some enemy files from DDra, then you will see something like:

ondoattackscript ani0020ani

My understanding is that you can NOT use that twice in an enemy file, right?

You can't have, say:
ondoattackscript ani0020ani
AND
ondoattackscript data/scripts/pinododge.c

Or... are you just saying in the model.txt file, declare it?
ondoattackscript data/scripts/pinododge.c

Either way, I have an ondoattackscript that is ALREADY used in ALL enemy.txts for every enemy AND now this NEW one.

So can I use both in the same enemy.txt file?

If not, it feels like I would to combine the NEW dodge script into the OLD master enemy behavior script.

Thx again for your feedback.
 
You can't have, say:
ondoattackscript ani0020ani
AND
ondoattackscript data/scripts/pinododge.c

You can't have more than one script FILE for an event hook, but that one file can have as may functions and logic chains in it as you feel like, AND it can pull material from other files using #import or #include. This is where you have to start learning enough about the scripts that you can integrate them.

The super short version is you copy (or more optimally, #import) functions you need into the existing file, and then execute them as needed.

All event hooks other than animationscript require a function called main() which they execute each time the event fires. You can then have main() run your functions and do stuff.

DC
 
  • Like
Reactions: L K
You can't have more than one script FILE for an event hook, but that one file can have as may functions and logic chains in it as you feel like, AND it can pull material from other files using #import or #include. This is where you have to start learning enough about the scripts that you can integrate them.

The super short version is you copy (or more optimally, #import) functions you need into the existing file, and then execute them as needed.

All event hooks other than animationscript require a function called main() which they execute each time the event fires. You can then have main() run your functions and do stuff.

DC
I will have to experiment some more. I more or less tried what you suggested and thought I had satisfied the conditions and such BUT then openbor.exe just wouldn't load the script. So I will have to try a few variations of what I'm doing to see where the bug is.
 
Last edited:
Thanks.

I've read the header to find this line:
ondoattackscript data/scripts/ondoattack.c

You should find ondoattack.c instead and copy the scripts from pinododge.c there.
But allow me to do that for you, can you post ondoattack.c in your reply?
 
  • Like
Reactions: L K
ah... that makes MORE sense.
Thanks.

I've read the header to find this line:


You should find ondoattack.c instead and copy the scripts from pinododge.c there.
But allow me to do that for you, can you post ondoattack.c in your reply?
Here ya go, the ondoattack.c code:

Code:
void main()

{

    void self;

    void other;

    int which;

    int hit_by_id;

    int attack_id;

    void vAniID = getentityproperty(self,"animationID");

    int  attacktype1 = getlocalvar("attacktype");

    self  = getlocalvar("self");

    other = getlocalvar("other");

    which = getlocalvar("which");


    if(which && getentityproperty(other,"exists") && vAniID == openborconstant("ANI_FALL31")){

      if(which == openborconstant("EXCHANGE_RECIPIANT") && vAniID == openborconstant("ANI_FALL31") && attacktype1 == openborconstant("ATK_NORMAL31")){

        hit_by_id   = getentityproperty(self, "hitbyid");

        attack_id   = getlocalvar("attackid");

        if(hit_by_id != attack_id){

          changeopenborvariant("lasthitc", 0);

        }

      }

    }

}


AND here's the Pinododge.c code:

Code:
void main()

{// Dodges runattack

// Only performed if enemy is in IDLE or WALK

// When he/she dodges, he/she will perform FOLLOW1 animation

    void self = getlocalvar("self"); //Get calling entity.

    void Anim = getentityproperty(self, "animationID");

    if(Anim == openborconstant("ANI_IDLE") || Anim == openborconstant("ANI_WALK")){

      void target = findtarget(self);

      void EAnim = getentityproperty(target, "animationID");

      if(EAnim == openborconstant("ANI_RUNATTACK") || EAnim == openborconstant("ANI_JUMPATTACK") || EAnim == openborconstant("ANI_JUMPATTACK2") || EAnim == openborconstant("ANI_RUNJUMPATTACK")){

        changeopenborvariant("lasthitc", 0);

        changeentityproperty(self, "velocity", 0, 0);

        performattack(self, openborconstant("ANI_FOLLOW1"));

      }

    }

}
 
Last edited:
ah... that makes MORE sense.

Here ya go, the ondoattack.c code:

void main()
{
void self;
void other;
int which;
int hit_by_id;
int attack_id;
void vAniID = getentityproperty(self,"animationID");
int attacktype1 = getlocalvar("attacktype");
self = getlocalvar("self");
other = getlocalvar("other");
which = getlocalvar("which");

if(which && getentityproperty(other,"exists") && vAniID == openborconstant("ANI_FALL31")){
if(which == openborconstant("EXCHANGE_RECIPIANT") && vAniID == openborconstant("ANI_FALL31") && attacktype1 == openborconstant("ATK_NORMAL31")){
hit_by_id = getentityproperty(self, "hitbyid");
attack_id = getlocalvar("attackid");
if(hit_by_id != attack_id){
changeopenborvariant("lasthitc", 0);
}
}
}

}


AND here's the Pinododge.c code:

void main()
{// Dodges runattack
// Only performed if enemy is in IDLE or WALK
// When he/she dodges, he/she will perform FOLLOW1 animation
void self = getlocalvar("self"); //Get calling entity.
void Anim = getentityproperty(self, "animationID");
if(Anim == openborconstant("ANI_IDLE") || Anim == openborconstant("ANI_WALK")){
void target = findtarget(self);
void EAnim = getentityproperty(target, "animationID");
if(EAnim == openborconstant("ANI_RUNATTACK") || EAnim == openborconstant("ANI_JUMPATTACK") || EAnim == openborconstant("ANI_JUMPATTACK2") || EAnim == openborconstant("ANI_RUNJUMPATTACK")){
changeopenborvariant("lasthitc", 0);
changeentityproperty(self, "velocity", 0, 0);
performattack(self, openborconstant("ANI_FOLLOW1"));
}
}

}

@L K, please do not copy + paste code directly into posts. Use code tags. They are specifically for this.

DC
 
  • Like
Reactions: L K
Thank you, here's the combined script:
C:
void main()
{
    void self = getlocalvar("self"); //Get calling entity.
    void other = getlocalvar("other");
    int which = getlocalvar("which");
    void Anim = getentityproperty(self,"animationID");
    int attacktype1 = getlocalvar("attacktype");
    int hit_by_id;
    int attack_id;

    if(Anim == openborconstant("ANI_IDLE") || Anim == openborconstant("ANI_WALK")){
      void target = findtarget(self);
      void EAnim = getentityproperty(target, "animationID");

      if(EAnim == openborconstant("ANI_RUNATTACK") || EAnim == openborconstant("ANI_JUMPATTACK") || EAnim == openborconstant("ANI_JUMPATTACK2") || EAnim == openborconstant("ANI_RUNJUMPATTACK")){
        changeopenborvariant("lasthitc", 0);
        changeentityproperty(self, "velocity", 0, 0);
        performattack(self, openborconstant("ANI_FOLLOW1"));
      }
    }
    if(which && getentityproperty(other,"exists") && Anim == openborconstant("ANI_FALL31")){
      if(which == openborconstant("EXCHANGE_RECIPIANT") && Anim == openborconstant("ANI_FALL31") && attacktype1 == openborconstant("ATK_NORMAL31")){
        hit_by_id = getentityproperty(self, "hitbyid");
        attack_id = getlocalvar("attackid");

        if(hit_by_id != attack_id){
          changeopenborvariant("lasthitc", 0);
        }
      }
    }
}
 
  • Love
Reactions: L K
Thank you, here's the combined script:
C:
void main()
{
    void self = getlocalvar("self"); //Get calling entity.
    void other = getlocalvar("other");
    int which = getlocalvar("which");
    void Anim = getentityproperty(self,"animationID");
    int attacktype1 = getlocalvar("attacktype");
    int hit_by_id;
    int attack_id;

    if(Anim == openborconstant("ANI_IDLE") || Anim == openborconstant("ANI_WALK")){
      void target = findtarget(self);
      void EAnim = getentityproperty(target, "animationID");

      if(EAnim == openborconstant("ANI_RUNATTACK") || EAnim == openborconstant("ANI_JUMPATTACK") || EAnim == openborconstant("ANI_JUMPATTACK2") || EAnim == openborconstant("ANI_RUNJUMPATTACK")){
        changeopenborvariant("lasthitc", 0);
        changeentityproperty(self, "velocity", 0, 0);
        performattack(self, openborconstant("ANI_FOLLOW1"));
      }
    }
    if(which && getentityproperty(other,"exists") && Anim == openborconstant("ANI_FALL31")){
      if(which == openborconstant("EXCHANGE_RECIPIANT") && Anim == openborconstant("ANI_FALL31") && attacktype1 == openborconstant("ATK_NORMAL31")){
        hit_by_id = getentityproperty(self, "hitbyid");
        attack_id = getlocalvar("attackid");

        if(hit_by_id != attack_id){
          changeopenborvariant("lasthitc", 0);
        }
      }
    }
}
So... it crashed.lol But I looked into it some more.

I think it is because it is looking for a command called "dodgez" so I researched the DEMO game some more and sure enough it is MORE involved than the simple "pinododge" script.

The boss from the DEMO was ALSO wanting code from a file called on by the command "animationscript" harden.c in his enemy.txt file.

In "Double Dragon Reloaded Alt" the enemies txt files will point to "ani0020_actual.h" insofar as the "animationscript" command goes.

So I was forced to merge the code from the "harden.c" into that...

Code:
// =========================
// NEW MERGED SCRIPT
// =========================

#include "data/scripts/library/basic.h"
#include "data/scripts/library/spawn.h"
#include "data/scripts/library/target.h"

void attack1(int RxMin, int RxMax, int Rz, void Ani)
{
    void self = getlocalvar("self");
    void target = findtarget(self);
    float x = getentityproperty(self, "x");
    float z = getentityproperty(self, "z");
    int dir = getentityproperty(self, "direction");

    if(target!=NULL()){
      float Tx = getentityproperty(target, "x");
      float Tz = getentityproperty(target, "z");
      float Disx = Tx - x;
      float Disz = Tz - z;

      if(Disz < 0){ Disz = -Disz; }

      if( Disx >= RxMin && Disx <= RxMax && Disz <= Rz && dir == 1){
        performattack(self, openborconstant(Ani));
      } else if( Disx >= -RxMax && Disx <= -RxMin && Disz <= Rz && dir == 0){
        performattack(self, openborconstant(Ani));
      }
    }
}

void dodgez(float Vx, float Vy, float Vz)
{
    void self = getlocalvar("self");
    int z = getentityproperty(self, "z");
    int dir = getentityproperty(self,"direction");

    if(dir==0){ Vx = -Vx; }

    if(z > (openborvariant("PLAYER_MIN_Z") + openborvariant("PLAYER_MAX_Z")) / 2 ) {
      Vz = -Vz;
    }

    if( Vx!=NULL() && Vy!=NULL() && Vz!=NULL() ){
      changeentityproperty(self, "velocity", Vx, Vz, Vy);
    }
}

void slamstart()
{
   void self = getlocalvar("self");
   void target = getentityproperty(self, "opponent");

   setlocalvar("Grab" + self, target);
   damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL"));
}

// renamed to avoid conflict
void grabbind(int null, float x, float z, float y, int dir){
   void self = getlocalvar("self");
   void target = getlocalvar("Grab" + self);

   if(target==NULL()){
     target = getentityproperty(self, "opponent");
     setlocalvar("Grab" + self, target);
   }
   if(target!=NULL()){
     if(null == 1){
       bindentity(target, self, x, z, y, dir, 0);
     } else if(null == 0){
       bindentity(target, NULL());
     }
   }
}

void forceanim(int anim, int Frame){
   void self = getlocalvar("self");
   void target = getlocalvar("Grab" + self);

   if(target==NULL()){
     target = getentityproperty(self, "opponent");
     setlocalvar("Grab" + self, target);
   }
   if(target!=NULL()){
     changeentityproperty(target, "animation", openborconstant(anim));
     updateframe(target, Frame);
   }
}

void hurt(int Damage)
{
   void self = getlocalvar("self");
   void target = getlocalvar("Grab" + self);

   if(target==NULL()){
     target = getentityproperty(self, "opponent");
     setlocalvar("Grab" + self, target);
   }
   if(target!=NULL()){
     void THealth = getentityproperty(target,"health");
     if(THealth > Damage){
       changeentityproperty(target, "health", THealth - Damage);
     } else {
       changeentityproperty(target, "health", 1);
     }
   }
}

void finish(int Damage, int x, int y, int z, int Face)
{
   void self = getlocalvar("self");
   void target = getlocalvar("Grab" + self);
   int SDir = getentityproperty(target,"direction");
   int MDir;

   if(Face==0){ MDir = SDir; }
   if(Face==1){
     if(SDir==0){ MDir = 1; } else { MDir = 0;}
   }

   if(target==NULL()){
     target = getentityproperty(self, "opponent");
     setlocalvar("Grab" + self, target);
   }
   if(target!=NULL()){
     int dir = getentityproperty(target,"direction");

     if(dir==0){ x = -x; }

     damageentity(target, self, Damage, 1, openborconstant("ATK_NORMAL"));
     tossentity(target, y, x, z);
     changeentityproperty(target, "direction", MDir);
   }
}

void throw(int Damage, int x, int y, int z, int Face)
{
   void self = getlocalvar("self");
   void target = getlocalvar("Grab" + self);

   if(target==NULL()){
     target = getentityproperty(self, "opponent");
     setlocalvar("Grab" + self, target);
   }
   if(target!=NULL()){
     int SDir = getentityproperty(target,"direction");
     int MDir;

     if(Face==0){
       MDir = SDir;
     } else if(Face==1){
       if(SDir==0){ MDir = 1; } else { MDir = 0;}
     }

     if(SDir==0){ x = -x; }

     damageentity(target, self, 0, 1, openborconstant("ATK_NORMAL"));
     changeentityproperty(target, "attacking", 1);
     changeentityproperty(target, "damage_on_landing", Damage);
     changeentityproperty(target, "projectile", 1);
     changeentityproperty(target, "direction", MDir);
     tossentity(target, y, x, z);
   }
}

That code I included into the end of the main script.

Then I tried it out... and... it didn't crash!

I kinda worked??

Hard to say... I was only able to trick the enemy once into doing his side dance at first, to avoid the running attack. I will have to go back into the script and see if there are values I can tweak to trigger this behavior better. I am NOT a coder so, being mathematically inclined and very logic, I am able to limp my way through it somewhat.

But this is where I am at.... GOOD NEWS: no more crashing. BAD NEWS: it barely works, so, meh.lol

EDIT: UPDATE... Well, having played around with it enough, it really doesn't work well with this at all unfortunately. Will have to look into alternative ways to make these guys dodge running attacks. Want this behavior to mimic that of the OG Golden Axe where the enemies cleverly side step the diving sword/axe attacks from above. That's my inspiration anyways. Open for help or suggestions towards that end of course! Thanx everyone for the help here.
 
Last edited:
Back
Top Bottom