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) -- TODO: Reset counters on new round. 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") 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) 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) 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 pointsToGivePly = math.Round(pointsToGive * settings.ZombiePointsFactor) - points * settings.LosePointReduction -- TODO: Reduce points on death, not round end to avoid cheating 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)