[Tutorial] [TUT]Basic Object Streamer
#1

Basic Object Streamer
This took me a total of 10 minutes .

Defines (This time I'm not using a enum because there isn't as much data and it's easier).

pawn Код:
#define MAX_STREAMED_OBJECTS 5000 //The less the better, this will total at around 3mb AMX file size.
new ObjectModel[MAX_STREAMED_OBJECTS]; //Objectmodel
new Float:ObjectPos[MAX_STREAMED_OBJECTS][3]; //ObjectPos (X, Y, Z)
new Float:ObjectRotation[MAX_STREAMED_OBJECTS][3]; //ObjectRotation (X, Y, Z)
new Float:ObjectDistance[MAX_STREAMED_OBJECTS]; //Veiw distance
new ObjectIDS[MAX_PLAYERS][MAX_STREAMED_OBJECTS]; //Object ID's.
new ObjectStreamed[MAX_PLAYERS][MAX_STREAMED_OBJECTS]; //Objects being viewed by a player
new ObjectID = -1; //ObjectCount
new ObjectUsed[MAX_STREAMED_OBJECTS]; //Disable = 0 enable = 1
We need to now set a timer for our streamed objects. You can muck around with the timing time because it does pass alot of info per time. Place this under OnGameModeInit or OnFilterScriptInit.
pawn Код:
SetTimer("Stream", 400, true);
OK, time for creating the objects, I've used a optional distance so the parameters are the same as create object . I would recommending using the distance if you are in a crowed object area.

pawn Код:
stock CreateObjectEx(ModelID, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ, Float:Dist = 100.0)
{
    ObjectID++; //ObjectID
    ObjectModel[ObjectID] = ModelID; //Model
    ObjectPos[ObjectID][0] = X; //XPos
    ObjectPos[ObjectID][1] = Y; //YPos
    ObjectPos[ObjectID][2] = Z; //ZPos
    ObjectRotation[ObjectID][0] = rX; //RotationX
    ObjectRotation[ObjectID][1] = rY;//RotationY
    ObjectRotation[ObjectID][2] = rZ; //RotationZ
    ObjectDistance[ObjectID] = Dist; //View distance
    ObjectUsed[ObjectID] = 1; //Disable/enable the object, it's starting off being enabled.
}
Now that was fast, lets STREAM!!

pawn Код:
forward Stream();
public Stream()
{
    for(new i; i<MAX_PLAYERS; i++)//Goes through all players
    {
      if(IsPlayerConnected(i)) //All online players
      {
        for(new S; S<ObjectID+1; S++) //All active Checkpoints
        {
          if(ObjectUsed[S] == 1) //Checks if the object is enabled
          {
                    if(IsPlayerInRangeOfPoint(i, ObjectDistance[S], ObjectPos[S][0], ObjectPos[S][1], ObjectPos[S][2]) && ObjectStreamed[i][S] == 0)//Is the player close enough to the object
                    {
                      ObjectIDS[i][S] = CreatePlayerObject(i, ObjectModel[S], ObjectPos[S][0], ObjectPos[S][1], ObjectPos[S][2], ObjectRotation[S][0], ObjectRotation[S][1], ObjectRotation[S][2]);//Create the object
              ObjectStreamed[i][S] = 1; //Shows the object streamed for the player
              continue;
                    }
                }
                if(!IsPlayerInRangeOfPoint(i, ObjectDistance[S], ObjectPos[S][0], ObjectPos[S][1], ObjectPos[S][2]) && ObjectStreamed[i][S] == 1) //If the object isn't in distance and the player is viewing, then we destory it!
                {
                ObjectStreamed[i][S] = 0;
                  DestroyPlayerObject(i, ObjectIDS[i][S]);
                  continue;
                }
            }
        }
    }
    return 1;
}
Here is a few extra functions that we may find useful:
pawn Код:
stock DestoryObjectEx(ObjectId) //Destroys the object
{
    ObjectUsed[ObjectId] = 0;
    for(new i; i<MAX_PLAYERS; i++)
    {
      if(ObjectStreamed[i][ObjectId] == 1)
      {
        ObjectStreamed[i][ObjectId] = 0;
        DestroyPlayerObject(i, ObjectIDS[i][ObjectId]);
        }
    }
}


stock SetObjectDistance(ObjectId, Float:Dist) //Sets the view distance of a object
{
    ObjectDistance[ObjectId] = Dist;
}
Have fun making your own object streamer, I'll make more tomorrow .
Reply
#2

Nice tutorial
Reply
#3

Quote:
Originally Posted by [03
Garsino ]
Nice tutorial
Thanks .
Reply
#4

Quote:
Originally Posted by [ЉǾǖŦĦЗŁΛẄ
~ [HellFire] ]
That's a good one I might have a bash at making my own, I can make it more efficient than the one i got and just make the stock function the same so no more converting!

Thanks
Good luck on your own object streamer, it's not that hard if you think about it .
Reply
#5

Nice Tut, Would be useful for some people.
Reply
#6

Quote:
Originally Posted by [HiC
TheKiller ]
pawn Код:
stock DestoryObjectEx(ObjectId) //Destroys the object
{
    ObjectUsed[ObjectId] = 0;
    for(new i; i<MAX_PLAYERS; i++)
    {
      if(ObjectStreamed[i][ObjectId] == 1)
      {
        ObjectStreamed[i][ObjectId] = 0;
        DestroyPlayerObject(i, ObjectIDS[i][ObjectId]);
        }
    }
}
Destroy spelling mistake, DestoryObjectEx(ObjectId)
Reply
#7

Quote:
Originally Posted by V1ceC1ty
Quote:
Originally Posted by [HiC
TheKiller ]
pawn Код:
stock DestoryObjectEx(ObjectId) //Destroys the object
{
    ObjectUsed[ObjectId] = 0;
    for(new i; i<MAX_PLAYERS; i++)
    {
      if(ObjectStreamed[i][ObjectId] == 1)
      {
        ObjectStreamed[i][ObjectId] = 0;
        DestroyPlayerObject(i, ObjectIDS[i][ObjectId]);
        }
    }
}
Destroy spelling mistake, DestoryObjectEx(ObjectId)
Oh thanks, I'll fix that.

Quote:
Originally Posted by [ЉǾǖŦĦЗŁΛẄ
~ [HellFire] ]
Quote:
Originally Posted by [HiC
TheKiller ]
it's not that hard if you think about it .
Yeah I always thought that, just detect if their near and create the object! I always wanted to make my own but never did now I found this it's motivated me! thanks again
Good luck .
Reply
#8

sorry,but i've created a FS with yours code,everything is good but how create an object with my streamer?
Reply
#9

Quote:
Originally Posted by XRVX
Quote:
Originally Posted by adytzu32
sorry,but i've created a FS with yours code,everything is good but how create an object with my streamer?
make in MTA
and then convert it to sa-mp
www.convertffs.com
yes,i know that but how can i add into my streamer...what function?
Reply
#10

Quote:
Originally Posted by adytzu32
Посмотреть сообщение
yes,i know that but how can i add into my streamer...what function?
Read more carefully.
pawn Код:
CreateObjectEx(ModelID, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ, Float:Dist = 100.0)
Nice tutorial, but i will stay with professional made scripts(y_less,incognito's)
Reply
#11

Hi... Thanks for the tutorial.. im having a trouble here... im testing this, i used to have another streamer (Midostream) so i changed the tutorial funtions so i didnt had to convernt anything...i dont know if theres the error.. the thing is, i connect (ID 0), and it wontshow the objects, the view distance is 200 by default, i setted it that way but it wont do... my code its basicly the same as that of yours... my create funtion is this one

Код:
stock CreateDynamicObject(ModelID, Float:X, Float:Y, Float:Z, Float:rX, Float:rY, Float:rZ,Float:Dist = 200.0) //Creates Objects
{
	ObjectID++; //Id of the Object
	ObjectModel[ObjectID] = ModelID; //Model of the Object
	ObjectPos[ModelID][0] = X; //X Position
	ObjectPos[ModelID][1] = Y; //Y position
	ObjectPos[ModelID][2] = Z; //Z Position
	ObjectRotation[ObjectID][0] = rX; //Rotation X
	ObjectRotation[ObjectID][1] = rY; //Rotation Y
	ObjectRotation[ObjectID][2] = rZ; //Rotation Z
	ObjectDistance[ObjectID] = Dist; //Viewing Distance
	ObjectUsed[ObjectID] = 1; //Disable/Enable the object, Its enabled at creation
}
and my objects are created this way

CreateDynamicObject(3866,2758.76342800,-2395.99682600,20.47137600,0.00000000,0.00000000,56 .25000000); //

The timer its the same as there, i modified a bit to debug it and see if it worked some other way but it did not so.. i need a hand...

Thanks in advance...
Reply
#12

Y_less, good critique.
I wan't to ask you, is this foreach i'm using is good?

pawn Код:
#define ForEachPlayer(%0) for(new index_%0=0, %0=ConnectedPlayerList[0]; index_%0<ConnectedPlayers; index_%0++, %0=ConnectedPlayerList[index_%0])
pawn Код:
public OnPlayerConnect(playerid)
{
    ConnectedPlayerList[ConnectedPlayers++]=playerid;
}
pawn Код:
public OnPlayerDisconnect(playerid, reason)
{
    for(new i=0;i<ConnectedPlayers;i++)
    {
        if(ConnectedPlayerList[i]==playerid)
        {
            ConnectedPlayers--;
            ConnectedPlayerList[i]=ConnectedPlayerList[ConnectedPlayers];
        }
    }
}
Reply
#13

I don't know how. Can you do that?
Reply
#14

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
I'm sorry but there's a reason for this! This is not a tutorial, it's a script release in topic form. A tutorial tells people WHY things happen. There has been a distinct increase in frankly low quality non-tutorials. This post took me longer than 10 minutes!



Isn't as much as what? That's also not really a reason, but that's beside the point.
It was posted right next to my other one, yes this is a shitty tut.



Quote:
Originally Posted by Y_Less
Посмотреть сообщение
"The less the better" - not really the point of a streamer, if there's too few you could fall below the limit of normal objects, and besides, 3mb isn't THAT much memory when most machines have several GB.
Still, less you need the better.


Quote:
Originally Posted by Y_Less
Посмотреть сообщение
What does all this do? There's no explanations of the lines at all. Or WAY too little - three comments in that huge chunk of code really doesn't cut it for a tutorial. Think of it this way, if you knew NOTHING about PAWN scripting and wanted to use this object streamer tutorial to make a checkpoint streamer, what information is there to help you?
Do you know how old this is?

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
Why is there a timer? What purpose does that serve? Firstly why do you need a looping function at all? Why not use OnPlayerUpdate? Why not use main and sleep etc?

What are the advantages of doing it this way? What other streaming algorithms are there? How does this method compare in speed to other streamers - the streamer plugin, xobjects, yobjects, mido stream etc?
As I said, this is old, my other tutorials are better explained.


Quote:
Originally Posted by Y_Less
Посмотреть сообщение
Why might we find them useful? What does it do? Why is there a loop (and why is that loop, being placed in a tutorial to tell people how to do things well, not using foreach - the current fastest loop method)?
[/Quote]
I had no idea about foreach a few months ago.
Reply
#15

Ok, I dont know if i did i wright, but here are the results:
Code:
pawn Код:
#include <a_samp>
#include <foreach>
forward OneSecTimer();
#define ForEachPlayer(%0) for(new index_%0=0, %0=ConnectedPlayerList[0]; index_%0<ConnectedPlayers; index_%0++, %0=ConnectedPlayerList[index_%0])
new item1[MAX_PLAYERS][10000],item2[MAX_PLAYERS][10000];
new ConnectedPlayers;
new ConnectedPlayerList[MAX_PLAYERS+1];//Loop would bug when server is full D:
main()
{
    print("\n----------------------------------");
    print("  This is a blank GameModeScript");
    print("----------------------------------\n");
   
    //printf("GetVehicleComponentType %u",GetVehicleComponentType(1100));
   
}

public OnGameModeInit()
{
    // Set timer of 1 second.
    for(new i;i<100;i++)
    {
        Itter_Add(Player, i);
        ConnectedPlayerList[ConnectedPlayers++]=i;
    }
   
    SetTimer("OneSecTimer", 1000, 1);
    print("GameModeInit()");
    SetGameModeText("Timer Test");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
    return 1;
}

public OneSecTimer() {
    new sText[256];
    format(sText,sizeof(sText),"GetTickCount = %d",GetTickCount());
    print(sText);
    SendClientMessageToAll(0xFF0000, sText);
   
   
    new time = GetTickCount();
    for (new i = 0; i < 10000; i++)
    {
        foreach(Player,I)
        {
            item1[I][i]=100;
        }
    }
    printf("Time #1: %d", GetTickCount() - time);

    time = GetTickCount();
    for (new i = 0; i < 10000; i++)
    {
        ForEachPlayer(I)
        {
            item2[I][i]=200;
        }
    }
    printf("Time #2: %d", GetTickCount() - time);
}


EDIT: New test:
pawn Код:
#include <a_samp>
#include <foreach>
forward OneSecTimer();
#define ForEachPlayer(%0) for(new index_%0=0, %0=ConnectedPlayerList[0]; index_%0<ConnectedPlayers; index_%0++, %0=ConnectedPlayerList[index_%0])
new item1[MAX_PLAYERS][10000],item2[MAX_PLAYERS][10000],item3[MAX_PLAYERS][10000];
new ConnectedPlayers;
new ConnectedPlayerList[MAX_PLAYERS+1];//Loop would bug when server is full D:
main()
{
    print("\n----------------------------------");
    print("  This is a blank GameModeScript");
    print("----------------------------------\n");
   
    //printf("GetVehicleComponentType %u",GetVehicleComponentType(1100));
   
}

public OnGameModeInit()
{
    // Set timer of 1 second.
    for(new i;i<100;i++)
    {
        Itter_Add(Player, i);
        ConnectedPlayerList[ConnectedPlayers++]=i;
    }
    Itter_Remove(Player,random(50));
    Itter_Remove(Player,random(100));
    for(new i=0;i<100;i++)
    {
        if(ConnectedPlayerList[i]==5)
        {
            ConnectedPlayers--;
            ConnectedPlayerList[i]=ConnectedPlayerList[ConnectedPlayers];
        }
    }
   
    SetTimer("OneSecTimer", 1000, 1);
    print("GameModeInit()");
    SetGameModeText("Timer Test");
    AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
    return 1;
}

public OneSecTimer() {
    new sText[256];
    format(sText,sizeof(sText),"GetTickCount = %d",GetTickCount());
    print(sText);
   
   
    new time = GetTickCount();
    for (new i = 0; i < 10000; i++)
    {
        foreach(Player,I)
        {
            item1[I][i]=100;
        }
    }
    printf("Time #1: %d", GetTickCount() - time);

    time = GetTickCount();
    for (new i = 0; i < 10000; i++)
    {
        ForEachPlayer(I)
        {
            item2[I][i]=200;
        }
    }
    printf("Time #2: %d", GetTickCount() - time);

    time = GetTickCount();
    for (new i = 0; i < 10000; i++)
    {
        for(new I;I<100;I++)
        {
            if(I != 40)
            {
                item3[I][i]=300;
            }
        }
    }
    printf("Time #3: %d", GetTickCount() - time);
}
Reply
#16

Erm.... Mmmmmm... I Belive you fellows were kinda out off topic.. im no mod or anthing but.. just saying.. altought what you guys are doing its of interest... but im also waiting for the answer if anyone knows... any help?......
Reply
#17

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
Why is there a timer? What purpose does that serve? Firstly why do you need a looping function at all? Why not use OnPlayerUpdate?
I'm not sure whether your intention from this paragraph was to try to convince the writer to explain the differences between OnPlayerUpdate and timers or to try to state that in a case like this OnPlayerUpdate would be a better option. If the latter:

A lot of people appear to be confused about OnPlayerUpdate (I'm not criticising you directly, I'm aware of your views on optimization). The callback is called approximately 10 times per second, per-player. I really don't think it would be a good idea to include ANYTHING in this callback, let alone anything as intense as this. I really think implementing this callback in the first place was an awful idea -- it's ruined many scripts and even bottlenecked servers. I've seen people posting scripts which included MySQL / SQLite queries in the callback.

Use timers people!
Reply
#18

Good Nice Man

Here my TUT
https://sampforum.blast.hk/showthread.php?tid=168347
Reply
#19

Sorry for offtopic, but it is an interesting discussion.
Y_less,
Here are the results with your code:
100 ms,
112 ms,
85 ms,

This means it sets it a little slower. But i don't get it, why the default loop is still the fastest? Maybe with function IsPlayerConnected, that would be slower?
Reply
#20

May I ask if this is as efficient as the other streamer's released?
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)