- /*	Formatright © 2009, ConnorMcLeod 
-   
- 	c4 management is free software; 
- 	you can redistribute it and/or modify it under the terms of the 
- 	GNU General Public License as published by the Free Software Foundation. 
-   
- 	This program is distributed in the hope that it will be useful, 
- 	but WITHOUT ANY WARRANTY; without even the implied warranty of 
- 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- 	GNU General Public License for more details. 
-   
- 	You should have received a copy of the GNU General Public License 
- 	along with c4 management; if not, write to the 
- 	Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
- 	Boston, MA 02111-1307, USA. 
- */ 
-   
- #include <amxmodx> 
- #include <amxmisc> 
- #include <fakemeta> 
- #include <hamsandwich> 
-   
- #define VERSION "0.2.7" 
-   
- #define MAX_PLAYERS 32 
-   
- enum _:BombSites_Datas { 
- 	iBsIndex, 
- 	szBsModel[5] 
- } 
-   
- enum _:BombSites_States { 
- 	AllSites, 
- 	MainSite, 
- 	NoSite 
- } 
-   
- #define StatusIconDontShow 0 
- #define StatusIconShow 1 
-   
- new const func_bomb_target[] = "func_bomb_target" 
- new const info_bomb_target[] = "info_bomb_target" 
-   
- new const classname[] = "classname" 
-   
- #define FIND_ENT_BY_CLASSNAME(%1,%2)	engfunc(EngFunc_FindEntityByString, %1, classname, %2) 
-   
- #define XTRA_OFS_PLAYER 5 
- #define m_iTeam 114 
- #define cs_get_user_team_index(%1)		get_pdata_int(%1, m_iTeam, XTRA_OFS_PLAYER) 
- #define CS_TEAM_CT 2 
-   
- new g_iMaxPlayers 
-   
- new g_pCvarMinCts, g_pCvarMidCts 
- new g_pCvarStartRoundText, g_pCvarPlanterText 
-   
- new bool:g_bMainSiteSet 
-   
- new szConfigFile[64], g_szMapName[32] 
- new g_mMainBombSite[BombSites_Datas] 
- new g_szBombSiteName[16] 
- new Array:g_aBombSites 
-   
- new Float:g_flCountUntilGameTime 
- new bool:g_bCountNewSpawns 
-   
- new g_iSyncHud 
-   
- new mp_buytime 
-   
- new gmsgStatusIcon 
-   
- new g_iBombSites_State 
-   
- new g_iC4Carrier 
-   
- public plugin_init() 
- { 
- 	new iEnt, mDatas[BombSites_Datas] 
- 	while( (iEnt = FIND_ENT_BY_CLASSNAME(iEnt, func_bomb_target)) ) 
- 	{ 
- 		if( g_aBombSites == Invalid_Array ) 
- 		{ 
- 			g_aBombSites = ArrayCreate(BombSites_Datas) 
- 		} 
-   
- 		mDatas[iBsIndex] = iEnt 
- 		pev(iEnt, pev_model, mDatas[szBsModel], charsmax(mDatas[szBsModel])) 
- 		ArrayPushString(g_aBombSites, mDatas) 
- 	} 
- 	while( (iEnt = FIND_ENT_BY_CLASSNAME(iEnt, info_bomb_target)) ) 
- 	{ 
- 		if( g_aBombSites == Invalid_Array ) 
- 		{ 
- 			g_aBombSites = ArrayCreate(BombSites_Datas) 
- 		} 
-   
- 		mDatas[iBsIndex] = iEnt 
- 		pev(iEnt, pev_model, mDatas[szBsModel], charsmax(mDatas[szBsModel])) 
- 		ArrayPushString(g_aBombSites, mDatas) 
- 	} 
-   
- 	if( g_aBombSites == Invalid_Array ) 
- 	{ 
- 		register_plugin("c4 management", "NotBombMap", "ConnorMcLeod") 
- 		pause("ad") 
- 		return 
- 	} 
-   
- 	register_plugin("c4 management", VERSION, "ConnorMcLeod") 
- 	register_dictionary("c4management.txt") 
-   
- 	g_pCvarMinCts = register_cvar("bm_minct", "0") 
- 	g_pCvarMidCts = register_cvar("bm_midct", "4") 
- 	g_pCvarStartRoundText = register_cvar("bm_roundstart_text", "1") 
- 	g_pCvarPlanterText = register_cvar("bm_planter_text", "1") 
-   
- 	get_mapname(g_szMapName, charsmax(g_szMapName)) 
-   
- 	get_localinfo("amxx_configsdir", szConfigFile, charsmax(szConfigFile)) 
- 	format(szConfigFile, charsmax(szConfigFile), "%s/bombsites.ini", szConfigFile) 
- 	if( !file_exists(szConfigFile) ) 
- 	{ 
- 		new iFile = fopen(szConfigFile, "at") 
- 		fprintf(iFile, "; c4 management configuration file^n") 
- 		fclose(iFile) 
- 	} 
-   
- 	g_iMaxPlayers = get_maxplayers() 
-   
- 	GetMainBombSiteByFile() 
-   
- 	register_event("HLTV", "Event_HLTV_New_Round", "a", "1=0", "2=0") 
- 	register_logevent("LogEvent_RoundStart", 2, "1=Round_Start") 
- 	register_logevent("Logevent_Round_End", 2, "1=Round_End") 
- 	RegisterHam(Ham_Spawn, "player", "Player_Spawn_Post", 1) 
-   
- 	register_event("WeapPickup", "Event_WeapPickup_c4", "be", "1=6") 
- 	register_message(get_user_msgid("StatusIcon"), "Message_StatusIcon") 
-   
- 	register_event("BombDrop", "Event_BombDrop", "bc") 
-   
- 	register_event("TextMsg", "Event_TextMsg_C4PlantAtBombSpot", "be", "1=4", "2=#C4_Plant_At_Bomb_Spot") 
-   
- 	register_clcmd("bm_mark_bs", "AdminCommand_MarkBombSite", ADMIN_CFG, " <BombSite Name>") 
-   
- 	g_iSyncHud = CreateHudSyncObj() 
- 	mp_buytime = get_cvar_pointer("mp_buytime") 
- 	gmsgStatusIcon = get_user_msgid("StatusIcon") 
- } 
-   
- GetMainBombSiteByFile() 
- { 
- 	new iFile = fopen(szConfigFile, "rt") 
- 	if( iFile ) 
- 	{ 
- 		new szData[64], szMapname[32], szModel[5], szBombSiteName[16] 
- 		while( fgets(iFile, szData, charsmax(szData)) ) 
- 		{ 
- 			if( !szData[0] || szData[0] == '/' || szData[0] == ';' || szData[0] == '#' ) 
- 			{ 
- 				continue 
- 			} 
-   
- 			trim(szData) 
- 			parse(szData, szMapname, charsmax(szMapname),  
- 						szModel, charsmax(szModel),  
- 						szBombSiteName, charsmax(szBombSiteName)) 
-   
- 			if( equali(szMapname, g_szMapName) ) 
- 			{ 
- 				new iEnt 
- 				// less efficient than engine but used only at map start 
- 				iEnt = FIND_ENT_BY_MODELNAME(g_iMaxPlayers, func_bomb_target, szModel) 
-   
- 				if( !iEnt ) 
- 				{ 
- 					iEnt = FIND_ENT_BY_MODELNAME(g_iMaxPlayers, info_bomb_target, szModel) 
- 				} 
-   
- 				if( iEnt ) 
- 				{ 
- 					g_mMainBombSite[iBsIndex] = iEnt 
- 					g_mMainBombSite[szBsModel] = szModel 
- 					remove_quotes(szBombSiteName) 
- 					g_szBombSiteName = szBombSiteName 
-   
- 					g_bMainSiteSet = true 
- 				}				 
- 				break 
- 			} 
- 		} 
- 		fclose(iFile) 
- 	} 
- } 
-   
- public plugin_pause() 
- { 
- 	new iBombSiteNum = ArraySize(g_aBombSites) 
- 	new mBombSiteDatas[BombSites_Datas] 
-   
- 	for(new i; i<iBombSiteNum; i++) 
- 	{ 
- 		ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 		SetBombSite(mBombSiteDatas[iBsIndex], true) 
- 	} 
- } 
-   
- public plugin_end() 
- { 
- 	if( g_aBombSites != Invalid_Array ) 
- 	{ 
- 		ArrayDestroy(g_aBombSites) 
- 	} 
- } 
-   
- public Event_HLTV_New_Round() 
- { 
- 	g_iC4Carrier = 0 
- 	g_bCountNewSpawns = false 
- 	g_iBombSites_State = AllSites 
- } 
-   
- public Event_BombDrop() 
- { 
- 	g_iC4Carrier = 0 
-   
- 	if( read_data(4) ) // Bomb Planted 
- 	{ 
- 		g_bCountNewSpawns = false 
- 	} 
- } 
-   
- public Logevent_Round_End() 
- { 
- 	g_bCountNewSpawns = false 
- } 
-   
- public LogEvent_RoundStart() 
- { 
- 	g_bCountNewSpawns = true 
- 	g_flCountUntilGameTime = get_gametime() + get_pcvar_float(mp_buytime) * 60.0 
-   
- 	if(!g_bMainSiteSet) 
- 	{ 
- 		return 
- 	} 
-   
- 	CountCounterTerrorists() 
- } 
-   
- public AdminCommand_MarkBombSite(id, level, cid) 
- { 
- 	if( !cmd_access(id, level, cid, 2) ) 
- 	{ 
- 		return PLUGIN_HANDLED 
- 	} 
-   
- 	if(g_bMainSiteSet) 
- 	{ 
- 		client_print(id, print_console, "%L", id, "BM_ALREADY") 
- 		client_cmd(id, "spk buttons/latchlocked1") 
- 		return PLUGIN_HANDLED 
- 	} 
-   
- 	new iBombSiteNum = ArraySize(g_aBombSites) 
-   
- 	new mBombSiteDatas[BombSites_Datas], iEnt 
- 	new Float:fVecOrigin[3], Float:fVecAbsMin[3], Float:fVecAbsMax[3] 
-   
- 	for(new i=0; i<iBombSiteNum; i++) 
- 	{ 
- 		ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 		iEnt = mBombSiteDatas[iBsIndex] 
-   
- 		pev(id, pev_origin, fVecOrigin) 
- 		pev(iEnt, pev_absmin, fVecAbsMin) 
- 		pev(iEnt, pev_absmax, fVecAbsMax) 
-   
- 		if(	(fVecAbsMin[0] <= fVecOrigin[0] <= fVecAbsMax[0]) 
- 		&&	(fVecAbsMin[1] <= fVecOrigin[1] <= fVecAbsMax[1]) 
- 		&&	(-72.0 <= (((fVecAbsMax[2] + fVecAbsMin[2]) / 2.0) - fVecOrigin[2]) <= 72.0)	) 
- 		{ 
- 			read_argv(1, g_szBombSiteName, charsmax(g_szBombSiteName)) 
- 			new iFile = fopen(szConfigFile, "at") 
- 			fprintf(iFile, "^n%s %s ^"%s^"", g_szMapName, mBombSiteDatas[szBsModel], g_szBombSiteName) 
- 			fclose(iFile) 
-   
- 			g_mMainBombSite = mBombSiteDatas 
- 			g_bMainSiteSet = true 
-   
- 			client_print(id, print_console, "%L", id, "BM_DEFINED") 
- 			client_cmd(id, "spk events/task_complete") 
- 			return PLUGIN_HANDLED 
- 		} 
- 	} 
-   
- 	client_print(id, print_console, "%L", id, "BM_NOTBOMBSITE") 
- 	client_cmd(id, "spk events/friend_died") 
- 	return PLUGIN_HANDLED 
- } 
-   
- public Event_WeapPickup_c4( id ) 
- { 
- 	g_iC4Carrier = id 
- } 
-   
- public Message_StatusIcon(/*iMsgId, iMsgDest, id*/) 
- { 
- 	if( g_iBombSites_State != AllSites && get_msg_arg_int(1) == StatusIconShow ) 
- 	{ 
- 		new szIcon[4] 
- 		get_msg_arg_string(2, szIcon, charsmax(szIcon)) 
- 		if(	get_msg_arg_string(2, szIcon, charsmax(szIcon)) == 2 // check "c4" length first 
- 		&&	equal(szIcon, "c4")	) 
- 		{ 
- 			switch( g_iBombSites_State ) 
- 			{ 
- 				case NoSite: 
- 				{ 
- 					set_msg_arg_int(1, ARG_BYTE, 0) 
- 				} 
- 				case MainSite: 
- 				{ 
- 					set_msg_arg_int(3, ARG_BYTE, 200) 
- 					set_msg_arg_int(4, ARG_BYTE, 100) 
- 				} 
- 			} 
- 		} 
- 	} 
- } 
-   
- public Event_TextMsg_C4PlantAtBombSpot(id) 
- { 
- 	if( !get_pcvar_num(g_pCvarPlanterText) ) 
- 	{ 
- 		return 
- 	} 
-   
- 	new iBombSiteNum = ArraySize(g_aBombSites) 
-   
- 	new mBombSiteDatas[BombSites_Datas], iEnt 
- 	new Float:fVecOrigin[3], Float:fVecAbsMin[3], Float:fVecAbsMax[3] 
-   
- 	for(new i=0; i<iBombSiteNum; i++) 
- 	{ 
- 		ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 		iEnt = mBombSiteDatas[iBsIndex] 
-   
- 		pev(id, pev_origin, fVecOrigin) 
- 		pev(iEnt, pev_absmin, fVecAbsMin) 
- 		pev(iEnt, pev_absmax, fVecAbsMax) 
-   
- 		if(	(fVecAbsMin[0] <= fVecOrigin[0] <= fVecAbsMax[0]) 
- 		&&	(fVecAbsMin[1] <= fVecOrigin[1] <= fVecAbsMax[1]) 
- 		&&	(-72.0 <= (((fVecAbsMax[2] + fVecAbsMin[2]) / 2.0) - fVecOrigin[2]) <= 72.0)	) 
- 		{ 
- 			switch( g_iBombSites_State ) 
- 			{ 
- 				case NoSite: 
- 				{ 
- 					client_print(id, print_center, "%L", id, "BM_AD_NOPLANT", get_pcvar_num(g_pCvarMinCts)) 
- 				} 
- 				case MainSite: 
- 				{ 
- 					client_print(id, print_center, "%L", id, "BM_AD_ONLYMAIN",  
- 											get_pcvar_num(g_pCvarMidCts), g_szBombSiteName) 
- 				} 
- 			} 
-   
- 			break 
- 		} 
- 	} 
- } 
-   
- public Player_Spawn_Post(id) 
- { 
- 	if(	g_bMainSiteSet 
- 	&&	g_bCountNewSpawns 
- 	&&	is_user_alive(id) 
- 	&&	cs_get_user_team_index(id) == CS_TEAM_CT	) 
- 	{ 
- 		if( g_flCountUntilGameTime < get_gametime() ) 
- 		{ 
- 			g_bCountNewSpawns = false 
- 			return 
- 		} 
- 		CountCounterTerrorists() 
- 	} 
- } 
-   
- CountCounterTerrorists() 
- { 
- 	new iPlayers[MAX_PLAYERS], iNum, iCtNum 
- 	get_players(iPlayers, iNum, "h") 
-   
- 	for(new i; i<iNum; i++) 
- 	{ 
- 		if( cs_get_user_team_index(iPlayers[i]) == CS_TEAM_CT ) 
- 		{ 
- 			iCtNum++ 
- 		} 
- 	} 
-   
- 	new iMinCts = get_pcvar_num(g_pCvarMinCts) 
- 	new iMidCts = get_pcvar_num(g_pCvarMidCts) 
-   
- 	new const szTag[] = "C4 Management" 
-   
- 	new iBombSiteNum = ArraySize(g_aBombSites) 
- 	new mBombSiteDatas[BombSites_Datas] 
-   
- 	if( iCtNum < iMinCts) 
- 	{ 
- 		switch( get_pcvar_num(g_pCvarStartRoundText) ) 
- 		{ 
- 			case 1: 
- 			{ 
- 				client_print(0, print_chat, "* [%s] %L", szTag, LANG_PLAYER, "BM_AD_NOPLANT", iMinCts) 
- 			} 
- 			case 2: 
- 			{ 
- 				set_hudmessage(200, 50, 50, -1.0, 0.15, .holdtime=8.0, .channel=-1) 
- 				ShowSyncHudMsg(0, g_iSyncHud, "%s : %L", szTag, LANG_PLAYER, "BM_AD_NOPLANT", iMinCts) 
- 			} 
- 		} 
-   
- 		for(new i; i<iBombSiteNum; i++) 
- 		{ 
- 			ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 			SetBombSite(mBombSiteDatas[iBsIndex], false) 
- 		} 
-   
- 		g_iBombSites_State = NoSite 
- 		if( g_iC4Carrier ) 
- 		{ 
- 			Send_StatusIcon_c4(g_iC4Carrier) 
- 		} 
- 	} 
- 	else if( iCtNum < iMidCts) 
- 	{ 
- 		switch( get_pcvar_num(g_pCvarStartRoundText) ) 
- 		{ 
- 			case 1: 
- 			{ 
- 				client_print(0, print_chat, "* [%s] %L", szTag, LANG_PLAYER, "BM_AD_ONLYMAIN", iMidCts, g_szBombSiteName) 
- 			} 
- 			case 2: 
- 			{ 
- 				set_hudmessage(200, 100, 0, -1.0, 0.15, .holdtime=8.0, .channel=-1) 
- 				ShowSyncHudMsg(0, g_iSyncHud, "%s : %L", szTag, LANG_PLAYER, "BM_AD_ONLYMAIN", iMidCts, g_szBombSiteName) 
- 			} 
- 		} 
-   
- 		new iEnt 
- 		for(new i; i<iBombSiteNum; i++) 
- 		{ 
- 			ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 			iEnt = mBombSiteDatas[iBsIndex] 
- 			SetBombSite(iEnt, iEnt == g_mMainBombSite[iBsIndex] ? true : false) 
- 		} 
-   
- 		g_iBombSites_State = MainSite 
- 		if( g_iC4Carrier ) 
- 		{ 
- 			Send_StatusIcon_c4(g_iC4Carrier, StatusIconShow, 200, 100, 0) 
- 		} 
- 	} 
- 	else 
- 	{ 
- 		switch( get_pcvar_num(g_pCvarStartRoundText) ) 
- 		{ 
- 			case 1: 
- 			{ 
- 				client_print(0, print_chat, "* [%s] %L", szTag, LANG_PLAYER, "BM_AD_ALLSITES") 
- 			} 
- 			case 2: 
- 			{ 
- 				set_hudmessage(50, 200, 50, -1.0, 0.15, .holdtime=8.0, .channel=-1) 
- 				ShowSyncHudMsg(0, g_iSyncHud, "%s : %L", szTag, LANG_PLAYER, "BM_AD_ALLSITES") 
- 			} 
- 		} 
-   
- 		for(new i; i<iBombSiteNum; i++) 
- 		{ 
- 			ArrayGetArray(g_aBombSites, i, mBombSiteDatas) 
- 			SetBombSite(mBombSiteDatas[iBsIndex], true) 
- 		} 
-   
- 		g_iBombSites_State = AllSites 
- 		if( g_iC4Carrier ) 
- 		{ 
- 			Send_StatusIcon_c4(g_iC4Carrier, StatusIconShow, 0, 160, 0) 
- 		} 
- 	} 
- } 
-   
- SetBombSite(iEnt, bool:bActive) 
- { 
- 	set_pev(iEnt, pev_solid, bActive ? SOLID_TRIGGER : SOLID_NOT) 
- } 
-   
- Send_StatusIcon_c4(id, Mode=StatusIconDontShow, r=0, g=0, b=0) 
- { 
- 	message_begin(MSG_ONE_UNRELIABLE, gmsgStatusIcon, .player=id) 
- 	write_byte(Mode) 
- 	write_string("c4") 
- 	if( Mode ) 
- 	{ 
- 		write_byte(r) 
- 		write_byte(g) 
- 		write_byte(b) 
- 	} 
- 	message_end() 
- } 
-   
- FIND_ENT_BY_MODELNAME(const iStartEnt, const szClassName[], const szModel[]) 
- { 
- 	new iEnt = iStartEnt 
- 	new szMdl[72] 
- 	while( (iEnt = FIND_ENT_BY_CLASSNAME(iEnt, szClassName)) ) 
- 	{ 
- 		pev(iEnt, pev_model, szMdl, charsmax(szMdl)) 
- 		if( equal(szMdl, szModel) ) 
- 		{ 
- 			return iEnt 
- 		} 
- 	} 
- 	return 0 
- }