Global Timer or Specific Timer
#1

I am confused when to use Global Timer or Unique Timer and how Global Timers will affects server performance same goes to Unique Timers.

I'm currently using Y_Timer.

here is one of my example of using timer:

Code:
task FurnaceTimer[1000]()
{
	for(new x = 0; x < MAX_BASES; x++)
	{
		if(BaseData[x][baseCreated])
		{
			if(BaseData[x][baseTotalFurnace] != 0)
			{
				for(new y = 0; y < MAX_BASEOBJECTS; y++)
				{
					if(BaseObjectData[x][y][oID] != INVALID_OBJECT_ID && BaseObjectData[x][y][oFurnace] && BaseObjectData[x][y][oFurnaceStatus])
					{
						if(BaseFurnaceData[x][y][furnaceMainItem] != -1 && BaseFurnaceData[x][y][furnaceSecondItem] != -1 || BaseFurnaceData[x][y][furnaceSecondItem] != -1)
						{
							if(BaseFurnaceData[x][y][furnaceSItemQuantity] < 2)  return BaseObjectData[x][y][oFurnaceStatus] = 0;
							if(++BaseObjectData[x][y][oFurnaceTimer] >= 120)
							{
								if(BaseFurnaceData[x][y][furnaceMainItem] != -1 && BaseFurnaceData[x][y][furnaceSecondItem] != -1)
								{
									if(BaseFurnaceData[x][y][furnaceMItemQuantity] > 0) BaseFurnaceData[x][y][furnaceMItemQuantity]--;
									if(BaseFurnaceData[x][y][furnaceMItemQuantity] <= 0)
									{
										//BaseObjectData[x][y][oFurnaceStatus] = 0;
										//BaseObjectData[x][y][oFurnaceTimer] = 0;
										BaseFurnaceData[x][y][furnaceMainItem] = -1;
										BaseFurnaceData[x][y][furnaceMItemQuantity] = 0;
									}
									switch(BaseFurnaceData[x][y][furnaceMainItem])
									{
										case ITEM_IRON:
										{
											if(BaseFurnaceData[x][y][furnaceFinalItem] == ITEM_IRONBAR && BaseFurnaceData[x][y][furnaceFinalItem] != -1)
											{
												BaseFurnaceData[x][y][furnaceFItemQuantity]++;
												UpdateBaseFurnace(x, y);
											}
											else
											{
												if(BaseFurnaceData[x][y][furnaceFinalItem] == -1)
												{
													BaseFurnaceData[x][y][furnaceFinalItem] = ITEM_IRONBAR;
													BaseFurnaceData[x][y][furnaceFItemQuantity]++;
													UpdateBaseFurnace(x, y);
												}
											}
											
										}
										case ITEM_BLUEIRON:
										{
											if(BaseFurnaceData[x][y][furnaceFinalItem] == ITEM_BLUEIRON && BaseFurnaceData[x][y][furnaceFinalItem] != -1)
											{
												BaseFurnaceData[x][y][furnaceFItemQuantity]++;
												UpdateBaseFurnace(x, y);

											}
											else 
											{
												if(BaseFurnaceData[x][y][furnaceFinalItem] == -1)
												{
													BaseFurnaceData[x][y][furnaceFinalItem] = ITEM_BLUEIRON;	
													BaseFurnaceData[x][y][furnaceFItemQuantity]++;
													UpdateBaseFurnace(x, y);
												}
											}
											

										}
										case ITEM_REDIRON:
										{
											if(BaseFurnaceData[x][y][furnaceFinalItem] == ITEM_REDIRON && BaseFurnaceData[x][y][furnaceFinalItem] != -1)
											{
												BaseFurnaceData[x][y][furnaceFItemQuantity]++;
												UpdateBaseFurnace(x, y);
											}
											else 
											{
												if(BaseFurnaceData[x][y][furnaceFinalItem] == -1)
												{
													BaseFurnaceData[x][y][furnaceFinalItem] = ITEM_REDIRONBAR;
													BaseFurnaceData[x][y][furnaceFItemQuantity]++;
													UpdateBaseFurnace(x, y);
												}
											}

										}
									}
								}
								if(BaseFurnaceData[x][y][furnaceSItemQuantity] > 0) BaseFurnaceData[x][y][furnaceSItemQuantity] -= 2;
								if(BaseFurnaceData[x][y][furnaceMItemQuantity] <= 0)
								{
									BaseObjectData[x][y][oFurnaceStatus] = 0;
									BaseFurnaceData[x][y][furnaceSItemQuantity] = -1;
									BaseFurnaceData[x][y][furnaceSItemQuantity] = 0;
								}
								BaseObjectData[x][y][oFurnaceTimer] = 0;
							}
						}
						else BaseObjectData[x][y][oFurnaceStatus] = 0;
					}
				}
				
			}
		}
	}
	return 1;
}
this code loops all 1000 buildings if exists and loop again if furnace found is this a good way to use this? any recommendation and advice? or should I use single timer in every base.

EDIT: Also should I use Timer Fix plugin for improving accuracy of each timers?
Reply
#2

bump
Reply
#3

It would be better to create a furnace system then simply loop through them and update. Seems the wrong way to go to loop through all bases, then loop through all objects. I can see by this code you have over thought your problem.
Reply
#4

https://sampforum.blast.hk/showthread.php?tid=643553
Reply
#5

This post only adding to good answers where Pottus & Kane_ has stated about the timers,

if i was you, i wouldn't attach furnace attributes with objects, even though you mark which base object is a furnace, from my logic, it does not seems that all objects actually have same function structure (unless every object is a furnace). I would just keep objects as what it is for, where objects only a visual representation of its function like furnace... You can put relation of its object id created to your Furnace variables to "attach" the function. The same if you want to separate "furnace" from the "base". But it's your choice since you may don't want to make a breaking changes.

And when you think complicated about timers, i would just look the real world usage, if furnace is a modern microwave oven known today, then i'd realize the timer is a part of each microwave have, where i can always decide when to start (StartTimer) or when to stop it (KillTimer). Our real world oven timers does not run from world global timers where each oven waits process order from another oven somewhere in another part of the world (or completely stops working because one oven causes a runtime error crash in the middle of the timer), so you don't need to worry about oven syncing within each other as they work alone.

Let's assume
BaseData // data about bases (x)
BaseObjectData // data about objects in a base
BaseFurnaceData // data about furnaces in a base
It is somewhat confusing me when you name it "BaseFurnaceData" when it looks implicit that you explain the furnace belongs to the base, not the objects as how you use them.. you are copying same amount of furnaces equals to all base objects, so it would be BaseObjectFurnaceData... Maybe you do not want to name it too long.
You also need to pay attention to the furnace items functionality, because the players can manage the items inside it? (or not?)
Sure it does not make sense when a furnace is still working when the object suddenly gone due to another script accidentally deleted wrong object id. But i hope you make functions / hook on that to register/unregister the furnace from Object functions.

Since i don't know completely the idea you are trying to achieve (and since i do not play all Survival Games). Let's assume the player can only start placing the items in furnace on their own base, they can not suddenly change main item or second item when the furnace is in process of burning. However they can cancel/stop it, with the items being returned to them, you decide wether the items should lose amount of original quantity or completely gone without returned.
From what i see you used the Y on MAX_BASE_OBJECTS as well in BaseFurnaceData, i assume that Y is equal to BaseObject or BaseFurnace array index (i.e. you did BaseObjectData[MAX_BASES][MAX_BASEOBJECTS][enumofobjects] and BaseFurnaceData[MAX_BASES][MAX_BASEOBJECTS][enumoffurnace])
Now if it's all clear, i'd just do something like this:
Code:
// I can only imagine the variable structure is like this:
enum e_FURNACE
{
	furnaceMainItem,
	furnaceMItemQuantity,
	furnaceSecondItem,
	furnaceSItemQuantity,
	furnaceFinalItem,
	furnaceFItemQuantity,
	Timer:furnaceTimer, // tag to match y_timers
	oFurnaceTime, // this has been moved here from BaseObjectData
	oFurnaceStatus
}
new BaseFurnaceData[MAX_BASES][MAX_BASEOBJECTS][e_FURNACE];


PlayerUseFurnace(playerid, baseid, furnaceid, mainItem, mainItemQty, secondItem, secondItemQty)
{
	// Called when player is ready to start boiling items (on their base, and not when items/timers already running)

	if (!BaseObjectData[baseid][furnaceid][oFurnace]) // Yes, furnaceid equals to BaseObjectData array index
	{
		SendClientMessage(playerid, -1, "This object is not a furnace!!!");
		return 0;
	}

	if (mainItem == 0 || mainItemQty == 0)
	{
		SendClientMessage(playerid, -1, "Missing main items...");
		return 0;
	}

	if (secondItem == 0 || secondItemQty == 0)
	{
		SendClientMessage(playerid, -1, "Missing second items...");
		return 0;
	}

	if (BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] == 1)
	{
		SendClientMessage(playerid, -1, "Sorry, this furnace is busy, you need to wait or cancel it...");
		return 0;
	}

	// Begin registering items
	BaseFurnaceData[baseid][furnaceid][furnaceMainItem] = mainItem;
	BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] = mainItemQty;
	BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] = secondItem;
	BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = secondItemQty;

	BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0; // tick count just start
	BaseFurnaceData[baseid][furnaceid][furnaceTimer] = repeat ProcessFurnaceItems(baseid, furnaceid); // begin the boiling timer...
	BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 1; /// i don't know what are values of oFurnaceStatus... you better define it like #define FURNACE_STATUS_RUNNING 1

	// Do something...
	SendClientMessage(playerid, -1, "You are now boiling your items...");
	return 1;
}

timer ProcessFurnaceItems[1000](baseid, furnaceid) // x is baseid, y is furnaceid
{
	// CHECK IF THE ITEMS ARE STILL ENOUGH TO BOIL
	if (
		(
			BaseFurnaceData[baseid][furnaceid][furnaceMainItem] == -1
			&& BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] == -1
			|| BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] == -1
		)
		|| BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] < 2 // OR SECOND ITEM AMOUNT IS NOT ENOUGH
 	)
	{
		StopTheFurnace(baseid, furnaceid); // SEE BELOW
		return 1; // stop?!
	}

	// CHECK IF BOILING PROCESS TOOK 120 SECONDS OTHERWISE CONTINUE BY A SECOND
	if (++BaseFurnaceData[baseid][furnaceid][oFurnaceTime] >= 120)
	{
		// Do something with the main item
		if (BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] > 0)
		{
			// Reduce the amount of main item (boil it)
			BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity]--;

			// moved here as it makes no sense when item quantity is 0
			switch(BaseFurnaceData[baseid][furnaceid][furnaceMainItem])
			{
				case ITEM_IRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_IRONBAR)
					{
	  					BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1) // No final items yet
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_IRONBAR; // now furnaceFinalItem is known
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}

				}
				case ITEM_BLUEIRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_BLUEIRON)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_BLUEIRON;
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
				}
				case ITEM_REDIRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if (BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_REDIRON)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_REDIRONBAR;
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
				}
			}
		}
		else // was if(BaseFurnaceData[x][y][furnaceMItemQuantity] <= 0) but it's equal to "else"
		{
			// NO MORE MAIN ITEMS LEFT
			//BaseObjectData[baseid][furnaceid][oFurnaceStatus] = 0;
			//BaseObjectData[baseid][furnaceid][oFurnaceTime] = 0;
			BaseFurnaceData[baseid][furnaceid][furnaceMainItem] = -1;
			BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] = 0;
		}
		// Do something with the second item
		if(BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] > 0)
		{
			// Reduce the amount of second item (boil it)
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] -= 2;
		}
		else // was if (BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] <= 0) but it's equal to "else"
		{
			// NO MORE SECOND ITEMS LEFT
			BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 0;
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = -1;
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = 0;
		}
		// BOILING HAS PRODUCED A FINAL ITEM, RESET TICK (ALLOWS ANOTHER ITEM TO BE BOILED AGAIN FROM START)
		BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0;
	}
	return 1;
}

StopTheFurnace(baseid, furnaceid) // Useful if you want to use this on user intervention
{
	// RESET STATUS OF FURNACE
	BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 0;

	// RESET TICK TO 0 (SO ITEMS DO NOT STUCK IN THE MIDDLE/FURNACE FREEZE)
	BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0;

	// STOP THE FURNACE TIMER
	stop BaseFurnaceData[baseid][furnaceid][furnaceTimer];
}
SO what has changed?
I added Timer:furnaceTimer to store the timer id
I moved oFurnaceTimer from BaseObjectData to BaseFurnaceData and renamed it to oFurnaceTime
x works as base id
y works as object base id or the furnace itself (even though all objects might not be a furnace, it's still possible to, from your idea)

Disclaimer: It may not work as best as you expected since you did not explain the details of the idea, this is only to illustrate what i think of to suggest. You still need to modify to what you need...
Hope you understand it, and sorry for my bad english
Reply
#6

Quote:
Originally Posted by Pottus
View Post
It would be better to create a furnace system then simply loop through them and update. Seems the wrong way to go to loop through all bases, then loop through all objects. I can see by this code you have over thought your problem.
That just I was thinking thanks.

Quote:
Originally Posted by Kane_
View Post
I just read the post and it enlightens me thank you

Quote:
Originally Posted by RoboN1X
View Post
This post only adding to good answers where Pottus & Kane_ has stated about the timers,

if i was you, i wouldn't attach furnace attributes with objects, even though you mark which base object is a furnace, from my logic, it does not seems that all objects actually have same function structure (unless every object is a furnace). I would just keep objects as what it is for, where objects only a visual representation of its function like furnace... You can put relation of its object id created to your Furnace variables to "attach" the function. The same if you want to separate "furnace" from the "base". But it's your choice since you may don't want to make a breaking changes.

And when you think complicated about timers, i would just look the real world usage, if furnace is a modern microwave oven known today, then i'd realize the timer is a part of each microwave have, where i can always decide when to start (StartTimer) or when to stop it (KillTimer). Our real world oven timers does not run from world global timers where each oven waits process order from another oven somewhere in another part of the world (or completely stops working because one oven causes a runtime error crash in the middle of the timer), so you don't need to worry about oven syncing within each other as they work alone.

Let's assume
BaseData // data about bases (x)
BaseObjectData // data about objects in a base
BaseFurnaceData // data about furnaces in a base
It is somewhat confusing me when you name it "BaseFurnaceData" when it looks implicit that you explain the furnace belongs to the base, not the objects as how you use them.. you are copying same amount of furnaces equals to all base objects, so it would be BaseObjectFurnaceData... Maybe you do not want to name it too long.
You also need to pay attention to the furnace items functionality, because the players can manage the items inside it? (or not?)
Sure it does not make sense when a furnace is still working when the object suddenly gone due to another script accidentally deleted wrong object id. But i hope you make functions / hook on that to register/unregister the furnace from Object functions.

Since i don't know completely the idea you are trying to achieve (and since i do not play all Survival Games). Let's assume the player can only start placing the items in furnace on their own base, they can not suddenly change main item or second item when the furnace is in process of burning. However they can cancel/stop it, with the items being returned to them, you decide wether the items should lose amount of original quantity or completely gone without returned.
From what i see you used the Y on MAX_BASE_OBJECTS as well in BaseFurnaceData, i assume that Y is equal to BaseObject or BaseFurnace array index (i.e. you did BaseObjectData[MAX_BASES][MAX_BASEOBJECTS][enumofobjects] and BaseFurnaceData[MAX_BASES][MAX_BASEOBJECTS][enumoffurnace])
Now if it's all clear, i'd just do something like this:
Code:
// I can only imagine the variable structure is like this:
enum e_FURNACE
{
	furnaceMainItem,
	furnaceMItemQuantity,
	furnaceSecondItem,
	furnaceSItemQuantity,
	furnaceFinalItem,
	furnaceFItemQuantity,
	Timer:furnaceTimer, // tag to match y_timers
	oFurnaceTime, // this has been moved here from BaseObjectData
	oFurnaceStatus
}
new BaseFurnaceData[MAX_BASES][MAX_BASEOBJECTS][e_FURNACE];


PlayerUseFurnace(playerid, baseid, furnaceid, mainItem, mainItemQty, secondItem, secondItemQty)
{
	// Called when player is ready to start boiling items (on their base, and not when items/timers already running)

	if (!BaseObjectData[baseid][furnaceid][oFurnace]) // Yes, furnaceid equals to BaseObjectData array index
	{
		SendClientMessage(playerid, -1, "This object is not a furnace!!!");
		return 0;
	}

	if (mainItem == 0 || mainItemQty == 0)
	{
		SendClientMessage(playerid, -1, "Missing main items...");
		return 0;
	}

	if (secondItem == 0 || secondItemQty == 0)
	{
		SendClientMessage(playerid, -1, "Missing second items...");
		return 0;
	}

	if (BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] == 1)
	{
		SendClientMessage(playerid, -1, "Sorry, this furnace is busy, you need to wait or cancel it...");
		return 0;
	}

	// Begin registering items
	BaseFurnaceData[baseid][furnaceid][furnaceMainItem] = mainItem;
	BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] = mainItemQty;
	BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] = secondItem;
	BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = secondItemQty;

	BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0; // tick count just start
	BaseFurnaceData[baseid][furnaceid][furnaceTimer] = repeat ProcessFurnaceItems(baseid, furnaceid); // begin the boiling timer...
	BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 1; /// i don't know what are values of oFurnaceStatus... you better define it like #define FURNACE_STATUS_RUNNING 1

	// Do something...
	SendClientMessage(playerid, -1, "You are now boiling your items...");
	return 1;
}

timer ProcessFurnaceItems[1000](baseid, furnaceid) // x is baseid, y is furnaceid
{
	// CHECK IF THE ITEMS ARE STILL ENOUGH TO BOIL
	if (
		(
			BaseFurnaceData[baseid][furnaceid][furnaceMainItem] == -1
			&& BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] == -1
			|| BaseFurnaceData[baseid][furnaceid][furnaceSecondItem] == -1
		)
		|| BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] < 2 // OR SECOND ITEM AMOUNT IS NOT ENOUGH
 	)
	{
		StopTheFurnace(baseid, furnaceid); // SEE BELOW
		return 1; // stop?!
	}

	// CHECK IF BOILING PROCESS TOOK 120 SECONDS OTHERWISE CONTINUE BY A SECOND
	if (++BaseFurnaceData[baseid][furnaceid][oFurnaceTime] >= 120)
	{
		// Do something with the main item
		if (BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] > 0)
		{
			// Reduce the amount of main item (boil it)
			BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity]--;

			// moved here as it makes no sense when item quantity is 0
			switch(BaseFurnaceData[baseid][furnaceid][furnaceMainItem])
			{
				case ITEM_IRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_IRONBAR)
					{
	  					BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1) // No final items yet
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_IRONBAR; // now furnaceFinalItem is known
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}

				}
				case ITEM_BLUEIRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_BLUEIRON)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_BLUEIRON;
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
				}
				case ITEM_REDIRON:
				{
					// removed BaseFurnaceData[x][y][furnaceFinalItem] != -1 as it's redundant
					if (BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == ITEM_REDIRON)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
					else if(BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] == -1)
					{
						BaseFurnaceData[baseid][furnaceid][furnaceFinalItem] = ITEM_REDIRONBAR;
						BaseFurnaceData[baseid][furnaceid][furnaceFItemQuantity]++;
						UpdateBaseFurnace(baseid, furnaceid);
					}
				}
			}
		}
		else // was if(BaseFurnaceData[x][y][furnaceMItemQuantity] <= 0) but it's equal to "else"
		{
			// NO MORE MAIN ITEMS LEFT
			//BaseObjectData[baseid][furnaceid][oFurnaceStatus] = 0;
			//BaseObjectData[baseid][furnaceid][oFurnaceTime] = 0;
			BaseFurnaceData[baseid][furnaceid][furnaceMainItem] = -1;
			BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] = 0;
		}
		// Do something with the second item
		if(BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] > 0)
		{
			// Reduce the amount of second item (boil it)
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] -= 2;
		}
		else // was if (BaseFurnaceData[baseid][furnaceid][furnaceMItemQuantity] <= 0) but it's equal to "else"
		{
			// NO MORE SECOND ITEMS LEFT
			BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 0;
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = -1;
			BaseFurnaceData[baseid][furnaceid][furnaceSItemQuantity] = 0;
		}
		// BOILING HAS PRODUCED A FINAL ITEM, RESET TICK (ALLOWS ANOTHER ITEM TO BE BOILED AGAIN FROM START)
		BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0;
	}
	return 1;
}

StopTheFurnace(baseid, furnaceid) // Useful if you want to use this on user intervention
{
	// RESET STATUS OF FURNACE
	BaseFurnaceData[baseid][furnaceid][oFurnaceStatus] = 0;

	// RESET TICK TO 0 (SO ITEMS DO NOT STUCK IN THE MIDDLE/FURNACE FREEZE)
	BaseFurnaceData[baseid][furnaceid][oFurnaceTime] = 0;

	// STOP THE FURNACE TIMER
	stop BaseFurnaceData[baseid][furnaceid][furnaceTimer];
}
SO what has changed?
I added Timer:furnaceTimer to store the timer id
I moved oFurnaceTimer from BaseObjectData to BaseFurnaceData and renamed it to oFurnaceTime
x works as base id
y works as object base id or the furnace itself (even though all objects might not be a furnace, it's still possible to, from your idea)

Disclaimer: It may not work as best as you expected since you did not explain the details of the idea, this is only to illustrate what i think of to suggest. You still need to modify to what you need...
Hope you understand it, and sorry for my bad english
a great thanks! You explain it very well and it helps me to finalize and optimize this thing. It is my big wrong to loop all bases and objects for updating the furnace it seems this way is more efficient
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)