diff --git a/lua/autorun/server/mapcalc.lua b/lua/autorun/server/mapcalc.lua index b68c9e3..aa137a7 100644 --- a/lua/autorun/server/mapcalc.lua +++ b/lua/autorun/server/mapcalc.lua @@ -1,186 +1,148 @@ if engine.ActiveGamemode() ~= "zombiesurvival" then return end --- this code grabs the data from the file about the map. if none exists it makes a default. -timer.Simple(25, function() - mapwins = 0 - maploss = 0 +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 - local mapname = string.lower(game.GetMap()) - if file.Exists("zsmapinfo/"..mapname..".txt", "DATA") then - local data = util.JSONToTable(file.Read("zsmapinfo/"..mapname..".txt", "DATA")) - mapwins = data.mapwins - maploss = data.maploss - mapboost = data.mapboost - mapjackpot = data.mapjackpot - else - local main = {} - main["mapwins"] = 0 - main["maploss"] = 0 - main["mapboost"] = 1-- use a scale from 1 to 5 - main["mapjackpot"] = 25 - file.Write( "zsmapinfo/"..mapname..".txt", util.TableToJSON( main ) ) - print("map win file not found. created one.") - end - zombpercentcountmap = 0 - totpercentcountmap = 1 -end) - --- this hook checks to make sure there are zombies on the server. later it should check to see if any are afk. -roundtime = 0 -prereqcount = false -hook.Add("WaveStateChanged", "zombpercentcalc", function() - roundtime = CurTime() + + file.Write("zsmapinfo/"..mapParams.Name..".txt", util.TableToJSON(mapParams)) +end - if !timer.Exists("zombiepercentcalc") then - timer.Create("zombiepercentcalc", 10, 0, function() - if #(team.GetPlayers(TEAM_UNDEAD)) >0 then - zombpercentcountmap =zombpercentcountmap + 1 - end - totpercentcountmap = totpercentcountmap + 1 - +-- 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) -hook.Add("EndRound", "givedapoints", function(winner) - timer.Destroy("zombiepercentcalc") +local function postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap) + PrintMessage(HUD_PRINTTALK,"This map has been played "..timesPlayed.." times with humans winning "..(mapParams.TimesWon).." times.("..(math.Round((mapParams.TimesWon/timesPlayed)*100)).."%)") + PrintMessage(HUD_PRINTTALK,"Zombies were only playing for "..math.Round(zombiePercentCalcMap * 100).."% of the time.") + PrintMessage(HUD_PRINTTALK,"frequency multiplier for this map is: "..freqMult..". play maps infrequently for a higher value!") + PrintMessage(HUD_PRINTTALK,"Special boost for this map is:"..(mapParams.Boost)..". tell an admin if you think it should be changed!") + PrintMessage(HUD_PRINTTALK,"Map jackpot is now "..(mapParams.Jackpot)..".") +end + +hook.Add("PostEndRound", "pointsave_givedapoints", function(winner) + timer.Destroy("pointsave_zombieintervalcounter") - timer.Simple(0,function() + -- TODO: Check if map should be ignored + + timer.Simple(0, function() print("point bonus hook") - local mapname = string.lower(game.GetMap()) - local zombiepercentcalcmap = (zombpercentcountmap/totpercentcountmap) or .01 - local mapplaytotal = mapwins + maploss - local pointstogive = 10 - zombiepercentcalcmap = zombiepercentcalcmap or .01 - -- we need to make sure that zombies were on the server for more than half the game. - if zombiepercentcalcmap <=.5 then - PrintMessage(HUD_PRINTTALK,"No end of game points because zombies were not even playing half the time!") - elseif mapplaytotal <= 5 then - --print(mapplaytotal) - PrintMessage(HUD_PRINTTALK,"sorry but this map needs to be played at least "..(5-mapplaytotal).." more times before you can get points for winning.") - if winner == TEAM_UNDEAD then - maploss = maploss + 1 - elseif winner == TEAM_HUMAN then - mapwins = mapwins +1 - else - print("wow you fucked up! no seriously how do you not have a winner?") - end - if winner == TEAM_UNDEAD then - if mapjackpot <= 2500 then - mapjackpot = mapjackpot*1.1 - end - end - local main = {} - main["mapwins"] = mapwins - main["maploss"] = maploss - main["mapboost"] = mapboost - main["mapjackpot"] = mapjackpot - file.Write( "zsmapinfo/"..mapname..".txt", util.TableToJSON( main ) ) + 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) + 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 - if winner == TEAM_UNDEAD then - if mapjackpot <= 2500 then - mapjackpot = math.Round(mapjackpot*1.1) - end - else - mapjackpot = 25 - end - local multiplywin = 2 - if mapplaytotal <10 then - multiplywin = 2 - elseif mapplaytotal<25 then - multiplywin = 1.9 - elseif mapplaytotal <50 then - multiplywin = 1.8 - elseif mapplaytotal<100 then - multiplywin = 1.7 - elseif mapplaytotal < 250 then - multiplywin = 1.6 - elseif mapplaytotal < 500 then - multiplywin = 1.4 - elseif mapplaytotal < 1000 then - multiplywin = 1.2 - else - multiplywin = 1 - end - - if winner == TEAM_UNDEAD then - maploss = maploss + 1 - elseif winner == TEAM_HUMAN then - mapwins = mapwins +1 - else - print("wow you fucked up!") - end - - local main = {} - main["mapwins"] = mapwins - main["maploss"] = maploss - main["mapboost"] = mapboost - main["mapjackpot"] = mapjackpot - file.Write( "zsmapinfo/"..mapname..".txt", util.TableToJSON( main ) ) - - local finalmultiply = 1 - if winner == TEAM_UNDEAD then - finalmultiply = (mapboost * (mapwins/mapplaytotal) * zombiepercentcalcmap) or .01 - pointstogive = math.Round(50 * finalmultiply) or 1 - elseif winner == TEAM_HUMAN then - finalmultiply = (mapboost * multiplywin * (maploss/mapplaytotal) *zombiepercentcalcmap) or .01 - pointstogive = math.Round((50 * finalmultiply) + mapjackpot) or 1 + 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 - - PrintMessage(HUD_PRINTTALK,"This map has been played "..mapplaytotal.." times with humans winning "..(mapwins).." times.("..(math.Round((mapwins/mapplaytotal)*100)).."%)") - PrintMessage(HUD_PRINTTALK,"Zombies were only playing for "..(zombiepercentcalcmap*100).."% of the time.") - PrintMessage(HUD_PRINTTALK,"frequency multiplier for this map is:"..multiplywin..". play maps infrequently for a higher value!") - PrintMessage(HUD_PRINTTALK,"Special boost for this map is:"..(mapboost)..". tell an admin if you think it should be changed!") - PrintMessage(HUD_PRINTTALK,"Map jackpot is now "..(mapjackpot)..".") - - --regular points ZS points - --[[if (game.GetMap() ~= "zs_obj_gauntlet_v3" and game.GetMap() ~="zs_gauntlet_reborn_b6") and gmod.GetGamemode().Name == "Zombie Survival" then - for k,v in pairs(team.GetPlayers(TEAM_HUMAN)) do - v:SetSavedPoints((v:GetDTInt(1) + pointstogive) ) - --WriteData(v:SteamID64(), v:GetPoints()) - v:PrintMessage(HUD_PRINTTALK,"You gained "..(pointstogive).." this round for playing to the end!") - end - for k,v in pairs(team.GetPlayers(TEAM_UNDEAD)) do - v:SetSavedPoints(math.Round((v:GetSavedPoints() + (pointstogive/5)) )) - --WriteData(v:SteamID64(), v:GetPoints()) - v:PrintMessage(HUD_PRINTTALK,"You gained "..(math.Round(pointstogive/2)).." points this round for playing to the end!") - end - end]] - end - if (game.GetMap() ~= "zs_obj_gauntlet_v3" and game.GetMap() ~="zs_gauntlet_reborn_b6") and gmod.GetGamemode().Name == "Zombie Survival" then - if winner == TEAM_HUMAN then - for k,ply in pairs(player.GetAll()) do - if ply:Team() == TEAM_HUMAN then - if ply:GetPoints()- ply:GetSavedPoints()> 0 then - ply:SetSavedPoints(ply:GetPoints()+((ply:GetPoints()- ply:GetSavedPoints()))+pointstogive) - ply:PrintMessage(HUD_PRINTTALK,"You gained "..(pointstogive).." this round for playing to the end!") - else - ply:SetSavedPoints(ply:GetPoints()+pointstogive) - ply:PrintMessage(HUD_PRINTTALK,"You gained "..(pointstogive).." this round for playing to the end!") - end - else - if ply:GetPoints()- ply:GetSavedPoints()> 0 then - ply:SetSavedPoints(ply:GetPoints()+((ply:GetPoints()- ply:GetSavedPoints())*.15)+(pointstogive/2)) - ply:PrintMessage(HUD_PRINTTALK,"You gained "..(pointstogive/2).." this round for playing to the end!") - else - ply:SetSavedPoints(ply:GetPoints()+(pointstogive/2)) - ply:PrintMessage(HUD_PRINTTALK,"You gained "..(pointstogive/2).." this round for playing to the end!") - end - 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) + 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,"Congratulations, you won the jackpot of "..mapParams.Jackpot.." for winning this round") + 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 - for k,ply in pairs(player.GetAll()) do - if ply:GetPoints()- ply:GetSavedPoints()> 0 then - ply:SetSavedPoints(ply:GetPoints()+((ply:GetPoints()- ply:GetSavedPoints())*.15)+(pointstogive/2)) - else - ply:SetSavedPoints(ply:GetPoints()+(pointstogive/2)) - end - end + pointsToGivePly = math.Round(pointsToGive * settings.ZombiePointsFactor) - points * settings.LosePointReduction + 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,"You gained "..(pointsToGivePly).." this round for playing to the end!") + elseif pointsToGivePly < 0 then + ply:PrintMessage(HUD_PRINTTALK,"You lost "..(-pointsToGivePly).." points this round!") end end + + -- Output general stats about this map + postStatistics(mapParams, timesPlayed, freqMult, zombiePercentCalcMap) + end) end) \ No newline at end of file