/*
	PostNuke Wasteland Gangmanagement
	Author:	NeoPhoenix
	Date:	21.07.2012
*/

#define gang:: gang_
#define turf:: turf_

#define MAX_GANGS					(20)			//Maximale Anzahl an Gangs
#define MAX_TURFS					(30)			//Maximale Anzahl an Ganggebieten
#define	GANG_MEMBER_LIMIT_BASE		(10)			//Membermaximum für Gangs (Standart)
#define MAX_GANG_TURFS				(3)				//Anzahl maximaler Gebiete für eine Gang
#define GANGWAR_MEMBERS_REQUIRED	(1)				//Anzahl an Membern der verteidigenden Gang für einen GW
#define GANGWAR_REQUIRED_KILLS		(3)				//Anzahl der benötigten Kills zum Sieg des GW
#define GANGWAR_FIGHT_TIME			(60*15)			//Sekunden bis zum Ende des GW
#define GANGWAR_DEATH_TIME			(30)			//In Sekunden
#define GANGWAR_ATTACK_COOLDOWN		(60*60*24)		//Abklingzeit nach einem Angriff
#define CAPTURE_WAIT_TIME			(600)			//Sekunden die ein Gebiet nach Eroberung Schutz hat
#define ATTACK_WAIT_TIME			(600)			//Sekunden die ein Gebiet nach Angriff Schutz hat
#define EXTEND_GW_ZONE				(200.0)			//Mapeinheiten, um die das Ganggebiet in einem Gangfight vergrößert wird
#define MAX_NON_READY_TIME			(60*60*24*7)	//Sekunden des NonReady Status bis alle Ganggebiete neutralisiert werden
#define MAX_NON_ONLINE_TIME			(60*60*24*7*8)	//Sekunden ohne online Member bis zur Löschung der ganzen Gang

enum ginfo_enum
{
	bool:gCreated,
	gName[20],
	gFounder,
	gFounded,
	gColor,
	gMembers,
	gMemberLimit,
	gAttack,
	gDefense,
	gWon,
	gLost,
	gTurfs,
	gTurfFight,
	gLastAttack,
	gLastOnline,
	gLastReady,
}
new GangInfo[MAX_GANGS][ginfo_enum];

enum tinfo_enum
{
	bool:tCreated,
	tOwner,
	tZoneID,
	tPickupID,
	Text3D:tLabelID,
	Float:tPosData[7],//MinX,MinY,MaxX,MaxY,X,Y,Z
	tCaptured,
	tLastAttack,
	tAttackerPoints,
	tDefenderPoints,
	tFightTimeLeft,
	tAttackerID,// = -1
}
new TurfInfo[MAX_TURFS][tinfo_enum];

gang::OnGangInit(ogid=-1)
{
	format(query,sizeof(query),"SELECT * FROM pnwl_gangs");
	mysql_query(query);
	mysql_store_result();
	if(mysql_num_rows() >= 1)
	{
		new created = 0;
		while(mysql_retrieve_row())
		{
			mysql_fetch_field_row(string,"gangid");
			new gid = strval(string);
			if(ogid != -1 && ogid != gid) return 	-1;
			if(gid < 0 || gid >= MAX_GANGS) return 	-1;
			mysql_fetch_field_row(GangInfo[gid][gName],"gName");
			mysql_fetch_field_row(string,"gFounder");
			GangInfo[gid][gFounder] 	= strval(string);
			mysql_fetch_field_row(string,"gFounded");
			GangInfo[gid][gFounded]		= strval(string);
			mysql_fetch_field_row(string,"gColor");
			GangInfo[gid][gColor]		= strval(string);
			mysql_fetch_field_row(string,"gMembers");
			GangInfo[gid][gMembers]		= strval(string);
			mysql_fetch_field_row(string,"gMemberLimit");
			GangInfo[gid][gMemberLimit]	= strval(string);
			mysql_fetch_field_row(string,"gAttack");
			GangInfo[gid][gAttack]		= strval(string);
			mysql_fetch_field_row(string,"gDefense");
			GangInfo[gid][gDefense]		= strval(string);
			mysql_fetch_field_row(string,"gTurfs");
			GangInfo[gid][gTurfs]		= strval(string);
			mysql_fetch_field_row(string,"gWon");
			GangInfo[gid][gWon]			= strval(string);
			mysql_fetch_field_row(string,"gLost");
			GangInfo[gid][gLost]		= strval(string);
			mysql_fetch_field_row(string,"gLastAttack");
			GangInfo[gid][gLastAttack]	= strval(string);
			mysql_fetch_field_row(string,"gLastOnline");
			GangInfo[gid][gLastOnline]	= strval(string);
			mysql_fetch_field_row(string,"gLastReady");
			GangInfo[gid][gLastReady]	= strval(string);
			GangInfo[gid][gTurfFight]	= -1;
			GangInfo[gid][gCreated] 	= true;
			created++;
		}
		return created;
	}
	return 0;
}

stock gang::UpdateGang(gid)
{
	format(query,sizeof(query),"SELECT * FROM pnwl_user WHERE gang='%d'",gid);
	mysql_query(query);
	mysql_store_result();
	GangInfo[gid][gMembers] = mysql_num_rows();
	mysql_free_result();
	if(GangInfo[gid][gMembers] > GangInfo[gid][gMemberLimit]) GangInfo[gid][gMemberLimit] = GangInfo[gid][gMembers];
	GangInfo[gid][gTurfs] = turf::CountGangTurfs(gid);	
	
	new count = gang::CountOnlineMembers(gid);
	if(count >=  GANGWAR_MEMBERS_REQUIRED) 	GangInfo[gid][gLastReady] 	= gettime(_,_,_);
	if(count >= 1) 							GangInfo[gid][gLastOnline] 	= gettime(_,_,_);
	
	format(string,sizeof(string),"UPDATE pnwl_gangs SET gName='%s',gColor='%d',gMembers='%d',gMemberLimit='%d',gAttack='%d',gDefense='%d',gWon='%d',gLost='%d',gTurfs='%d',gLastOnline='%d',",\
	GangInfo[gid][gName],\
	GangInfo[gid][gColor],\
	GangInfo[gid][gMembers],\
	GangInfo[gid][gMemberLimit],\
	GangInfo[gid][gAttack],\
	GangInfo[gid][gDefense],\
	GangInfo[gid][gWon],\
	GangInfo[gid][gLost],\
	GangInfo[gid][gTurfs],\
	GangInfo[gid][gLastOnline]);
	format(string,sizeof(string),"%sgLastReady='%d',gLastAttack='%d' WHERE gangid='%d'",\
	string,\
	GangInfo[gid][gLastReady],\
	GangInfo[gid][gLastAttack],\
	gid);
	
	mysql_query_once(string);
	format(string,sizeof(string),"");
	return 1;
}

stock gang::CreateGang(gname[],gfounder)
{
	new gid = -1;
	for(new i; i<MAX_GANGS; i++)
	{
		if(!GangInfo[i][gCreated])
		{
			gid = i;
			break;
		}
	}
	if(gid == -1) return -1;
	format(query,sizeof(query),"SELECT * FROM pnwl_gangs WHERE gangid='%d'",gid);
	mysql_query(query);
	mysql_store_result();
	if(mysql_num_rows() != 0)
	{
		gang::OnGangInit(gid);
		gid = -1;
	}
	mysql_free_result();
	if(gid == -1) return -1;
	new timestamp = gettime(_,_,_);
	
	format(GangInfo[gid][gName],20,gname);
	GangInfo[gid][gFounder]		=  gfounder;
	GangInfo[gid][gFounded]		=  gettime(_,_,_);
	GangInfo[gid][gColor]		=  0;
	GangInfo[gid][gMembers]		=  1;
	GangInfo[gid][gMemberLimit]	=  GANG_MEMBER_LIMIT_BASE;
	GangInfo[gid][gAttack]		=  0;
	GangInfo[gid][gDefense]		=  0;
	GangInfo[gid][gWon]			=  0;
	GangInfo[gid][gLost]		=  0;
	GangInfo[gid][gTurfs]		=  0;
	GangInfo[gid][gTurfFight]	= -1;
	GangInfo[gid][gLastOnline] 	=  timestamp;
	GangInfo[gid][gLastReady] 	=  timestamp;
	GangInfo[gid][gLastAttack] 	=  timestamp;
	GangInfo[gid][gCreated] = true;
	
	format(query,sizeof(query),"INSERT INTO pnwl_gangs ('gangid','gName','gFounder','gFounded','gColor','gMembers','gMemberLimit','gLastOnline','gLastReady','gLastAttack') VALUES ('%d','%s','%d','%d','0','1','%d','%d','%d','%d')",gid,gname,gfounder,GangInfo[gid][gFounded],GANG_MEMBER_LIMIT_BASE,GangInfo[gid][gLastOnline],GangInfo[gid][gLastReady],GangInfo[gid][gLastAttack]);
	mysql_query_once(query);
	return gid;
}

stock gang::DeleteGang(gid)
{
	if(!GangInfo[gid][gCreated]) return 0;
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(IsPlayerConnected(i) && PlayerInfo[i][pGang] == gid)
		{
			SendClientMessage(i,ROT,"INFO: Deine Gang wurde aufgelöst");
			PlayerInfo[i][pGang] 		= -1;
			PlayerInfo[i][pGangRang]	=  0;
		}
	}
	turf::OnGangDelete(gid);
	format(GangInfo[gid][gName],20,"");
	GangInfo[gid][gCreated] 	= false;
	GangInfo[gid][gFounder] 	= 0;
	GangInfo[gid][gFounded] 	= 0;
	GangInfo[gid][gColor]   	= 0;
	GangInfo[gid][gMembers] 	= 0;
	GangInfo[gid][gMemberLimit] = 0;
	GangInfo[gid][gAttack] 		= 0;
	GangInfo[gid][gDefense] 	= 0;
	GangInfo[gid][gTurfs] 		= 0;
	GangInfo[gid][gTurfFight] 	= 0;
	GangInfo[gid][gLastReady]	= 0;
	GangInfo[gid][gLastOnline]	= 0;
	GangInfo[gid][gLastAttack]	= 0;
	format(string,sizeof(string),"DELETE FROM pnwl_gangs WHERE gangid='%d'",gid);
	mysql_query_once(string);
	format(string,sizeof(string),"UPDATE pnwl_user SET gang='-1',grang='0' WHERE gang='%d'",gid);
	mysql_query_once(string);
	return 1;
}

stock gang::OnPlayerJoinGang(forum_id,gid)
{
	if(gid < 0 || gid >= MAX_GANGS) 							return 0;
	if(forum_id <= 0) 											return 0;
	if(GangInfo[gid][gMembers] >= GangInfo[gid][gMemberLimit]) 	return 0;
	new playerid=-1;
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++) 
	{
		if(PlayerInfo[i][PLAYER_ID] == forum_id)
		{
			playerid = i;
			break;
		}
	}
	if(mysql_GetIntByInt("pnwl_user","gang","userid",forum_id) != -1) return 0;
	
	if(playerid != -1)
	{
		PlayerInfo[playerid][pGang] 	= gid;
		PlayerInfo[playerid][pGangRang]	= 1;
		SetPlayerTeam(playerid,gid);
	}
	GangInfo[gid][gMembers]++;
	mysql_SetIntByInt("pnwl_gangs","gMembers",GangInfo[gid][gMembers],"gangid",gid);
	mysql_SetIntByInt("pnwl_user","gang",gid,"userid",forum_id);
	
	format(string,sizeof(string),"GANG: %s ist der Gang beigetreten",mysql_GetStringByInt("pnwl_user","username","userid",forum_id));
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(IsPlayerConnected(i) && PlayerInfo[i][pGang] == gid)
		{
			SendClientMessage(i,GRUEN,string);
		}
	}
	return 1;
}

stock gang::OnPlayerLeaveGang(forum_id,reason[]="",bool:rauswurf=false,rid=0)
{
	new gid = mysql_GetIntByInt("pnwl_user","gang","userid",forum_id);
	if(gid < 0 || gid >= MAX_GANGS) return 0;
	format(query,sizeof(query),"UPDATE pnwl_user SET gang='0',grang='0' WHERE userid='%d'",forum_id);
	mysql_query_once(query);
	format(query,sizeof(query),"UPDATE pnwl_gang SET gMembers=gMembers-1 WHERE gangid='%d'",gid);
	mysql_query_once(query);
	
	if(!rauswurf) 	format(string,sizeof(string),"INFO: %s (fID %d) hat die Gang verlassen",mysql_GetStringByInt("pnwl_user","username","userid",forum_id),forum_id);
	else			format(string,sizeof(string),"INFO: %s (fID %d) wurde von %s (fID %d) aus der Gang entlassen",mysql_GetStringByInt("pnwl_user","username","userid",forum_id),forum_id,mysql_GetStringByInt("pnwl_user","username","userid",rid),rid);
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++) if(PlayerInfo[i][pGang] == gid) SendClientMessage(i,ROT,string);
	
	if(!rauswurf) 	format(string,sizeof(string),"INFO: Du hast die Gang verlassen");
	else			format(string,sizeof(string),"INFO: Du wurdest von %s (fID %d) aus der Gang entlassen (%s)",mysql_GetStringByInt("pnwl_user","username","userid",rid),rid,reason);
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++) 
	{
		if(PlayerInfo[i][PLAYER_ID] == forum_id)
		{
			SendClientMessage(i,ROT,string);
			PlayerInfo[i][pGang] 		= -1;
			PlayerInfo[i][pGangRang] 	=  0;
			SetPlayerTeam(i,NO_TEAM);
		}
	}
	return 1;
}

gang::GetColor(cid=0)
{
	new cstr[7] = "808080";
	switch(cid)
	{
		case 0: cstr = "0094FF";
		case 1: cstr = "267F00";
		case 2: cstr = "00FF21";
		case 3: cstr = "724F0E";
		case 4: cstr = "FF0000";
		case 5: cstr = "FF6A00";
		case 6: cstr = "FFD800";
		case 7: cstr = "B200FF";
		case 8: cstr = "FF7FED";
		case 9: cstr = "808080";
		default:cstr = "808080";
	}
	return cstr;
}

gang::CountOnlineMembers(gid)
{
	new count = 0;
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
		if(PlayerInfo[i][pGang] == gid) count++;
	}
	return count;
}

gang::SendMessageToGang(gid,color=BLAU,msg[])
{
	new count = 0;
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
		if(PlayerInfo[i][pGang] == gid)
		{
			SendClientMessage(i,color,msg);
			count++;
		}
	}
	return count;
}

new gCR_time = 0;
gang::Cronjob(time)
{//time = Sekunden
	new members_online[MAX_GANGS],
		count_online 	= gang::CountAllOnlineMembers(members_online),
		timestamp		= gettime(_,_,_);
	#pragma unused count_online
	
	for(new gid; gid<MAX_GANGS; gid++)
	{
		if(!GangInfo[gid][gCreated]) continue;
		new online = members_online[gid];
		if(online >= GANGWAR_MEMBERS_REQUIRED) 	GangInfo[gid][gLastReady] 	= timestamp;
		if(online >= 1) 						GangInfo[gid][gLastOnline]	= timestamp;
	}

	gCR_time += time;
	if(gCR_time >= (60*30))
	{//Alle 30 Minuten
		gCR_time = 0;
	}
	return 1;
}

gang::CountAllOnlineMembers(dest[])
{
	new count = 0;
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
		if(PlayerInfo[i][pGang] != -1)
		{
			dest[PlayerInfo[i][pGang]]++;
			count++;
		}
	}
	return count;
}

gang::OnPlayerConnect(playerid)
{
	new gid = PlayerInfo[playerid][pGang];
	if(gid == -1) return 0;
	new newcount = gang::CountOnlineMembers(gid),
		oldcount = (newcount-1),
		timestamp = gettime(_,_,_);
	if(newcount >=  GANGWAR_MEMBERS_REQUIRED)
	{
		GangInfo[gid][gLastReady] = timestamp;
	}
	GangInfo[gid][gLastOnline] = timestamp;
	#pragma unused oldcount
	return 1;
}

gang::OnPlayerDisconnect(playerid)
{
	new gid = PlayerInfo[playerid][pGang];
	if(gid == -1) return 0;
	new oldcount = gang::CountOnlineMembers(gid),
		newcount = (oldcount-1);
	if(newcount < GANGWAR_MEMBERS_REQUIRED)
	{
		if(GangInfo[gid][gTurfFight] != -1)
		{
			new tid 	= GangInfo[gid][gTurfFight];
			new winner 	= -1;
			if(TurfInfo[tid][tOwner] == gid) 	winner = TurfInfo[tid][tAttackerID];
			else								winner = TurfInfo[tid][tOwner];
			turf::OnFightEnd(tid,winner);
		}
	}
	return 1;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//Turfs

turf::OnTurfInit()
{
	print("turf::Loading...");
	format(query,sizeof(query),"SELECT * FROM pnwl_turfs");
	mysql_query(query);
	mysql_store_result();
	if(mysql_num_rows() >= 1)
	{
		new created = 0;
		while(mysql_retrieve_row())
		{
			mysql_fetch_field_row(string,"tID");
			new tid = strval(string);
			if(tid < 0 || tid >= MAX_TURFS) 
			{
				printf("turf::OnTurfInit -> invalid tID %d",tid);
				continue;
			}
			mysql_fetch_field_row(string,"tOwner");
			TurfInfo[tid][tOwner] 		= strval(string);
			//Positionen
			mysql_fetch_field_row(string,"minX");
			TurfInfo[tid][tPosData][0]		=  floatstr(string);
			mysql_fetch_field_row(string,"minY");
			TurfInfo[tid][tPosData][1] 		=  floatstr(string);
			mysql_fetch_field_row(string,"maxX");
			TurfInfo[tid][tPosData][2] 		=  floatstr(string);
			mysql_fetch_field_row(string,"maxY");
			TurfInfo[tid][tPosData][3] 		=  floatstr(string);			
			mysql_fetch_field_row(string,"middleX");
			TurfInfo[tid][tPosData][4] 		=  floatstr(string);
			mysql_fetch_field_row(string,"middleY");
			TurfInfo[tid][tPosData][5] 		=  floatstr(string);
			mysql_fetch_field_row(string,"middleZ");
			TurfInfo[tid][tPosData][6] 		=  floatstr(string);
			
			//Angriffe
			mysql_fetch_field_row(string,"tCaptured");
			TurfInfo[tid][tCaptured]		=  strval(string);
			mysql_fetch_field_row(string,"tLastAttack");
			TurfInfo[tid][tLastAttack]		=  strval(string);
			TurfInfo[tid][tAttackerPoints] 	=  0;
			TurfInfo[tid][tDefenderPoints] 	=  0;
			TurfInfo[tid][tFightTimeLeft]	=  0;
			TurfInfo[tid][tAttackerID]		= -1;
			TurfInfo[tid][tCreated]			=  true;
			
			TurfInfo[tid][tZoneID]			= GangZoneCreate(TurfInfo[tid][tPosData][0],TurfInfo[tid][tPosData][1],TurfInfo[tid][tPosData][2],TurfInfo[tid][tPosData][3]);	
			format(string,sizeof(string),"TID %d",tid);
			TurfInfo[tid][tLabelID]			= Create3DTextLabel(string,WEISS,TurfInfo[tid][tPosData][4],TurfInfo[tid][tPosData][5],TurfInfo[tid][tPosData][6],20.0,0);
			created++;
		}
		mysql_free_result();
		for(new tid; tid<MAX_TURFS; tid++) turf::UpdateTurf(tid,false);
		printf("turf::OnTurfInit -> %d turfs created",created);
		return created;
	}
	mysql_free_result();
	print("turf::OnTurfInit -> No turfs found");
	return 0;
}

stock turf::UpdateTurf(tid,bool:db_update=true)
{
	if(!TurfInfo[tid][tCreated]) return 0;
	if(TurfInfo[tid][tOwner] == -1) format(string,sizeof(string),"Gangzone\nBesitzer: Niemand\nBenutze /gangwar, um es einzunehmen");
	else
	{
		new time = (gettime(_,_,_)-TurfInfo[tid][tCaptured]),
			weeks,days,hours;
		ConvertTime(time,weeks,days,hours);
		format(string,sizeof(string),"Gangzone\nBesitzer: %s\nErobert vor %dW %dT %dS\nBenutze /gangwar, um es zu erobern",mysql_GetStringByInt("pnwl_gangs","gName","gangid",TurfInfo[tid][tOwner]),weeks,days,hours);
	}

	Delete3DTextLabel(TurfInfo[tid][tLabelID]);
	TurfInfo[tid][tLabelID]			= Create3DTextLabel(string,WEISS,TurfInfo[tid][tPosData][4],TurfInfo[tid][tPosData][5],TurfInfo[tid][tPosData][6],20.0,0);
	if(TurfInfo[tid][tPickupID] != 0) DestroyPickup(TurfInfo[tid][tPickupID]);
	TurfInfo[tid][tPickupID] 		= CreatePickup(1274,1,TurfInfo[tid][tPosData][4],TurfInfo[tid][tPosData][5],TurfInfo[tid][tPosData][6]);

	turf::DisplayGangzone(tid);	
	if(db_update)
	{
		format(string,sizeof(string),"UPDATE pnwl_turfs SET tOwner='%s',tCaptured='%d',tLastAttack='%d' WHERE tID='%d'",TurfInfo[tid][tOwner],TurfInfo[tid][tCaptured],TurfInfo[tid][tLastAttack],tid);
		mysql_query_once(string);
	}
	return 1;
}

stock turf::OnGangDelete(gid)
{
	for(new i; i<MAX_TURFS; i++)
	{
		if(TurfInfo[i][tFightTimeLeft])
		{
			if(TurfInfo[i][tOwner] == gid)
			{
				turf::OnFightEnd(i,TurfInfo[i][tAttackerID]);
				continue;
			}
			if(TurfInfo[i][tAttackerID] == gid)
			{
				turf::OnFightEnd(i,TurfInfo[i][tOwner]);
				continue;
			}
		}
		if(TurfInfo[i][tOwner] == gid) turf::NeutralizeTurf(i);
	}
	return 1;
}	

stock turf::OnFightEnd(tid,owinner=-1)
{
	if(!TurfInfo[tid][tCreated]) return 0;
	new winner = -1, loser = -1;
	if(owinner != -1) winner = owinner;
	else
	{
		if(TurfInfo[tid][tAttackerPoints] > TurfInfo[tid][tDefenderPoints]) winner = TurfInfo[tid][tAttackerID];
		else																winner = TurfInfo[tid][tOwner];
	}
	if(winner == TurfInfo[tid][tAttackerID])	loser = TurfInfo[tid][tOwner];
	else 										loser = TurfInfo[tid][tAttackerID];
	if(winner < 0 || winner >= MAX_GANGS || loser < 0 || loser >= MAX_GANGS) return 0;
	
	for(new i; i<__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(PlayerInfo[i][pGang] == winner)
		{
			if(PlayerInfo[i][pGang] == TurfInfo[tid][tAttackerID])  format(string,sizeof(string),"INFO: Deine Gang hat den Gangfight mit %d:%d Punkten gewonnen. Das Gebiet gehört nun euch!",TurfInfo[tid][tAttackerPoints],TurfInfo[tid][tDefenderPoints]);
			else													format(string,sizeof(string),"INFO: Deine Gang hat den Gangfight mit %d:%d Punkten gewonnen. Ihr habt das Gebiet verteidigt!",TurfInfo[tid][tDefenderPoints],TurfInfo[tid][tAttackerPoints]);
			SendClientMessage(i,ROT,string);
		}
		if(PlayerInfo[i][pGang] == loser)
		{
			if(PlayerInfo[i][pGang] == TurfInfo[tid][tAttackerID])  format(string,sizeof(string),"INFO: Deine Gang hat den Gangfight mit %d:%d Punkten verloren. Ihr konntet das Gebiet nicht erobern!",TurfInfo[tid][tAttackerPoints],TurfInfo[tid][tDefenderPoints]);
			else													format(string,sizeof(string),"INFO: Deine Gang hat den Gangfight mit %d:%d Punkten gewonnen. Ihr habt das Gebiet verloren!",TurfInfo[tid][tDefenderPoints],TurfInfo[tid][tAttackerPoints]);
			SendClientMessage(i,ROT,string);
		}
	}	
	if(TurfInfo[tid][tOwner] == winner) TurfInfo[tid][tLastAttack] 	= gettime(_,_,_);
	else 								TurfInfo[tid][tCaptured]	= gettime(_,_,_);
	TurfInfo[tid][tOwner] 								=  winner;
	TurfInfo[tid][tAttackerPoints] 						=  0;
	TurfInfo[tid][tDefenderPoints] 						=  0;
	TurfInfo[tid][tFightTimeLeft] 						=  0;
	GangInfo[TurfInfo[tid][tAttackerID]][gAttack]		+= 1;
	GangInfo[TurfInfo[tid][tOwner]][gDefense]			+= 1;
	GangInfo[loser][gLost]								+= 1;
	GangInfo[winner][gWon]								+= 1;
	GangInfo[TurfInfo[tid][tOwner]][gTurfFight]			= -1;
	GangInfo[TurfInfo[tid][tAttackerID]][gTurfFight]	= -1;
	TurfInfo[tid][tAttackerID]							= -1;
	GangZoneStopFlashForAll(TurfInfo[tid][tZoneID]);
	GangZoneHideForAll(TurfInfo[tid][tZoneID]);
	turf::UpdateTurf(tid);
	gang::UpdateGang(winner);
	gang::UpdateGang(loser);
	return 1;
}

stock turf::NeutralizeTurf(tid)
{
	if(!TurfInfo[tid][tCreated]) return 0;	
	new attacker 	= TurfInfo[tid][tAttackerID],
		owner		= TurfInfo[tid][tOwner];
	if(attacker != -1)
	{
		for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
		{
			if(PlayerInfo[i][pGang] == attacker) 	SendClientMessage(i,BLAU,"GANG: Der Gangwar wurde beendet");
			if(PlayerInfo[i][pGang] == owner) 		SendClientMessage(i,BLAU,"GANG: Der Gangwar wurde beendet");
		}
		GangInfo[attacker][gTurfFight] 	= -1;
		GangInfo[owner][gTurfFight] 	= -1;
	}
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(!IsPlayerConnected(i) || IsPlayerNPC(i)) continue;
		if(PlayerInfo[i][pGang] == owner) SendClientMessage(i,BLAU,"GANG: Deine Gang hat ein Gebiet verloren!");
	}
	if(TurfInfo[tid][tOwner] >= 0 && TurfInfo[tid][tOwner] < MAX_GANGS)
	{
		new gid = TurfInfo[tid][tOwner];
		GangInfo[gid][gTurfs]--;
		gang::UpdateGang(gid);
	}	
	TurfInfo[tid][tOwner] 				= -1;
	TurfInfo[tid][tAttackerPoints] 		=  0;
	TurfInfo[tid][tDefenderPoints] 		=  0;
	TurfInfo[tid][tFightTimeLeft] 		=  0;
	TurfInfo[tid][tAttackerID]			= -1;
	turf::UpdateTurf(tid);
	return 1;
}

stock turf::DisplayGangzone(tid)
{
	if(!TurfInfo[tid][tCreated]) return 0;
	if(TurfInfo[tid][tZoneID] != 0) 
	{
		GangZoneHideForAll(TurfInfo[tid][tZoneID]);
		GangZoneDestroy(TurfInfo[tid][tZoneID]);
		TurfInfo[tid][tZoneID] = 0;
	}
	
	new bool:_fight = false;
	if(TurfInfo[tid][tFightTimeLeft] && TurfInfo[tid][tAttackerID] != -1) _fight = true;
	if(_fight) 	TurfInfo[tid][tZoneID] = GangZoneCreate(TurfInfo[tid][tPosData][0]-EXTEND_GW_ZONE,TurfInfo[tid][tPosData][1]-EXTEND_GW_ZONE,TurfInfo[tid][tPosData][2]+EXTEND_GW_ZONE,TurfInfo[tid][tPosData][3]+EXTEND_GW_ZONE);
	else 		TurfInfo[tid][tZoneID] = GangZoneCreate(TurfInfo[tid][tPosData][0],TurfInfo[tid][tPosData][1],TurfInfo[tid][tPosData][2],TurfInfo[tid][tPosData][3]);
	
	if(TurfInfo[tid][tOwner] < 0 || TurfInfo[tid][tOwner] >= MAX_GANGS)
	{
		GangZoneShowForAll(TurfInfo[tid][tZoneID],0x8080807e);//Grau
		return 1;
	}
	
	switch(GangInfo[TurfInfo[tid][tOwner]][gColor])
	{
		case 0: GangZoneShowForAll(TurfInfo[tid][tZoneID],0x0094FF7e);//Hellblau
		case 1: GangZoneShowForAll(TurfInfo[tid][tZoneID],0x267F007e);//Dunkelgrün
		case 2: GangZoneShowForAll(TurfInfo[tid][tZoneID],0x00FF217e);//Hellgrün
		case 3: GangZoneShowForAll(TurfInfo[tid][tZoneID],0x724F0E7e);//Braun
		case 4: GangZoneShowForAll(TurfInfo[tid][tZoneID],0xFF00007e);//Rot
		case 5: GangZoneShowForAll(TurfInfo[tid][tZoneID],0xFF6A007e);//Orange
		case 6: GangZoneShowForAll(TurfInfo[tid][tZoneID],0xFFD8007e);//Gelb
		case 7: GangZoneShowForAll(TurfInfo[tid][tZoneID],0xB200FF7e);//Violett
		case 8: GangZoneShowForAll(TurfInfo[tid][tZoneID],0xFF7FED7e);//Rosa
		case 9: GangZoneShowForAll(TurfInfo[tid][tZoneID],0x8080807e);//Grau
		default:GangZoneShowForAll(TurfInfo[tid][tZoneID],0x8080807e);//Grau
	}
	
	if(_fight)
	{//Im Gangfight
		if(GangInfo[TurfInfo[tid][tAttackerID]][gColor] == GangInfo[TurfInfo[tid][tOwner]][gColor]) GangZoneFlashForAll(TurfInfo[tid][tZoneID],WEISS);
		else
		{
			switch(GangInfo[TurfInfo[tid][tAttackerID]][gColor])
			{
				case 0: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x0094FF7e);//Hellblau
				case 1: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x267F007e);//Dunkelgrün
				case 2: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x00FF217e);//Hellgrün
				case 3: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x724F0E7e);//Braun
				case 4: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0xFF00007e);//Rot
				case 5: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0xFF6A007e);//Orange
				case 6: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0xFFD8007e);//Gelb
				case 7: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0xB200FF7e);//Violett
				case 8: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0xFF7FED7e);//Rosa
				case 9: GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x8080807e);//Grau
				default:GangZoneFlashForAll(TurfInfo[tid][tZoneID],0x8080807e);//Grau
			}
		}
	}	
	return 1;
}

stock turf::OnFightScore(gid,killergid)
{
	if(gid < 0 || gid >= MAX_GANGS || killergid < 0 || killergid >= MAX_GANGS) 	return 0;
	if(gid == killergid) 														return 0;
	if(GangInfo[gid][gTurfFight] != GangInfo[killergid][gTurfFight]) 			return 0;
	new tid = GangInfo[gid][gTurfFight];
	if(tid < 0 || tid >= MAX_TURFS)												return 0;
	if(TurfInfo[tid][tOwner] == gid)
	{
		if(++TurfInfo[tid][tAttackerPoints] >= GANGWAR_REQUIRED_KILLS)
		{
			turf::OnFightEnd(tid,killergid);
			return 1;
		}
	}
	else
	{
		if(++TurfInfo[tid][tDefenderPoints] >= GANGWAR_REQUIRED_KILLS)
		{
			turf::OnFightEnd(tid,gid);
			return 1;
		}
	}
	
	format(string,sizeof(string),"GANGWAR: Es steht nun %d:%d für die Angreifer",TurfInfo[tid][tAttackerPoints],TurfInfo[tid][tDefenderPoints]);
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(PlayerInfo[i][pGang] == gid) 		SendClientMessage(i,BLAU,string);
		if(PlayerInfo[i][pGang] == killergid) 	SendClientMessage(i,BLAU,string);
	}
	return 1;
}

stock turf::GetPlayerTurfMiddle(playerid,Float:range=10.0)
{
	for(new i; i<MAX_TURFS; i++)
	{
		if(IsPlayerInRangeOfPoint(playerid,range,TurfInfo[i][tPosData][4],TurfInfo[i][tPosData][5],TurfInfo[i][tPosData][6]))
		{
			return i;
		}
	}
	return -1;
}

stock turf::GetPlayerTurfArea(playerid)
{
	for(new i; i<MAX_TURFS; i++)
	{
		if(IsPlayerInArea(playerid,TurfInfo[i][tPosData][0],TurfInfo[i][tPosData][1],TurfInfo[i][tPosData][2],TurfInfo[i][tPosData][3]))
		{
			return i;
		}
	}
	return -1;
}

stock turf::CountGangTurfs(gid)
{
	new count = 0;
	for(new tid; tid<MAX_TURFS; tid++)
	{
		if(!TurfInfo[tid][tCreated]) 		continue;
		if(TurfInfo[tid][tOwner] == gid) 	count++;
	}
	return count;
}

stock turf::StartGangwar(tid,attacker)
{
	if(attacker < 0 || attacker >= MAX_GANGS) 									return 0;
	if(!GangInfo[attacker][gCreated] || GangInfo[attacker][gTurfFight] != -1) 	return 0;
	if(tid < 0 || tid >= MAX_TURFS || !TurfInfo[tid][tCreated])					return 0;
	new defender					= TurfInfo[tid][tOwner];
	TurfInfo[tid][tLastAttack] 		= gettime(_,_,_);
	TurfInfo[tid][tAttackerPoints] 	= 0;
	TurfInfo[tid][tDefenderPoints] 	= 0;
	TurfInfo[tid][tFightTimeLeft] 	= GANGWAR_FIGHT_TIME;
	TurfInfo[tid][tAttackerID] 		= attacker;
	GangInfo[attacker][gTurfFight]	= tid;
	GangInfo[defender][gTurfFight] 	= tid;
	turf::DisplayGangzone(tid);
	for(new i; i<=__SERVER[HIGHEST_PLAYER_ID]; i++)
	{
		if(!IsPlayerConnected(i) || IsPlayerNPC(i) || !PlayerEvent[i][LOGGED_IN]) continue;
		if(PlayerInfo[i][pGang] == TurfInfo[tid][tOwner])
		{
			SendClientMessage(i,ROT,"---> GANG: Ein Gebiet deiner Gang wird angegriffen!");
			continue;
		}
		if(PlayerInfo[i][pGang] == attacker) SendClientMessage(i,ROT,"---> GANG: Deine Gang greift ein Gebiet an!");
	}
	return 1;
}

new tCR_time = 0;
turf::Cronjob(time)
{//time = Sekunden
	for(new tid; tid<MAX_TURFS; tid++)
	{
		if(!TurfInfo[tid][tCreated]) continue;
		if(TurfInfo[tid][tFightTimeLeft] >= 1)
		{
			TurfInfo[tid][tFightTimeLeft] -= time;
			if(TurfInfo[tid][tFightTimeLeft] <= 0)
			{
				new owner 		= TurfInfo[tid][tOwner],
					attacker	= TurfInfo[tid][tAttackerID];
				if(TurfInfo[tid][tAttackerPoints] >= TurfInfo[tid][tDefenderPoints]) 	turf::OnFightEnd(tid,attacker);
				else																	turf::OnFightEnd(tid,owner);
			}
		}
	}
	
	tCR_time += time;
	if(tCR_time >= (60*20))
	{//Alle 20 Minuten
		for(new tid; tid<MAX_TURFS; tid++) turf::DisplayGangzone(tid);
		tCR_time = 0;
	}
	return 1;
}