How to loop through a specific object?
#1

I'm trying to create a fire system, and so far it's working properly. There's only one issue;

When player 1 creates a fire, he can cook on it until another players creates a fire. It's like the fire's id is being shifted around. How can i make the code detect if a player is in range of ANY fire? I have CreateObjects as the fire, as assigned a varialbe to them. Would I need to loop through them? If so, how? (The floats are global, by the way.)

pawn Код:
if(IsPlayerInRangeOfPoint(playerid, 3.0,Float:fx, Float:fy, Float:fz))
            {
                RandomCook(playerid);
            }



GetPlayerPos(playerid, Float:fx, Float:fy, Float:fz);
            hasfire[playerid] = 1;
            fire = CreateObject(841,Float:fx,Float:fy,Float:fz-1,0.0000000,0.0000000,0.0000000); //object(dead_tree_13) (1)
            fire1 = CreateObject(3461,Float:fx,Float:fy,Float:fz-3,0.0000000,0.0000000,0.0000000); //object(tikitorch01_lvs) (1)
            SetTimerEx("firetimer", 5000, false, "i", playerid);
            TogglePlayerControllable(playerid, 0);
            ApplyAnimation(playerid,"BOMBER","BOM_Plant_Loop",4,1,0,0, 0,0,1);
            logs[playerid] --;
If you need more code, let me know. Thank you.

EDIT: Would i need to #define MAX_FIRES ? And if so, how do i use it? I'm not very good at looping through things at all.
Reply
#2

You're using a single variable to store the ID of fires. Variables can only hold ONE value. When you create a new fire, the ID of the old one will be overwritten. You need one variable to store every fire ID. You need to use an array.
Reply
#3

Could you specify a example please?
Reply
#4

Say you wanted every player to be able to have ONE fire, and only ONE. You need a variable for every player, so you need an array with the size of MAX_PLAYERS:

pawn Код:
new PlayerFireObjectID[MAX_PLAYERS];
This needs to be global.

Then to set it:
pawn Код:
PlayerFireObjectID[playerid] = CreateObject(...);
Reply
#5

Would i still need to add it to a array? Such as:

pawn Код:
new PlayerFire[MAX_PLAYERS];
PlayerFire[playerid] =
{
       //CreateObject
};
EDIT: Also, would I use the existing global floats i have to detect the position of the fires?

EDIT2: I also tested something similar to the code you gave me earlier. And ONLY the player who created the fire could cook next to it, and no one else. How would I enable it so everyone can use it?
Reply
#6

pawn Код:
// Global variables
new bool:PlayerFireCreated[MAX_PLAYERS char];
new PlayerFireObjectID[MAX_PLAYERS][2]; // 0=wood 1=flame
new PlayerFireLogCount[MAX_PLAYERS]; // Could use a char array if they won't ever have more than 255 logs

if(IsPlayerInRangeOfPoint(playerid, 3.0, fx, fy, fz))
{
    RandomCook(playerid);
}

GetPlayerPos(playerid, fx, fy, fz);
PlayerFireCreated{playerid} = true; // Note the use of { } instead of [ ] for a char array
PlayerFireObjectID[playerid][0] = CreateObject(841, fx, fy, fz-1, 0.0, 0.0, 0.0); // Wood
PlayerFireObjectID[playerid][1] = CreateObject(3461, fx, fy, fz-3, 0.0, 0.0, 0.0); // Flame
SetTimerEx("firetimer", 5000, false, "i", playerid);
TogglePlayerControllable(playerid, false);
ApplyAnimation(playerid,"BOMBER","BOM_Plant_Loop", 4, 1, 0, 0, 0, 0, 1);
PlayerFireLogCount[playerid] --;
I also changed a couple of other things. You need to learn to name variables better. Don't just call a variable/array 'logs', call it something like 'PlayerFireLogCount'.

I have used a char-array for the 'PlayerFireCreated' array. This saves memory (only uses 25%). You have to use { and } to access values (not to declare though, see the declaration 'char' keyword) like so:

pawn Код:
PlayerFireCreated{playerid} = true;
I also removed all the Float: tags as they are unnecessary and clutter the code. Also added spaces after commas as it looks messy otherwise.

As for the main issue, look at the CreateObject lines. Those two array slots (PlayerFireObjectID[playerid][0] and PlayerFireObjectID[playerid][1]) hold the player's two fire objects. 0=wood 1=flame.

Also 'firetimer' should have a better name. I personally prefix all my timers with 'TMR_' and give them an upper camel case descriptive name.
Reply
#7

I'm trying to understand it, but it's just not coming to me. I'll try to read over it in the morning.

Thank you for your help.

Also, quick question. Wouldn't
pawn Код:
new PlayerFireObjectID[MAX_PLAYERS][2]; // 0=wood 1=flame
begin at "0"? Therefor, have [1]?
And why'd you remove the Float: tags? Upon not using them (previous experience.) it sets me at god knows where. My screen would be distorted, and have the "Stay within world boundaries" game text.

EDIT: I'm starting to understand the way you specified, but it's messing with my whole system, giving me a bazillion errors. Maybe I'll just assign the object to a playerid for now.
Reply
#8

Make sure 'fx', 'fy' and 'fz' have the Float: tag in the declaration ('new Float:fx' etc.). Tags only need to be specified in the declaration.

As for the array indexes, yes they do start at 0, but in the declaration you are specifying how many indexes you need - which is 2 - index 0 and 1.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)