diff --git a/serverfiles/left4dead2/addons/sourcemod/gamedata/defib_fix.txt b/serverfiles/left4dead2/addons/sourcemod/gamedata/defib_fix.txt
new file mode 100644
index 0000000..2b3a385
--- /dev/null
+++ b/serverfiles/left4dead2/addons/sourcemod/gamedata/defib_fix.txt
@@ -0,0 +1,105 @@
+"Games"
+{
+ "left4dead2"
+ {
+ "Functions"
+ {
+ "CItemDefibrillator::OnActionComplete"
+ {
+ "offset" "CItemDefibrillator::OnActionComplete"
+ "hooktype" "entity"
+ "return" "int"
+ "this" "ignore"
+ "arguments"
+ {
+ "Reviver"
+ {
+ "type" "cbaseentity"
+ }
+ "DeathModel"
+ {
+ "type" "cbaseentity"
+ }
+ }
+ }
+ "CItemDefibrillator::OnStartAction"
+ {
+ "offset" "CItemDefibrillator::OnStartAction"
+ "hooktype" "entity"
+ "return" "int"
+ "this" "ignore"
+ "arguments"
+ {
+ "BackpackItemActionType"
+ {
+ type "int"
+ }
+ "Reviver"
+ {
+ "type" "cbaseentity"
+ }
+ "DeathModel"
+ {
+ "type" "cbaseentity"
+ }
+ "somefloat"
+ {
+ "type" "float"
+ }
+ }
+ }
+ "CTerrorPlayer::GetPlayerByCharacter"
+ {
+ "signature" "CTerrorPlayer::GetPlayerByCharacter"
+ "callconv" "cdecl"
+ "return" "cbaseentity"
+ "this" "ignore"
+ "arguments"
+ {
+ "CharacterIndex"
+ {
+ "type" "int"
+ }
+ }
+ }
+ "CSurvivorDeathModel::Create"
+ {
+ "signature" "CSurvivorDeathModel::Create"
+ "callconv" "thiscall"
+ "return" "cbaseentity"
+ "this" "entity"
+ }
+ }
+ "Offsets"
+ {
+ "CItemDefibrillator::OnActionComplete"
+ {
+ "linux" "456"
+ "windows" "454"
+ }
+ "CItemDefibrillator::OnStartAction"
+ {
+ "linux" "451"
+ "windows" "449"
+ }
+ }
+ "Signatures"
+ {
+ "CTerrorPlayer::GetPlayerByCharacter"
+ {
+ "library" "server"
+ "linux" "@_ZN13CTerrorPlayer20GetPlayerByCharacterE21SurvivorCharacterType"
+ "windows" "\x55\x8B\xEC\x8B\x45\x08\x83\xEC\x08\x83\xF8\x08"
+ /* 55 8B EC 8B 45 08 83 EC 08 83 F8 08 */
+ }
+ "CSurvivorDeathModel::Create"
+ {
+ "library" "server"
+ "linux" "@_ZN19CSurvivorDeathModel6CreateEP13CTerrorPlayer"
+ "windows" "\x55\x8B\xEC\x57\x8B\x7D\x08\x85\xFF\x75\x2A\x33\xC0\x5F\x5D\xC3\x8B\x87\x38\x01\x00\x00"
+ /* 55 8B EC 57 8B 7D 08 85 FF 75 ? 33 C0 5F 5D C3 8B 87 38 01 00 00 */
+ }
+ }
+ }
+}
+//some gamedata from here https://github.com/Satanic-Spirit/defib-fix/blob/master/defibfix.txt credit to whoever
\ No newline at end of file
diff --git a/serverfiles/left4dead2/addons/sourcemod/plugins/Defib_Fix.smx b/serverfiles/left4dead2/addons/sourcemod/plugins/Defib_Fix.smx
new file mode 100644
index 0000000..7caf954
Binary files /dev/null and b/serverfiles/left4dead2/addons/sourcemod/plugins/Defib_Fix.smx differ
diff --git a/serverfiles/left4dead2/addons/sourcemod/scripting/Defib_Fix.sp b/serverfiles/left4dead2/addons/sourcemod/scripting/Defib_Fix.sp
new file mode 100644
index 0000000..c672965
--- /dev/null
+++ b/serverfiles/left4dead2/addons/sourcemod/scripting/Defib_Fix.sp
@@ -0,0 +1,285 @@
+/*
+* Fixes for gamebreaking bugs and stupid gameplay aspects
+* Copyright (C) 2019 LuxLuma acceliacat@gmail.com
+*
+* This program 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, either version 3 of the License, or
+* (at your option) any later version.
+*
+* 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 this program. If not, see .
+*/
+
+#pragma semicolon 1
+
+#include
+#include
+#include
+#include
+
+#pragma newdecls required
+
+#define GAMEDATA "defib_fix"
+
+#define PLUGIN_VERSION "2.0.1"
+
+GlobalForward g_hForward_SurvivorDeathModelCreated;
+
+Handle hOnActionComplete;
+Handle hOnStartAction;
+
+bool g_bFixChar;
+int g_iCurrentDeathModel;
+int g_iDeathModelOwner[2048+1];
+
+
+public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
+{
+ if(GetEngineVersion() != Engine_Left4Dead2)
+ {
+ strcopy(error, err_max, "Plugin only supports Left 4 Dead 2");
+ return APLRes_SilentFailure;
+ }
+
+ g_hForward_SurvivorDeathModelCreated = new GlobalForward("L4D2_OnSurvivorDeathModelCreated", ET_Event, Param_Cell, Param_Cell);
+ RegPluginLibrary("Defib_Fix");
+ return APLRes_Success;
+}
+
+public Plugin myinfo =
+{
+ name = "[L4D2]Defib_Fix",
+ author = "Lux",
+ description = "Fixes defibbing from failing when defibbing an alive character index",
+ version = PLUGIN_VERSION,
+ url = "forums.alliedmods.net/showthread.php?p=2647018"
+};
+
+public void OnPluginStart()
+{
+ Handle hGamedata = LoadGameConfigFile(GAMEDATA);
+ if(hGamedata == null)
+ SetFailState("Failed to load \"%s.txt\" gamedata.", GAMEDATA);
+
+ hOnActionComplete = DHookCreateFromConf(hGamedata, "CItemDefibrillator::OnActionComplete");
+ if(hOnActionComplete == null)
+ SetFailState("Failed to make hook for 'CItemDefibrillator::OnActionComplete'");
+
+ hOnStartAction = DHookCreateFromConf(hGamedata, "CItemDefibrillator::OnStartAction");
+ if(hOnStartAction == null)
+ SetFailState("Failed to make hook for 'CItemDefibrillator::OnStartAction'");
+
+ Handle hDetour;
+ hDetour = DHookCreateFromConf(hGamedata, "CTerrorPlayer::GetPlayerByCharacter");
+ if(!hDetour)
+ SetFailState("Failed to find 'CTerrorPlayer::GetPlayerByCharacter' signature");
+
+ if(!DHookEnableDetour(hDetour, false, GetPlayerByCharacter))
+ SetFailState("Failed to detour 'CTerrorPlayer::GetPlayerByCharacter'");
+
+ hDetour = DHookCreateFromConf(hGamedata, "CSurvivorDeathModel::Create");
+ if(!hDetour)
+ SetFailState("Failed to find 'CSurvivorDeathModel::Create' signature");
+
+ if(!DHookEnableDetour(hDetour, false, DeathModelCreatePre))
+ SetFailState("Failed to detour 'CSurvivorDeathModel::Create'");
+
+ if(!DHookEnableDetour(hDetour, true, DeathModelCreatePost))
+ SetFailState("Failed to detour 'CSurvivorDeathModel::Create'");
+
+ delete hGamedata;
+
+ CreateConVar("defib_fix_version", PLUGIN_VERSION, "", FCVAR_NOTIFY|FCVAR_DONTRECORD);
+}
+
+public void OnEntityCreated(int iEntity, const char[] sClassname)
+{
+ if(sClassname[0] != 'w' || !StrEqual(sClassname, "weapon_defibrillator", false))
+ return;
+
+ DHookEntity(hOnActionComplete, false, iEntity, _, OnActionCompletePre);
+ DHookEntity(hOnActionComplete, true, iEntity, _, OnActionCompletePost);
+ DHookEntity(hOnStartAction, false, iEntity, _, OnStartActionPre);
+}
+
+public MRESReturn OnActionCompletePre(Handle hReturn, Handle hParams)
+{
+ int iDeathModel = DHookGetParam(hParams, 2);
+ if(!iDeathModel)
+ return MRES_Ignored;
+
+ if(IsAllSurvivorsAlive())//rare case
+ {
+ KillAllDeathModels();
+ DHookSetReturn(hReturn, 0);
+ return MRES_Supercede;
+ }
+
+ g_iCurrentDeathModel = iDeathModel;
+ g_bFixChar = true;
+ return MRES_Ignored;
+}
+
+public MRESReturn OnActionCompletePost(Handle hReturn, Handle hParams)
+{
+ if(IsAllSurvivorsAlive())
+ KillAllDeathModels();
+
+ g_bFixChar = false;//just incase
+ return MRES_Ignored;
+}
+
+public MRESReturn GetPlayerByCharacter(Handle hReturn, Handle hParams)
+{
+ if(!g_bFixChar)
+ return MRES_Ignored;
+ g_bFixChar = false;
+
+ static int iChar[MAXPLAYERS+1];
+
+ int iCurrentChar = GetClientOfUserId(g_iDeathModelOwner[g_iCurrentDeathModel]);
+ if(iCurrentChar > 0 && IsClientInGame(iCurrentChar) && !IsPlayerAlive(iCurrentChar) && GetClientTeam(iCurrentChar) == 2)//check if owner of model death model is dead
+ {
+ DHookSetReturn(hReturn, iCurrentChar);
+ return MRES_Supercede;
+ }
+
+ iCurrentChar = DHookGetParam(hParams, 1);
+
+ for(int i = 1; i <= MaxClients; i++)
+ {
+ if(IsClientInGame(i) && !IsPlayerAlive(i) && GetClientTeam(i) == 2)
+ {
+ iChar[i] = GetEntProp(i, Prop_Send, "m_survivorCharacter", 1);
+ if(iCurrentChar == iChar[i])//if found player same char type
+ {
+ DHookSetReturn(hReturn, i);
+ return MRES_Supercede;
+ }
+ }
+ else
+ {
+ iChar[i] = -1;
+ }
+ }
+
+ int iFoundPlayer;
+ iCurrentChar = ConvertToInternalCharacter(iCurrentChar);
+ for(int i = 1; i <= MaxClients; i++)
+ {
+ if(iChar[i] != -1)
+ iFoundPlayer = i;//fallback incase noone matches
+
+ if(iCurrentChar == iChar[i])
+ {
+ iFoundPlayer = i;
+ break;
+ }
+ }
+ if(!iFoundPlayer)
+ return MRES_Ignored;//better safe than sorry
+
+ DHookSetReturn(hReturn, iFoundPlayer);
+ return MRES_Supercede;
+}
+
+public MRESReturn OnStartActionPre(Handle hReturn, Handle hParams)
+{
+ if(IsAllSurvivorsAlive())
+ {
+ KillAllDeathModels();
+ DHookSetReturn(hReturn, 0);
+ return MRES_Supercede;
+ }
+ return MRES_Ignored;
+}
+
+int g_iTempClient;
+public MRESReturn DeathModelCreatePost(int pThis, Handle hReturn)
+{
+ int iDeathModel = DHookGetReturn(hReturn);
+ if(!iDeathModel)
+ return MRES_Ignored;
+
+ float vPos[3];
+ GetClientAbsOrigin(g_iTempClient, vPos);
+
+ TeleportEntity(iDeathModel, vPos, NULL_VECTOR, NULL_VECTOR);
+
+ g_iDeathModelOwner[iDeathModel] = GetClientUserId(g_iTempClient);
+
+ Call_StartForward(g_hForward_SurvivorDeathModelCreated);
+ Call_PushCell(g_iTempClient);
+ Call_PushCell(iDeathModel);
+ Call_Finish();
+
+ return MRES_Ignored;
+}
+
+public MRESReturn DeathModelCreatePre(int pThis)
+{
+ g_iTempClient = pThis;
+}
+
+public void OnEntityDestroyed(int iEntity)
+{
+ if(iEntity < 1)
+ return;
+
+ g_iDeathModelOwner[iEntity] = 0;
+}
+
+int ConvertToInternalCharacter(int iChar)
+{
+ switch(iChar)
+ {
+ case 4:
+ {
+ return 0;
+ }
+ case 5:
+ {
+ return 1;
+ }
+ case 6:
+ {
+ return 3;
+ }
+ case 7:
+ {
+ return 2;
+ }
+ case 9:
+ {
+ return 8;
+ }
+ }
+ return iChar;// some people set survivors to 8 or 9 index so revive them too
+}
+
+bool IsAllSurvivorsAlive()
+{
+ for(int i = 1; i <= MaxClients; i++)// rare case it could happen
+ {
+ if(IsClientInGame(i) && !IsPlayerAlive(i) && GetClientTeam(i) == 2)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+void KillAllDeathModels()
+{
+ int i = INVALID_ENT_REFERENCE;
+ while((i = FindEntityByClassname(i, "survivor_death_model")) != INVALID_ENT_REFERENCE)
+ {
+ AcceptEntityInput(i, "Kill");
+ }
+}
diff --git a/serverfiles/left4dead2/addons/sourcemod/scripting/include/Defib_Fix.inc b/serverfiles/left4dead2/addons/sourcemod/scripting/include/Defib_Fix.inc
new file mode 100644
index 0000000..21bf5b7
--- /dev/null
+++ b/serverfiles/left4dead2/addons/sourcemod/scripting/include/Defib_Fix.inc
@@ -0,0 +1,30 @@
+/*
+* https://github.com/LuxLuma/Left-4-fix/tree/master/left%204%20fix/Defib_Fix
+*/
+
+#if defined _Defib_Fix_included
+#endinput
+#endif
+#define _Defib_Fix_included
+
+/**
+* @Note only called if Defib_Fix is installed
+*
+* Deathmodels are "survivor_death_model" that can be used with defibrillator.
+*
+* @param iClient Client Index who died.
+* @param iDeathModel Entity Index of Deathmodel for client who died
+* @no return
+*/
+forward void L4D2_OnSurvivorDeathModelCreated(int iClient, int iDeathModel);
+
+public SharedPlugin __pl_Defib_Fix =
+{
+ name = "Defib_Fix",
+ file = "Defib_Fix.smx",
+#if defined REQUIRE_PLUGIN
+ required = 1,
+#else
+ required = 0,
+#endif
+};