432 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			432 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #include <zombiereloaded>
 | |
| #include <sourcemod>
 | |
| #include <sdktools>
 | |
| #include <morecolors.inc>
 | |
| 
 | |
| public Plugin myinfo =
 | |
| {
 | |
| 	name 		= "Meteors",
 | |
| 	author 		= "Neon",
 | |
| 	description = "",
 | |
| 	version 	= "Meteors",
 | |
| 	url 		= "https://steamcommunity.com/id/n3ontm"
 | |
| }
 | |
| 
 | |
| //ambient/explosions/explode_9.wav
 | |
| //models/effects/vol_light128x512.mdl
 | |
| 
 | |
| new String:debugString[64];
 | |
| 
 | |
| bool g_bEnabled = false;
 | |
| 
 | |
| public void OnPluginStart()
 | |
| {
 | |
| 	HookEvent("round_end", OnRoundEnding);
 | |
| 	RegAdminCmd("sm_meteors", Command_Meteors, ADMFLAG_ROOT);
 | |
| }
 | |
| 
 | |
| public void OnMapStart()
 | |
| {
 | |
| 	g_bEnabled = false;
 | |
| 	PrecacheModel("models/props/cs_office/vending_machine.mdl");
 | |
| 	CreateTimer(5.0, MeteorMain, INVALID_HANDLE, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
 | |
| }
 | |
| 
 | |
| public void OnRoundEnding(Event hEvent, const char[] sEvent, bool bDontBroadcast)
 | |
| {
 | |
| 	g_bEnabled = false;
 | |
| }
 | |
| 
 | |
| public Action Command_Meteors(int client, int args)
 | |
| {
 | |
|     if (g_bEnabled)
 | |
| 	{
 | |
| 		g_bEnabled = false;
 | |
| 		CPrintToChatAll("{darkred}[Meteors] {white}%N has disabled Meteors!", client);
 | |
| 	}
 | |
| 	else if (!(g_bEnabled))
 | |
| 	{
 | |
| 		g_bEnabled = true;
 | |
| 		CPrintToChatAll("{darkred}[Meteors] {white}%N has enabled Meteors!", client);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public Action MeteorMain(Handle timer)
 | |
| {
 | |
| 	if (!(g_bEnabled))
 | |
| 		return;
 | |
| 
 | |
| 	int victimClient = GetTargetClient()
 | |
| 
 | |
| 	if (victimClient == -1)
 | |
| 		return;
 | |
| 
 | |
| 	int indicator = SpawnIndicator(victimClient);
 | |
| 	int model = SpawnMeteor2(victimClient);
 | |
| 	int hurt = SpawnTriggerHurt(victimClient);
 | |
| 	int move = SpawnMoveLinear(victimClient);
 | |
| 	int explosion = SpawnExplosion(victimClient);
 | |
| 	int sound = SpawnAmbientGeneric(victimClient);
 | |
| 	int particle = SpawnParticle(victimClient);
 | |
| 	int particle2 = SpawnParticle(victimClient);
 | |
| 
 | |
| 	SetVariantString("!activator");
 | |
|     AcceptEntityInput(model, "SetParent", move);
 | |
| 
 | |
| 	SetVariantString("!activator");
 | |
|     AcceptEntityInput(hurt, "SetParent", move);
 | |
| 
 | |
| 	SetVariantString("!activator");
 | |
|     AcceptEntityInput(particle, "SetParent", move);
 | |
| 
 | |
| 	SetVariantString("!activator");
 | |
|     AcceptEntityInput(particle2, "SetParent", move);
 | |
| 
 | |
| 	AcceptEntityInput(move, "Open");
 | |
| }
 | |
| 
 | |
| public Action SpawnParticle(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("info_particle_system")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "info_particle_system_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_particle");
 | |
|     DispatchKeyValue(Entity, "effect_name", "fire_large_01");
 | |
|     DispatchSpawn(Entity);
 | |
|     ActivateEntity(Entity);
 | |
|     AcceptEntityInput(Entity, "start");
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	fVector[2] += 7000.0;
 | |
| 
 | |
| 	TeleportEntity(Entity, fVector, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	return Entity;
 | |
| 
 | |
| }
 | |
| 
 | |
| public Action SpawnAmbientGeneric(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 
 | |
|     // Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("ambient_generic")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "ambient_generic_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_sound");
 | |
|     DispatchKeyValue(Entity, "spawnflags", "48");
 | |
|     DispatchKeyValue(Entity, "SourceEntityName", "meteor_model2");
 | |
|     DispatchKeyValue(Entity, "radius", "3050");
 | |
|     DispatchKeyValue(Entity, "message", "ambient/explosions/explode_9.wav");
 | |
| 	DispatchKeyValue(Entity, "volume", "10");
 | |
| 	DispatchKeyValue(Entity, "health", "10");
 | |
| 	DispatchKeyValue(Entity, "preset", "0");
 | |
| 	DispatchKeyValue(Entity, "pitch", "100");
 | |
| 	DispatchKeyValue(Entity, "pitchstart", "100");
 | |
|     DispatchSpawn(Entity);
 | |
| 	ActivateEntity(Entity);
 | |
| 
 | |
|     return Entity;
 | |
| }
 | |
| 
 | |
| public Action SpawnTriggerHurt(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 
 | |
|     // Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("trigger_hurt")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "trigger_hurt_%i", Entity);
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	fVector[2] += 7000.0;
 | |
| 
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_hurt");
 | |
|     DispatchKeyValue(Entity, "spawnflags", "1");
 | |
|     DispatchKeyValue(Entity, "StartDisabled", "0");
 | |
|     DispatchKeyValueVector(Entity, "origin", fVector);
 | |
|     DispatchKeyValue(Entity, "nodmgforce", "0");
 | |
|     DispatchKeyValue(Entity, "damage", "320");
 | |
| 	DispatchKeyValue(Entity, "damagetype", "128");
 | |
|     DispatchKeyValue(Entity, "damagemodel", "0");
 | |
|     DispatchSpawn(Entity);
 | |
|     ActivateEntity(Entity);
 | |
| 
 | |
|     SetEntityModel(Entity, "models/props/cs_office/vending_machine.mdl");
 | |
| 
 | |
|     new Float:minbounds[3] = {-50.0, -50.0, -100.0};
 | |
| 	new Float:maxbounds[3] = {50.0, 50.0, 100.0};
 | |
|     SetEntPropVector(Entity, Prop_Send, "m_vecMins", minbounds);
 | |
|     SetEntPropVector(Entity, Prop_Send, "m_vecMaxs", maxbounds);
 | |
| 
 | |
|     SetEntProp(Entity, Prop_Send, "m_nSolidType", 2);
 | |
| 
 | |
|     new enteffects = GetEntProp(Entity, Prop_Send, "m_fEffects");
 | |
|     enteffects |= 32;
 | |
|     SetEntProp(Entity, Prop_Send, "m_fEffects", enteffects);
 | |
| 
 | |
|     return Entity;
 | |
| }
 | |
| 
 | |
| public Action SpawnMeteor2(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("prop_physics_multiplayer")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "prop_physics_multiplayer_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_model2");
 | |
|     DispatchKeyValue(Entity, "model",      "models/props/cs_militia/militiarock05.mdl");
 | |
| 	DispatchKeyValue(Entity, "spawnflags",      "8");
 | |
| 	DispatchKeyValue(Entity, "pressuredelay",      "0");
 | |
| 	DispatchKeyValue(Entity, "physicsmode",      "2");
 | |
| 	DispatchKeyValue(Entity, "physdamagescale",      "0.1");
 | |
| 	DispatchKeyValue(Entity, "modelscale",      "2.0");
 | |
|     DispatchSpawn(Entity);
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	fVector[2] += 7000.0;
 | |
| 	//fVector[1] += 1000.0;
 | |
| 
 | |
| 	TeleportEntity(Entity, fVector, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	return Entity;
 | |
| 
 | |
| }
 | |
| public Action SpawnExplosion(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("env_explosion")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "env_explosion_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_explosion");
 | |
|     DispatchKeyValue(Entity, "fireballsprite",      "sprites/zerogxplode.spr");
 | |
| 	DispatchKeyValue(Entity, "rendermode",      "5");
 | |
| 	DispatchKeyValue(Entity, "iMagnitude",      "300");
 | |
| 	DispatchKeyValue(Entity, "iRadiusOverride", "70");
 | |
| 
 | |
| 	DispatchKeyValue(Entity, "spawnflags",      "81");
 | |
| 
 | |
|     DispatchSpawn(Entity);
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	TeleportEntity(Entity, fVector, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	return Entity;
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| public Action SpawnMeteor(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("prop_dynamic")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "prop_dynamic_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_model");
 | |
|     DispatchKeyValue(Entity, "model",      "models/props/cs_militia/militiarock05.mdl");
 | |
|     DispatchKeyValue(Entity, "solid",      "0");
 | |
| 	DispatchKeyValue(Entity, "modelscale",      "1.0");
 | |
| 	DispatchKeyValue(Entity, "renderamt",      "255");
 | |
| 	DispatchKeyValue(Entity, "rendercolor",      "0 181 240");
 | |
| 	DispatchKeyValue(Entity, "renderfx",      "0");
 | |
| 	DispatchKeyValue(Entity, "rendermode",      "0");
 | |
| 
 | |
|     DispatchSpawn(Entity);
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	fVector[2] += 7000.0;
 | |
| 	//fVector[1] += 1000.0;
 | |
| 
 | |
| 	TeleportEntity(Entity, fVector, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	return Entity;
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| public Action SpawnMoveLinear(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("func_movelinear")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "func_movelinear_%i", Entity);
 | |
| 
 | |
| 	float fVectorClient[3];
 | |
| 	float fVectorStart[3];
 | |
| 	float fAngles[3];
 | |
| 	float fVectorCalculated[3];
 | |
| 	float fAnglesCalculated[3];
 | |
| 	GetClientAbsOrigin(client, fVectorClient);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	fVectorStart = fVectorClient;
 | |
| 	fVectorStart[2] += 7000.0;
 | |
| 
 | |
|     SubtractVectors(fVectorClient, fVectorStart, fVectorCalculated);
 | |
| 	float distanceF =  GetVectorLength(fVectorCalculated, false)
 | |
| 	distanceF -= 128.0;
 | |
|     NormalizeVector(fVectorCalculated, fVectorCalculated);
 | |
|     GetVectorAngles(fVectorCalculated, fAnglesCalculated);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_linear");
 | |
|     DispatchKeyValueVector(Entity, "movedir", fAnglesCalculated);
 | |
| 	DispatchKeyValueVector(Entity, "origin", fVectorStart);
 | |
|     DispatchKeyValue(Entity, "speed", "3000");
 | |
|     DispatchKeyValueFloat(Entity, "movedistance", distanceF);
 | |
|     DispatchKeyValue(Entity, "spawnflags", "8");
 | |
|     DispatchKeyValue(Entity, "rendermode", "3");
 | |
|     DispatchKeyValue(Entity, "rendercolor", "136 0 0");
 | |
|     DispatchKeyValue(Entity, "OnFullyOpen", "!self,KillHierarchy,,0.01,1");
 | |
| 	DispatchKeyValue(Entity, "OnFullyOpen", "meteor_indicator,Kill,,0,1");
 | |
| 	DispatchKeyValue(Entity, "OnFullyOpen", "meteor_explosion,Explode,,0,1");
 | |
| 	DispatchKeyValue(Entity, "OnFullyOpen", "meteor_explosion,Kill,,0.01,1");
 | |
| 	DispatchKeyValue(Entity, "OnFullyOpen", "meteor_sound,PlaySound,,0,1");
 | |
| 	DispatchKeyValue(Entity, "OnFullyOpen", "meteor_sound,Kill,,0.01,1");
 | |
|     DispatchSpawn(Entity);
 | |
| 
 | |
| 	return Entity;
 | |
| }
 | |
| 
 | |
| 
 | |
| public Action SpawnIndicator(int client)
 | |
| {
 | |
| 	new Entity;
 | |
| 	// Spawn dynamic prop entity
 | |
|     if ((Entity = CreateEntityByName("prop_dynamic")) == INVALID_ENT_REFERENCE)
 | |
| 		return -1;
 | |
| 
 | |
|     // Generate unique id for the entity
 | |
|     new String:StrEntityName[64]; Format(StrEntityName, sizeof(StrEntityName), "prop_dynamic_%i", Entity);
 | |
| 
 | |
|     // Setup entity
 | |
|     DispatchKeyValue(Entity, "targetname", "meteor_indicator");
 | |
|     DispatchKeyValue(Entity, "model",      "models/effects/vol_light128x512.mdl");
 | |
|     DispatchKeyValue(Entity, "solid",      "0");
 | |
| 	DispatchKeyValue(Entity, "modelscale",      "1.0");
 | |
| 	DispatchKeyValue(Entity, "angles",      "0 0 180");
 | |
| 	DispatchKeyValue(Entity, "renderamt",      "255");
 | |
| 	DispatchKeyValue(Entity, "rendercolor",      "0 181 240");
 | |
| 	DispatchKeyValue(Entity, "renderfx",      "0");
 | |
| 	DispatchKeyValue(Entity, "rendermode",      "0");
 | |
| 
 | |
|     DispatchSpawn(Entity);
 | |
| 
 | |
| 	float fVector[3];
 | |
| 	float fAngles[3];
 | |
| 	GetClientAbsOrigin(client, fVector);
 | |
| 	GetClientAbsAngles(client, fAngles);
 | |
| 
 | |
| 	//fVector[2] += 320.0;
 | |
| 
 | |
| 	TeleportEntity(Entity, fVector, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	return Entity;
 | |
| }
 | |
| 
 | |
| public int GetTargetClient()
 | |
| {
 | |
| 
 | |
| 	int outsideClientCount = 0;
 | |
| 	new int:outsideClients[MaxClients];
 | |
| 
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsClientInGame(i) && IsPlayerAlive(i) && (ZR_IsClientHuman(i)) && (GetClientDistanceToCeiling(i) > 200.0))
 | |
| 		{
 | |
| 			outsideClients[outsideClientCount] = i
 | |
| 			outsideClientCount += 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (outsideClientCount == 0)
 | |
| 		return -1;
 | |
| 
 | |
| 	int randomIndex = GetRandomInt(0, outsideClientCount - 1)
 | |
| 
 | |
| 	return outsideClients[randomIndex];
 | |
| 
 | |
| }
 | |
| 
 | |
| public float GetClientDistanceToCeiling(int client)
 | |
| {
 | |
|     float distanceF = 0.0;
 | |
| 
 | |
|     new Float:fOrigin[3], Float:fCeiling[3];
 | |
|     GetClientAbsOrigin(client, fOrigin);
 | |
| 
 | |
|     fOrigin[2] += 10.0;
 | |
| 
 | |
|     TR_TraceRayFilter(fOrigin, Float:{-90.0,0.0,0.0}, MASK_PLAYERSOLID, RayType_Infinite, TraceRayNoPlayers, client);
 | |
|     if (TR_DidHit())
 | |
|     {
 | |
|         TR_GetEndPosition(fCeiling);
 | |
|         fOrigin[2] -= 10.0;
 | |
| 		distanceF = GetVectorDistance(fOrigin, fCeiling);
 | |
|     }
 | |
| 	//PrintToChatAll("Client: %d - %f", client,distanceF);
 | |
| 	return distanceF;
 | |
| }
 | |
| 
 | |
| public bool:TraceRayNoPlayers(entity, mask, any:data)
 | |
| {
 | |
|     if(entity == data || (entity >= 1 && entity <= MaxClients))
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 |