[Tutorial] [TuT]How to create a Vehicle Shooting (laser) + Some [Trigonometry]
#21

Thanks.
Reply
#22

Extremely detailed, and excellently explained. You obviously put a lot of time and effort into it which is amazing. For the gamemode I am creating I don't necessarily need it, but in the event I ever make a deathmatch freeroam type script, this will be added as a gamemode. Excellent. Good job.
Reply
#23

Some things are useless tho. The timer, ShotFire, for example isn't needed because you can do this:

pawn Code:
public OnObjectMoved(objectid)
{
    for(new i;i<MAX_PLAYERS;i++)
    {
        if(objectid == gRocketObj[i])
        {
            new
                Float:x,
                Float:y,
                Float:z;

            GetObjectPos(gRocketObj[i], x, y, z);
            CreateExplosion(x, y, z, 11, 3.0);
            DestroyObject(gRocketObj[i]);
            FireShot[i] = 0;
        }
    }
}
Or even better .. You don't need "FireShot". All what you need to check is if the object of the player exists. One less variable then If the player fired the laser, then the object is valid right ?

So you could delete these lines:
pawn Code:
new FireShot[MAX_PLAYERS];

FireShot[playerid] = 1;
SetTimerEx("ShotFire", 1000, 0, "i", playerid);

forward ShotFire(playerid);
public ShotFire(playerid)
{
        FireShot[playerid] = 0;
        return 1;
}
... and it should still work.
Reply
#24

Quote:
Originally Posted by Michael@Belgium
View Post

... and it should still work.
Correct, But i've put the timer for 2 things.
First, If someone want's to make them wait 5 seconds, Then they can edit the timer. Because if there's no Timer, I think the object get's destroyed after like 1-2 Seconds itself.

2nd thing is that, If i shot and the target is near, Then i can Spam the lasers as the object get's deleted fast because the target is near.
Thanks for your comments.

Thanks everyone.
Reply
#25

Woah, really nice, very well detailed
Reply
#26

You have just one tutorial but this one is equal to 10 . It is awesome yaar . I liked it so much
Reply
#27

Thanks Arxalan
Reply
#28

Nice tutorial, I have learned some things myself, however I also think you could have made it better:
  • Although it's not necessary, you could tag FireShot[MAX_PLAYERS] as a bool so it only accepts two values.
  • I'm not sure but I think IsPlayerInAnyVehicle(playerid) works for passengers too, and I guess you don't want passengers to shoot. I would use if GetPlayerState(playerid) == PLAYER_STATE_DRIVER instead.
  • Instead of newkeys & 4 I would use newkeys & KEY_FIRE for better readability and because you never know if sa-mp might change its defines someday for some reason.
  • Why are you using SetPlayerTime(playerid,0,0) when the laser is fired?
  • When you do Float:dist = 50.0 and if(IsPlayerInRangeOfPoint(i, 50.0, x, y, z)) I think it's better that 50.0 be a define at the top of your script, so you can easily change that value if you want.
  • Instead of SetTimerEx("ShotFire", 1000, 0, "i", playerid) I think it's better to use GetTickCount() and a variable to store the time. I think with this you wouldn't even need FireShot[MAX_PLAYERS] anymore.
  • In your two loops you should use break; after your code is executed so the loop will not continue checking for players.
  • EDIT: VERY IMPORTANT!!! If you write a filterscript, you must return a value in your callbacks because otherwise those callbacks won't be called in your gamemode.
So I would script it like this. I have commented those lines of yours that I would remove or replace for others:

pawn Code:
#include <a_samp>

#define LASER_DISTANCE 50 // Added this

//new FireShot[MAX_PLAYERS];
new TimeOfLastShot[MAX_PLAYERS]; // This instead
new gRocketObj[MAX_PLAYERS];

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    //if(IsPlayerInAnyVehicle(playerid) && FireShot[playerid] == 0 && newkeys & 4 && !IsValidObject(gRocketObj[playerid]))   // Only run the code if the object doesn't already exist, otherwise more objects will take up gRocketObj and the previous ones won't be deleted
    if( (GetPlayerState(playerid) == PLAYER_STATE_DRIVER) && ( (GetTickCount() - TimeOfLastShot[playerid]) >= 1000 ) && (newkeys & KEY_FIRE) && !IsValidObject(gRocketObj[playerid]) ) // This instead
    {
        SetPlayerTime(playerid,0,0);
        new
            vehicleid = GetPlayerVehicleID(playerid),
            Float:x,
            Float:y,
            Float:z,
            Float:r,
            //Float:dist = 50.0,
            Float:dist = LASER_DISTANCE, // This instead
            Float:tmpang,
            Float:tmpx,
            Float:tmpy,
            Float:tmpz;

        //FireShot[playerid] = 1;
        //SetTimerEx("ShotFire", 1000, 0, "i", playerid);
        TimeOfLastShot[playerid] = GetTickCount(); // This instead
        GetVehiclePos(vehicleid, x, y, z);
        GetVehicleZAngle(vehicleid, r);
        new rand = random(12);
        switch(rand)
        {
            case 0: gRocketObj[playerid] = CreateObject(18647, x, y, z, 0, 0, r);
            case 1: gRocketObj[playerid] = CreateObject(18648, x, y, z, 0, 0, r);
            case 2: gRocketObj[playerid] = CreateObject(18649, x, y, z, 0, 0, r);
            case 3: gRocketObj[playerid] = CreateObject(18650, x, y, z, 0, 0, r);
            case 4: gRocketObj[playerid] = CreateObject(18651, x, y, z, 0, 0, r);
            case 5: gRocketObj[playerid] = CreateObject(18652, x, y, z, 0, 0, r);
            case 6: gRocketObj[playerid] = CreateObject(18647, x, y, z, 0, 0, r+90);
            case 7: gRocketObj[playerid] = CreateObject(18648, x, y, z, 0, 0, r+90);
            case 8: gRocketObj[playerid] = CreateObject(18649, x, y, z, 0, 0, r+90);
            case 9: gRocketObj[playerid] = CreateObject(18650, x, y, z, 0, 0, r+90);
            case 10: gRocketObj[playerid] = CreateObject(18651, x, y, z, 0, 0, r+90);
            case 11: gRocketObj[playerid] = CreateObject(18652, x, y, z, 0, 0, r+90);
        }
        for(new i;i<MAX_PLAYERS;i++)
        {
            if(IsPlayerConnected(i))
            if(i == playerid)continue;
            //if(IsPlayerInRangeOfPoint(i, 50.0, x, y, z))
            if(IsPlayerInRangeOfPoint(i, LASER_DISTANCE, x, y, z)) // This instead
            {
                GetPlayerPos(i, tmpx, tmpy, tmpz);
                tmpang = (90-atan2(tmpy-y, tmpx-x));
                if(tmpang < 0)tmpang = 360.0+tmpang;
                tmpang = 360.0 - tmpang;
                if(floatabs(tmpang-r) < 5.0)
                {
                    dist = GetPlayerDistanceFromPoint(i, x, y, z);
                    break; // Added this
                }
            }
        }
        MoveObject(gRocketObj[playerid],x + (dist * floatsin(-r, degrees)),y + (dist * floatcos(-r, degrees)),z,100.0);                             // Nice and fast!
    }
    return 1; // Added this
}



/*forward ShotFire(playerid);
public ShotFire(playerid)
{
        FireShot[playerid] = 0;
        return 1;
}*/
 //Not needed

public OnObjectMoved(objectid)
{
        for(new i;i<MAX_PLAYERS;i++)
        {
                if(objectid == gRocketObj[i])
                {
                    new
                        Float:x,
                        Float:y,
                        Float:z;

                    GetObjectPos(gRocketObj[i], x, y, z);
                    CreateExplosion(x, y, z, 11, 3.0);
                    DestroyObject(gRocketObj[i]);
                    break; // Added this
                }
        }
        return 1; // Added this
}
Reply
#29

Quote:
Originally Posted by Gryphus One
View Post
Nice tutorial, I have learned some things myself, however I also think you could have made it better.
Hello.
Thanks for pointing those silly mistakes out :P
Actually yeah, it could be a lot better.Actually i made the FS in ' 30/07/2012 ' and i never looked back at it again :P

Thanks
Reply
#30

Actually this really amazed me,

I actually have a problem
Reply
#31

Quote:
Originally Posted by Arastair
View Post
Actually this really amazed me,

I actually have a problem
What is it?
Reply
#32

Quote:
Originally Posted by Rudy_
View Post
e.g if i press LMB (KEY_FIRE), it's newkeys untill i release it then it's oldkeys.
pawn Code:
if(IsPlayerInAnyVehicle(playerid) && FireShot[playerid] == 0 && newkeys & 4 && !IsValidObject(gRocketObj[playerid]))
Haven't read it all yet, but this seems to be a recurrent problem among many users. Why don't you just use KEY_FIRE? I've noticed many people do the same when they need to use, for example, PLAYER_STATE_DRIVER. I reckon using the definition is a lot more clearer than 4 or 2?
Reply
#33

Quote:
Originally Posted by Vince
View Post
Haven't read it all yet, but this seems to be a recurrent problem among many users. Why don't you just use KEY_FIRE? I've noticed many people do the same when they need to use, for example, PLAYER_STATE_DRIVER. I reckon using the definition is a lot more clearer than 4 or 2?
I wanted to change it, But then i thought if anyone reads it and don't know what ' 4 ' is, Might learn it aswell... For minor knowledge ^^
Reply
#34

very nice detalied tutorial
Reply
#35

amazing tutorial
Reply
#36

Thanks, Glad you liked it
Reply
#37

Awesome tut,keep it up
Reply
#38

Glad you liked it..
Reply
#39

Awesome Tutorial
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)