Delete house command creates a loop that crashes server
#1

I have a delete house command, that whenever I use it near a house, creates a loop of messages that crashes the server.
Код:
CMD:delhouse(playerid, params[])
{
	new string[128];
	new HouseID;

	if(pInfo[playerid][Admin] >= 4)
	{
		foreach(new h : Houses)
		{
			if(IsPlayerInRangeOfPoint(playerid, 3.5, hInfo[h][HouseX], hInfo[h][HouseY], hInfo[h][HouseZ]))
			{
			    format(string, sizeof(string), "-| House ID %d deleted. |-", h);
			    SendClientMessage(playerid, COLOR_RED, string);
			    hInfo[h][Owned] = false;
			    strmid(hInfo[HouseID][HouseName], "Deleted", 0, strlen("Deleted"), strlen("Deleted"));
		    	DestroyDynamicPickup(hInfo[h][DoorPickup]);
		    	HouseFileRemove(h);
				DestroyDynamic3DTextLabel(hInfo[h][DoorTextID]);
				hInfo[h][Buyable] = false;
				Iter_Remove(Houses, h);
				zInfo[GetPlayer2DZoneID(playerid)][HousesInZone]--;
				HouseCount--;
			}
			else
			{
			    SendClientMessage(playerid, COLOR_RED, "ERROR: No house in range to delete.");
			}
		}
	}
	else
	{
	    SendClientMessage(playerid, COLOR_RED, "ERROR: You are not a high enough level to use this command.");
	}
	return 1;
}
What's wrong with it?
Reply
#2

Код:
CMD:delhouse(playerid, params[])
{
	new string[128];
	new HouseID;

	if(pInfo[playerid][Admin] >= 4)
	{
		foreach(new h : Houses)
		{
			if(IsPlayerInRangeOfPoint(playerid, 3.5, hInfo[h][HouseX], hInfo[h][HouseY], hInfo[h][HouseZ]))
			{
			    format(string, sizeof(string), "-| House ID %d deleted. |-", h);
			    SendClientMessage(playerid, COLOR_RED, string);
			    hInfo[h][Owned] = false;
			    strmid(hInfo[HouseID][HouseName], "Deleted", 0, strlen("Deleted"), strlen("Deleted"));
		    	DestroyDynamicPickup(hInfo[h][DoorPickup]);
		    	HouseFileRemove(h);
				DestroyDynamic3DTextLabel(hInfo[h][DoorTextID]);
				hInfo[h][Buyable] = false;
				Iter_Remove(Houses, h);
				zInfo[GetPlayer2DZoneID(playerid)][HousesInZone]--;
				HouseCount--;
				break; // You'll need to stop the loop
			}
			else
			{
			    SendClientMessage(playerid, COLOR_RED, "ERROR: No house in range to delete.");
				break; // You'll need to stop the loop
			}
		}
	}
	else
	{
	    SendClientMessage(playerid, COLOR_RED, "ERROR: You are not a high enough level to use this command.");
	}
	return 1;
}
Reply
#3

Thanks again!
Reply
#4

Read more about why you can't use Iter_Remove inside a foreach of same iterator loop
if you are gonna keep looping you need to use Iter_SafeRemove (not the case here by the looks of it tho)

Edit: gurmani11's solution is wrong, simply because you shouldn't return the not inrange error while in loop, you should do that after looping has finished and no house were found, and return 1 to exit the function when you have deleted the house.
In his way if you are not in range of first home it'll stop looping and show you the error.
PHP код:
for()
{
     ...
     if(
IsPlayerInRange...)
     {
     ...
     return 
1;
     }
}
SendClientMessage(playeridCOLOR_RED"ERROR: No house in range to delete.");
return 
1
Reply
#5

Quote:
Originally Posted by PrO.GameR
Посмотреть сообщение
Read more about why you can't use Iter_Remove inside a foreach of same iterator loop
if you are gonna keep looping you need to use Iter_SafeRemove (not the case here by the looks of it tho)

Edit: gurmani11's solution is wrong, simply because you shouldn't return the not inrange error while in loop, you should do that after looping has finished and no house were found, and return 1 to exit the function when you have deleted the house.
In his way if you are not in range of first home it'll stop looping and show you the error.
PHP код:
for()
{
     ...
     if(
IsPlayerInRange...)
     {
     ...
     return 
1;
     }
}
SendClientMessage(playeridCOLOR_RED"ERROR: No house in range to delete.");
return 
1
I did seem to have that issue when I tried to remove a house. So, how should I fix it?
Reply
#6

Quote:
Originally Posted by stormchaser206
Посмотреть сообщение
I did seem to have that issue when I tried to remove a house. So, how should I fix it?
Already told you, you need to remove this:
PHP код:
            else
            {
                
SendClientMessage(playeridCOLOR_RED"ERROR: No house in range to delete.");
                break; 
// You'll need to stop the loop
            

And add it the way I explained, after the loop.
And you need to add a
PHP код:
return 1
after your
PHP код:
HouseCount--; 
to break the loop.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)