[Tutorial] Anti No-Reload
#1

Hello,

In this thread I'll explain to you step by step how to create simple Anti No-reload functionality.

First, You'll need latest (0.3z) version of SA:MP as we are going to use callback "OnPlayerWeaponShot", second you'll need to implement your own "GetPlayerSkill" function.

So let's start, firstly we'll define how many round per minute can any weapon fire on each player skill level. For this we'll use information from THIS source.

*Almost each weapon have 3 different RPM's, RPM depends on player shooting skill for that weapon.

After we gather all required informations we will create an array containing each RPM for each weapon, It will look something like this.

pawn Код:
enum _weapon_info {
    clipSize,
    rpm[3]
}
new wInfos[47][_weapon_info] = {
    {0, {0,0,0}},//none weapon
    ...// list of weapons
    {7, {65, 75, 85}},//desert eagle
    ...// rest of list
}
So, now when we have RPM informations for each weapon we need to define some more arrays and public functions.

Functions:
pawn Код:
forward GetPlayerWeaponSkill(playerid, weaponid); // will return integer which presents player skill for certain weapon
forward ClearLastShot(playerid); // will clear number of shots
Array:
pawn Код:
enum _player_shot_infos {
    weaponId,
    shotCount,
    timer
};

new pLastShot[MAX_PLAYERS][_player_shot_infos]
Okay, now we are ready to implement our functionality.

pawn Код:
public GetPlayerSkillLevel(playerid, weaponid)
{
    return 400;
}

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    new rpm, time, skilLLevel = GetPlayerSkillLevel(playerid, weaponid)// get player skill level;

    if (pLastShot[playerid][lWeaponId] != weaponid) {// check is current weapon same as on previous shot

        if (pLastShot[playerid][timer]) {// check is timer active
            KillTimer(pLastShot[playerid][timer]);//if so, deactivate timer
        }

        pLastShot[playerid][lWeaponId] = weaponid; // set weapon to current one
        pLastShot[playerid][lCount] = 0; // reset shot counter

        if (skilLLevel < 300) { // check for skill level and set required array offset
            rpm_offset = 0;
        } else if (skilLLevel < 600) {
            rpm_offset = 1;
        } else if (skilLLevel < 900) {
            rpm_offset = 2;
        }

        // calculate time required to reset shot counter
        // as we have RPM (Round per minute) we'll need to convert that to RPS (round per second)
        // and then multiply it with weapon's clip size
        // that's how we'll get time required to shot out all bullets from one clip
        time = floatround((wInfo[weaponid][rpm][rpm_offset] / 60)) * wInfo[weaponid][clipSize];

        // now we start timer with calculated time multiplied with 1000 to convert it to milliseconds
        pLastShot[playerid][timer] = SetTimerEx("ClearLastShot", time * 1000, false, "d", playerid);
    } else {// in case that shot came from same weapon as last one
        pLastShot[playerid][shotCount]++;// add +1 bullet to counter
    }

    if (pLastShot[playerid][shotCount] > wInfo[weaponid][clipSize]) {// check is player shooting more than weapon can hold
        return 0;// if yes, return 0 to prevent bullet from causing damage
    }

    return 1;//in case that all is okay, bullet should cause damage
}

public ClearLastShot(playerid)
{
    pLastShot[playerid][shotCount] = 0; // reset counter to 0
}
I hope you understood tutorial, if you have any question or if you find any bug please notify me. Feel free to ask anything

Cheers...
Reply
#2

Quote:
Originally Posted by CoaPsyFactor
Посмотреть сообщение
First, You'll need latest (0.3z) version of SA:MP
Been living under a rock?
Reply
#3

No dude, I know it's 0.3.7 latest version, but if you go HERE you will see that this is supported in and after 0.3z version... so please, if you have nothing smart to say....
Reply
#4

Then you explained it wrong, you should say you need atleast 0.3z not latest 0.3z, it makes a difference.
Reply
#5

Quote:
Originally Posted by DaniceMcHarley
Посмотреть сообщение
Then you explained it wrong, you should say you need atleast 0.3z not latest 0.3z, it makes a difference.
thank you
Reply
#6

Quote:
Originally Posted by Vince
Посмотреть сообщение
Been living under a rock?
why u critizing on that one thing.. i think its unnecessary. He is just making sure that people have the right version. Plus its always good to have the latest .0.3.7.

tutorials should be user friendly because its mostly for new scripters remember. good tutorial
Reply
#7

gimme the full code, without any explanation. So, i can put that in my GM

I dont understand what you're saying.

Nice one tho :P
Reply
#8

Quote:
Originally Posted by Airman123
Посмотреть сообщение
gimme the full code, without any explanation. So, i can put that in my GM

I dont understand what you're saying.

Nice one tho :P
Here is what I've scirpted for my gamemode

pawn Код:
enum _weapon_data {
    wId,
    wSlot,
    wModel,
    Float:wDamage,
    bool:wShootable,
    wName[32],
    wClipSize,
    wRPM[3]
};

// weapons data
new wInfo[47][_weapon_data] = {
    {0, 0, 0, 0.0},
    {WEAPON_BRASSKNUCKLE, 0, 331, 1.0, false, "", 0, {0, 0, 0}},
    {WEAPON_GOLFCLUB, 1, 333, 1.2, false, "", 0, {0, 0, 0}},
    {WEAPON_NITESTICK, 1, 334, 1.2, false, "", 0, {0, 0, 0}},
    {WEAPON_KNIFE, 1, 335, 1.5, false, "", 0, {0, 0, 0}},
    {WEAPON_BAT, 1, 336, 1.2, false, "", 0, {0, 0, 0}},
    {WEAPON_SHOVEL, 1, 337, 1.2, false, "", 0, {0, 0, 0}},
    {WEAPON_POOLSTICK, 1, 338, 0.9, false, "", 0, {0, 0, 0}},
    {WEAPON_KATANA, 1, 339, 3.0, false, "", 0, {0, 0, 0}},
    {WEAPON_CHAINSAW, 1, 341, 5.0, false, "", 0, {0, 0, 0}},
    {WEAPON_DILDO, 10, 321, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_DILDO2, 10, 322, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_VIBRATOR, 10, 323, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_VIBRATOR2, 10, 324, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_FLOWER, 10, 325, 0.0, false, "", 0, {0, 0, 0}},
    {WEAPON_CANE, 10, 326, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_GRENADE, 8, 342, 100.0, false, "", 0, {0, 0, 0}},
    {WEAPON_TEARGAS, 8, 343, 10.0, false, "", 0, {0, 0, 0}},
    {WEAPON_MOLTOV, 8, 344, 50.0, false, "", 0, {0, 0, 0}},
    {0, 0, 0, 0.0, false, "", 0, {0, 0, 0}},
    {0, 0, 0, 0.0, false, "", 0, {0, 0, 0}},
    {0, 0, 0, 0.0, false, "", 0, {0, 0, 0}},
    {WEAPON_COLT45, 2, 346, 10.0, true, "", 12, {165, 200, 300}},
    {WEAPON_SILENCED, 2, 347, 10.0, true, "", 17, {130, 150, 165}},
    {WEAPON_DEAGLE, 2, 348, 25.0, true, "", 7, {65, 75, 85}},
    {WEAPON_SHOTGUN, 3, 349, 50.0, true, "", 1, {55, 55, 55}},
    {WEAPON_SAWEDOFF, 3, 350, 50.0, true, "", 2, {200, 200, 400}},
    {WEAPON_SHOTGSPA, 3, 351, 50.0, true, "", 7, {150, 180, 180}},
    {WEAPON_UZI, 4, 352, 10.0, true, "", 50, {450, 450, 900}},
    {WEAPON_MP5, 4, 353, 10.0, true, "", 30, {650, 650, 650}},
    {WEAPON_AK47, 5, 355, 15.0, true, "", 30, {450, 450, 450}},
    {WEAPON_M4, 5, 356, 15.0, true, "", 50, {450, 450, 450}},
    {WEAPON_TEC9, 4, 372, 8.0, true, "", 50, {450, 450, 900}},
    {WEAPON_RIFLE, 6, 357, 5.0, true, "", 1, {55, 55, 55}},
    {WEAPON_SNIPER, 6, 358, 50.0, true, "", 1, {55, 55, 55}},
    {WEAPON_ROCKETLAUNCHER, 7, 359, 100.0, true, "", 1, {55, 55, 55}},
    {WEAPON_HEATSEEKER, 7, 360, 100.0, true, "", 1, {55, 55, 55}},
    {WEAPON_FLAMETHROWER, 7, 361, 50.0, true, "", 0, {180, 180, 180}},
    {WEAPON_MINIGUN, 7, 362, 10.0, true, "", 0, {1800, 1800, 1800}},
    {WEAPON_SATCHEL, 8. 363, 50.0, false, "", 0, {0, 0, 0}},
    {WEAPON_BOMB, 12, 364, 0.0, false, "", 0, {0, 0, 0}},
    {WEAPON_SPRAYCAN, 9, 365, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_FIREEXTINGUISHER, 9, 366, 0.1, false, "", 0, {0, 0, 0}},
    {WEAPON_CAMERA, 9, 367, 0.0, false, "", 0, {0, 0, 0}},
    {0, 0, 0, 0.0, false, "", 0, {0, 0, 0}},
    {0, 0, 0, 0.0, false, "", 0, {0, 0, 0}},
    {WEAPON_PARACHUTE, 11, 371, 0.0, false, "", 0, {0, 0, 0}}
};

enum _player_skills {
    ORM:sOrmId,
    sId,
    sPlayerId,
    sColt,
    sSilenced,
    sDeagle,
    sShotgun,
    sSawnoff,
    sCombat,
    sUzi,
    sSMG,
    sAK47,
    sM4,
    sTec9,
    sRifle,
    sSniper
};

// skill definitions
new sInfo[MAX_PLAYERS][_player_skills];

enum _last_shot_info {
    lWeaponId,
    lCount,
    lTime
};

// last shot data
new pLastShot[MAX_PLAYERS][_last_shot_info];

public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ)
{
    new rpm, time, skilLLevel = GetPlayerSkillLevel(playerid, weaponid);


    if (pLastShot[playerid][lWeaponId] != weaponid) {

        if (pLastShot[playerid][lTime]) {
            KillTimer(pLastShot[playerid][lTime]);
        }

        pLastShot[playerid][lWeaponId] = weaponid;
        pLastShot[playerid][lCount] = 0;

        if (skilLLevel < 300) {
            rpm = 0;
        } else if (skilLLevel < 600) {
            rpm = 1;
        } else if (skilLLevel < 900) {
            rpm = 2;
        }

        time = floatround((wInfo[weaponid][wRPM][rpm] / 60)) * wInfo[weaponid][wClipSize];

        pLastShot[playerid][lTime] = SetTimerEx("ClearLastShot", time * 1000, false, "d", playerid);
    } else {
        pLastShot[playerid][lCount]++;
    }

    if (pLastShot[playerid][lCount] > wInfo[weaponid][wClipSize]) {
        return 0;
    }

    return 1;
}

forward ClearLastShot(playerid);
public ClearLastShot(playerid)
{
    pLastShot[playerid][lCount] = 0;
}

forward GetPlayerSkillLevel(playerid, weaponid);
public GetPlayerSkillLevel(playerid, weaponid)
{
    new skill = 0;

    if (weaponid >= WEAPON_COLT45 && weaponid <= WEAPON_SNIPER) {
        switch (weaponid) {
            case WEAPON_COLT45: {
                skill = sInfo[playerid][sColt];
            }
            case WEAPON_SILENCED: {
                skill = sInfo[playerid][sSilenced];
            }
            case WEAPON_DEAGLE: {
                skill = sInfo[playerid][sShotgun];
            }
            case WEAPON_SHOTGUN: {
                skill = sInfo[playerid][sShotgun];
            }
            case WEAPON_SAWEDOFF: {
                skill = sInfo[playerid][sSawnoff];
            }
            case WEAPON_SHOTGSPA: {
                skill = sInfo[playerid][sCombat];
            }
            case WEAPON_UZI: {
                skill = sInfo[playerid][sUzi];
            }
            case WEAPON_MP5: {
                skill = sInfo[playerid][sSMG];
            }
            case WEAPON_AK47: {
                skill = sInfo[playerid][sAK47];
            }
            case WEAPON_M4: {
                skill = sInfo[playerid][sM4];
            }
            case WEAPON_TEC9: {
                skill = sInfo[playerid][sTec9];
            }
            case WEAPON_RIFLE: {
                skill = sInfo[playerid][sRifle];
            }
            case WEAPON_SNIPER: {
                skill = sInfo[playerid][sSniper];
            }
        }
    }

    return skill;
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)