Create/DestroyObject messing up
#1

Okay so I'm working with a system that involves destroying 12 objects at a time then creating 12 new ones at the same time. I will give an example below:
pawn Код:
new green_light_1,
    green_light_2,
    green_light_3,
    green_light_4,
    green_light_5,
    green_light_6,
    green_light_7,
    green_light_8,
    green_light_9,
    green_light_10,
    green_light_11,
    green_light_12,
    red_light_1,
    red_light_2,
    red_light_3,
    red_light_4,
    red_light_5,
    red_light_6,
    red_light_7,
    red_light_9,
    red_light_9,
    red_light_10,
    red_light_11,
    red_light_12,
    purple_light_1,
    purple_light_2,
    purple_light_3,
    purple_light_4,
    purple_light_5,
    purple_light_6,
    purple_light_7,
    purple_light_8,
    purple_light_9,
    purple_light_10,
    purple_light_11,
    purple_light_12;
   
CMD:green(playerid, params[])
{
    ClearObjectsFirst(); //clears the last set of created lights for the new set
    green_light_1 = CreateObject(bla bla bla);
    green_light_2 = CreateObject(bla bla bla);
    //continue to create all the green lights and setting them to green_light_x
    return 1;
}

stock ClearObjectsFirst()
{
    if(IsValidObject(green_light_1)) //Im only checking for the first one in the set since if one is valid they all should be
    {
        DestroyObject(green_light_1);
        DestroyObject(green_light_2);
        DestroyObject(green_light_3);
        DestroyObject(green_light_4);
        DestroyObject(green_light_5);
        DestroyObject(green_light_6);
        DestroyObject(green_light_7);
        DestroyObject(green_light_8);
        DestroyObject(green_light_9);
        DestroyObject(green_light_10);
        DestroyObject(green_light_11);
        DestroyObject(green_light_12);
    }
    else if(IsValidObject(red_light_1))
    {
        //Do the same as above, destroy all red lights if they're valid
    }
    else //the purple lights must be the ones spawned then
    {
        //Same as above, destroy all purple lights
    }
    return 1;
}
So what is basically happening is sometimes certain objects aren't destroyed (visibly anyway, I can see them when testing in-game but I guess the script thinks they've been destroyed) and it just seems like object ID's get mixed up, sometimes different objects a created to what I want and sometimes only for example half a set of objects are created. As far as I know there isn't anything wrong with my code, so I'm not sure what the problem is.

If it helps, the objects I'm working with are PinSpotLights and smoke machines, and in my actual script I'm using more than just 3 sets of lights, I'm using 14, there are 12 objects in a set, you can imagine it's quite a big chunk of code.
Reply
#2

I do not suggest you creating 12 variables for each colour, I suggest you use Array it's easier, so you can just loop them and delete them, I am writing a code, please wait :P

EDIT - You must use curly braces ( { and } )] because we are using char-array

pawn Код:
#include <a_samp>
#include <zcmd>
#include <YSI\y_stringhash>

#define MAX_LIGHTS \
    (12)

new
    green_light[MAX_LIGHTS char],
    red_light[MAX_LIGHTS char],
    purple_light[MAX_LIGHTS char]
;

CMD:lights(playerid, params[])
{
    if(isnull(params))
        return SendClientMessage(playerid, -1, "Syntax: /lights [colour]");
       
    ClearObjectsFirst(); //clears the last set of created lights for the new set

    switch ( YHash( params ), false )
    {
        case _H<green>:
        {
            //You need to start from 0
            green_light{0} = CreateObject( ... );
            green_light{1} = CreateObject( ... );
            // and so on.
        }
        case _H<red>:
        {
            //You need to start from 0
            red_light{0} = CreateObject( ... );
            red_light{1} = CreateObject( ... );
            // and so on.
        }
        case _H<purple>:
        {
            //You need to start from 0
            purple_light{0} = CreateObject( ... );
            purple_light{1} = CreateObject( ... );
            // and so on.
        }
    }
    //continue to create all the green lights and setting them to green_light_x
    return 1;
}


stock ClearObjectsFirst()
{
    new
        i = 0
    ;
    while(i < MAX_LIGHTS)
    {
        if(IsValidObject( green_light{i} ) ) //Im only checking for the first one in the set since if one is valid they all should be
        {
            DestroyObject( green_light{i} );
        }
        else if(IsValidObject( red_light{i} ) )
        {
            DestroyObject( red_light{i} );
        }
        else //the purple lights must be the ones spawned then
        {
            DestroyObject( purple_light{i} );
        }
        i++;
    }
    return 1;
}
Reply
#3

I don't want to be rude against pds2k12, you may use his code too if you prefer it. But I'd do it this way:

There are two ways of doing this, if the green, purple and red lights are on different positions you should use the next:
pawn Код:
new light[12];

new Float:green_light_pos[12][6] = { // Positions of the green lights
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}}
};
   
new Float:red_light_pos[12][6] = { // Positions of the red lights
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}}
};
   
new Float:purple_light_pos[12][6] = { // Positions of the purple lights
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}}
};
   
CMD:green(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*green light modelid*, green_light_pos[i][0], green_light_pos[i][1], green_light_pos[i][2], green_light_pos[i][3], green_light_pos[i][4], green_light_pos[i][5]);
        }
    return 1;
}
   
CMD:red(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*red light modelid*, red_light_pos[i][0], red_light_pos[i][1], red_light_pos[i][2], red_light_pos[i][3], red_light_pos[i][4], red_light_pos[i][5]);
        }
    return 1;
}
   
CMD:purple(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*purple light modelid*, purple_light_pos[i][0], purple_light_pos[i][1], purple_light_pos[i][2], purple_light_pos[i][3], purple_light_pos[i][4], purple_light_pos[i][5]);
        }
    return 1;
}

stock ClearObjectsFirst()
{
    for(new i = 0; i < 12; i++)
        {
        if(IsValidObject(light[i]) && light[i] != 24688642)
            {
            DestroyObject(light[i]);
            light[i] = 24688642; // 24688642 is a random number, the check for the number is just a extra one.
            }
        }
    return 1;
}
If they're on the same location but just different object models you can do it like this:
pawn Код:
new light[12];

new Float:light_pos[12][6] = { // Positions of the lights
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}},
{{X},{Y},{Z},{rX},{rY},{rZ}}
};
   
CMD:green(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*green light modelid*, light_pos[i][0], light_pos[i][1], light_pos[i][2], light_pos[i][3], light_pos[i][4], light_pos[i][5]);
        }
    return 1;
}
   
CMD:red(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*red light modelid*, light_pos[i][0], light_pos[i][1], light_pos[i][2], light_pos[i][3], light_pos[i][4], light_pos[i][5]);
        }
    return 1;
}
   
CMD:purple(playerid, params[])
{
    ClearObjectsFirst();
    for(new i = 0; i < 12; i++)
        {
        light[i] = CreateObject(*purple light modelid*, light_pos[i][0], light_pos[i][1], light_pos[i][2], light_pos[i][3], light_pos[i][4], light_pos[i][5]);
        }
    return 1;
}

stock ClearObjectsFirst()
{
    for(new i = 0; i < 12; i++)
        {
        if(IsValidObject(light[i]) && light[i] != 24688642)
            {
            DestroyObject(light[i]);
            light[i] = 24688642; // 24688642 is a random number, the check for the number is just a extra one.
            }
        }
    return 1;
}
I just kept 3 commands because you used 3, you can indeed also go with a param to select which color you want within 1 command.

Best regards,
Jesse
Reply
#4

Quote:
Originally Posted by jessejanssen
Посмотреть сообщение
I don't want to be rude against pds2k12, you may use his code too if you prefer it. But I'd do it this way:

There are two ways of doing this, if the green, purple and red lights are on different positions you should use the next:
pawn Код:
//code
I just kept 3 commands because you used 3, you can indeed also go with a param to select which color you want within 1 command.

Best regards,
Jesse
I don't consider this as rude Jesse, I'll consider this as another idea by You(Jesse), this is actually a good idea by using 2 Dimensional Array, You could combine My code & Jesse's code together, I used char-array to save some memory, also because it doesn't have the size of 255+ or lower than 0 that's why I used char-array
Reply
#5

Quote:
Originally Posted by pds2k12
Посмотреть сообщение
[..] I used char-array to save some memory, also because it doesn't have the size of 255+ or lower than 0 that's why I used p char-array
Keep in mind though that it returned the objectid and MAX_OBJECTS is defined as 1000 which exceeds 255.
Reply
#6

I know, but on the code I provided does not include MAX_OBJECTS, or any value that is over than 255 and lower than 0

Tested that code with crashdetect #include & #plugin doesn't show me any CrashDetect warning, it's also compiled with -d3, test it your self if you don't believe

Код:
Pawn compiler 3.2.3664	 	 	Copyright © 1997-2006, ITB CompuPhase

Header size:            968 bytes
Code size:            11028 bytes
Data size:             4680 bytes
Stack/heap size:      16384 bytes; estimated max. usage=113 cells (452 bytes)
Total requirements:   33060 bytes
pawn Код:
#include <a_samp>
#include <zcmd>
#include <crashdetect>
#include <YSI\y_stringhash>

#define MAX_LIGHTS \
    (12)

new
    green_light[MAX_LIGHTS char],
    red_light[MAX_LIGHTS char],
    purple_light[MAX_LIGHTS char]
;

main(){}

public OnGameModeInit() return AddPlayerClass(0, 1958.33, 1343.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0), 1;
public OnGameModeExit() return true;
public OnPlayerSpawn(playerid) return true;


CMD:lights(playerid, params[])
{
    if(isnull(params))
        return SendClientMessage(playerid, -1, "Syntax: /lights [colour]");

    ClearObjectsFirst(); //clears the last set of created lights for the new set

    switch ( YHash( params ) )
    {
        case _H<green>:
        {
            SetPlayerPos(playerid, 2001.195679, 1547.113892, 14.283400);
            //You need to start from 0
            for(new i = 0; i < MAX_LIGHTS; i++)
            green_light{i} = CreateObject(18649, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
            SendClientMessage(playerid, -1, "Created Colour Green");
            // and so on.
        }
        case _H<red>:
        {
            //You need to start from 0
            for(new i = 0; i < MAX_LIGHTS; i++) red_light{i} = CreateObject(18647, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
            SendClientMessage(playerid, -1, "Created Colour Red");
            // and so on.
        }
        case _H<purple>:
        {
            //You need to start from 0
            for(new i = 0; i < MAX_LIGHTS; i++) purple_light{i} = CreateObject(18651, 2001.195679, 1547.113892, 14.283400, 0.0, 0.0, 96.0);
            SendClientMessage(playerid, -1, "Created Colour Purple");
            // and so on.
        }
        default: SendClientMessage(playerid, -1, "Default - None");
    }
    //continue to create all the green lights and setting them to green_light_x
    return 1;
}

stock ClearObjectsFirst()
{
    new
        i = 0
    ;
    while(i < MAX_LIGHTS)
    {
        if(IsValidObject( green_light{i} ) ) //Im only checking for the first one in the set since if one is valid they all should be
        {
            DestroyObject( green_light{i} );
        }
        else if(IsValidObject( red_light{i} ) )
        {
            DestroyObject( red_light{i} );
        }
        else //the purple lights must be the ones spawned then
        {
            DestroyObject( purple_light{i} );
        }
        i++;
    }
    return 1;
}
Reply
#7

The point is that if he's going to add it to a server that uses more than 255 objects, a runtime error: Index out of bounds will be caused. char must be used in parts that the value will not exceed 0-255 and it's 100 percent sure that it will not. Unlike the example you gave, CreateObject will return the objectid that is not sure will be between 0-255 with more objects - this is what I'm trying to say.
Reply
#8

Okay, thanks so much guys, I'll mess around with the various pieces of code you gave me and see if I can come up with a decent solution.
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)