Sulfito_PointSaving/lua/autorun/server/pointsaving_mapstats.lua

165 lines
6.5 KiB
Lua

if engine.ActiveGamemode() ~= "zombiesurvival" then return end
local settings = {
JackpotStart = 25,
JackpotMax = 2500,
JackpotMultiplier = 1.1,
MinimumRounds = 5,
EndroundPoints = 50, -- Points to give at the end of the round (Jackpot gets added to the points the players get)
ZombiePointsFactor = 0.5, -- Factor of points zombies get of the points payout after round end
LosePointReduction = 0.85 -- Factor of points that gets taken away from players who lost
}
-- Grab the data from the file about the map.
local function getMapParams(mapName)
local data = {}
if file.Exists("zsmapinfo/"..mapName..".txt", "DATA") then
data = util.JSONToTable(file.Read("zsmapinfo/"..mapName..".txt", "DATA")) or {}
end
-- Get map params or default values
local mapParams = {}
mapParams.Name = mapName
mapParams.TimesWon = data.TimesWon or 0
mapParams.TimesLost = data.TimesLost or 0
mapParams.Boost = data.Boost or 1
mapParams.Jackpot = data.Jackpot or settings.JackpotStart
return mapParams
end
local mapParams = getMapParams(string.lower(game.GetMap()))
local function saveMapParams(mapParams)
if not file.Exists("zsmapinfo", "DATA") then
file.CreateDir("zsmapinfo")
end
file.Write("zsmapinfo/"..mapParams.Name..".txt", util.TableToJSON(mapParams))
end
-- This hook checks to make sure there are zombies on the server. TODO: Check for AFK zombies
local zombieIntervalCounter, totalIntervalCounter = 0, 0
hook.Add("WaveStateChanged", "pointsave_zombieintervalactivator", function()
if not timer.Exists("pointsave_zombieintervalcounter") then
timer.Create("pointsave_zombieintervalcounter", 10, 0, function()
if #(team.GetPlayers(TEAM_UNDEAD)) > 0 then
zombieIntervalCounter = zombieIntervalCounter + 1
end
totalIntervalCounter = totalIntervalCounter + 1
end)
end
end)
local function resetVariables()
zombieIntervalCounter, totalIntervalCounter = 0, 0
end
local function postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap)
PrintMessage(HUD_PRINTTALK,"<c=0,255,255>This map has been played "..timesPlayed.." times with humans winning "..(mapParams.TimesWon).." times.("..(math.Round((mapParams.TimesWon/timesPlayed)*100)).."%)</c>")
PrintMessage(HUD_PRINTTALK,"<c=0,255,255>Zombies were only playing for "..math.Round(zombiePercentCalcMap * 100).."% of the time.</c>")
PrintMessage(HUD_PRINTTALK,"<c=0,255,255>frequency multiplier for this map is: "..freqMult..". play maps infrequently for a higher value!</c>")
PrintMessage(HUD_PRINTTALK,"<c=0,255,255>Special boost for this map is:"..(mapParams.Boost)..". tell an admin if you think it should be changed!</c>")
PrintMessage(HUD_PRINTTALK,"<c=204,204,0>Map jackpot is now "..(mapParams.Jackpot)..".</c>")
end
hook.Add("PlayerDeath", "pointsave_death", function(ply)
if PointSaving_shouldIgnoreMap(game.GetMap()) then return end
if ply:Team() == TEAM_HUMAN then
--print("### PS Saved: "..ply:GetPoints())
ply:SetSavedPoints(ply:GetPoints() * settings.LosePointReduction)
ply:PrintMessage(HUD_PRINTTALK,"<c=255,0,0>You lost "..(settings.LosePointReduction * 100).."% of your saved points because you died!</c>")
end
end)
hook.Add("PostEndRound", "pointsave_givedapoints", function(winner)
timer.Destroy("pointsave_zombieintervalcounter")
if PointSaving_shouldIgnoreMap(game.GetMap()) then return end
timer.Simple(0, function()
print("point bonus hook")
local zombiePercentCalcMap = (zombieIntervalCounter / totalIntervalCounter) or .01
local timesPlayed = mapParams.TimesWon + mapParams.TimesLost
-- Check if zombies did even play most of the map
if zombiePercentCalcMap <= .5 then
PrintMessage(HUD_PRINTTALK, "No end of game points because zombies were not even playing half the time!")
postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap)
saveMapParams(mapParams)
resetVariables()
return
end
-- Increase counters
if winner == TEAM_UNDEAD then
mapParams.TimesLost = mapParams.TimesLost + 1
elseif winner == TEAM_HUMAN then
mapParams.TimesWon = mapParams.TimesWon + 1
else
print("Wow you fucked up! No seriously how do you not have a winner?")
end
-- Increase jackpot
if winner == TEAM_UNDEAD then
mapParams.Jackpot = mapParams.Jackpot * settings.JackpotMultiplier
if mapParams.Jackpot > settings.JackpotMax then
mapParams.Jackpot = settings.JackpotMax
end
end
-- Check if map was played enough times
if timesPlayed < settings.MinimumRounds then
PrintMessage(HUD_PRINTTALK,"Sorry, this map needs to be played at least "..(settings.MinimumRounds - timesPlayed).." more times, before you can get points for winning.")
postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap)
saveMapParams(mapParams)
resetVariables()
return
end
-- Calculate points to give
local freqMult = 1 / math.pow(timesPlayed / 10, 0.2) + 1
local pointsToGive
if winner == TEAM_HUMAN then
local finalMultiply = (mapParams.Boost * freqMult * (mapParams.TimesLost / timesPlayed) * zombiePercentCalcMap)
PrintMessage(HUD_PRINTTALK,"<c=0,255,255>Congratulations, you won the jackpot of "..mapParams.Jackpot.." for winning this round</c>")
pointsToGive = math.Round((settings.EndroundPoints * finalMultiply) + mapParams.Jackpot)
mapParams.Jackpot = settings.JackpotStart
else
local finalMultiply = (mapParams.Boost * (mapParams.TimesWon / timesPlayed) * zombiePercentCalcMap)
pointsToGive = math.Round(settings.EndroundPoints * finalMultiply)
end
saveMapParams(mapParams)
-- Give or take points, and output messages for each player
for k, ply in pairs(player.GetAll()) do
local pointsToGivePly
local points = ply:GetPoints()
-- Calculate points to give for each player (Depending on if the round was lost or won)
if ply:Team() == TEAM_HUMAN then
pointsToGivePly = math.Round(pointsToGive)
else
pointsToGivePly = math.Round(pointsToGive * settings.ZombiePointsFactor)
end
-- Limit pointsToGivePly
if points + pointsToGivePly < 0 then pointsToGivePly = -points end
-- Set points
ply:SetPoints(points + pointsToGivePly)
ply:SetSavedPoints(points + pointsToGivePly)
-- Display message
if pointsToGivePly > 0 then
ply:PrintMessage(HUD_PRINTTALK,"<c=255,0,0>You gained "..(pointsToGivePly).." this round for playing to the end!</c>")
elseif pointsToGivePly < 0 then
ply:PrintMessage(HUD_PRINTTALK,"<c=255,0,0>You lost "..(-pointsToGivePly).." points this round!</c>")
end
end
-- Output general stats about this map
postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap)
resetVariables()
end)
end)