SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help

Reply
 
Thread Tools Display Modes
Old 10/02/2019, 03:24 AM   #1
ToiletDuck
Huge Clucker
 
ToiletDuck's Avatar
 
Join Date: Apr 2012
Location: Philippines, Lucena City
Posts: 400
Reputation: 43
Default Global Timer or Specific Timer

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?
ToiletDuck is offline   Reply With Quote
Old 11/02/2019, 01:03 AM   #2
ToiletDuck
Huge Clucker
 
ToiletDuck's Avatar
 
Join Date: Apr 2012
Location: Philippines, Lucena City
Posts: 400
Reputation: 43
Default Re: Global Timer or Specific Timer

bump
ToiletDuck is offline   Reply With Quote
Old 11/02/2019, 01:47 AM   #3
Pottus
High-roller
 
Pottus's Avatar
 
Join Date: Jun 2012
Posts: 4,885
Reputation: 1351
Default Re: Global Timer or Specific Timer

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.
Pottus is offline   Reply With Quote
Old 11/02/2019, 02:52 AM   #4
Kane
Gangsta
 
Kane's Avatar
 
Join Date: Sep 2012
Posts: 824
Reputation: 130
Default Re: Global Timer or Specific Timer

https://forum.sa-mp.com/showthread.php?t=643553
__________________
Developer, @ls-rp.com

Former Beta Tester

Kane is offline   Reply With Quote
Old 11/02/2019, 05:35 AM   #5
RoboN1X
Huge Clucker
 
RoboN1X's Avatar
 
Join Date: Feb 2011
Location: Indonesia
Posts: 453
Reputation: 145
Default Re: Global Timer or Specific Timer

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
__________________
Need Help? Use Search, WIKI, and FAQ
RoboN1X is offline   Reply With Quote
Old 12/02/2019, 12:09 AM   #6
ToiletDuck
Huge Clucker
 
ToiletDuck's Avatar
 
Join Date: Apr 2012
Location: Philippines, Lucena City
Posts: 400
Reputation: 43
Default Re: Global Timer or Specific Timer

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
ToiletDuck is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Global Timer ElMaestro123 Scripting Help 6 19/03/2017 01:58 PM
Which is better Per Player Timer or Global timer? (issue with timer) Dokins Scripting Help 4 07/06/2016 09:50 AM
How to set a timer for a specific player? AndreiWow Scripting Help 2 19/01/2016 06:10 PM
Global Timer? UberSocks Help Archive 2 29/01/2010 11:13 AM
Hide specific TextDraw with a timer clavador Help Archive 4 23/09/2009 11:12 PM


All times are GMT. The time now is 07:43 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.