From 5e0321c8fff8e7820aac72a6b5bf39944b66eb7a Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Wed, 22 Feb 2023 00:18:30 +0100 Subject: [PATCH 01/13] new fork, branch and Changes --- .../smrpg_upgrade_armorplus_cstrike.sp | 4 +- .../smrpg_upgrade_armorregen_cstrike.sp | 2 +- .../upgrades/smrpg_upgrade_conversion.sp | 256 ++++++++++++++++++ scripting/upgrades/smrpg_upgrade_regen.sp | 2 +- scripting/upgrades/smrpg_upgrade_turtle.sp | 176 ++++++++++++ 5 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 scripting/upgrades/smrpg_upgrade_conversion.sp create mode 100644 scripting/upgrades/smrpg_upgrade_turtle.sp diff --git a/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp index 21cc760..920e21c 100644 --- a/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp +++ b/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp @@ -132,7 +132,7 @@ public void SMRPG_BuySell(int client, UpgradeQueryType type) // Client currently had his old maxarmor or more? // Set him to his new higher maxarmor immediately. // Don't touch his armor, if he were already damaged. - if(iArmor >= (iMaxArmor - g_hCVMaxIncrease.IntValue)) + if(iArmor >= (iMaxArmor - RoundToFloor(g_hCVMaxIncrease.FloatValue))) SetClientArmor(client, iMaxArmor); } case UpgradeQueryType_Sell: @@ -176,7 +176,7 @@ int GetClientMaxArmor(int client) if(iLevel <= 0) return iDefaultMaxArmor; - int iNewMaxArmor = iDefaultMaxArmor + g_hCVMaxIncrease.IntValue * iLevel; + int iNewMaxArmor = iDefaultMaxArmor + RoundToFloor(g_hCVMaxIncrease.FloatValue * iLevel); int iGameMaxArmor = CSS_MAX_ARMOR; if (g_bIsCSGO) iGameMaxArmor = CSGO_MAX_ARMOR; diff --git a/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp index 82b23af..479e394 100644 --- a/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp +++ b/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp @@ -143,7 +143,7 @@ public Action Timer_IncreaseArmor(Handle timer, any userid) return Plugin_Continue; } - int iIncrease = g_hCVAmount.IntValue + g_hCVAmountIncrease.IntValue * (iLevel - 1); + int iIncrease = RoundToFloor(g_hCVAmount.FloatValue) + RoundToFloor(g_hCVAmountIncrease.FloatValue * (iLevel - 1)); int iNewArmor = iCurrentArmor + iIncrease; if(iNewArmor > iMaxArmor) iNewArmor = iMaxArmor; diff --git a/scripting/upgrades/smrpg_upgrade_conversion.sp b/scripting/upgrades/smrpg_upgrade_conversion.sp new file mode 100644 index 0000000..9c8599f --- /dev/null +++ b/scripting/upgrades/smrpg_upgrade_conversion.sp @@ -0,0 +1,256 @@ +#pragma semicolon 1 +#include + +#pragma newdecls required +#include + +#define UPGRADE_SHORTNAME "conversion" +#define PLUGIN_VERSION "1.0" + +public Plugin myinfo = +{ + name = "SM:RPG Upgrade > Conversion ", + author = "WanekWest", + description = "Conversion allows the player to turn excess money into exp.", + version = PLUGIN_VERSION, + url = "https://vk.com/wanek_west" + + +} + +ConVar g_hCvMoneyConvertType, + g_hCvMoneyConvertRequestAmount, g_hCvMoneyConvertIncreaserPerLevel, g_hCvMoneyConvertBaseAmount; + +int hCvMoneyConvertType, hCvMoneyConvertRequestAmount; +float hCvMoneyConvertIncreaserPerLevel, hCvMoneyConvertBaseAmount; + +int g_MoneyOffset; + +public void OnPluginStart() +{ + LoadTranslations("smrpg_stock_upgrades.phrases"); + + + HookEvent("bomb_defused", Event_OnBombDefused); + HookEvent("player_spawn", Event_OnPlayerSpawn); + HookEvent("hostage_rescued", Event_OnHostageRescue); + HookEvent("bomb_exploded", Event_OnBombExploded); + HookEvent("player_death", Event_OnPlayerDeath); +// HookEvent("round_start", Event_OnRoundStart); + HookEvent("round_end", Event_OnRoundEnd); + HookEvent("hostage_follows", Event_OnHostageFollow); + + g_MoneyOffset = FindSendPropInfo("CCSPlayer", "m_iAccount"); + if (g_MoneyOffset == -1) + { + SetFailState("Can not find m_iAccount."); + } +} + +public void OnPluginEnd() +{ + if (SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) + SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); +} + +public void OnAllPluginsLoaded() +{ + OnLibraryAdded("smrpg"); +} + +public void OnLibraryAdded(const char[] name) +{ + // Register this upgrade in SM:RPG + if (StrEqual(name, "smrpg")) + { + // Register the upgrade type. + SMRPG_RegisterUpgradeType("Conversion", UPGRADE_SHORTNAME, "Conversion allows the player to turn excess money into credits.", 10, true, 5, 15, 10); + SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); + + g_hCvMoneyConvertType = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_type", "0", "Conversion type. 0 - to EXP, 1 - to Credits", _, true, 0.0); + g_hCvMoneyConvertType.AddChangeHook(OnConverChangeType); + hCvMoneyConvertType = g_hCvMoneyConvertType.IntValue; + + g_hCvMoneyConvertRequestAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_request_amount", "100", "How much money to take for 1 unit of Experience/Credits.", _, true, 0.0); + g_hCvMoneyConvertRequestAmount.AddChangeHook(OnConverChangeReqMoney); + hCvMoneyConvertRequestAmount = g_hCvMoneyConvertRequestAmount.IntValue; + + g_hCvMoneyConvertIncreaserPerLevel = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_increase", "1.0", "Increase value per level.", _, true, 0.0); + g_hCvMoneyConvertIncreaserPerLevel.AddChangeHook(OnConverChangeIncreaseValue); + hCvMoneyConvertIncreaserPerLevel = g_hCvMoneyConvertIncreaserPerLevel.FloatValue; + + g_hCvMoneyConvertBaseAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_base_amount", "1.0", "The base amount to start with at level 1.", _, true, 0.0); + g_hCvMoneyConvertBaseAmount.AddChangeHook(OnConverChangeBaseAmount); + hCvMoneyConvertBaseAmount = g_hCvMoneyConvertBaseAmount.FloatValue; + } +} + +public void OnConverChangeType(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) +{ + hCvMoneyConvertType = hCvar.IntValue; +} + +public void OnConverChangeReqMoney(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) +{ + hCvMoneyConvertRequestAmount = hCvar.IntValue; +} + +public void OnConverChangeIncreaseValue(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) +{ + hCvMoneyConvertIncreaserPerLevel = hCvar.FloatValue; +} + +public void OnConverChangeBaseAmount(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) +{ + hCvMoneyConvertBaseAmount = hCvar.FloatValue; +} + +// The core wants to display your upgrade somewhere. Translate it into the clients language! +public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) +{ + // Easy pattern is to use the shortname of your upgrade in the translation file + if (type == TranslationType_Name) + Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); + // And "shortname description" as phrase in the translation file for the description. + else if (type == TranslationType_Description) + { + char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH + 12] = UPGRADE_SHORTNAME; + StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); + Format(translation, maxlen, "%T", sDescriptionKey, client); + } +} + +public void Event_OnRoundEnd(Event event, const char[] error, bool dontBroadcast) +{ + int maxClients = MaxClients; + int time; + GetMapTimeLeft(time); + + //This is the time before mapchange. After the last round it takes about 3 seconds for the map to change. Depending on server settings. + if(time <= 4) + { + for (int client = 1; client <= maxClients; client++) + { + + Conversion(client, 0); + if(client==maxClients) + return; + + } + return; + } +} + +public void Event_OnHostageFollow(Event event, const char[] error, bool dontBroadcast) +{ + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client) + return; + + Conversion(client, 10000); + return; +} + +public void Event_OnPlayerDeath(Event event, const char[] error, bool dontBroadcast) +{ + + int client = GetClientOfUserId(event.GetInt("attacker")); + if (!client) + return; + + Conversion(client, 9700); + return; + +} + + +public void Event_OnHostageRescue(Event event, const char[] name, bool dontBroadcast) +{ + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client) + return; + + Conversion(client, 10000); + return; +} + +public void Event_OnBombDefused(Event event, const char[] name, bool dontBroadcast) +{ + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client) + return; + + Conversion(client, 10000); + return; +} + +public void Event_OnBombExploded(Event event, const char[] name, bool dontBroadcast) +{ + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client) + return; + + Conversion(client, 10000); + return; +} + +public void Event_OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) +{ + + int client = GetClientOfUserId(event.GetInt("userid")); + if (!client) + return; + + Conversion(client, 10000); + return; +} + +public void Conversion(int client, int moneyThreshold) +{ + if (!client) + return; + + // SM:RPG is disabled? + if (!SMRPG_IsEnabled()) + return; + + // The upgrade is disabled completely? + if (!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) + return; + + // Are bots allowed to use this upgrade? + //if (IsFakeClient(client) && SMRPG_IgnoreBots()) + //return; + + // Player didn't buy this upgrade yet. + int iLevel = SMRPG_GetClientUpgradeLevel(client, UPGRADE_SHORTNAME); + if (iLevel <= 0) + return; + + int currentClientMoney = GetEntData(client, g_MoneyOffset); + if (currentClientMoney >= moneyThreshold + hCvMoneyConvertRequestAmount) + { + + // int clientMoney = GetEntProp(client, Prop_Send, "m_iAccount"); + int amountToSubstract = currentClientMoney - moneyThreshold; + float amountToAdd = hCvMoneyConvertBaseAmount + hCvMoneyConvertIncreaserPerLevel * (iLevel - 1); + int amountToGive = RoundToCeil(amountToSubstract / hCvMoneyConvertRequestAmount * amountToAdd); + PrintToConsole(client, "You have earned %d experience for converting $", amountToGive); + char reason[256]; + FormatEx(reason, sizeof(reason), "converting %d$", amountToSubstract); + + if (hCvMoneyConvertType == 0) + { + SMRPG_AddClientExperience(client, amountToGive, reason, false, -1); + SetEntData(client, g_MoneyOffset, moneyThreshold); + } + else + { + SMRPG_SetClientCredits(client, SMRPG_GetClientCredits(client) + amountToGive); + SetEntData(client, g_MoneyOffset, moneyThreshold); + } + } + + return; +} + diff --git a/scripting/upgrades/smrpg_upgrade_regen.sp b/scripting/upgrades/smrpg_upgrade_regen.sp index c9ac041..5405b68 100644 --- a/scripting/upgrades/smrpg_upgrade_regen.sp +++ b/scripting/upgrades/smrpg_upgrade_regen.sp @@ -125,7 +125,7 @@ public Action Timer_IncreaseHealth(Handle timer, any userid) if(!SMRPG_RunUpgradeEffect(client, UPGRADE_SHORTNAME)) return Plugin_Continue; // Some other plugin doesn't want this effect to run - int iIncrease = g_hCVAmount.IntValue + g_hCVAmountIncrease.IntValue * (iLevel - 1); + int iIncrease = RoundToFloor(g_hCVAmount.FloatValue) + RoundToFloor(g_hCVAmountIncrease.FloatValue * (iLevel - 1)); int iNewHealth = iOldHealth + iIncrease; // Limit the regeneration to the maxhealth. if(iNewHealth > iMaxHealth) diff --git a/scripting/upgrades/smrpg_upgrade_turtle.sp b/scripting/upgrades/smrpg_upgrade_turtle.sp new file mode 100644 index 0000000..b120adf --- /dev/null +++ b/scripting/upgrades/smrpg_upgrade_turtle.sp @@ -0,0 +1,176 @@ +/** + * SM:RPG Reduced Fall Damage Upgrade + * Reduces the damage you take from falling from great heights. + */ + +#pragma semicolon 1 +#include +#include + +#pragma newdecls required +#include + +#define UPGRADE_SHORTNAME "turtle" + +ConVar g_hCVPercent; +ConVar g_hCVDuration; +bool turtlemode; + +public Plugin myinfo = +{ + name = "SM:RPG Upgrade > Turtle", + author = "DeewaTT", + description = "Let's you take decreased damage after taking a headshot for a limit amount of time.", + version = SMRPG_VERSION, + url = "http://www.wcfan.de/" +} + +public void OnPluginStart() +{ + LoadTranslations("smrpg_stock_upgrades.phrases"); + + // Account for late loading + for(int i=1;i<=MaxClients;i++) + { + if(IsClientInGame(i)) + OnClientPutInServer(i); + } +} + +public void OnPluginEnd() +{ + if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) + SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); +} + +public void OnAllPluginsLoaded() +{ + OnLibraryAdded("smrpg"); +} + +public void OnLibraryAdded(const char[] name) +{ + // Register this upgrade in SM:RPG + if(StrEqual(name, "smrpg")) + { + // Register the upgrade type. + SMRPG_RegisterUpgradeType("Turtle", UPGRADE_SHORTNAME, "Reduces the damage you receive after taking a headshot.", 0, true, 5, 10, 10); + + SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); + + // Create your convars through the SM:RPG core. That way they are added to your upgrade's own config file in cfg/sourcemod/smrpg/smrpg_upgrade_example.cfg! + g_hCVPercent = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_turtle_percent", "0.01", "How much percent of the damage should be removed (multiplied by level)?", _, true, 0.01, true, 1.0); + g_hCVDuration = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_turtle_duration", "0.01", "How long should the damage reduction last (multiplied by level)?", _, true, 0.01, true, 10.0); + } +} + +public void OnClientPutInServer(int client) +{ + SDKHook(client, SDKHook_OnTakeDamage, Hook_OnTakeDamage); + SDKHook(client, SDKHook_TraceAttackPost, Hook_TraceAttackPost); +} + +/** + * SM:RPG Upgrade callbacks + */ + +// The core wants to display your upgrade somewhere. Translate it into the clients language! +public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) +{ + // Easy pattern is to use the shortname of your upgrade in the translation file + if(type == TranslationType_Name) + Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); + // And "shortname description" as phrase in the translation file for the description. + else if(type == TranslationType_Description) + { + char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; + StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); + Format(translation, maxlen, "%T", sDescriptionKey, client); + } +} + +/** + * SDK Hooks callbacks + */ + + +public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float damage, int damagetype, int ammotype, int hitbox, int hitgroup) +{ + // Check if the victim is a player and if the last hit was a headshot. + if (IsClientInGame(victim) && hitgroup == 1 && hitbox == 12 && turtlemode == false) + { + // Check if the victim has the "turtle" skill. + int iLevel = SMRPG_GetClientUpgradeLevel(victim, "turtle"); + if (iLevel > 0) + { + // Activate "turtlemode" for the player + SetTurtlemode(victim, true); + // Schedule a timer to deactivate "turtlemode" after x seconds + float turtleDuration = float(iLevel) * g_hCVDuration.FloatValue; + CreateTimer(turtleDuration, RemoveTurtleMode, victim, TIMER_FLAG_NO_MAPCHANGE); + } + } + return; +} + public Action RemoveTurtleMode(Handle timer, int victim) +{ + // Deactivate "turtlemode" for the player + SetTurtlemode(victim, false); + return Plugin_Handled; +} + + +public Action Hook_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, + float damageForce[3], float damagePosition[3], int damagecustom) +{ + // We need to check if we are in damage reduction mode. + if(turtlemode == false) + return Plugin_Continue; + + // SM:RPG is disabled? + if(!SMRPG_IsEnabled()) + return Plugin_Continue; + + // The upgrade is disabled completely? + if(!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) + return Plugin_Continue; + + // Are bots allowed to use this upgrade? + if(IsFakeClient(victim) && SMRPG_IgnoreBots()) + return Plugin_Continue; + + // Player didn't buy this upgrade yet. + int iLevel = SMRPG_GetClientUpgradeLevel(victim, UPGRADE_SHORTNAME); + if(iLevel <= 0) + return Plugin_Continue; + + // This calls the SMRPG_OnUpgradeEffect global forward where other plugins can stop you from applying your effect, if it conflicts with theirs. + // This also returns false, if the client doesn't have the required admin flags to use the upgrade, so no need to call SMRPG_CheckUpgradeAccess. + if(!SMRPG_RunUpgradeEffect(victim, UPGRADE_SHORTNAME)) + return Plugin_Continue; // Some other plugin doesn't want this effect to run + + + float fReducePercent = g_hCVPercent.FloatValue * float(iLevel); + // Never block the whole damage. + if (fReducePercent >= 1.0) + fReducePercent = 0.99; + + // Reduce the damage taken. + damage -= damage * fReducePercent; + return Plugin_Changed; +} + +// Turns the Turtlemode on or off. +public void SetTurtlemode(int client, bool bool) +{ + turtlemode = bool; + if(turtlemode == true) + { + PrintToConsole(client, "You are now in turtlemode!"); + } + else + { + PrintToConsole(client, "You are no longer in turtlemode!"); + } + return; +} \ No newline at end of file From 7644f07dd4a0ff1f67562228350d027211d42396 Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Wed, 22 Feb 2023 04:19:00 +0100 Subject: [PATCH 02/13] new upgrade pickpocket, updated translation file to include new upgrades --- .../upgrades/smrpg_upgrade_pickpocket.sp | 171 ++++++++++++++++++ translations/smrpg_stock_upgrades.phrases.txt | 30 +++ 2 files changed, 201 insertions(+) create mode 100644 scripting/upgrades/smrpg_upgrade_pickpocket.sp diff --git a/scripting/upgrades/smrpg_upgrade_pickpocket.sp b/scripting/upgrades/smrpg_upgrade_pickpocket.sp new file mode 100644 index 0000000..5551fcf --- /dev/null +++ b/scripting/upgrades/smrpg_upgrade_pickpocket.sp @@ -0,0 +1,171 @@ +#pragma semicolon 1 +#include +#include +#include + + +#pragma newdecls required +#include + +#undef REQUIRE_PLUGIN + +#define UPGRADE_SHORTNAME "pickpocket" + + +ConVar g_hCVAmount; +ConVar g_hCVAmountIncrease; +ConVar g_hCVWeapon; + + +int g_MoneyOffset; + +public Plugin myinfo = +{ + name = "SM:RPG Upgrade > Pickpocket", + author = "DeewaTT", + description = "Pickpocket upgrade for SM:RPG. Steals money with every hit from your knife.", + version = SMRPG_VERSION, + url = "http://www.wcfan.de/" +} + +public void OnPluginStart() +{ + LoadTranslations("smrpg_stock_upgrades.phrases"); + + // We define this variable to check for the players money later. + g_MoneyOffset = FindSendPropInfo("CCSPlayer", "m_iAccount"); + if (g_MoneyOffset == -1) + { + SetFailState("Can not find m_iAccount."); + } +} + +public void OnPluginEnd() +{ + if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) + SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); +} + +public void OnAllPluginsLoaded() +{ + OnLibraryAdded("smrpg"); +} + +public void OnLibraryAdded(const char[] name) +{ + // Register this upgrade in SM:RPG + if(StrEqual(name, "smrpg")) + { + SMRPG_RegisterUpgradeType("Pickpocket", UPGRADE_SHORTNAME, "Steals money when knifing.", 0, true, 5, 5, 10); + SMRPG_SetUpgradeBuySellCallback(UPGRADE_SHORTNAME, SMRPG_BuySell); + SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); + + g_hCVAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_amount", "1", "Specify the base amount of money stolen at the first level.", 0, true, 0.1); + g_hCVAmountIncrease = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_amount_inc", "1", "Additional money to steal multiplied by level. (base + inc * (level-1))", 0, true, 0.0); + g_hCVWeapon = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_weapon", "knife", "Entity name of the weapon which should trigger the effect. (e.g. knife)"); + } +} + +public void OnClientPutInServer(int client) +{ + // Declare the hook we will use. + SDKHook(client, SDKHook_OnTakeDamagePost, Hook_OnTakeDamagePost); +} + +/** + * SM:RPG Upgrade callbacks + */ + +public void SMRPG_BuySell(int client, UpgradeQueryType type) +{ + // Inform the player that he is now a thief + PrintToChat(client, "You can now steal money by knifing people."); +} + +public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) +{ + if(type == TranslationType_Name) + Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); + else if(type == TranslationType_Description) + { + char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; + StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); + Format(translation, maxlen, "%T", sDescriptionKey, client); + } +} + +public void Hook_OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, const float damageForce[3], const float damagePosition[3]) +{ + if(attacker <= 0 || attacker > MaxClients || !IsClientInGame(attacker) || victim <= 0 || victim > MaxClients) + return; + + // Ignore team attack if not FFA + if(!SMRPG_IsFFAEnabled() && GetClientTeam(attacker) == GetClientTeam(victim)) + return; + + int iWeapon = inflictor; + if(inflictor > 0 && inflictor <= MaxClients) + iWeapon = Client_GetActiveWeapon(inflictor); + + if(iWeapon == -1) + return; + + char sWeapon[256], sTargetWeapon[128]; + g_hCVWeapon.GetString(sTargetWeapon, sizeof(sTargetWeapon)); + GetEntityClassname(iWeapon, sWeapon, sizeof(sWeapon)); + ReplaceString(sWeapon, sizeof(sWeapon), "weapon_", "", false); + + // This effect only applies to the specified weapon. + if(StrContains(sWeapon, sTargetWeapon) == -1) + return; + + Takemoney(attacker, victim); +} + +public void Takemoney(int attacker, int victim) +{ + + if (!attacker) + return; + + // Are bots allowed to use this upgrade? + if(SMRPG_IgnoreBots() && IsFakeClient(attacker)) + return; + + // Some other plugin doesn't want this effect to run + if(!SMRPG_RunUpgradeEffect(attacker, UPGRADE_SHORTNAME)) + return; + + // SM:RPG is disabled? + if (!SMRPG_IsEnabled()) + return; + + // This upgrade is disabled? + if (!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) + return; + + // Player didn't buy this upgrade yet. + int iLevel = SMRPG_GetClientUpgradeLevel(attacker, UPGRADE_SHORTNAME); + if (iLevel <= 0) + return; + + // Determine how much money will be taken. + int amountToSteal = RoundToNearest(g_hCVAmount.FloatValue + g_hCVAmountIncrease.FloatValue*(iLevel-1)); + + // Check the victims money. If it's less than the attacker wants to take, set it to 0. + int currentVictimMoney = GetEntData(victim, g_MoneyOffset); + int newVictimMoney = currentVictimMoney - amountToSteal; + if (currentVictimMoney <= amountToSteal) + { + amountToSteal = currentVictimMoney; + newVictimMoney = 0; + } + SetEntData(victim, g_MoneyOffset, newVictimMoney); + + // Check attackers money and add the stolen amount to it. + int currentAttackerMoney = GetEntData(attacker, g_MoneyOffset); + int newAttackerMoney = currentAttackerMoney + amountToSteal; + SetEntData(attacker, g_MoneyOffset, newAttackerMoney); + + return; +} \ No newline at end of file diff --git a/translations/smrpg_stock_upgrades.phrases.txt b/translations/smrpg_stock_upgrades.phrases.txt index 99c7de4..8b4683c 100644 --- a/translations/smrpg_stock_upgrades.phrases.txt +++ b/translations/smrpg_stock_upgrades.phrases.txt @@ -329,4 +329,34 @@ { "en" "Gives you the chance to swap positions with your attacker." } + + "conversion" + { + "en" "Conversion" + } + + "conversion description" + { + "en" "Allows you to turn excess money into experience." + } + + "turtle" + { + "en" "Turtle" + } + + "turtle description" + { + "en" "Reduces the damage you take after receiving a headshot." + } + + "pickpocket" + { + "en" "Pickpocket" + } + + "pickpocket description" + { + "en" "Steals some money with every hit." + } } From 488193c3083714b3a017aa5f981cd741f03b9202 Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Fri, 24 Feb 2023 10:39:10 +0100 Subject: [PATCH 03/13] changed turtle to not have a global bool --- scripting/upgrades/smrpg_upgrade_turtle.sp | 32 ++++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/scripting/upgrades/smrpg_upgrade_turtle.sp b/scripting/upgrades/smrpg_upgrade_turtle.sp index b120adf..12dd277 100644 --- a/scripting/upgrades/smrpg_upgrade_turtle.sp +++ b/scripting/upgrades/smrpg_upgrade_turtle.sp @@ -14,7 +14,9 @@ ConVar g_hCVPercent; ConVar g_hCVDuration; -bool turtlemode; + +Handle g_turtleTimers[65]; +bool g_turtleMode[65]; public Plugin myinfo = { @@ -97,7 +99,7 @@ public void SMRPG_TranslateUpgrade(int client, const char[] shortname, Translati public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float damage, int damagetype, int ammotype, int hitbox, int hitgroup) { // Check if the victim is a player and if the last hit was a headshot. - if (IsClientInGame(victim) && hitgroup == 1 && hitbox == 12 && turtlemode == false) + if (IsClientInGame(victim) && hitgroup == 1 && hitbox == 12) { // Check if the victim has the "turtle" skill. int iLevel = SMRPG_GetClientUpgradeLevel(victim, "turtle"); @@ -105,9 +107,12 @@ public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float { // Activate "turtlemode" for the player SetTurtlemode(victim, true); - // Schedule a timer to deactivate "turtlemode" after x seconds + // Find out how long the player will be protected float turtleDuration = float(iLevel) * g_hCVDuration.FloatValue; - CreateTimer(turtleDuration, RemoveTurtleMode, victim, TIMER_FLAG_NO_MAPCHANGE); + if (g_turtleTimers[victim] != INVALID_HANDLE) + return; + // Schedule a timer to deactivate "turtlemode" after x seconds + g_turtleTimers[victim] = CreateTimer(turtleDuration, RemoveTurtleMode, victim, TIMER_FLAG_NO_MAPCHANGE); } } return; @@ -115,8 +120,9 @@ public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float public Action RemoveTurtleMode(Handle timer, int victim) { // Deactivate "turtlemode" for the player - SetTurtlemode(victim, false); - return Plugin_Handled; + SetTurtlemode(victim, false); + g_turtleTimers[victim] = INVALID_HANDLE; + return Plugin_Handled; } @@ -124,7 +130,7 @@ public Action Hook_OnTakeDamage(int victim, int &attacker, int &inflictor, float float damageForce[3], float damagePosition[3], int damagecustom) { // We need to check if we are in damage reduction mode. - if(turtlemode == false) + if(g_turtleMode[victim] == false) return Plugin_Continue; // SM:RPG is disabled? @@ -160,17 +166,19 @@ public Action Hook_OnTakeDamage(int victim, int &attacker, int &inflictor, float return Plugin_Changed; } + // Turns the Turtlemode on or off. -public void SetTurtlemode(int client, bool bool) +public void SetTurtlemode(int victim, bool bool) { - turtlemode = bool; - if(turtlemode == true) + g_turtleMode[victim] = bool; + + if(g_turtleMode[victim] == true) { - PrintToConsole(client, "You are now in turtlemode!"); + PrintToChat(victim, "You are now in turtlemode!"); } else { - PrintToConsole(client, "You are no longer in turtlemode!"); + PrintToChat(victim, "You are no longer in turtlemode!"); } return; } \ No newline at end of file From e971df7b6aeae395bfa9e493c3a793c676975afb Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Fri, 24 Feb 2023 12:29:12 +0100 Subject: [PATCH 04/13] rm info on pickpocket since it was called on mapstart, rm turtle debug messages --- scripting/upgrades/smrpg_upgrade_pickpocket.sp | 6 ------ scripting/upgrades/smrpg_upgrade_turtle.sp | 8 ++++---- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/scripting/upgrades/smrpg_upgrade_pickpocket.sp b/scripting/upgrades/smrpg_upgrade_pickpocket.sp index 5551fcf..71c3655 100644 --- a/scripting/upgrades/smrpg_upgrade_pickpocket.sp +++ b/scripting/upgrades/smrpg_upgrade_pickpocket.sp @@ -76,12 +76,6 @@ public void OnClientPutInServer(int client) * SM:RPG Upgrade callbacks */ -public void SMRPG_BuySell(int client, UpgradeQueryType type) -{ - // Inform the player that he is now a thief - PrintToChat(client, "You can now steal money by knifing people."); -} - public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) { if(type == TranslationType_Name) diff --git a/scripting/upgrades/smrpg_upgrade_turtle.sp b/scripting/upgrades/smrpg_upgrade_turtle.sp index 12dd277..fe78c82 100644 --- a/scripting/upgrades/smrpg_upgrade_turtle.sp +++ b/scripting/upgrades/smrpg_upgrade_turtle.sp @@ -117,7 +117,7 @@ public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float } return; } - public Action RemoveTurtleMode(Handle timer, int victim) +public Action RemoveTurtleMode(Handle timer, int victim) { // Deactivate "turtlemode" for the player SetTurtlemode(victim, false); @@ -171,14 +171,14 @@ public Action Hook_OnTakeDamage(int victim, int &attacker, int &inflictor, float public void SetTurtlemode(int victim, bool bool) { g_turtleMode[victim] = bool; - + if(g_turtleMode[victim] == true) { - PrintToChat(victim, "You are now in turtlemode!"); + PrintToConsole(victim, "You are now in turtlemode, taking %d%% reduced damage.", RoundToNearest(100*g_hCVPercent.FloatValue * float(SMRPG_GetClientUpgradeLevel(victim, UPGRADE_SHORTNAME)))); } else { - PrintToChat(victim, "You are no longer in turtlemode!"); + PrintToConsole(victim, "You are no longer in turtlemode, taking normal damage."); } return; } \ No newline at end of file From c8ae71cba18d1ca39a6d038c862c78c67b35b9c9 Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Sat, 11 Mar 2023 02:28:23 +0100 Subject: [PATCH 05/13] changed to allow float values --- scripting/smrpg/smrpg_stats.sp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripting/smrpg/smrpg_stats.sp b/scripting/smrpg/smrpg_stats.sp index 17981e4..6fc0b26 100644 --- a/scripting/smrpg/smrpg_stats.sp +++ b/scripting/smrpg/smrpg_stats.sp @@ -86,7 +86,7 @@ int Stats_LvlToExp(int iLevel) if(iLevel <= 1) iExp = g_hCVExpStart.IntValue; else - iExp = iLevel * g_hCVExpInc.IntValue + g_hCVExpStart.IntValue; + iExp = iLevel * RoundToNearest(g_hCVExpInc.FloatValue + g_hCVExpStart.FloatValue); return iExp > g_hCVExpMax.IntValue ? g_hCVExpMax.IntValue : iExp; } @@ -1225,7 +1225,7 @@ float GetWeaponExperience(const char[] sWeapon, WeaponExperienceType type) if(weaponExperience.bonus < 0.0) weaponExperience.bonus = g_hCVExpKillBonus.FloatValue; - switch(type) + switch(WeaponExperience_Damage) { case WeaponExperience_Damage: return weaponExperience.damage; From d50055041a5f14b28f0974fa89c67132be960d15 Mon Sep 17 00:00:00 2001 From: DeewaTT91 Date: Fri, 17 Mar 2023 00:54:18 +0100 Subject: [PATCH 06/13] changed to accept float --- scripting/upgrades/smrpg_upgrade_regen.sp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/upgrades/smrpg_upgrade_regen.sp b/scripting/upgrades/smrpg_upgrade_regen.sp index 5405b68..040474e 100644 --- a/scripting/upgrades/smrpg_upgrade_regen.sp +++ b/scripting/upgrades/smrpg_upgrade_regen.sp @@ -125,7 +125,7 @@ public Action Timer_IncreaseHealth(Handle timer, any userid) if(!SMRPG_RunUpgradeEffect(client, UPGRADE_SHORTNAME)) return Plugin_Continue; // Some other plugin doesn't want this effect to run - int iIncrease = RoundToFloor(g_hCVAmount.FloatValue) + RoundToFloor(g_hCVAmountIncrease.FloatValue * (iLevel - 1)); + int iIncrease = RoundToFloor(g_hCVAmount.FloatValue + g_hCVAmountIncrease.FloatValue * (iLevel - 1)); int iNewHealth = iOldHealth + iIncrease; // Limit the regeneration to the maxhealth. if(iNewHealth > iMaxHealth) From 740469779d8630f3eb14aa695585ab99e1635b46 Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:03:06 +0100 Subject: [PATCH 07/13] Delete smrpg_stats.sp --- scripting/smrpg/smrpg_stats.sp | 1291 -------------------------------- 1 file changed, 1291 deletions(-) delete mode 100644 scripting/smrpg/smrpg_stats.sp diff --git a/scripting/smrpg/smrpg_stats.sp b/scripting/smrpg/smrpg_stats.sp deleted file mode 100644 index 6fc0b26..0000000 --- a/scripting/smrpg/smrpg_stats.sp +++ /dev/null @@ -1,1291 +0,0 @@ -#pragma semicolon 1 -#include -#include - -// Allow to refetch the rank every 20 seconds. -#define RANK_CACHE_UPDATE_INTERVAL 20 - -int g_iCachedRank[MAXPLAYERS+1] = {-1,...}; -int g_iNextCacheUpdate[MAXPLAYERS+1]; -int g_iCachedRankCount = 0; -int g_iNextCacheCountUpdate; - -enum struct SessionStats { - int joinTime; - int joinLevel; - int joinExperience; - int joinCredits; - int joinRank; - bool wantsAutoUpdate; - bool wantsMenuOpen; - bool okToClose; - ArrayList lastExperience; -} - -SessionStats g_iPlayerSessionStartStats[MAXPLAYERS+1]; -bool g_bBackToStatsMenu[MAXPLAYERS+1]; - -Handle g_hfwdOnAddExperience; -Handle g_hfwdOnAddExperiencePost; - -// AFK Handling -enum struct AFKInfo { - float lastPosition[3]; - int startTime; - int spawnTime; - int deathTime; -} -AFKInfo g_PlayerAFKInfo[MAXPLAYERS+1]; -bool g_bPlayerSpawnProtected[MAXPLAYERS+1]; - -// Individual weapon experience settings -StringMap g_hWeaponExperience; - -enum struct WeaponExperienceContainer { - float damage; - float kill; - float bonus; -} - -void RegisterStatsNatives() -{ - // native bool SMRPG_AddClientExperience(int client, int exp, const char[] reason, bool bHideNotice, int other=-1, SMRPG_ExpTranslationCb callback=INVALID_FUNCTION); - CreateNative("SMRPG_AddClientExperience", Native_AddClientExperience); - // native int SMRPG_LevelToExperience(int iLevel); - CreateNative("SMRPG_LevelToExperience", Native_LevelToExperience); - // native int SMRPG_GetClientRank(int client); - CreateNative("SMRPG_GetClientRank", Native_GetClientRank); - // native int SMRPG_GetRankCount(); - CreateNative("SMRPG_GetRankCount", Native_GetRankCount); - - // native void SMRPG_GetTop10Players(SQLQueryCallback callback, any data=0); - CreateNative("SMRPG_GetTop10Players", Native_GetTop10Players); - - // native bool SMRPG_IsClientAFK(int client); - CreateNative("SMRPG_IsClientAFK", Native_IsClientAFK); - // native bool SMRPG_IsClientSpawnProtected(int client); - CreateNative("SMRPG_IsClientSpawnProtected", Native_IsClientSpawnProtected); - - // native float SMRPG_GetWeaponExperience(const char[] sWeapon, WeaponExperienceType type); - CreateNative("SMRPG_GetWeaponExperience", Native_GetWeaponExperience); -} - -void RegisterStatsForwards() -{ - // forward Action SMRPG_OnAddExperience(int client, const char[] reason, int &iExperience, int other); - g_hfwdOnAddExperience = CreateGlobalForward("SMRPG_OnAddExperience", ET_Hook, Param_Cell, Param_String, Param_CellByRef, Param_Cell); - // forward void SMRPG_OnAddExperiencePost(int client, const char[] reason, int iExperience, int other); - g_hfwdOnAddExperiencePost = CreateGlobalForward("SMRPG_OnAddExperiencePost", ET_Ignore, Param_Cell, Param_String, Param_Cell, Param_Cell); -} - -/* Calculate the experience needed for this level */ -int Stats_LvlToExp(int iLevel) -{ - int iExp; - - if(iLevel <= 1) - iExp = g_hCVExpStart.IntValue; - else - iExp = iLevel * RoundToNearest(g_hCVExpInc.FloatValue + g_hCVExpStart.FloatValue); - - return iExp > g_hCVExpMax.IntValue ? g_hCVExpMax.IntValue : iExp; -} - -/* Calculate how many levels to increase by current level and experience */ -int Stats_CalcLvlInc(int iLevel, int iExp) -{ - int iLevelIncrease; - - int iExpRequired = Stats_LvlToExp(iLevel); - while(iExp >= iExpRequired) - { - iLevelIncrease++; - iExp -= iExpRequired; - iExpRequired = Stats_LvlToExp(iLevel+iLevelIncrease); - } - - return iLevelIncrease; -} - -void Stats_PlayerNewLevel(int client, int iLevelIncrease) -{ - int iMaxLevel; - bool bMaxLevelReset; - if(IsFakeClient(client)) - { - iMaxLevel = g_hCVBotMaxlevel.IntValue; - bMaxLevelReset = g_hCVBotMaxlevelReset.BoolValue; - } - else - { - iMaxLevel = g_hCVPlayerMaxlevel.IntValue; - bMaxLevelReset = g_hCVPlayerMaxlevelReset.BoolValue; - } - - // Check if the player reached the maxlevel - if(iMaxLevel > 0) - { - int iNewLevel = GetClientLevel(client) + iLevelIncrease; - // Player surpassed the maxlevel? - if(iNewLevel > iMaxLevel) - { - // Reset him immediately if we want to. - if(bMaxLevelReset) - { - DebugMsg("Player %N has surpassed the maximum level of %d, resetting his stats", client, iMaxLevel); - Client_PrintToChatAll(false, "%t", "Player reached maxlevel", client, iMaxLevel); - LogMessage("%L surpassed the maximum level of %d, resetting his stats.", client, iMaxLevel); - ResetStats(client); - return; - } - else - { - // Only increase so much until we reach the maxlevel. - iLevelIncrease = iMaxLevel - GetClientLevel(client); - } - } - } - - // Don't do anything, if we don't really have a new level. - if(iLevelIncrease <= 0) - return; - - // Make sure to keep the experience he gained in addition to the needed exp for the levels. - int iExperience = GetClientExperience(client); - for(int i=0;i 1) - { - bool bAllAFK; - int iTeam; - for(int i=1;i<=MaxClients;i++) - { - if(IsClientInGame(i)) - { - if(IsFakeClient(i) && !bBotEnable) - continue; - - iTeam = GetClientTeam(i); - // This is an enemy? - if(iTeam > 1 && iTeam != iMyTeam) - { - // This enemy isn't afk? Add experience then. - if(!IsClientAFK(i)) - { - bAllAFK = false; - break; - } - else - { - bAllAFK = true; - } - } - } - } - - // Don't count any experience, if all players in the opposite team are AFK. - if(bAllAFK) - return false; - } - } - } - - // Don't give the players any more exp when they already reached the maxlevel. - int iMaxlevel; - if(IsFakeClient(client)) - iMaxlevel = g_hCVBotMaxlevel.IntValue; - else - iMaxlevel = g_hCVPlayerMaxlevel.IntValue; - - if(iMaxlevel > 0 && GetClientLevel(client) >= iMaxlevel) - return false; - - // Handle experience with bots - if(other > 0 && other <= MaxClients && IsClientInGame(other)) - { - bool bClientBot = IsFakeClient(client); - bool bOtherBot = IsFakeClient(other); - if(bClientBot && bOtherBot) - { - if(!g_hCVBotKillBot.BoolValue) - return false; - } - else if(bClientBot && !bOtherBot) - { - if(!g_hCVBotKillPlayer.BoolValue) - return false; - } - else if(!bClientBot && bOtherBot) - { - if(!g_hCVPlayerKillBot.BoolValue) - return false; - } - } - - // See if some other plugin doesn't like this. - if(Stats_CallOnExperienceForward(client, sReason, iExperience, other) > Plugin_Changed) - return false; - - SetClientExperience(client, GetClientExperience(client) + iExperience); - - int iExpRequired = Stats_LvlToExp(GetClientLevel(client)); - - if(GetClientExperience(client) >= iExpRequired) - Stats_PlayerNewLevel(client, Stats_CalcLvlInc(GetClientLevel(client), GetClientExperience(client))); - - Stats_CallOnExperiencePostForward(client, sReason, iExperience, other); - - if(!bHideNotice && g_hCVExpNotice.BoolValue) - PrintHintText(client, "%t", "Experience Gained Hintbox", iExperience, GetClientExperience(client), Stats_LvlToExp(GetClientLevel(client))); - - return true; -} - -void Stats_PlayerDamage(int attacker, int victim, float fDamage, const char[] sWeapon) -{ - if(!g_hCVEnable.BoolValue) - return; - - // Don't give the attacker any exp when his victim was afk. - if(IsClientAFK(victim)) - return; - - // Don't give the attacker any exp when his victim just spawned and didn't do anything at all yet. - if(IsClientSpawnProtected(victim)) - return; - - // Ignore teamattack if not FFA - if(!g_hCVFFA.BoolValue && GetClientTeam(attacker) == GetClientTeam(victim)) - return; - - int iExp = RoundToCeil(fDamage * GetWeaponExperience(sWeapon, WeaponExperience_Damage)); - - SMRPG_AddClientExperience(attacker, iExp, ExperienceReason_PlayerHurt, true, victim); -} - -void Stats_PlayerKill(int attacker, int victim, const char[] sWeapon) -{ - // Ignore suicide. - if(attacker == victim) - return; - - if(!g_hCVEnable.BoolValue) - return; - - // Don't give the attacker any exp when his victim was afk. - if(IsClientAFK(victim)) - return; - - // Don't give the attacker any exp when his victim just spawned and didn't do anything at all yet. - if(IsClientSpawnProtected(victim)) - return; - - // Ignore teamattack if not FFA - if(!g_hCVFFA.BoolValue && GetClientTeam(attacker) == GetClientTeam(victim)) - return; - - int iExp = RoundToCeil(GetClientLevel(victim) * GetWeaponExperience(sWeapon, WeaponExperience_Kill) + GetWeaponExperience(sWeapon, WeaponExperience_Bonus)); - int iExpMax = g_hCVExpKillMax.IntValue; - // Limit the possible experience to this. - if(iExpMax > 0 && iExp > iExpMax) - iExp = iExpMax; - - SMRPG_AddClientExperience(attacker, iExp, ExperienceReason_PlayerKill, false, victim); -} - -void Stats_WinningTeam(int iTeam) -{ - if(!g_hCVEnable.BoolValue) - return; - - float fTeamRatio; - if(iTeam == 2) - fTeamRatio = SMRPG_TeamRatio(3); - else if(iTeam == 3) - fTeamRatio = SMRPG_TeamRatio(2); - else - return; - - int iExperience; - for(int i=1;i<=MaxClients;i++) - { - if(IsClientInGame(i) && GetClientTeam(i) == iTeam) - { - iExperience = RoundToCeil(float(Stats_LvlToExp(GetClientLevel(i))) * g_hCVExpTeamwin.FloatValue * fTeamRatio); - SMRPG_AddClientExperience(i, iExperience, ExperienceReason_RoundEnd, false, -1); - } - } -} - -// forward Action SMRPG_OnAddExperience(int client, const char[] reason, int &iExperience, int other); -Action Stats_CallOnExperienceForward(int client, const char[] sReason, int &iExperience, int other) -{ - Action result; - Call_StartForward(g_hfwdOnAddExperience); - Call_PushCell(client); - Call_PushString(sReason); - Call_PushCellRef(iExperience); - Call_PushCell(other); - Call_Finish(result); - return result; -} - -// forward void SMRPG_OnAddExperiencePost(int client, const char[] reason, int iExperience, int other); -void Stats_CallOnExperiencePostForward(int client, const char[] sReason, int iExperience, int other) -{ - Call_StartForward(g_hfwdOnAddExperiencePost); - Call_PushCell(client); - Call_PushString(sReason); - Call_PushCell(iExperience); - Call_PushCell(other); - Call_Finish(); -} - -// AFK Handling -void StartAFKChecker() -{ - CreateTimer(0.5, Timer_CheckAFKPlayers, _, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); -} - -public Action Timer_CheckAFKPlayers(Handle timer) -{ - float fOrigin[3], fLastPosition[3]; - for(int i=1;i<=MaxClients;i++) - { - if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) > 1) - { - GetClientAbsOrigin(i, fOrigin); - - // See if the player just spawned.. - if(g_PlayerAFKInfo[i].spawnTime > 0) - { - int iDifference = GetTime() - g_PlayerAFKInfo[i].spawnTime; - // The player spawned 2 seconds ago. He's now ready to be checked for being afk again. - if(iDifference > 2) - { - g_PlayerAFKInfo[i].spawnTime = 0; - if(g_PlayerAFKInfo[i].startTime > 0) - g_PlayerAFKInfo[i].startTime += iDifference; - Array_Copy(fOrigin, g_PlayerAFKInfo[i].lastPosition, 3); - } - continue; - } - - // See if we need to subtract some time while he was dead. - if(g_PlayerAFKInfo[i].deathTime > 0) - { - if(g_PlayerAFKInfo[i].startTime > 0) - g_PlayerAFKInfo[i].startTime += GetTime() - g_PlayerAFKInfo[i].deathTime; - g_PlayerAFKInfo[i].deathTime = 0; - } - - Array_Copy(g_PlayerAFKInfo[i].lastPosition, fLastPosition, 3); - if(Math_VectorsEqual(fOrigin, fLastPosition, 1.0)) - { - if(g_PlayerAFKInfo[i].startTime == 0) - g_PlayerAFKInfo[i].startTime = GetTime(); - } - else - { - g_PlayerAFKInfo[i].startTime = 0; - } - - Array_Copy(fOrigin, g_PlayerAFKInfo[i].lastPosition, 3); - } - } - - return Plugin_Continue; -} - -bool IsClientAFK(int client) -{ - if(g_PlayerAFKInfo[client].startTime == 0) - return false; - - int iAFKTime = g_hCVAFKTime.IntValue; - if(iAFKTime <= 0) - return false; - - if((GetTime() - g_PlayerAFKInfo[client].startTime) > iAFKTime) - return true; - return false; -} - -void ResetAFKPlayer(int client) -{ - g_PlayerAFKInfo[client].startTime = 0; - g_PlayerAFKInfo[client].spawnTime = 0; - g_PlayerAFKInfo[client].deathTime = 0; - Array_Copy(view_as({0.0,0.0,0.0}), g_PlayerAFKInfo[client].lastPosition, 3); -} - -// Spawn Protection handling -bool IsClientSpawnProtected(int client) -{ - if(!g_hCVSpawnProtect.BoolValue) - return false; - return g_bPlayerSpawnProtected[client]; -} - -void ResetSpawnProtection(int client) -{ - g_bPlayerSpawnProtected[client] = false; -} - -/** - * Native Callbacks - */ -// native bool SMRPG_AddClientExperience(int client, int &exp, const char[] reason, bool bHideNotice, int other=-1, SMRPG_ExpTranslationCb callback=INVALID_FUNCTION); -public int Native_AddClientExperience(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - if(client < 0 || client > MaxClients) - { - ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d.", client); - return false; - } - - int iExperience = GetNativeCellRef(2); - int iLen; - GetNativeStringLength(3, iLen); - char[] sReason = new char[iLen+1]; - GetNativeString(3, sReason, iLen+1); - - bool bHideNotice = view_as(GetNativeCell(4)); - int other = GetNativeCell(5); - Function translationCallback = GetNativeFunction(6); - - int iOriginalExperience = iExperience; - // TODO: Expose bIgnoreChecks parameter. - bool bAdded = Stats_AddExperience(client, iExperience, sReason, bHideNotice, other); - if(iOriginalExperience != iExperience) - SetNativeCellRef(2, iExperience); - - if(bAdded && !IsFakeClient(client)) - { - char sTranslatedReason[256]; - strcopy(sTranslatedReason, sizeof(sTranslatedReason), sReason); - if(translationCallback != INVALID_FUNCTION) - { - // functag SMRPG_ExpTranslationCb(client, const char[] reason, iExperience, other, char[] buffer, maxlen); - Call_StartFunction(plugin, translationCallback); - Call_PushCell(client); - Call_PushString(sReason); - Call_PushCell(iExperience); - Call_PushCell(other); - Call_PushStringEx(sTranslatedReason, sizeof(sTranslatedReason), SM_PARAM_STRING_UTF8|SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); - Call_PushCell(sizeof(sTranslatedReason)); - Call_Finish(); - } - - // String wasn't changed or no callback set? - if(StrEqual(sTranslatedReason, sReason)) - { - if(other > 0 && other <= MaxClients) - Format(sTranslatedReason, sizeof(sTranslatedReason), "%T", "Experience Reason Other Client", client, iExperience, sReason, other); - else - Format(sTranslatedReason, sizeof(sTranslatedReason), "%T", "Experience Reason General", client, iExperience, sReason); - } - - InsertSessionExperienceString(client, sTranslatedReason); - } - - return bAdded; -} - -public int Native_LevelToExperience(Handle plugin, int numParams) -{ - int iLevel = GetNativeCell(1); - return Stats_LvlToExp(iLevel); -} - -public int Native_GetClientRank(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - if(client < 0 || client > MaxClients) - return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d.", client); - - return GetClientRank(client); -} - -public int Native_GetRankCount(Handle plugin, int numParams) -{ - return GetRankCount(); -} - -public int Native_IsClientAFK(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - if(client < 0 || client > MaxClients) - return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d.", client); - - return IsClientAFK(client); -} - -public int Native_IsClientSpawnProtected(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - if(client < 0 || client > MaxClients) - return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d.", client); - - return IsClientSpawnProtected(client); -} - -public int Native_GetTop10Players(Handle plugin, int numParams) -{ - Function callback = GetNativeFunction(1); - int data = GetNativeCell(2); - - DataPack hData = new DataPack(); - hData.WriteCell(view_as(plugin)); - hData.WriteFunction(callback); - hData.WriteCell(data); - - char sQuery[128]; - Format(sQuery, sizeof(sQuery), "SELECT name, level, experience, credits FROM %s ORDER BY level DESC, experience DESC LIMIT 10", TBL_PLAYERS); - g_hDatabase.Query(SQL_GetTop10Native, sQuery, hData); - return 0; -} - -public void SQL_GetTop10Native(Database db, DBResultSet results, const char[] error, DataPack data) -{ - data.Reset(); - Handle hPlugin = view_as(data.ReadCell()); - Function callback = data.ReadFunction(); - int extraData = data.ReadCell(); - delete data; - - // Don't care if the calling plugin is gone. - if(!IsValidPlugin(hPlugin)) - return; - - Call_StartFunction(hPlugin, callback); - Call_PushCell(INVALID_HANDLE); - Call_PushCell(results); - Call_PushString(error); - Call_PushCell(extraData); - Call_Finish(); -} - -// native float SMRPG_GetWeaponExperience(const char[] sWeapon, WeaponExperienceType type); -public int Native_GetWeaponExperience(Handle plugin, int numParams) -{ - char sWeapon[64]; - GetNativeString(1, sWeapon, sizeof(sWeapon)); - WeaponExperienceType type = view_as(GetNativeCell(2)); - - return view_as(GetWeaponExperience(sWeapon, type)); -} - -// rpgsession handling -void InitPlayerSessionStartStats(int client) -{ - g_iPlayerSessionStartStats[client].joinTime = GetTime(); - g_iPlayerSessionStartStats[client].joinLevel = GetClientLevel(client); - g_iPlayerSessionStartStats[client].joinExperience = GetClientExperience(client); - g_iPlayerSessionStartStats[client].joinCredits = GetClientCredits(client); - g_iPlayerSessionStartStats[client].joinRank = -1; - g_iPlayerSessionStartStats[client].wantsAutoUpdate = false; - g_iPlayerSessionStartStats[client].wantsMenuOpen = false; - g_iPlayerSessionStartStats[client].okToClose = false; - - ArrayList hLastExperience = new ArrayList(ByteCountToCells(256)); - hLastExperience.Resize(g_hCVLastExperienceCount.IntValue); - hLastExperience.SetString(0, ""); - g_iPlayerSessionStartStats[client].lastExperience = hLastExperience; -} - -void ResetPlayerSessionStats(int client) -{ - g_iPlayerSessionStartStats[client].joinTime = 0; - g_iPlayerSessionStartStats[client].joinLevel = 0; - g_iPlayerSessionStartStats[client].joinExperience = 0; - g_iPlayerSessionStartStats[client].joinCredits = 0; - g_iPlayerSessionStartStats[client].joinRank = -1; - g_iPlayerSessionStartStats[client].wantsAutoUpdate = false; - g_iPlayerSessionStartStats[client].wantsMenuOpen = false; - g_iPlayerSessionStartStats[client].okToClose = false; - ClearHandle(g_iPlayerSessionStartStats[client].lastExperience); -} - -// Use our own forward to initialize the session info :) -public void SMRPG_OnClientLoaded(int client) -{ - // Only set it once and leave it that way until he really disconnects. - if(g_iPlayerSessionStartStats[client].joinTime == 0) - InitPlayerSessionStartStats(client); -} - -void InsertSessionExperienceString(int client, const char[] sExperience) -{ - ArrayList hLastExperience = g_iPlayerSessionStartStats[client].lastExperience; - // Not loaded yet.. - if(hLastExperience == null) - return; - - // Insert the string at the start of the array! - hLastExperience.ShiftUp(0); - hLastExperience.SetString(0, sExperience); -} - -public void ConVar_LastExperienceCountChanged(ConVar convar, const char[] oldValue, const char[] newValue) -{ - // Apply the new size immediately. - for(int i=1;i<=MaxClients;i++) - { - if(g_iPlayerSessionStartStats[i].joinTime > 0) - g_iPlayerSessionStartStats[i].lastExperience.Resize(convar.IntValue); - } -} - -void StartSessionMenuUpdater() -{ - CreateTimer(1.0, Timer_UpdateSessionMenus, _, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT); -} - -public Action Timer_UpdateSessionMenus(Handle timer) -{ - for(int i=1;i<=MaxClients;i++) - { - // Refresh the contents of the menu here. - if(IsClientInGame(i) && !IsFakeClient(i) && g_iPlayerSessionStartStats[i].wantsMenuOpen && g_iPlayerSessionStartStats[i].wantsAutoUpdate) - DisplaySessionStatsMenu(i); - } - - return Plugin_Continue; -} - -void DisplaySessionStatsMenu(int client) -{ - Panel hPanel = new Panel(); - - char sBuffer[128]; - Format(sBuffer, sizeof(sBuffer), "%T", "Stats", client); - hPanel.DrawItem(sBuffer); - - Format(sBuffer, sizeof(sBuffer), " %T", "Level", client, GetClientLevel(client)); - hPanel.DrawText(sBuffer); - Format(sBuffer, sizeof(sBuffer), " %T", "Experience short", client, GetClientExperience(client), Stats_LvlToExp(GetClientLevel(client))); - hPanel.DrawText(sBuffer); - Format(sBuffer, sizeof(sBuffer), " %T", "Credits", client, GetClientCredits(client)); - hPanel.DrawText(sBuffer); - Format(sBuffer, sizeof(sBuffer), " %T", "Rank", client, GetClientRank(client), GetRankCount()); - hPanel.DrawText(sBuffer); - - Format(sBuffer, sizeof(sBuffer), "%T", "Session", client); - hPanel.DrawItem(sBuffer); - - SecondsToString(sBuffer, sizeof(sBuffer), GetTime()-g_iPlayerSessionStartStats[client].joinTime, false); - Format(sBuffer, sizeof(sBuffer), " %T", "Playtime", client, sBuffer); - hPanel.DrawText(sBuffer); - - int iChangedLevels = GetClientLevel(client) - g_iPlayerSessionStartStats[client].joinLevel; - Format(sBuffer, sizeof(sBuffer), " %T: %s%d", "Changed level", client, iChangedLevels>0?"+":"", iChangedLevels); - hPanel.DrawText(sBuffer); - - // Need to calculate the total earned experience. - int iEarnedExperience = GetClientExperience(client) - g_iPlayerSessionStartStats[client].joinExperience; - for(int i=0;i0?"+":"", iEarnedExperience); - hPanel.DrawText(sBuffer); - - int iBuffer = GetClientCredits(client) - g_iPlayerSessionStartStats[client].joinCredits; - Format(sBuffer, sizeof(sBuffer), " %T: %s%d", "Changed credits", client, iBuffer>0?"+":"", iBuffer); - hPanel.DrawText(sBuffer); - - if(g_iPlayerSessionStartStats[client].joinRank != -1) - { - iBuffer = g_iPlayerSessionStartStats[client].joinRank - GetClientRank(client); - Format(sBuffer, sizeof(sBuffer), " %T: %s%d", "Changed rank", client, iBuffer>0?"+":"", iBuffer); - hPanel.DrawText(sBuffer); - } - - hPanel.DrawItem("", ITEMDRAW_SPACER); - - Format(sBuffer, sizeof(sBuffer), "%T: %T", "Auto refresh panel", client, (g_iPlayerSessionStartStats[client].wantsAutoUpdate?"Yes":"No"), client); - hPanel.DrawItem(sBuffer); - - Format(sBuffer, sizeof(sBuffer), "%T", "Last Experience", client); - hPanel.DrawItem(sBuffer); - - // The old menu is closed when we open the new one. - // The logic here is like this: - // We want to stop redisplaying the session menu, if the menu was closed gracefully or was interrupted by a different menu. - // If the old menu is currently displaying (callback was not called yet) we don't want it to stay closed when we display it again. - // So we set OKToClose to true, so it doesn't set WantsMenuOpen to false as if the menu was closed by an interrupting menu. - // That way the menu stays open and is refreshed every second while staying closed if the player closes it or some other menu is displayed over it. - if(g_iPlayerSessionStartStats[client].wantsMenuOpen) - g_iPlayerSessionStartStats[client].okToClose = true; - g_iPlayerSessionStartStats[client].wantsMenuOpen = true; - - hPanel.Send(client, Panel_HandleSessionMenu, MENU_TIME_FOREVER); - delete hPanel; -} - -public int Panel_HandleSessionMenu(Menu menu, MenuAction action, int param1, int param2) -{ - if(action == MenuAction_Select) - { - g_iPlayerSessionStartStats[param1].wantsMenuOpen = false; - g_iPlayerSessionStartStats[param1].okToClose = false; - - // Toggle the auto update - if(param2 == 4) - { - g_iPlayerSessionStartStats[param1].wantsAutoUpdate = !g_iPlayerSessionStartStats[param1].wantsAutoUpdate; - DisplaySessionStatsMenu(param1); - return 0; - } - else if(param2 == 5) - { - DisplaySessionLastExperienceMenu(param1, false); - } - } - else if(action == MenuAction_Cancel) - { - - if(!g_iPlayerSessionStartStats[param1].okToClose) - g_iPlayerSessionStartStats[param1].wantsMenuOpen = false; - g_iPlayerSessionStartStats[param1].okToClose = false; - } - return 0; -} - -void DisplaySessionLastExperienceMenu(int client, bool bBackToStatsMenu) -{ - ArrayList hLastExperience = g_iPlayerSessionStartStats[client].lastExperience; - // Player not loaded yet. - if(hLastExperience == null) - return; - - // Remember what the back button in the menu should do. - g_bBackToStatsMenu[client] = bBackToStatsMenu; - - Menu hMenu = new Menu(Menu_HandleLastExperience); - hMenu.SetTitle("%t: %N", "Last Experience", client); - hMenu.ExitBackButton = true; - - int iSize = hLastExperience.Length; - char sBuffer[256]; - for(int i=0;i %d OR (level = %d AND experience > %d)", TBL_PLAYERS, GetClientLevel(client), GetClientLevel(client), GetClientExperience(client)); - g_hDatabase.Query(SQL_GetClientRank, sQuery, GetClientUserId(client)); - g_iNextCacheUpdate[client] = GetTime() + RANK_CACHE_UPDATE_INTERVAL; -} - -int GetClientRank(int client) -{ - if(IsFakeClient(client)) - return -1; - - // Only update the cache, if we actually used it for a while. - if(g_iNextCacheUpdate[client] < GetTime()) - UpdateClientRank(client); - return g_iCachedRank[client]; -} - -void ClearClientRankCache(int client) -{ - g_iCachedRank[client] = -1; - g_iNextCacheUpdate[client] = 0; -} - -public void SQL_GetClientRank(Database db, DBResultSet results, const char[] error, any userid) -{ - int client = GetClientOfUserId(userid); - if(!client) - return; - - if(results == null) - { - LogError("Unable to get player rank (%s)", error); - return; - } - - if(!results.FetchRow()) - return; - - g_iCachedRank[client] = results.FetchInt(0) + 1; // +1 since the query returns the count, not the rank - - // Save the first time we fetch the rank for him. - if(g_iPlayerSessionStartStats[client].joinRank == -1) - g_iPlayerSessionStartStats[client].joinRank = g_iCachedRank[client]; -} - -void UpdateRankCount() -{ - if(!g_hDatabase) - return; - - char sQuery[128]; - Format(sQuery, sizeof(sQuery), "SELECT COUNT(*) FROM %s", TBL_PLAYERS); - g_hDatabase.Query(SQL_GetRankCount, sQuery); - g_iNextCacheCountUpdate = GetTime() + RANK_CACHE_UPDATE_INTERVAL; -} - -int GetRankCount() -{ - // Only update the cache, if we actually used it for a while. - if(g_iNextCacheCountUpdate < GetTime()) - UpdateRankCount(); - - if(g_iCachedRankCount > 0) - return g_iCachedRankCount; - - return 0; -} - -public void SQL_GetRankCount(Database db, DBResultSet results, const char[] error, any data) -{ - if(results == null) - { - LogError("Unable to get player rank count (%s)", error); - return; - } - - if(!results.FetchRow()) - return; - - g_iCachedRankCount = results.FetchInt(0); - - PlayerInfo info; - for(int i=1;i<=MaxClients;i++) - { - if(IsClientInGame(i) && !IsFakeClient(i)) - { - GetClientRPGInfo(i, info); - if(info.dbId < 0) - g_iCachedRankCount++; /* accounts for players not saved in the db */ - } - } -} - -void PrintRankToChat(int client, int sendto) -{ - if(sendto == -1) - Client_PrintToChatAll(false, "%t", "rpgrank", client, GetClientLevel(client), GetClientRank(client), GetRankCount(), GetClientExperience(client), Stats_LvlToExp(GetClientLevel(client)), GetClientCredits(client)); - else - Client_PrintToChat(sendto, false, "%t", "rpgrank", client, GetClientLevel(client), GetClientRank(client), GetRankCount(), GetClientExperience(client), Stats_LvlToExp(GetClientLevel(client)), GetClientCredits(client)); -} - -stock void DisplayTop10Menu(int client) -{ - if(!g_hDatabase) - return; // TODO: Print message about database problems. - - char sQuery[128]; - Format(sQuery, sizeof(sQuery), "SELECT name, level, experience, credits FROM %s ORDER BY level DESC, experience DESC LIMIT 10", TBL_PLAYERS); - g_hDatabase.Query(SQL_GetTop10, sQuery, GetClientUserId(client)); -} - -public void SQL_GetTop10(Database db, DBResultSet results, const char[] error, any userid) -{ - int client = GetClientOfUserId(userid); - if(!client) - return; - - if(results == null) - { - LogError("Unable to get player top10 (%s)", error); - return; - } - - char sBuffer[128]; - Format(sBuffer, sizeof(sBuffer), "%T\n-----\n", "Top 10 Players", client); - - Panel hPanel = new Panel(); - hPanel.SetTitle(sBuffer); - - int iIndex = 1; - while(results.MoreRows) - { - if(!results.FetchRow()) - continue; - - results.FetchString(0, sBuffer, sizeof(sBuffer)); - Format(sBuffer, sizeof(sBuffer), "%d. %s Lvl: %d Exp: %d Cr: %d", iIndex++, sBuffer, results.FetchInt(1), results.FetchInt(2), results.FetchInt(3)); - hPanel.DrawText(sBuffer); - } - - // Let the panel close on any number - hPanel.SetKeys(255); - - hPanel.Send(client, Panel_DoNothing, MENU_TIME_FOREVER); - delete hPanel; -} - -public int Panel_DoNothing(Menu menu, MenuAction action, int param1, int param2) -{ - return 0; -} - -void DisplayNextPlayersInRanking(int client) -{ - if(!g_hDatabase) - return; // TODO: Print message about database problems. - - char sQuery[512]; - Format(sQuery, sizeof(sQuery), "SELECT player_id, name, level, experience, credits, (SELECT COUNT(*) FROM %s ps WHERE p.level < ps.level OR (p.level = ps.level AND p.experience < ps.experience))+1 AS rank FROM %s p WHERE level > %d OR (level = %d AND experience >= %d) ORDER BY level ASC, experience ASC LIMIT 20", TBL_PLAYERS, TBL_PLAYERS, GetClientLevel(client), GetClientLevel(client), GetClientExperience(client)); - g_hDatabase.Query(SQL_GetNext10, sQuery, GetClientUserId(client)); -} - -enum struct NextPlayersSorting { - int DBID; - int rank; - int level; - int exp; - int credits; - char name[MAX_NAME_LENGTH]; -} - -public void SQL_GetNext10(Database db, DBResultSet results, const char[] error, any userid) -{ - int client = GetClientOfUserId(userid); - if(!client) - return; - - if(results == null) - { - LogError("Unable to get the next 20 players in front of the current rank of a player (%s)", error); - return; - } - - char sBuffer[128]; - Format(sBuffer, sizeof(sBuffer), "%T\n-----\n", "Next ranked players", client); - - NextPlayersSorting nextCache[20]; - int iCount; - - Panel hPanel = new Panel(); - hPanel.SetTitle(sBuffer); - - while(results.MoreRows) - { - if(!results.FetchRow()) - continue; - - results.FetchString(1, nextCache[iCount].name, MAX_NAME_LENGTH); - nextCache[iCount].DBID = results.FetchInt(0); - nextCache[iCount].level = results.FetchInt(2); - nextCache[iCount].exp = results.FetchInt(3); - nextCache[iCount].credits = results.FetchInt(4); - nextCache[iCount].rank = results.FetchInt(5); - iCount++; - } - - // TODO: Account for currently ingame players that got above us in the ranking and aren't in the db yet, so they aren't in the result set of the query. - - // See if some players are currently connected and possibly have newer stats in the cache than stored in the db - int iLocalPlayer; - for(int i=0;i 10 ? 10 : iCount; - for(int i=0;i0;i++) - { - if(nextCache[i].level < GetClientLevel(client) || (nextCache[i].level == GetClientLevel(client) && nextCache[i].exp < GetClientExperience(client))) - continue; - - Format(sBuffer, sizeof(sBuffer), "%d. %s Lvl: %d Exp: %d Cr: %d", nextCache[i].rank, nextCache[i].name, nextCache[i].level, nextCache[i].exp, nextCache[i].credits); - hPanel.DrawText(sBuffer); - iNeeded--; - } - - // Let the panel close on any number - hPanel.SetKeys(255); - - hPanel.Send(client, Panel_DoNothing, MENU_TIME_FOREVER); - delete hPanel; -} - -// Sort players ascending by level and experience -public int Sort2D_NextPlayers(int[] elem1, int[] elem2, const int[][] array, Handle hndl) -{ - if(elem1[NextPlayersSorting::level] > elem2[NextPlayersSorting::level]) - return 1; - - if(elem1[NextPlayersSorting::level] == elem2[NextPlayersSorting::level] && elem1[NextPlayersSorting::exp] > elem2[NextPlayersSorting::exp]) - return 1; - - return -1; -} - -/** - * Extra experience per weapon parsing - */ -void InitWeaponExperienceConfig() -{ - g_hWeaponExperience = new StringMap(); -} - -bool ReadWeaponExperienceConfig() -{ - // Clear all the previous configs first. - g_hWeaponExperience.Clear(); - - char sPath[PLATFORM_MAX_PATH]; - BuildPath(Path_SM, sPath, sizeof(sPath), "configs/smrpg/weapon_experience.cfg"); - - if(!FileExists(sPath)) - return false; - - KeyValues hKV = CreateKeyValues("SMRPGWeaponExperience"); - if(!hKV.ImportFromFile(sPath)) - { - delete hKV; - return false; - } - - if(!hKV.GotoFirstSubKey()) - { - delete hKV; - return false; - } - - char sWeapon[64]; - WeaponExperienceContainer weaponExperience; - do { - hKV.GetSectionName(sWeapon, sizeof(sWeapon)); - RemovePrefixFromString("weapon_", sWeapon, sWeapon, sizeof(sWeapon)); - - weaponExperience.damage = hKV.GetFloat("exp_damage", -1.0); - weaponExperience.kill = hKV.GetFloat("exp_kill", -1.0); - weaponExperience.bonus = hKV.GetFloat("exp_bonus", -1.0); - - g_hWeaponExperience.SetArray(sWeapon, weaponExperience, sizeof(WeaponExperienceContainer)); - - } while(hKV.GotoNextKey()); - - delete hKV; - return true; -} - -float GetWeaponExperience(const char[] sWeapon, WeaponExperienceType type) -{ - WeaponExperienceContainer weaponExperience; - weaponExperience.damage = -1.0; - weaponExperience.kill = -1.0; - weaponExperience.bonus = -1.0; - - char sBuffer[64]; - RemovePrefixFromString("weapon_", sWeapon, sBuffer, sizeof(sBuffer)); - // We default back to the convar values, if this fails. - g_hWeaponExperience.GetArray(sBuffer, weaponExperience, sizeof(WeaponExperienceContainer)); - - // Fall back to default convar values, if unset or invalid. - if(weaponExperience.damage < 0.0) - weaponExperience.damage = g_hCVExpDamage.FloatValue; - if(weaponExperience.kill < 0.0) - weaponExperience.kill = g_hCVExpKill.FloatValue; - if(weaponExperience.bonus < 0.0) - weaponExperience.bonus = g_hCVExpKillBonus.FloatValue; - - switch(WeaponExperience_Damage) - { - case WeaponExperience_Damage: - return weaponExperience.damage; - case WeaponExperience_Kill: - return weaponExperience.kill; - case WeaponExperience_Bonus: - return weaponExperience.bonus; - default: - ThrowError("Unknown WeaponExperienceType: %d", type); - } - return 0.0; -} - -/** - * Helper functions - */ -// Taken from SourceBans 2's sb_bans :) -void SecondsToString(char[] sBuffer, int iLength, int iSecs, bool bTextual = true) -{ - if(bTextual) - { - char sDesc[6][8] = {"mo", "wk", "d", "hr", "min", "sec"}; - int iCount, iDiv[6] = {60 * 60 * 24 * 30, 60 * 60 * 24 * 7, 60 * 60 * 24, 60 * 60, 60, 1}; - sBuffer[0] = '\0'; - - for(int i = 0; i < sizeof(iDiv); i++) - { - if((iCount = iSecs / iDiv[i]) > 0) - { - Format(sBuffer, iLength, "%s%i %s, ", sBuffer, iCount, sDesc[i]); - iSecs %= iDiv[i]; - } - } - sBuffer[strlen(sBuffer) - 2] = '\0'; - } - else - { - int iHours = iSecs / 60 / 60; - iSecs -= iHours * 60 * 60; - int iMins = iSecs / 60; - iSecs %= 60; - Format(sBuffer, iLength, "%02i:%02i:%02i", iHours, iMins, iSecs); - } -} - -// This removes a prefix from a string including anything before the prefix. -// This is useful for TF2's tfweapon_ prefix vs. default weapon_ prefix in other sourcegames. -stock void RemovePrefixFromString(const char[] sPrefix, const char[] sInput, char[] sOutput, int maxlen) -{ - int iPos = StrContains(sInput, sPrefix, false); - // The prefix isn't in the string, just copy the whole string. - if(iPos == -1) - iPos = 0; - // Skip the prefix and all other stuff before it. - else - iPos += strlen(sPrefix); - - // Support for inputstring == outputstring? - char[] sBuffer = new char[maxlen+1]; - strcopy(sBuffer, maxlen, sInput[iPos]); - - strcopy(sOutput, maxlen, sBuffer); -} From 90cb4c6f4362d33e1427d30122ae954de12edf24 Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:03:37 +0100 Subject: [PATCH 08/13] Delete smrpg_upgrade_armorplus_cstrike.sp --- .../smrpg_upgrade_armorplus_cstrike.sp | 209 ------------------ 1 file changed, 209 deletions(-) delete mode 100644 scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp diff --git a/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp deleted file mode 100644 index 920e21c..0000000 --- a/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp +++ /dev/null @@ -1,209 +0,0 @@ -#pragma semicolon 1 -#include -#include - -#pragma newdecls required -#include -#include - -#define UPGRADE_SHORTNAME "armorplus" - -/** Technical maximal armor value in Counter-Strike: Source */ -#define CSS_MAX_ARMOR 127 // m_ArmorValue is a signed byte in the HUD. - -/** Technical maximal armor value in Counter-Strike: Global Offensive */ -#define CSGO_MAX_ARMOR 255 // m_ArmorValue is an unsigned byte - -ConVar g_hCVMaxIncrease; - -// Remember which flavor of Counter-Strike we're running. -bool g_bIsCSGO; - -public Plugin myinfo = -{ - name = "SM:RPG Upgrade > Armor+", - author = "Jannik \"Peace-Maker\" Hartung", - description = "Armor+ upgrade for SM:RPG. Increases player's armor.", - version = SMRPG_VERSION, - url = "http://www.wcfan.de/" -} - -public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) -{ - EngineVersion engine = GetEngineVersion(); - if(engine != Engine_CSS && engine != Engine_CSGO) - { - Format(error, err_max, "This plugin is for use in Counter-Strike games only. Bad engine version %d.", engine); - return APLRes_SilentFailure; - } - g_bIsCSGO = engine == Engine_CSGO; - - RegPluginLibrary("smrpg_armorplus"); - CreateNative("SMRPG_Armor_GetClientMaxArmorEx", Native_GetMaxArmor); - return APLRes_Success; -} - -public void OnPluginStart() -{ - HookEvent("player_spawn", Event_OnPlayerSpawn); - - LoadTranslations("smrpg_stock_upgrades.phrases"); -} - -public void OnPluginEnd() -{ - if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) - SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); -} - -public void OnAllPluginsLoaded() -{ - OnLibraryAdded("smrpg"); -} - -public void OnLibraryAdded(const char[] name) -{ - // Register this upgrade in SM:RPG - if(StrEqual(name, "smrpg")) - { - SMRPG_RegisterUpgradeType("Armor+", UPGRADE_SHORTNAME, "Increases your armor.", 0, true, 5, 10, 10); - SMRPG_SetUpgradeBuySellCallback(UPGRADE_SHORTNAME, SMRPG_BuySell); - SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); - - g_hCVMaxIncrease = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armor_inc", "5", "Armor max increase for each level", 0, true, 1.0); - } -} - -/** - * Event callbacks - */ -public void Event_OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - if(!client) - return; - - // Only change alive players. - if(!IsPlayerAlive(client) || IsClientObserver(client)) - return; - - int iMaxArmor = GetClientMaxArmor(client); - int iArmor = GetClientArmor(client); - if(iArmor == DEFAULT_MAX_ARMOR && iMaxArmor > iArmor) - SetClientArmor(client, iMaxArmor); -} - -public Action CS_OnBuyCommand(int client, const char[] weapon) -{ - // If the client bought a vest, set it to the new maxlimit - if(StrContains(weapon, "vest") != 0) - return Plugin_Continue; - - int iMaxArmor = GetClientMaxArmor(client); - int iArmor = GetClientArmor(client); - if(iArmor < iMaxArmor) - SetClientArmor(client, iMaxArmor); - return Plugin_Continue; -} - -/** - * SM:RPG Upgrade callbacks - */ -public void SMRPG_BuySell(int client, UpgradeQueryType type) -{ - if(!IsClientInGame(client)) - return; - - // Only change alive players. - if(!IsPlayerAlive(client) || IsClientObserver(client)) - return; - - // Are bots allowed to use this upgrade? - if(IsFakeClient(client) && SMRPG_IgnoreBots()) - return; - - int iArmor = GetClientArmor(client); - int iMaxArmor = GetClientMaxArmor(client); - - switch(type) - { - case UpgradeQueryType_Buy: - { - // Client currently had his old maxarmor or more? - // Set him to his new higher maxarmor immediately. - // Don't touch his armor, if he were already damaged. - if(iArmor >= (iMaxArmor - RoundToFloor(g_hCVMaxIncrease.FloatValue))) - SetClientArmor(client, iMaxArmor); - } - case UpgradeQueryType_Sell: - { - // Client had more armor than his new maxarmor? - // Decrease it. - if(iArmor > iMaxArmor) - SetClientArmor(client, iMaxArmor); - } - } -} - -public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) -{ - if(type == TranslationType_Name) - Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); - else if(type == TranslationType_Description) - { - char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; - StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); - Format(translation, maxlen, "%T", sDescriptionKey, client); - } -} - -int GetClientMaxArmor(int client) -{ - int iDefaultMaxArmor = DEFAULT_MAX_ARMOR; - - if(!SMRPG_IsEnabled()) - return iDefaultMaxArmor; - - if(!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) - return iDefaultMaxArmor; - - // Are bots allowed to use this upgrade? - if(IsFakeClient(client) && SMRPG_IgnoreBots()) - return iDefaultMaxArmor; - - // Player didn't buy this upgrade yet. - int iLevel = SMRPG_GetClientUpgradeLevel(client, UPGRADE_SHORTNAME); - if(iLevel <= 0) - return iDefaultMaxArmor; - - int iNewMaxArmor = iDefaultMaxArmor + RoundToFloor(g_hCVMaxIncrease.FloatValue * iLevel); - int iGameMaxArmor = CSS_MAX_ARMOR; - if (g_bIsCSGO) - iGameMaxArmor = CSGO_MAX_ARMOR; - - if(iNewMaxArmor > iGameMaxArmor) - iNewMaxArmor = iGameMaxArmor; - - return iNewMaxArmor; -} - -// Check if the other plugins are ok with setting the armor before doing it. -void SetClientArmor(int client, int armor) -{ - if(!SMRPG_RunUpgradeEffect(client, UPGRADE_SHORTNAME)) - return; // Some other plugin doesn't want this effect to run - - SetEntProp(client, Prop_Send, "m_ArmorValue", armor); -} - -/** - * Native callbacks - */ -public int Native_GetMaxArmor(Handle plugin, int numParams) -{ - int client = GetNativeCell(1); - if(client < 0 || client > MaxClients) - return ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index %d.", client); - - return GetClientMaxArmor(client); -} \ No newline at end of file From 64be3c69b3f3f4c7e97af4870e59a6565b8d49ac Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:03:47 +0100 Subject: [PATCH 09/13] Delete smrpg_upgrade_armorregen_cstrike.sp --- .../smrpg_upgrade_armorregen_cstrike.sp | 153 ------------------ 1 file changed, 153 deletions(-) delete mode 100644 scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp diff --git a/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp deleted file mode 100644 index 479e394..0000000 --- a/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp +++ /dev/null @@ -1,153 +0,0 @@ -#pragma semicolon 1 -#include -#include - -#pragma newdecls required -#include - -#undef REQUIRE_PLUGIN -#include - -#define UPGRADE_SHORTNAME "armorregen" - -ConVar g_hCVAmount; -ConVar g_hCVAmountIncrease; -ConVar g_hCVInterval; -ConVar g_hCVIntervalDecrease; -ConVar g_hCVGiveHelmet; - -Handle g_hRegenerationTimer[MAXPLAYERS+1]; - -public Plugin myinfo = -{ - name = "SM:RPG Upgrade > Armor regeneration", - author = "Jannik \"Peace-Maker\" Hartung", - description = "Armor regeneration upgrade for SM:RPG. Regenerates armor regularly.", - version = SMRPG_VERSION, - url = "http://www.wcfan.de/" -} - -public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) -{ - EngineVersion engine = GetEngineVersion(); - if(engine != Engine_CSS && engine != Engine_CSGO) - { - Format(error, err_max, "This plugin is for use in Counter-Strike games only. Bad engine version %d.", engine); - return APLRes_SilentFailure; - } - return APLRes_Success; -} - -public void OnPluginStart() -{ - LoadTranslations("smrpg_stock_upgrades.phrases"); -} - -public void OnPluginEnd() -{ - if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) - SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); -} - -public void OnAllPluginsLoaded() -{ - OnLibraryAdded("smrpg"); -} - -public void OnLibraryAdded(const char[] name) -{ - // Register this upgrade in SM:RPG - if(StrEqual(name, "smrpg")) - { - SMRPG_RegisterUpgradeType("Armor regeneration", UPGRADE_SHORTNAME, "Regenerates armor regularly.", 0, true, 5, 5, 10); - SMRPG_SetUpgradeBuySellCallback(UPGRADE_SHORTNAME, SMRPG_BuySell); - SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); - - g_hCVAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armorregen_amount", "1", "Specify the base amount of armor which is regenerated at the first level.", 0, true, 0.1); - g_hCVAmountIncrease = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armorregen_amount_inc", "1", "Additional armor to regenerate each interval multiplied by level. (base + inc * (level-1))", 0, true, 0.0); - g_hCVInterval = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armorregen_interval", "1.0", "Specify the base interval rate at which armor is regenerated in seconds at the first level.", 0, true, 0.1); - g_hCVIntervalDecrease = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armorregen_interval_dec", "0.0", "How much is the base interval reduced for each level?", 0, true, 0.0); - g_hCVGiveHelmet = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_armorregen_give_helmet", "1", "Give players helmet after they regenerated to 100% of their armor?", 0, true, 0.0, true, 1.0); - } -} - -public void OnClientDisconnect(int client) -{ - ClearHandle(g_hRegenerationTimer[client]); -} - -/** - * SM:RPG Upgrade callbacks - */ -public void SMRPG_BuySell(int client, UpgradeQueryType type) -{ - // Change timer interval to correct interval for new level. - ClearHandle(g_hRegenerationTimer[client]); - int iLevel = SMRPG_GetClientUpgradeLevel(client, UPGRADE_SHORTNAME); - if(iLevel <= 0) - return; - - float fInterval = g_hCVInterval.FloatValue - g_hCVIntervalDecrease.FloatValue * (iLevel - 1); - g_hRegenerationTimer[client] = CreateTimer(fInterval, Timer_IncreaseArmor, GetClientUserId(client), TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); -} - -public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) -{ - if(type == TranslationType_Name) - Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); - else if(type == TranslationType_Description) - { - char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; - StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); - Format(translation, maxlen, "%T", sDescriptionKey, client); - } -} - -public Action Timer_IncreaseArmor(Handle timer, any userid) -{ - int client = GetClientOfUserId(userid); - if(!client) - return Plugin_Stop; - - if(!SMRPG_IsEnabled()) - return Plugin_Continue; - - if(!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) - return Plugin_Continue; - - // Are bots allowed to use this upgrade? - if(SMRPG_IgnoreBots() && IsFakeClient(client)) - return Plugin_Continue; - - // Only change alive players. - if(!IsClientInGame(client) || !IsPlayerAlive(client) || IsClientObserver(client)) - return Plugin_Continue; - - // Player didn't buy this upgrade yet. - int iLevel = SMRPG_GetClientUpgradeLevel(client, UPGRADE_SHORTNAME); - if(iLevel <= 0) - return Plugin_Continue; - - if(!SMRPG_RunUpgradeEffect(client, UPGRADE_SHORTNAME)) - return Plugin_Continue; // Some other plugin doesn't want this effect to run - - int iMaxArmor = SMRPG_Armor_GetClientMaxArmor(client); - int iCurrentArmor = GetClientArmor(client); - - // He already is regenerated completely. - if(iCurrentArmor >= iMaxArmor) - { - // Give him an helmet now. - if (g_hCVGiveHelmet.BoolValue && !GetEntProp(client, Prop_Send, "m_bHasHelmet")) - SetEntProp(client, Prop_Send, "m_bHasHelmet", 1); - return Plugin_Continue; - } - - int iIncrease = RoundToFloor(g_hCVAmount.FloatValue) + RoundToFloor(g_hCVAmountIncrease.FloatValue * (iLevel - 1)); - int iNewArmor = iCurrentArmor + iIncrease; - if(iNewArmor > iMaxArmor) - iNewArmor = iMaxArmor; - SetEntProp(client, Prop_Send, "m_ArmorValue", iNewArmor); - - return Plugin_Continue; -} \ No newline at end of file From 1d9d60ce1c94a272cae9d726f3de611322b3d75b Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:03:59 +0100 Subject: [PATCH 10/13] Delete smrpg_upgrade_conversion.sp --- .../upgrades/smrpg_upgrade_conversion.sp | 256 ------------------ 1 file changed, 256 deletions(-) delete mode 100644 scripting/upgrades/smrpg_upgrade_conversion.sp diff --git a/scripting/upgrades/smrpg_upgrade_conversion.sp b/scripting/upgrades/smrpg_upgrade_conversion.sp deleted file mode 100644 index 9c8599f..0000000 --- a/scripting/upgrades/smrpg_upgrade_conversion.sp +++ /dev/null @@ -1,256 +0,0 @@ -#pragma semicolon 1 -#include - -#pragma newdecls required -#include - -#define UPGRADE_SHORTNAME "conversion" -#define PLUGIN_VERSION "1.0" - -public Plugin myinfo = -{ - name = "SM:RPG Upgrade > Conversion ", - author = "WanekWest", - description = "Conversion allows the player to turn excess money into exp.", - version = PLUGIN_VERSION, - url = "https://vk.com/wanek_west" - - -} - -ConVar g_hCvMoneyConvertType, - g_hCvMoneyConvertRequestAmount, g_hCvMoneyConvertIncreaserPerLevel, g_hCvMoneyConvertBaseAmount; - -int hCvMoneyConvertType, hCvMoneyConvertRequestAmount; -float hCvMoneyConvertIncreaserPerLevel, hCvMoneyConvertBaseAmount; - -int g_MoneyOffset; - -public void OnPluginStart() -{ - LoadTranslations("smrpg_stock_upgrades.phrases"); - - - HookEvent("bomb_defused", Event_OnBombDefused); - HookEvent("player_spawn", Event_OnPlayerSpawn); - HookEvent("hostage_rescued", Event_OnHostageRescue); - HookEvent("bomb_exploded", Event_OnBombExploded); - HookEvent("player_death", Event_OnPlayerDeath); -// HookEvent("round_start", Event_OnRoundStart); - HookEvent("round_end", Event_OnRoundEnd); - HookEvent("hostage_follows", Event_OnHostageFollow); - - g_MoneyOffset = FindSendPropInfo("CCSPlayer", "m_iAccount"); - if (g_MoneyOffset == -1) - { - SetFailState("Can not find m_iAccount."); - } -} - -public void OnPluginEnd() -{ - if (SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) - SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); -} - -public void OnAllPluginsLoaded() -{ - OnLibraryAdded("smrpg"); -} - -public void OnLibraryAdded(const char[] name) -{ - // Register this upgrade in SM:RPG - if (StrEqual(name, "smrpg")) - { - // Register the upgrade type. - SMRPG_RegisterUpgradeType("Conversion", UPGRADE_SHORTNAME, "Conversion allows the player to turn excess money into credits.", 10, true, 5, 15, 10); - SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); - - g_hCvMoneyConvertType = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_type", "0", "Conversion type. 0 - to EXP, 1 - to Credits", _, true, 0.0); - g_hCvMoneyConvertType.AddChangeHook(OnConverChangeType); - hCvMoneyConvertType = g_hCvMoneyConvertType.IntValue; - - g_hCvMoneyConvertRequestAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_request_amount", "100", "How much money to take for 1 unit of Experience/Credits.", _, true, 0.0); - g_hCvMoneyConvertRequestAmount.AddChangeHook(OnConverChangeReqMoney); - hCvMoneyConvertRequestAmount = g_hCvMoneyConvertRequestAmount.IntValue; - - g_hCvMoneyConvertIncreaserPerLevel = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_increase", "1.0", "Increase value per level.", _, true, 0.0); - g_hCvMoneyConvertIncreaserPerLevel.AddChangeHook(OnConverChangeIncreaseValue); - hCvMoneyConvertIncreaserPerLevel = g_hCvMoneyConvertIncreaserPerLevel.FloatValue; - - g_hCvMoneyConvertBaseAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_conversion_base_amount", "1.0", "The base amount to start with at level 1.", _, true, 0.0); - g_hCvMoneyConvertBaseAmount.AddChangeHook(OnConverChangeBaseAmount); - hCvMoneyConvertBaseAmount = g_hCvMoneyConvertBaseAmount.FloatValue; - } -} - -public void OnConverChangeType(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) -{ - hCvMoneyConvertType = hCvar.IntValue; -} - -public void OnConverChangeReqMoney(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) -{ - hCvMoneyConvertRequestAmount = hCvar.IntValue; -} - -public void OnConverChangeIncreaseValue(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) -{ - hCvMoneyConvertIncreaserPerLevel = hCvar.FloatValue; -} - -public void OnConverChangeBaseAmount(ConVar hCvar, const char[] szOldValue, const char[] szNewValue) -{ - hCvMoneyConvertBaseAmount = hCvar.FloatValue; -} - -// The core wants to display your upgrade somewhere. Translate it into the clients language! -public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) -{ - // Easy pattern is to use the shortname of your upgrade in the translation file - if (type == TranslationType_Name) - Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); - // And "shortname description" as phrase in the translation file for the description. - else if (type == TranslationType_Description) - { - char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH + 12] = UPGRADE_SHORTNAME; - StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); - Format(translation, maxlen, "%T", sDescriptionKey, client); - } -} - -public void Event_OnRoundEnd(Event event, const char[] error, bool dontBroadcast) -{ - int maxClients = MaxClients; - int time; - GetMapTimeLeft(time); - - //This is the time before mapchange. After the last round it takes about 3 seconds for the map to change. Depending on server settings. - if(time <= 4) - { - for (int client = 1; client <= maxClients; client++) - { - - Conversion(client, 0); - if(client==maxClients) - return; - - } - return; - } -} - -public void Event_OnHostageFollow(Event event, const char[] error, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client) - return; - - Conversion(client, 10000); - return; -} - -public void Event_OnPlayerDeath(Event event, const char[] error, bool dontBroadcast) -{ - - int client = GetClientOfUserId(event.GetInt("attacker")); - if (!client) - return; - - Conversion(client, 9700); - return; - -} - - -public void Event_OnHostageRescue(Event event, const char[] name, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client) - return; - - Conversion(client, 10000); - return; -} - -public void Event_OnBombDefused(Event event, const char[] name, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client) - return; - - Conversion(client, 10000); - return; -} - -public void Event_OnBombExploded(Event event, const char[] name, bool dontBroadcast) -{ - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client) - return; - - Conversion(client, 10000); - return; -} - -public void Event_OnPlayerSpawn(Event event, const char[] name, bool dontBroadcast) -{ - - int client = GetClientOfUserId(event.GetInt("userid")); - if (!client) - return; - - Conversion(client, 10000); - return; -} - -public void Conversion(int client, int moneyThreshold) -{ - if (!client) - return; - - // SM:RPG is disabled? - if (!SMRPG_IsEnabled()) - return; - - // The upgrade is disabled completely? - if (!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) - return; - - // Are bots allowed to use this upgrade? - //if (IsFakeClient(client) && SMRPG_IgnoreBots()) - //return; - - // Player didn't buy this upgrade yet. - int iLevel = SMRPG_GetClientUpgradeLevel(client, UPGRADE_SHORTNAME); - if (iLevel <= 0) - return; - - int currentClientMoney = GetEntData(client, g_MoneyOffset); - if (currentClientMoney >= moneyThreshold + hCvMoneyConvertRequestAmount) - { - - // int clientMoney = GetEntProp(client, Prop_Send, "m_iAccount"); - int amountToSubstract = currentClientMoney - moneyThreshold; - float amountToAdd = hCvMoneyConvertBaseAmount + hCvMoneyConvertIncreaserPerLevel * (iLevel - 1); - int amountToGive = RoundToCeil(amountToSubstract / hCvMoneyConvertRequestAmount * amountToAdd); - PrintToConsole(client, "You have earned %d experience for converting $", amountToGive); - char reason[256]; - FormatEx(reason, sizeof(reason), "converting %d$", amountToSubstract); - - if (hCvMoneyConvertType == 0) - { - SMRPG_AddClientExperience(client, amountToGive, reason, false, -1); - SetEntData(client, g_MoneyOffset, moneyThreshold); - } - else - { - SMRPG_SetClientCredits(client, SMRPG_GetClientCredits(client) + amountToGive); - SetEntData(client, g_MoneyOffset, moneyThreshold); - } - } - - return; -} - From 97c743f187ef49948095a1eccea0c02d3d54ac82 Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:04:10 +0100 Subject: [PATCH 11/13] Delete smrpg_upgrade_pickpocket.sp --- .../upgrades/smrpg_upgrade_pickpocket.sp | 165 ------------------ 1 file changed, 165 deletions(-) delete mode 100644 scripting/upgrades/smrpg_upgrade_pickpocket.sp diff --git a/scripting/upgrades/smrpg_upgrade_pickpocket.sp b/scripting/upgrades/smrpg_upgrade_pickpocket.sp deleted file mode 100644 index 71c3655..0000000 --- a/scripting/upgrades/smrpg_upgrade_pickpocket.sp +++ /dev/null @@ -1,165 +0,0 @@ -#pragma semicolon 1 -#include -#include -#include - - -#pragma newdecls required -#include - -#undef REQUIRE_PLUGIN - -#define UPGRADE_SHORTNAME "pickpocket" - - -ConVar g_hCVAmount; -ConVar g_hCVAmountIncrease; -ConVar g_hCVWeapon; - - -int g_MoneyOffset; - -public Plugin myinfo = -{ - name = "SM:RPG Upgrade > Pickpocket", - author = "DeewaTT", - description = "Pickpocket upgrade for SM:RPG. Steals money with every hit from your knife.", - version = SMRPG_VERSION, - url = "http://www.wcfan.de/" -} - -public void OnPluginStart() -{ - LoadTranslations("smrpg_stock_upgrades.phrases"); - - // We define this variable to check for the players money later. - g_MoneyOffset = FindSendPropInfo("CCSPlayer", "m_iAccount"); - if (g_MoneyOffset == -1) - { - SetFailState("Can not find m_iAccount."); - } -} - -public void OnPluginEnd() -{ - if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) - SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); -} - -public void OnAllPluginsLoaded() -{ - OnLibraryAdded("smrpg"); -} - -public void OnLibraryAdded(const char[] name) -{ - // Register this upgrade in SM:RPG - if(StrEqual(name, "smrpg")) - { - SMRPG_RegisterUpgradeType("Pickpocket", UPGRADE_SHORTNAME, "Steals money when knifing.", 0, true, 5, 5, 10); - SMRPG_SetUpgradeBuySellCallback(UPGRADE_SHORTNAME, SMRPG_BuySell); - SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); - - g_hCVAmount = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_amount", "1", "Specify the base amount of money stolen at the first level.", 0, true, 0.1); - g_hCVAmountIncrease = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_amount_inc", "1", "Additional money to steal multiplied by level. (base + inc * (level-1))", 0, true, 0.0); - g_hCVWeapon = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_steal_weapon", "knife", "Entity name of the weapon which should trigger the effect. (e.g. knife)"); - } -} - -public void OnClientPutInServer(int client) -{ - // Declare the hook we will use. - SDKHook(client, SDKHook_OnTakeDamagePost, Hook_OnTakeDamagePost); -} - -/** - * SM:RPG Upgrade callbacks - */ - -public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) -{ - if(type == TranslationType_Name) - Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); - else if(type == TranslationType_Description) - { - char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; - StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); - Format(translation, maxlen, "%T", sDescriptionKey, client); - } -} - -public void Hook_OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, const float damageForce[3], const float damagePosition[3]) -{ - if(attacker <= 0 || attacker > MaxClients || !IsClientInGame(attacker) || victim <= 0 || victim > MaxClients) - return; - - // Ignore team attack if not FFA - if(!SMRPG_IsFFAEnabled() && GetClientTeam(attacker) == GetClientTeam(victim)) - return; - - int iWeapon = inflictor; - if(inflictor > 0 && inflictor <= MaxClients) - iWeapon = Client_GetActiveWeapon(inflictor); - - if(iWeapon == -1) - return; - - char sWeapon[256], sTargetWeapon[128]; - g_hCVWeapon.GetString(sTargetWeapon, sizeof(sTargetWeapon)); - GetEntityClassname(iWeapon, sWeapon, sizeof(sWeapon)); - ReplaceString(sWeapon, sizeof(sWeapon), "weapon_", "", false); - - // This effect only applies to the specified weapon. - if(StrContains(sWeapon, sTargetWeapon) == -1) - return; - - Takemoney(attacker, victim); -} - -public void Takemoney(int attacker, int victim) -{ - - if (!attacker) - return; - - // Are bots allowed to use this upgrade? - if(SMRPG_IgnoreBots() && IsFakeClient(attacker)) - return; - - // Some other plugin doesn't want this effect to run - if(!SMRPG_RunUpgradeEffect(attacker, UPGRADE_SHORTNAME)) - return; - - // SM:RPG is disabled? - if (!SMRPG_IsEnabled()) - return; - - // This upgrade is disabled? - if (!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) - return; - - // Player didn't buy this upgrade yet. - int iLevel = SMRPG_GetClientUpgradeLevel(attacker, UPGRADE_SHORTNAME); - if (iLevel <= 0) - return; - - // Determine how much money will be taken. - int amountToSteal = RoundToNearest(g_hCVAmount.FloatValue + g_hCVAmountIncrease.FloatValue*(iLevel-1)); - - // Check the victims money. If it's less than the attacker wants to take, set it to 0. - int currentVictimMoney = GetEntData(victim, g_MoneyOffset); - int newVictimMoney = currentVictimMoney - amountToSteal; - if (currentVictimMoney <= amountToSteal) - { - amountToSteal = currentVictimMoney; - newVictimMoney = 0; - } - SetEntData(victim, g_MoneyOffset, newVictimMoney); - - // Check attackers money and add the stolen amount to it. - int currentAttackerMoney = GetEntData(attacker, g_MoneyOffset); - int newAttackerMoney = currentAttackerMoney + amountToSteal; - SetEntData(attacker, g_MoneyOffset, newAttackerMoney); - - return; -} \ No newline at end of file From 2321c5f38a398a76464e12c2c39e61bf9c543531 Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:04:20 +0100 Subject: [PATCH 12/13] Delete smrpg_stock_upgrades.phrases.txt --- translations/smrpg_stock_upgrades.phrases.txt | 362 ------------------ 1 file changed, 362 deletions(-) delete mode 100644 translations/smrpg_stock_upgrades.phrases.txt diff --git a/translations/smrpg_stock_upgrades.phrases.txt b/translations/smrpg_stock_upgrades.phrases.txt deleted file mode 100644 index 8b4683c..0000000 --- a/translations/smrpg_stock_upgrades.phrases.txt +++ /dev/null @@ -1,362 +0,0 @@ -"Phrases" -{ - "regen" - { - "en" "HP Regeneration" - } - - "regen description" - { - "en" "Regenerates HP regularly." - } - - "health" - { - "en" "Health+" - } - - "health description" - { - "en" "Increases your maximal health." - } - - "resup" - { - "en" "Resupply" - } - - "resup description" - { - "en" "Regenerates ammo every third second." - } - - "vamp" - { - "en" "Vampire" - } - - "vamp description" - { - "en" "Steal HP from players when damaging them." - } - - "stealth" - { - "en" "Stealth" - } - - "stealth description" - { - "en" "Renders yourself more and more invisible." - } - - "ljump" - { - "en" "Long Jump" - } - - "ljump description" - { - "en" "Boosts your jump speed." - } - - "fnade" - { - "en" "Fire Grenade" - } - - "fnade description" - { - "en" "Ignites players damaged by your grenade." - } - - "icestab" - { - "en" "Ice Stab" - } - - "icestab description" - { - "en" "Freeze a player in place when knifing him." - } - - "fpistol" - { - "en" "Frost Pistol" - } - - "fpistol description" - { - "en" "Slow down players hit with a pistol." - } - - "denial" - { - "en" "Denial" - } - - "denial description" - { - "en" "Keep your weapons the next time you spawn after you've died." - } - - "impulse" - { - "en" "Impulse" - } - - "impulse description" - { - "en" "Gain speed for a short time when being shot." - } - - "medic" - { - "en" "Medic" - } - - "medic description" - { - "en" "Heals team mates around you." - } - - "speed" - { - "en" "Speed+" - } - - "speed description" - { - "en" "Increase your average movement speed." - } - - "damage" - { - "en" "Damage+" - } - - "damage description" - { - "en" "Deal additional damage on enemies." - } - - "armorregen" - { - "en" "Armor Regeneration" - } - - "armorregen description" - { - "en" "Regenerates armor regularly." - } - - "clipsize" - { - "en" "Increase Clipsize" - } - - "clipsize description" - { - "en" "Increases the size of a weapon's clip." - } - - "shrinking" - { - "en" "Shrinking" - } - - "shrinking description" - { - "en" "Makes your player model smaller and harder to hit." - } - - "armorplus" - { - "en" "Armor+" - } - - "armorplus description" - { - "en" "Increases your maximal armor." - } - - "fastreload" - { - "en" "Fast Reload" - } - - "fastreload description" - { - "en" "Increases the reload speed of your guns." - } - - "firepistol" - { - "en" "Fire Pistol" - } - - "firepistol description" - { - "en" "Ignites players hit with a pistol." - } - - "gravity" - { - "en" "Reduced Gravity" - } - - "gravity description" - { - "en" "Reduces your gravity and lets you jump higher." - } - - "poisonsmoke" - { - "en" "Poison Smoke" - } - - "poisonsmoke description" - { - "en" "Damages players inside the smoke of a smoke grenade" - } - - "firerate" - { - "en" "Increase firerate" - } - - "firerate description" - { - "en" "Increases the firerate of weapons." - } - - "icenade" - { - "en" "Ice Grenade" - } - - "icenade description" - { - "en" "Freeze a player in place when damaging him with your grenade." - } - - "grenaderesup" - { - "en" "Grenade Resupply" - } - - "grenaderesup description" - { - "en" "Regenerates grenades x seconds after you threw them." - } - - "antidote" - { - "en" "Antidote" - } - - "antidote description" - { - "en" "Shorten the duration of bad effects like freezing, burning or slowdown on you." - } - - "bouncybullets" - { - "en" "Bouncy Bullets" - } - - "bouncybullets description" - { - "en" "Push enemies away by shooting them." - } - - "falldamage" - { - "en" "Reduced Fall Damage" - } - - "falldamage description" - { - "en" "Reduces the damage you take from falling from great heights." - } - - "armorhelmet" - { - "en" "Armor Helmet" - } - - "armorhelmet description" - { - "en" "Gives you a chance to get a helmet on spawn." - } - - "antiflash" - { - "en" "Antiflash" - } - - "antiflash description" - { - "en" "Reduce blinding effect of flashbangs on you." - } - - "adrenaline" - { - "en" "Adrenaline" - } - - "adrenaline description" - { - "en" "Increase your speed shortly when firing a weapon." - } - - "mirrordmg" - { - "en" "Mirror Damage" - } - - "mirrordmg description" - { - "en" "Mirror some of your received damage back to the attacker." - } - - "positionswap" - { - "en" "Position Swap" - } - - "positionswap description" - { - "en" "Gives you the chance to swap positions with your attacker." - } - - "conversion" - { - "en" "Conversion" - } - - "conversion description" - { - "en" "Allows you to turn excess money into experience." - } - - "turtle" - { - "en" "Turtle" - } - - "turtle description" - { - "en" "Reduces the damage you take after receiving a headshot." - } - - "pickpocket" - { - "en" "Pickpocket" - } - - "pickpocket description" - { - "en" "Steals some money with every hit." - } -} From 0fc0e4900e71699699fec7693824bcbd7ea2be3d Mon Sep 17 00:00:00 2001 From: DeewaTT91 <121842068+DeewaTT91@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:04:33 +0100 Subject: [PATCH 13/13] Delete smrpg_upgrade_turtle.sp --- scripting/upgrades/smrpg_upgrade_turtle.sp | 184 --------------------- 1 file changed, 184 deletions(-) delete mode 100644 scripting/upgrades/smrpg_upgrade_turtle.sp diff --git a/scripting/upgrades/smrpg_upgrade_turtle.sp b/scripting/upgrades/smrpg_upgrade_turtle.sp deleted file mode 100644 index fe78c82..0000000 --- a/scripting/upgrades/smrpg_upgrade_turtle.sp +++ /dev/null @@ -1,184 +0,0 @@ -/** - * SM:RPG Reduced Fall Damage Upgrade - * Reduces the damage you take from falling from great heights. - */ - -#pragma semicolon 1 -#include -#include - -#pragma newdecls required -#include - -#define UPGRADE_SHORTNAME "turtle" - -ConVar g_hCVPercent; -ConVar g_hCVDuration; - -Handle g_turtleTimers[65]; -bool g_turtleMode[65]; - -public Plugin myinfo = -{ - name = "SM:RPG Upgrade > Turtle", - author = "DeewaTT", - description = "Let's you take decreased damage after taking a headshot for a limit amount of time.", - version = SMRPG_VERSION, - url = "http://www.wcfan.de/" -} - -public void OnPluginStart() -{ - LoadTranslations("smrpg_stock_upgrades.phrases"); - - // Account for late loading - for(int i=1;i<=MaxClients;i++) - { - if(IsClientInGame(i)) - OnClientPutInServer(i); - } -} - -public void OnPluginEnd() -{ - if(SMRPG_UpgradeExists(UPGRADE_SHORTNAME)) - SMRPG_UnregisterUpgradeType(UPGRADE_SHORTNAME); -} - -public void OnAllPluginsLoaded() -{ - OnLibraryAdded("smrpg"); -} - -public void OnLibraryAdded(const char[] name) -{ - // Register this upgrade in SM:RPG - if(StrEqual(name, "smrpg")) - { - // Register the upgrade type. - SMRPG_RegisterUpgradeType("Turtle", UPGRADE_SHORTNAME, "Reduces the damage you receive after taking a headshot.", 0, true, 5, 10, 10); - - SMRPG_SetUpgradeTranslationCallback(UPGRADE_SHORTNAME, SMRPG_TranslateUpgrade); - - // Create your convars through the SM:RPG core. That way they are added to your upgrade's own config file in cfg/sourcemod/smrpg/smrpg_upgrade_example.cfg! - g_hCVPercent = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_turtle_percent", "0.01", "How much percent of the damage should be removed (multiplied by level)?", _, true, 0.01, true, 1.0); - g_hCVDuration = SMRPG_CreateUpgradeConVar(UPGRADE_SHORTNAME, "smrpg_turtle_duration", "0.01", "How long should the damage reduction last (multiplied by level)?", _, true, 0.01, true, 10.0); - } -} - -public void OnClientPutInServer(int client) -{ - SDKHook(client, SDKHook_OnTakeDamage, Hook_OnTakeDamage); - SDKHook(client, SDKHook_TraceAttackPost, Hook_TraceAttackPost); -} - -/** - * SM:RPG Upgrade callbacks - */ - -// The core wants to display your upgrade somewhere. Translate it into the clients language! -public void SMRPG_TranslateUpgrade(int client, const char[] shortname, TranslationType type, char[] translation, int maxlen) -{ - // Easy pattern is to use the shortname of your upgrade in the translation file - if(type == TranslationType_Name) - Format(translation, maxlen, "%T", UPGRADE_SHORTNAME, client); - // And "shortname description" as phrase in the translation file for the description. - else if(type == TranslationType_Description) - { - char sDescriptionKey[MAX_UPGRADE_SHORTNAME_LENGTH+12] = UPGRADE_SHORTNAME; - StrCat(sDescriptionKey, sizeof(sDescriptionKey), " description"); - Format(translation, maxlen, "%T", sDescriptionKey, client); - } -} - -/** - * SDK Hooks callbacks - */ - - -public void Hook_TraceAttackPost(int victim, int attacker, int inflictor, float damage, int damagetype, int ammotype, int hitbox, int hitgroup) -{ - // Check if the victim is a player and if the last hit was a headshot. - if (IsClientInGame(victim) && hitgroup == 1 && hitbox == 12) - { - // Check if the victim has the "turtle" skill. - int iLevel = SMRPG_GetClientUpgradeLevel(victim, "turtle"); - if (iLevel > 0) - { - // Activate "turtlemode" for the player - SetTurtlemode(victim, true); - // Find out how long the player will be protected - float turtleDuration = float(iLevel) * g_hCVDuration.FloatValue; - if (g_turtleTimers[victim] != INVALID_HANDLE) - return; - // Schedule a timer to deactivate "turtlemode" after x seconds - g_turtleTimers[victim] = CreateTimer(turtleDuration, RemoveTurtleMode, victim, TIMER_FLAG_NO_MAPCHANGE); - } - } - return; -} -public Action RemoveTurtleMode(Handle timer, int victim) -{ - // Deactivate "turtlemode" for the player - SetTurtlemode(victim, false); - g_turtleTimers[victim] = INVALID_HANDLE; - return Plugin_Handled; -} - - -public Action Hook_OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, - float damageForce[3], float damagePosition[3], int damagecustom) -{ - // We need to check if we are in damage reduction mode. - if(g_turtleMode[victim] == false) - return Plugin_Continue; - - // SM:RPG is disabled? - if(!SMRPG_IsEnabled()) - return Plugin_Continue; - - // The upgrade is disabled completely? - if(!SMRPG_IsUpgradeEnabled(UPGRADE_SHORTNAME)) - return Plugin_Continue; - - // Are bots allowed to use this upgrade? - if(IsFakeClient(victim) && SMRPG_IgnoreBots()) - return Plugin_Continue; - - // Player didn't buy this upgrade yet. - int iLevel = SMRPG_GetClientUpgradeLevel(victim, UPGRADE_SHORTNAME); - if(iLevel <= 0) - return Plugin_Continue; - - // This calls the SMRPG_OnUpgradeEffect global forward where other plugins can stop you from applying your effect, if it conflicts with theirs. - // This also returns false, if the client doesn't have the required admin flags to use the upgrade, so no need to call SMRPG_CheckUpgradeAccess. - if(!SMRPG_RunUpgradeEffect(victim, UPGRADE_SHORTNAME)) - return Plugin_Continue; // Some other plugin doesn't want this effect to run - - - float fReducePercent = g_hCVPercent.FloatValue * float(iLevel); - // Never block the whole damage. - if (fReducePercent >= 1.0) - fReducePercent = 0.99; - - // Reduce the damage taken. - damage -= damage * fReducePercent; - return Plugin_Changed; -} - - -// Turns the Turtlemode on or off. -public void SetTurtlemode(int victim, bool bool) -{ - g_turtleMode[victim] = bool; - - if(g_turtleMode[victim] == true) - { - PrintToConsole(victim, "You are now in turtlemode, taking %d%% reduced damage.", RoundToNearest(100*g_hCVPercent.FloatValue * float(SMRPG_GetClientUpgradeLevel(victim, UPGRADE_SHORTNAME)))); - } - else - { - PrintToConsole(victim, "You are no longer in turtlemode, taking normal damage."); - } - return; -} \ No newline at end of file