is this abuse?
This commit is contained in:
		
							parent
							
								
									91d4f57b8f
								
							
						
					
					
						commit
						6df6be624d
					
				
							
								
								
									
										596
									
								
								Turret/scripting/Turret.sp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										596
									
								
								Turret/scripting/Turret.sp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,596 @@ | |||||||
|  | #include <multicolors> | ||||||
|  | #include <sourcemod> | ||||||
|  | #include <sdkhooks> | ||||||
|  | #include <zombiereloaded> | ||||||
|  | #include <sdktools> | ||||||
|  | #include <cstrike> | ||||||
|  | 
 | ||||||
|  | #pragma semicolon 1 | ||||||
|  | #pragma newdecls required | ||||||
|  | 
 | ||||||
|  | int g_iVelocity; | ||||||
|  | int g_iCurrentTick; | ||||||
|  | int g_iTicksSinceLastAttack; | ||||||
|  | 
 | ||||||
|  | #define MAX_TURRETS 65 | ||||||
|  | 
 | ||||||
|  | int g_iTurrets[MAX_TURRETS] = {INVALID_ENT_REFERENCE,...}; | ||||||
|  | int g_iMarkers[MAX_TURRETS] = {INVALID_ENT_REFERENCE,...}; | ||||||
|  | int g_iGunfire[MAX_TURRETS] = {INVALID_ENT_REFERENCE,...}; | ||||||
|  | int g_iExplosion[MAX_TURRETS] = {INVALID_ENT_REFERENCE,...}; | ||||||
|  | int g_iOwner[MAX_TURRETS]; | ||||||
|  | bool g_bCanPlace[MAX_TURRETS]; | ||||||
|  | bool g_bPlaced[MAX_TURRETS]; | ||||||
|  | 
 | ||||||
|  | float g_fMaxRange; | ||||||
|  | float g_fMinAccuracy; | ||||||
|  | float g_fMaxAccuracy; | ||||||
|  | float g_fDestroyRange; | ||||||
|  | float g_fKnockback; | ||||||
|  | int g_iDamage; | ||||||
|  | int g_iTicksToSkip; | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public Plugin myinfo = | ||||||
|  | { | ||||||
|  | 	name         = "Turrets", | ||||||
|  | 	author       = "Neon", | ||||||
|  | 	description  = "", | ||||||
|  | 	version      = "1.0.0", | ||||||
|  | 	url 		= "https://steamcommunity.com/id/n3ontm" | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnPluginStart() | ||||||
|  | { | ||||||
|  | 	//RegConsoleCmd("sm_turret", Command_Turret); | ||||||
|  | 	RegAdminCmd("sm_turret", Command_Turret, ADMFLAG_RCON); | ||||||
|  | 	HookEvent("round_end", OnRound); | ||||||
|  | 	HookEvent("round_start", OnRound); | ||||||
|  | 
 | ||||||
|  | 	ConVar cvar; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_max_range", "1500", "")), Cvar_MaxRange); | ||||||
|  | 	g_fMaxRange = cvar.FloatValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_min_accuracy", "0.7", "")), Cvar_MinAccuracy); | ||||||
|  | 	g_fMinAccuracy = cvar.FloatValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_max_accuracy", "0.99", "")), Cvar_MaxAccuracy); | ||||||
|  | 	g_fMaxAccuracy = cvar.FloatValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_destroy_range", "100", "")), Cvar_DestroyRange); | ||||||
|  | 	g_fDestroyRange = cvar.FloatValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_knockback", "20", "")), Cvar_Knockback); | ||||||
|  | 	g_fKnockback = cvar.FloatValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_damage", "10", "")), Cvar_Damage); | ||||||
|  | 	g_iDamage = cvar.IntValue; | ||||||
|  | 	HookConVarChange((cvar = CreateConVar("sm_turrets_ticks_to_skip", "3", "")), Cvar_TicksToSkip); // to decrease CPU usage | ||||||
|  | 	g_iTicksToSkip = cvar.IntValue; | ||||||
|  | 	delete cvar; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnMapStart() | ||||||
|  | { | ||||||
|  | 	g_iVelocity = FindDataMapInfo(0, "m_vecAbsVelocity"); | ||||||
|  | 
 | ||||||
|  | 	PrecacheModel("models/unloze/dronegun/dronegun.mdl"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.dx90.vtx"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.dx80.vtx"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.mdl"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.phy"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.sw.vtx"); | ||||||
|  | 	AddFileToDownloadsTable("models/unloze/dronegun/dronegun.vvd"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/dronegun/dronegun.vmt"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/dronegun/dronegun.vtf"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/dronegun/dronegun_laser.vmt"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/dronegun/dronegun_laser.vtf"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/dronegun/dronegun_selfillum.vtf"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/weapons/w_models/w_mach_m249para/m249.vmt"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/weapons/w_models/w_mach_m249para/m249.vtf"); | ||||||
|  | 	AddFileToDownloadsTable("materials/models/unloze/weapons/w_models/w_mach_m249para/m249_exponent.vtf"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnPluginEnd() | ||||||
|  | { | ||||||
|  | 	for (int i = 0; i < MAX_TURRETS; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (g_iTurrets[i] == INVALID_ENT_REFERENCE) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		ClearTurret(i); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnRound(Event hEvent, const char[] sEvent, bool bDontBroadcast) | ||||||
|  | { | ||||||
|  | 	for (int i = 0; i < MAX_TURRETS; i++) | ||||||
|  | 	{ | ||||||
|  | 		g_iTurrets[i] = INVALID_ENT_REFERENCE; | ||||||
|  | 		g_iMarkers[i] = INVALID_ENT_REFERENCE; | ||||||
|  | 		g_iGunfire[i] = INVALID_ENT_REFERENCE; | ||||||
|  | 		g_iExplosion[i] = INVALID_ENT_REFERENCE; | ||||||
|  | 		g_iOwner[i] = 0; | ||||||
|  | 		g_bCanPlace[i] = false; | ||||||
|  | 		g_bPlaced[i] = false; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public Action Command_Turret(int client, int args) | ||||||
|  | { | ||||||
|  | 	if (!ZR_IsClientHuman(client)) | ||||||
|  | 	{ | ||||||
|  | 		ReplyToCommand(client, "[ZR] You need to be human to use this command."); | ||||||
|  | 		return Plugin_Handled; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Clear old turret | ||||||
|  | 	for (int j = 0; j < MAX_TURRETS; j++) | ||||||
|  | 	{ | ||||||
|  | 		if ((g_iOwner[j] != 0) && (g_iOwner[j] == client)) | ||||||
|  | 		{ | ||||||
|  | 			ClearTurret(j); | ||||||
|  | 			ReplyToCommand(client, "[ZR] Turret Removed."); | ||||||
|  | 			return Plugin_Handled; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// find free index | ||||||
|  | 	int i; | ||||||
|  | 	for (i = 0; i < MAX_TURRETS; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (g_iTurrets[i] == INVALID_ENT_REFERENCE) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		if (i == (MAX_TURRETS -1)) | ||||||
|  | 		{ | ||||||
|  | 			ReplyToCommand(client, "[ZR] Too many turrets active already."); | ||||||
|  | 			return Plugin_Handled; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float vecOrigin[3]; | ||||||
|  | 	GetClientAbsOrigin(client, vecOrigin); | ||||||
|  | 
 | ||||||
|  | 	g_iTurrets[i] = CreateEntityAtOrigin("prop_dynamic_override", vecOrigin); | ||||||
|  | 	SetEntityModel(g_iTurrets[i], "models/unloze/dronegun/dronegun.mdl"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "targetname",            "turret_%d", i); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "solid",                 "0"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "modelscale",            "1.0"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "disableshadows",        "1"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "disablereceiveshadows", "1"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "disablebonefollowers",  "1"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "OnUser1",           	 "gunfire_%d,Kill,,0,1", i); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "OnUser1",           	 "marker_%d,Kill,,0,1", i); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "OnUser1",           	 "!self,Kill,,0,1"); | ||||||
|  | 	DispatchKeyFormat(g_iTurrets[i], "OnUser2",           	 "explosion_%d,Explode,,0,1", i); | ||||||
|  | 	SpawnAndActivate(g_iTurrets[i]); | ||||||
|  | 
 | ||||||
|  | 	//traget for env_gunfire to aim at | ||||||
|  | 	g_iMarkers[i] = CreateEntityAtOrigin("path_track", vecOrigin); | ||||||
|  | 	DispatchKeyFormat(g_iMarkers[i], "targetname",            "marker_%d", i); | ||||||
|  | 	SpawnAndActivate(g_iMarkers[i]); | ||||||
|  | 
 | ||||||
|  | 	vecOrigin[2] += 42.0; // "middle" of turret | ||||||
|  | 	g_iGunfire[i] = CreateEntityAtOrigin("env_gunfire", vecOrigin); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "targetname",            "gunfire_%d", i); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "target",                "marker_%d", i); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "StartDisabled",         "1"); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "spread",         		 "0"); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "collisions",         	 "1"); | ||||||
|  | 	DispatchKeyFormat(g_iGunfire[i], "rateoffire",         	 "10"); | ||||||
|  | 	SpawnAndActivate(g_iGunfire[i]); | ||||||
|  | 	ParentToEntity(g_iGunfire[i], g_iTurrets[i]); | ||||||
|  | 
 | ||||||
|  | 	g_iExplosion[i] = CreateEntityAtOrigin("env_explosion", vecOrigin); | ||||||
|  | 	DispatchKeyFormat(g_iExplosion[i], "targetname",				"explosion_%d", i); | ||||||
|  | 	DispatchKeyFormat(g_iExplosion[i], "fireballsprite",			"sprites/zerogxplode.spr"); | ||||||
|  | 	DispatchKeyFormat(g_iExplosion[i], "rendermode",			    "0"); | ||||||
|  | 	DispatchKeyFormat(g_iExplosion[i], "iMagnitude",         	"100"); | ||||||
|  | 	DispatchKeyFormat(g_iExplosion[i], "spawnflags",         	"1"); | ||||||
|  | 	SpawnAndActivate(g_iExplosion[i]); | ||||||
|  | 	ParentToEntity(g_iExplosion[i], g_iTurrets[i]); | ||||||
|  | 
 | ||||||
|  | 	g_iOwner[i] = client; | ||||||
|  | 	ReplyToCommand(client, "[ZR] Press E to place a turret."); | ||||||
|  | 	return Plugin_Handled; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnGameFrame() // Tick Turrets | ||||||
|  | { | ||||||
|  | 	g_iCurrentTick++; | ||||||
|  | 	g_iTicksSinceLastAttack++; | ||||||
|  | 	if (g_iCurrentTick < g_iTicksToSkip) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	g_iCurrentTick = 0; | ||||||
|  | 
 | ||||||
|  | 	bool bAttack = false; | ||||||
|  | 	if (g_iTicksSinceLastAttack > 15) | ||||||
|  | 		bAttack = true; | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < MAX_TURRETS; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (g_iTurrets[i] == INVALID_ENT_REFERENCE) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (!g_bPlaced[i]) // not placed yet | ||||||
|  | 		{ | ||||||
|  | 			PlaceTurret(i); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		float vecOriginClient[3]; | ||||||
|  | 		float vecOriginTurret[3]; | ||||||
|  | 		GetEntPropVector(g_iTurrets[i], Prop_Send, "m_vecOrigin", vecOriginTurret); | ||||||
|  | 		vecOriginTurret[2] += 42.0; | ||||||
|  | 
 | ||||||
|  | 		int iNearestZombie; | ||||||
|  | 		float fNearestDistance; | ||||||
|  | 
 | ||||||
|  | 		for (int client = 1; client <= MaxClients; client++) | ||||||
|  | 		{ | ||||||
|  | 			if (!IsClientInGame(client) || !IsPlayerAlive(client) || !ZR_IsClientZombie(client)) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			GetClientAbsOrigin(client, vecOriginClient); | ||||||
|  | 			vecOriginClient[2] += 50.0; //aim for chest | ||||||
|  | 
 | ||||||
|  | 			Handle hTraceRay = TR_TraceRayFilterEx(vecOriginClient, vecOriginTurret, MASK_ALL, RayType_EndPoint, TraceEntityFilter, g_iTurrets[i]); | ||||||
|  | 
 | ||||||
|  | 			if(TR_DidHit(hTraceRay)) | ||||||
|  | 			{ | ||||||
|  | 				delete hTraceRay; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			delete hTraceRay; | ||||||
|  | 
 | ||||||
|  | 			float vecVector[3]; | ||||||
|  | 			float vecAngles[3]; | ||||||
|  | 			MakeVectorFromPoints(vecOriginTurret, vecOriginClient, vecVector); | ||||||
|  | 			GetVectorAngles(vecVector, vecAngles); | ||||||
|  | 
 | ||||||
|  | 			if (!((vecAngles[0] <= 45.0) || (vecAngles[0] >= 315.0))) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			float fDistance = GetVectorLength(vecVector, false); | ||||||
|  | 
 | ||||||
|  | 			if ((fDistance < fNearestDistance) || (iNearestZombie == 0)) | ||||||
|  | 			{ | ||||||
|  | 				iNearestZombie = client; | ||||||
|  | 				fNearestDistance = fDistance; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (iNearestZombie == 0) // no target found | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		// ZM too close, destroy turret | ||||||
|  | 		if (fNearestDistance <= g_fDestroyRange) | ||||||
|  | 		{ | ||||||
|  | 			ClearTurret(i, true); | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		float vecVector[3]; | ||||||
|  | 		float vecAngles[3]; | ||||||
|  | 		GetClientAbsOrigin(iNearestZombie, vecOriginClient); | ||||||
|  | 		vecOriginClient[2] += 50.0; //aim for chest | ||||||
|  | 		MakeVectorFromPoints(vecOriginTurret, vecOriginClient, vecVector); | ||||||
|  | 		GetVectorAngles(vecVector, vecAngles); | ||||||
|  | 
 | ||||||
|  | 		float fA = ((vecAngles[1]+180.0)/360.0); | ||||||
|  | 		if (fA > 1.0) | ||||||
|  | 			fA -= 1.0; | ||||||
|  | 
 | ||||||
|  | 		float fB; | ||||||
|  | 		if (vecAngles[0] <= 45.0) | ||||||
|  | 		{ | ||||||
|  | 			fB = ((1.0/90.0) * vecAngles[0]) + 0.5; | ||||||
|  | 		} | ||||||
|  | 		else if (vecAngles[0] >= 315.0) | ||||||
|  | 		{ | ||||||
|  | 			fB = ((1.0/90.0) * (vecAngles[0] - 315.0)) + 0.0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		// why the fuck can i only set one of those angles???? | ||||||
|  | 		//SetEntPropFloat(g_iTurrets[i], Prop_Data, "m_flPoseParameter", fB, 1); | ||||||
|  | 		//SetEntPropFloat(g_iTurrets[i], Prop_Send, "m_flCycle", 1.0); | ||||||
|  | 		SetEntPropFloat(g_iTurrets[i], Prop_Data, "m_flPoseParameter", fA, 0); | ||||||
|  | 		SetEntPropFloat(g_iTurrets[i], Prop_Send, "m_flCycle", 0.0); | ||||||
|  | 
 | ||||||
|  | 		// randomly spread the bullets | ||||||
|  | 		vecOriginClient[0] += GetRandomFloat(-15.0, 15.0); | ||||||
|  | 		vecOriginClient[1] += GetRandomFloat(-15.0, 15.0); | ||||||
|  | 		vecOriginClient[2] += GetRandomFloat(-20.0, 20.0); | ||||||
|  | 		TeleportEntity(g_iMarkers[i], vecOriginClient, NULL_VECTOR, NULL_VECTOR); | ||||||
|  | 
 | ||||||
|  | 		if (bAttack) | ||||||
|  | 		{ | ||||||
|  | 			g_iTicksSinceLastAttack = 0; | ||||||
|  | 
 | ||||||
|  | 			// check for max range | ||||||
|  | 			float fDistance = GetVectorDistance(vecOriginClient, vecOriginTurret, false); | ||||||
|  | 			if (fDistance > g_fMaxRange) | ||||||
|  | 			{ | ||||||
|  | 				AcceptEntityInput(g_iGunfire[i], "Disable"); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			AcceptEntityInput(g_iGunfire[i], "Enable"); | ||||||
|  | 
 | ||||||
|  | 			// Accuracy | ||||||
|  | 			float fAccuracy = (((-(g_fMaxAccuracy - g_fMinAccuracy))/g_fMaxRange) * fDistance) + g_fMaxAccuracy; | ||||||
|  | 			float R = GetRandomFloat(0.0, 100.0); | ||||||
|  | 			if (FloatCompare(R, fAccuracy) == -1) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			// DMG | ||||||
|  | 			int iHealth = GetClientHealth(iNearestZombie); | ||||||
|  | 			if(iHealth > g_iDamage) | ||||||
|  | 				SetEntityHealth(iNearestZombie, iHealth - g_iDamage); | ||||||
|  | 			else | ||||||
|  | 				ForcePlayerSuicide(iNearestZombie); | ||||||
|  | 
 | ||||||
|  | 			// KB | ||||||
|  | 			MakeVectorFromPoints(vecOriginTurret, vecOriginClient, vecVector); | ||||||
|  | 			NormalizeVector(vecVector, vecVector); | ||||||
|  | 			ScaleVector(vecVector, g_fKnockback); | ||||||
|  | 			float fClientVelocity[3]; | ||||||
|  | 			GetEntDataVector(iNearestZombie, g_iVelocity, fClientVelocity); | ||||||
|  | 			AddVectors(fClientVelocity, vecVector, fClientVelocity); | ||||||
|  | 			SetEntDataVector(iNearestZombie, g_iVelocity, fClientVelocity); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void PlaceTurret(int i) | ||||||
|  | { | ||||||
|  | 	if (g_iTurrets[i] == INVALID_ENT_REFERENCE) // no turret | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	int client = g_iOwner[i]; | ||||||
|  | 	if (!IsValidClient(client)) | ||||||
|  | 	{ | ||||||
|  | 		ClearTurret(i); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!(IsPlayerAlive(client) && ZR_IsClientHuman(client))) | ||||||
|  | 	{ | ||||||
|  | 		ClearTurret(i); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float vecEyeAngles[3]; | ||||||
|  | 	float vecEyeOrigin[3]; | ||||||
|  | 
 | ||||||
|  | 	GetClientEyeAngles(client, vecEyeAngles); | ||||||
|  | 	GetClientEyePosition(client, vecEyeOrigin); | ||||||
|  | 
 | ||||||
|  | 	Handle hTraceRay = TR_TraceRayFilterEx(vecEyeOrigin, vecEyeAngles, MASK_ALL, RayType_Infinite, TraceEntityFilter, client); | ||||||
|  | 
 | ||||||
|  | 	g_bCanPlace[i] = false; | ||||||
|  | 	if(TR_DidHit(hTraceRay)) | ||||||
|  | 	{ | ||||||
|  | 		float vecEndPosAim[3]; | ||||||
|  | 		TR_GetEndPosition(vecEndPosAim, hTraceRay); | ||||||
|  | 
 | ||||||
|  | 		float vecDown[3] = {90.0, 0.0, 0.0}; | ||||||
|  | 		delete hTraceRay; | ||||||
|  | 		hTraceRay = TR_TraceRayFilterEx(vecEndPosAim, vecDown, MASK_ALL, RayType_Infinite, TraceEntityFilter, client); | ||||||
|  | 
 | ||||||
|  | 		if(TR_DidHit(hTraceRay)) | ||||||
|  | 		{ | ||||||
|  | 			float vecEndPosDown[3]; | ||||||
|  | 			TR_GetEndPosition(vecEndPosDown, hTraceRay); | ||||||
|  | 			TeleportEntity(g_iTurrets[i], vecEndPosDown, NULL_VECTOR, NULL_VECTOR); | ||||||
|  | 
 | ||||||
|  | 			if (GetVectorDistance(vecEyeOrigin, vecEndPosDown, false) > 500) // maximum distance to place a turret | ||||||
|  | 			{ | ||||||
|  | 				delete hTraceRay; | ||||||
|  | 				SetEntityRenderColor(g_iTurrets[i], 255, 0, 0, 0); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 			vecEndPosDown[2] += 5.0; | ||||||
|  | 			vecEndPosAim[2] += 5.0; | ||||||
|  | 
 | ||||||
|  | 			float vecMins[3] = {-30.0, -30.0, 0.0}; | ||||||
|  | 			float vecMaxs[3] = {30.0, 30.0, 63.0}; | ||||||
|  | 
 | ||||||
|  | 			delete hTraceRay; | ||||||
|  | 			hTraceRay = TR_TraceHullFilterEx(vecEndPosDown, vecEndPosAim, vecMins, vecMaxs, MASK_ALL, TraceEntityFilter, client); | ||||||
|  | 			if(!TR_DidHit(hTraceRay)) | ||||||
|  | 				g_bCanPlace[i] = true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	delete hTraceRay; | ||||||
|  | 
 | ||||||
|  | 	if(g_bCanPlace[i]) | ||||||
|  | 		SetEntityRenderColor(g_iTurrets[i], 0, 255, 0, 0); | ||||||
|  | 	else | ||||||
|  | 		SetEntityRenderColor(g_iTurrets[i], 255, 0, 0, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void OnPlayerRunCmdPost(int client, int buttons) | ||||||
|  | { | ||||||
|  | 	for (int i = 0; i < MAX_TURRETS; i++) | ||||||
|  | 	{ | ||||||
|  | 		if (g_iTurrets[i] == INVALID_ENT_REFERENCE) // no turret | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (g_bPlaced[i]) // already placed | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if(!g_bCanPlace[i]) // cant be placed atm | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		if (g_iOwner[i] == client) | ||||||
|  | 		{ | ||||||
|  | 			if (buttons & IN_USE) | ||||||
|  | 			{ | ||||||
|  | 				SetEntityRenderColor(g_iTurrets[i], 255, 255, 255, 0); | ||||||
|  | 				//g_iOwner[i] = 0; | ||||||
|  | 				g_bPlaced[i] = true; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock bool TraceEntityFilter(int entity, int contentsMask, int turret) | ||||||
|  | { | ||||||
|  | 	if ((entity == turret) || (0 <= entity <= MaxClients)) | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock int CreateEntityAtOrigin(const char[] classname, const float origin[3]) | ||||||
|  | { | ||||||
|  | 	int entity = CreateEntityByName(classname); | ||||||
|  | 
 | ||||||
|  | 	TeleportEntity(entity, origin, NULL_VECTOR, NULL_VECTOR); | ||||||
|  | 
 | ||||||
|  | 	return entity; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock bool DispatchKeyFormat(int entity, const char[] key, const char[] value, any ...) | ||||||
|  | { | ||||||
|  | 	char buffer[1024]; | ||||||
|  | 	VFormat(buffer, sizeof(buffer), value, 4); | ||||||
|  | 
 | ||||||
|  | 	DispatchKeyValue(entity, key, buffer); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock void SpawnAndActivate(int entity) | ||||||
|  | { | ||||||
|  | 	DispatchSpawn(entity); | ||||||
|  | 	ActivateEntity(entity); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock void ParentToEntity(int entity, int parent) | ||||||
|  | { | ||||||
|  | 	SetVariantString("!activator"); | ||||||
|  | 	AcceptEntityInput(entity, "SetParent", parent, parent); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | void ClearTurret(int index, bool bExplode = false) | ||||||
|  | { | ||||||
|  | 	if (bExplode) | ||||||
|  | 		AcceptEntityInput(g_iTurrets[index], "FireUser2"); | ||||||
|  | 
 | ||||||
|  | 	AcceptEntityInput(g_iTurrets[index], "FireUser1"); | ||||||
|  | 	g_iTurrets[index] = INVALID_ENT_REFERENCE; | ||||||
|  | 	g_iMarkers[index] = INVALID_ENT_REFERENCE; | ||||||
|  | 	g_iGunfire[index] = INVALID_ENT_REFERENCE; | ||||||
|  | 	g_iExplosion[index] = INVALID_ENT_REFERENCE; | ||||||
|  | 	g_iOwner[index] = 0; | ||||||
|  | 	g_bCanPlace[index] = false; | ||||||
|  | 	g_bPlaced[index] = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | stock bool IsValidClient(int client, bool nobots = true) | ||||||
|  | { | ||||||
|  | 	if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client))) | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
|  | 	return IsClientInGame(client); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_MaxRange(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_fMaxRange = convar.FloatValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_MinAccuracy(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_fMinAccuracy = convar.FloatValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_MaxAccuracy(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_fMaxAccuracy = convar.FloatValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_DestroyRange(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_fDestroyRange = convar.FloatValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_Knockback(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_fKnockback = convar.FloatValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_Damage(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_iDamage = convar.IntValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | // Purpose: | ||||||
|  | //---------------------------------------------------------------------------------------------------- | ||||||
|  | public void Cvar_TicksToSkip(ConVar convar, const char[] oldValue, const char[] newValue) | ||||||
|  | { | ||||||
|  | 	g_iTicksToSkip = convar.IntValue; | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 neon
						neon