/*
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 <http://www.gnu.org/licenses/>.
*/
/* Survivor Upgrades - A modification for the game Left4Dead */
/* Note: The upgrades were created by Valve - this mod simply makes them available. */
/* Version History
* 1.0
* -Initial release.
* 1.1
* - Filtered out #L4D_Upgrade_laser_sight_expire text broadcast when turning off a laser.
* - Added cvars to allow disabling of specific upgrades. (Hot Meal is disabled, by default.)
* - Added verbosity cvar. 0 for no messages, 1 for expire events only, 2 for expire events
* and short self messages, 3 for everything.
* - Added potential fix for bots taking over for players getting upgrades.
*/
#include <sourcemod>
#include <sdktools>
#define NUPGRADES 31
#define NVALID 14
#define PLUGIN_VERSION "1.1"
#define PLUGIN_NAME "Survivor Upgrades"
#define PLUGIN_TAG "[SurUp]"
//CTerrorPlayer::AddUpgrade(SurvivorUpgradeType)
//_ZN13CTerrorPlayer10AddUpgradeE19SurvivorUpgradeType
new Handle:AddUpgrade = INVALID_HANDLE;
//CTerrorPlayer::RemoveUpgrade(SurvivorUpgradeType)
//_ZN13CTerrorPlayer13RemoveUpgradeE19SurvivorUpgradeType
new Handle:RemoveUpgrade = INVALID_HANDLE;
//CTerrorPlayer::GiveRandomUpgrade()
//_ZN13CTerrorPlayer17GiveRandomUpgradeEv
new Handle:GiveRandomUpgrade = INVALID_HANDLE;
new bool:bHooked = false;
new bool:bUpgraded[MAXPLAYERS+1];
new bool:bBotControlled[MAXPLAYERS+1];
new IndexToUpgrade[NVALID];
new bool:bClientHasUpgrade[MAXPLAYERS+1][NVALID];
new String:UpgradeShortInfo[NVALID][256];
new String:UpgradeLongInfo[NVALID][1024];
new Handle:UpgradeAllowed[NVALID];
new Handle:AlwaysLaser = INVALID_HANDLE;
new Handle:UpgradesAtSpawn = INVALID_HANDLE;
new Handle:UpgradesAtWitchKillKiller = INVALID_HANDLE;
new Handle:UpgradesAtWitchKillAll = INVALID_HANDLE;
new Handle:UpgradesAtTankSpawn = INVALID_HANDLE;
new Handle:UpgradesAtTankKillKiller = INVALID_HANDLE;
new Handle:UpgradesAtTankKillAll = INVALID_HANDLE;
new Handle:Verbosity = INVALID_HANDLE;
new bool:bBlockUntilRoundStart;
new UserMsg:sayTextMsgId;
public OnPluginStart()
{
// Try the windows version first.
StartPrepSDKCall(SDKCall_Player);
if (!PrepSDKCall_SetSignature(SDKLibrary_Server, "\xA1****\x83***\x57\x8B\xF9\x0F*****\x8B***\x56\x51\xE8****\x8B\xF0\x83\xC4\x04", 34))
{
PrepSDKCall_SetSignature(SDKLibrary_Server, "@_ZN13CTerrorPlayer10AddUpgradeE19SurvivorUpgradeType", 0);
}
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_ByValue);
AddUpgrade = EndPrepSDKCall();
StartPrepSDKCall(SDKCall_Player);
if (!PrepSDKCall_SetSignature(SDKLibrary_Server, "\x51\x53\x55\x8B***\x8B\xD9\x56\x8B\xCD\x83\xE1\x1F\xBE\x01\x00\x00\x00\x57\xD3\xE6\x8B\xFD\xC1\xFF\x05\x89***", 32))
{
PrepSDKCall_SetSignature(SDKLibrary_Server, "@_ZN13CTerrorPlayer13RemoveUpgradeE19SurvivorUpgradeType", 0);
}
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_ByValue);
RemoveUpgrade = EndPrepSDKCall();
StartPrepSDKCall(SDKCall_Player);
if (!PrepSDKCall_SetSignature(SDKLibrary_Server, "\x83\xEC\x18\xA1****\x56\x33\xF6\x39\x70\x30\x89***\x0F*****\x53\x55\x57\x33\xED\x33\xDB\x33\xFF", 33))
{
PrepSDKCall_SetSignature(SDKLibrary_Server, "@_ZN13CTerrorPlayer17GiveRandomUpgradeEv", 0);
}
GiveRandomUpgrade = EndPrepSDKCall();
IndexToUpgrade[0] = 1;
UpgradeShortInfo[0] = "護身裝甲 - (受到更少傷害)";
UpgradeLongInfo[0] = "當你穿上裝甲, 感染者攻擊對你造成更少傷害";
UpgradeAllowed[0] = CreateConVar("surup_allow_kevlar_body_armor", "1", "能否得到護身裝甲", FCVAR_PLUGIN);
IndexToUpgrade[1] = 8;
UpgradeShortInfo[1] = "雨衣 - (擋住BOOMER的嘔吐物) [即用即棄]";
UpgradeLongInfo[1] = "這件雨衣用來擋住BOOMER的嘔吐物, 可惜雨衣會被侵食, 不能再用了";
UpgradeAllowed[1] = CreateConVar("surup_allow_raincoat", "1", "能否得到雨衣", FCVAR_PLUGIN);