Solved Weapon Durability

Question that is answered or resolved.

Luca Natale

New member
I couldn't find anything related to this in the legacy manual or forums so I guess I'll put this out there.

What I'm going for here is to limit a weapon's number of uses. The weapon in question will break once it has been used enough times.

I know I can use shootnum for guns and missiles, what about physical weapons? The manual says shootnum is how many times you can fire a weapon. I feel like if I assign shootnum of 8 to, say, a baseball bat, that will mean I can only swing the bat 8 times regardless of whether or not I hit something.

Am I wrong about this and I can use shootnum for physical weapons, or do I need some kind of script for this?
 
Solution
Too bad...
I did gain an idea that might not need the script. Checking the manual I found that "followcond" can trigger a "follow" after an attack box connects.
I might be able to link the weapon attack to a follow animation that includes an empty shootframe to count the shot.

Do I still need to script or am I on to something here?
Shootnum doesn't care what the weapon is or does. Why would it? It will work for any sort of weapon.

That's why I always advice creators to think abstractly and not literally. 😀

DC
 
I tried this out a moment ago on a pipe weapon in this game. I have assigned shootnum of 8 to the pipe item.
When I pick up the pipe the shotnum is displayed, but it doesn't change when I use it. I'm not too sure what I'm doing wrong.

I think I might need to use shootframe in the armed player's txt for it to count as a shot spent, but if I do, I'm not sure how to make it so that the shot is only spent when a hit is made.
 
Ahh, my bad. You can turn off the numeric display, but there's no native way to only expend "ammo" on hit. I thought you wanted to expend on every swing.

For on hit only we will need to do a script.

DC
 
Too bad...
I did gain an idea that might not need the script. Checking the manual I found that "followcond" can trigger a "follow" after an attack box connects.
I might be able to link the weapon attack to a follow animation that includes an empty shootframe to count the shot.

Do I still need to script or am I on to something here?
 
Solution
I'm usually not big on workarounds like that. They tend to be unstable and a ton of work just to avoid what amounts to a 2-3 line script, but so long as you are careful in how you set it up this should work.

DC
 
What I'm going for here is to limit a weapon's number of uses. The weapon in question will break once it has been used enough times
@Luca Natale

I'm using this kind of mechanic in the SORX. I don't know if the code will fit for your purpose but can give you an idea of how it works, then you can make some modifications or erase the parts you don't need.

The concept is basically using the didhitscript event to register every weapon hit and change the animation when it reaches the limit. The takedamagescript is used only to reset the counter variable in case the player loses the weapon before reaching the limit.

didhitscript
C:
void breakWeapon()
{//Script to limit the weapon usage (Heroes only)
    void self        = getlocalvar("self");
    void dModel        = getentityproperty(self, "defaultmodel");
    void vModel        = getentityproperty(self, "model");
    void atkType    = getlocalvar("attacktype");
    int blocked        = getlocalvar("blocked");
    int valid1        = getentityproperty(self, "animvalid", openborconstant("ANI_FOLLOW14"));
    int valid2        = getentityproperty(self, "animvalid", openborconstant("ANI_FOLLOW15"));
    int valid3        = getentityproperty(self, "animvalid", openborconstant("ANI_FOLLOW16"));

    //CHECK IF THE ENTITY IS A WEAPON MODEL OR THE DEFAULT MODEL, AND IF THE ATTACK WAS NOT BLOCKED
    if(dModel != vModel && !blocked){

        //CHECK IF IT'S A WEAPON ATTACK
        if(atkType == openborconstant("ATK_NORMAL4") || atkType == openborconstant("ATK_NORMAL5")){
           
            //CHECK IF THE ENTITY HAS THE REQUIRED ANIMATION
            if(valid1 || valid2 || valid3){
                void vSpawn;
                int height        = getentityproperty(self, "y");
                int base        = getentityproperty(self, "base");
                int limit        = 10;

                //START THE VARIABLE COUNTER
                if(getentityvar(self, "weapCounter") == NULL()){setentityvar(self, "weapCounter", 1);}

                //AVOID CHANGING ANIMATION IF THE CHARACTER IS IN THE AIR OR DURING DEFINED MOVES
                if(getentityvar(self, "weapCounter") >= limit){
                    if(height == base){

                        //BACK HIT, LIKE MAX PIPE
                        if(atkType == openborconstant("ATK_NORMAL5")){
                            changeentityproperty(self, "velocity", 0, 0, 0);
                            performattack(self, openborconstant("ANI_FOLLOW15"), 1);
                        }else

                        //DEFAULT
                        {
                            changeentityproperty(self, "velocity", 0, 0, 0);
                            performattack(self, openborconstant("ANI_FOLLOW14"), 1);
                        }
                    }
                    else //AIR HIT, LIKE MAX PIPE JUMPATTACK
                    {
                        performattack(self, openborconstant("ANI_FOLLOW16"), 1);
                    }
                }
                else
                {
                    //WEAPON USAGE COUNTER
                    setentityvar(self, "weapCounter", getentityvar(self, "weapCounter")+1);
                }
            }
        }
    }
    else //NO WEAPON?? RESET THE VARIABLE
    {
        if(getentityvar(self, "weapCounter") != NULL()){setentityvar(self, "weapCounter", NULL());}
    }
}

takedamagescript
C:
void resetWeapon()
{//Clear weapon's variables while falling and losing a weapon (Heroes only)
    void self    = getlocalvar("self");
    int drop    = getlocalvar("drop");

    if(drop){
        if(getentityvar(self, "weapCounter") != NULL()){setentityvar(self, "weapCounter", NULL());}
    }
}

Here's an example of how I'm using it in a character, don't forget to put the correct attack number in your attack box, in this case is the "attack4", and to declare the throwframe command to return the character to his default model.
C:
anim attack1 #NORMAL ATTACK
    fastattack 1
    jugglecost 16
    forcedirection -1
    otg 1
    loop    0
    delay    8
    offset    62 125
    bbox    55 48 18 81
    @cmd hitfx "data/sounds/sor2_hit5.wav"
    @cmd sound "data/sounds/sor2_pipe.wav"
    frame    data/chars/heroes/axel/pipe/a100.png
    attack4 114 42 4 4 12 1 0 0 30 12
    bbox    49 51 20 78
    frame    data/chars/heroes/axel/pipe/a101.png
    attack4 77 93 71 6 12 1 0 0 30 12
    bbox    69 61 26 67
    frame    data/chars/heroes/axel/pipe/a102.png
    attack 0 0 0 0 0 0 0 0 0 0
    bbox    72 64 27 64
    frame    data/chars/heroes/axel/pipe/a103.png
   
anim follow14 #SPEND WEAPON
    throwframe 0 9999
    loop    0
    delay    8
    offset    62 125
    @cmd throWeapon 60 24 -1 0.5 1 0 1
    frame    data/chars/heroes/axel/pipe/a104.png
    frame    data/chars/heroes/axel/pipe/a104.png

 
Last edited:
Back
Top Bottom