diff --git a/paid_support_sentry_buster.sp b/paid_support_sentry_buster.sp index 551b5cb0..876a450d 100644 --- a/paid_support_sentry_buster.sp +++ b/paid_support_sentry_buster.sp @@ -33,6 +33,26 @@ public Plugin myinfo = url = "www.sourcemod.com" } +enum struct SentryBuster +{ + int userid; + float radius; + float damage; + + float position[3]; + + void Set(int client) + { + if (client > 0 && client <= MaxClients) + this.userid = GetClientUserId(client); + } + int Get() + { + return GetClientOfUserId(this.userid); + } +} +SentryBuster LastBuster; + bool g_Taunt_clamp = false; public void OnPluginStart() { @@ -324,6 +344,27 @@ public Action Bewm(Handle timer, any userid) RemoveEdict(explosion); } bool FF = false; + + // Set our struct info for the sentry buster + LastBuster.Set(client); // Set this client as the current exploding sentry buster + LastBuster.radius = 300.0; // Whatever we want the explosion radius to be + LastBuster.damage = 2500.0; // Damage to deal + LastBuster.position = clientPos; + + PrintToChatAll("Last Buster = Client: %i\nRadius = %.1f\nDamage = %.1f", LastBuster.Get(), LastBuster.radius, LastBuster.damage); + + // This will include everything in one go, no need to loop through all clients and then also entities + TR_EnumerateEntitiesSphere(clientPos, LastBuster.radius, MASK_SHOT, FindEntitiesInSphere, LastBuster.Get()); + + PrintToChatAll("Enumerating"); + + EmitSoundToAll("mvm/sentrybuster/mvm_sentrybuster_explode.wav", client); + AttachParticle(client, "fluidSmokeExpl_ring_mvm"); + DoDamage(client, client, 2500); + FakeClientCommand(client, "kill"); + //CreateTimer(0.0, Timer_RemoveRagdoll, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); + + /* Going to try replacing all this with a simple sphere trace for (int i = 1; i <= MaxClients; i++) { if (!IsValidClient(i)) continue; @@ -370,15 +411,68 @@ public Action Bewm(Handle timer, any userid) // } } } - EmitSoundToAll("mvm/sentrybuster/mvm_sentrybuster_explode.wav", client); - AttachParticle(client, "fluidSmokeExpl_ring_mvm"); - DoDamage(client, client, 2500); - FakeClientCommand(client, "kill"); - //CreateTimer(0.0, Timer_RemoveRagdoll, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE); - TracedTarget = INVALID_ENT_REFERENCE; + */ + return Plugin_Handled; } +bool FindEntitiesInSphere(int entity, int exclude) +{ + // Ignore entities that we can't or shouldn't damage + bool damage = false; + + if (exclude == entity) + return true; // continue, do nothing + + if (entity == 0) + return true; // Ignore the world + + PrintToChatAll("Found entity"); + + float endPos[3]; + + // Check if this is a client.. we shouldn't have to check for team relations since we can't damage teammates regardless + if (entity <= MaxClients) + { + PrintToChatAll("Entity is a client"); + if (IsPlayerAlive(entity)) // This really shouldn't ever error... but if it for some reason does, just add an additional check for IsClientInGame() + { + damage = true; + + GetClientAbsOrigin(entity, endPos); + endPos[2] += 40.0; // Center mass + } + } + else if (IsValidEntity(entity)) // Probably not needed? If it's not a client it should always be a valid entity, regardless.. + { + char classname[64]; + GetEntityClassname(entity, classname, sizeof classname); + + PrintToChatAll("Entity is a building: %s", classname); + + // All building types + if (StrContains(classname, "obj_") != -1) + { + damage = true; + + GetEntPropVector(entity, Prop_Data, "m_vecOrigin", endPos); + } + } + + if (damage) + { + //TracedTarget = INVALID_ENT_REFERENCE; + if (CanSeeTarget(LastBuster.position, endPos, entity, LastBuster.Get())) + { + PrintToChatAll("Target is visible"); + // Damage the entity + SDKHooks_TakeDamage(entity, LastBuster.Get(), LastBuster.Get(), LastBuster.damage, DMG_BLAST); + } + } + + return true; // We want to keep iterating until we run out of overlapped entities.. nothing should really need to stop this +} + bool CanSeeTarget(float start[3], float end[3], int target, int source) { bool result = false;