diff --git a/scripting/smrpg/smrpg_stats.sp b/scripting/smrpg/smrpg_stats.sp deleted file mode 100644 index 17981e4..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 * g_hCVExpInc.IntValue + g_hCVExpStart.IntValue; - - 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(type) - { - 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); -} diff --git a/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorplus_cstrike.sp deleted file mode 100644 index 21cc760..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 - g_hCVMaxIncrease.IntValue)) - 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 + g_hCVMaxIncrease.IntValue * 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 diff --git a/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp b/scripting/upgrades/smrpg_upgrade_armorregen_cstrike.sp deleted file mode 100644 index 82b23af..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 = g_hCVAmount.IntValue + g_hCVAmountIncrease.IntValue * (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 diff --git a/scripting/upgrades/smrpg_upgrade_regen.sp b/scripting/upgrades/smrpg_upgrade_regen.sp index c9ac041..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 = g_hCVAmount.IntValue + g_hCVAmountIncrease.IntValue * (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) diff --git a/translations/smrpg_stock_upgrades.phrases.txt b/translations/smrpg_stock_upgrades.phrases.txt deleted file mode 100644 index 99c7de4..0000000 --- a/translations/smrpg_stock_upgrades.phrases.txt +++ /dev/null @@ -1,332 +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." - } -}