169 lines
6.8 KiB
Lua
169 lines
6.8 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
|
|
|
|
-- TODO: When round is lost, take away points from human players that were there at the beginning of the game (All Human players that were there at the end of round 1, when late joiners join as zombies)
|
|
--[[
|
|
Cases:
|
|
- When round is lost:
|
|
- Only players from the end of Wave 1 (online or disconnected) get the 85% reduction of points. But online players get some additional points
|
|
- When round is won:
|
|
- All humans get points + jackpot
|
|
- Zombies get a few points (but a reduction of 85% if they were there since the end of wave 1)
|
|
]]--
|
|
|
|
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
|
|
local freqMult = 1 / math.pow(timesPlayed / 10, 0.2) + 1
|
|
|
|
-- 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
|
|
|
|
-- Again, as the counter changed
|
|
timesPlayed = mapParams.TimesWon + mapParams.TimesLost
|
|
freqMult = 1 / math.pow(timesPlayed / 10, 0.2) + 1
|
|
|
|
-- 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 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) - 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,"<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) |