Lots of stuff

- Changed XP distribution
- Changed level names
- Moved string to the settings file
- Overlay position is now inside settings file
- Added map statistics
- Added Use_Hammer permission
- Added spreadsheet for XP calculation
This commit is contained in:
David Vogel 2016-10-09 18:11:56 +02:00
parent a50c3e0359
commit ada745fd1b
13 changed files with 246 additions and 62 deletions

BIN
XP Spreadsheet.ods Normal file

Binary file not shown.

View File

@ -6,12 +6,9 @@ end
-- HUD on the left top of the screen
function d3stats.Overlay_Init()
local screenscale = BetterScreenScale()
d3stats.D3StatsOverlay = vgui.Create( "D3StatsOverlay" )
d3stats.D3StatsOverlay:SetPos( 0, screenscale * 80 )
d3stats.D3StatsOverlay:SetPos( d3stats.Overlay_X, d3stats.Overlay_Y )
d3stats.D3StatsOverlay:SetSize( 350, 100 )
end
-- Call this function from cl_targetid.lua in the gamemode. Works for ZS, needs adjustments for other gamemodes.

View File

@ -14,4 +14,3 @@ include( "vgui/overlay.lua" )
hook.Add( "Initialize", "D3Stats_Init", function ()
d3stats.Overlay_Init()
end )

View File

@ -23,4 +23,28 @@ end )
-- Message on levelchange
hook.Add( "D3Stats_LevelChanged", "D3Stats_ZS_LevelChanged", function ( ply, oldLevel, Level )
ply:CenterNotify( Color( 0, 255, 255 ), "You ascended to level " .. tostring( Level ) .. " \"" .. d3stats.Levels[Level].Name .. "\"")
end )
-- Handle "Use_Hammer" permission. TODO: Only prevent that the person can nail things
hook.Add( "PlayerSwitchWeapon", "D3Stats_ZS_EquipHammer", function( ply, oldWeapon, newWeapon )
local Class = newWeapon:GetClass()
if not ply:D3Stats_HasPermission( "Use_Hammer" ) then
if Class == "weapon_zs_hammer" or Class == "weapon_zs_electrohammer" then
ply:CenterNotify( Color( 255, 0, 0 ), string.format( d3stats.Disallow_Hold_Hammer, d3stats.GetPermissionLevel( "Use_Hammer" ) ) )
return true
end
end
end )
-- Handle EndRound events for statistics
hook.Add( "EndRound", "D3Stats_ZS_EndRound", function( team )
local won = ( TEAM_SURVIVORS == team ) and true or false
d3stats.Map_End( won )
end )
-- Display map statistic message when the player joined
hook.Add( "PlayerReady", "D3Stats_Map_PlayerReady", function ( ply )
d3stats.Map_Message( false, ply )
end )

View File

@ -21,6 +21,8 @@ include( "sh_level.lua" )
include( "sh_concommand.lua" )
include( "gamemodes/sv_zombiesurvival.lua" )
include( "sv_storage.lua" )
include( "sv_map.lua" )
include( "sv_network.lua" )
hook.Add( "PlayerInitialSpawn", "D3Stats_PlayerSpawn", function ( ply )
@ -32,6 +34,15 @@ hook.Add( "PlayerInitialSpawn", "D3Stats_PlayerSpawn", function ( ply )
ply:SetNWInt( "D3Stats_Level", ply.D3Stats_Level )
end )
-- Initialisation
hook.Add( "Initialize", "D3Stats_Init", function ()
d3stats.Storage.Initialize()
resource.AddFile("resource/fonts/ghoulfriaoe.ttf")
resource.AddFile("resource/fonts/hauntaoe.ttf")
resource.AddFile("resource/fonts/nightaoe.ttf")
end )
local meta = FindMetaTable( "Player" )
if not meta then return end
@ -84,4 +95,4 @@ function meta:D3Stats_HasPermission( Permission )
end
return d3stats.LevelCheckPermission( self:D3Stats_GetLevel(), Permission )
end
end

View File

@ -2,7 +2,7 @@
function d3stats.CalculateLevel( XP )
local Level = 1
for key, value in pairs(d3stats.Levels) do
for key, value in pairs( d3stats.Levels ) do
if value.XP_needed <= XP then
Level = key
else
@ -17,7 +17,12 @@ end
function d3stats.LevelCheckPermission( Level, Permission )
local Granted = false
for key, value in pairs(d3stats.Levels) do
-- If the permission is not on the list, allow it
if not d3stats.Permissions[Permission] then
return true
end
for key, value in pairs( d3stats.Levels ) do
if key <= Level then
if value.Permissions and value.Permissions[Permission] then
Granted = value.Permissions[Permission]
@ -30,6 +35,23 @@ function d3stats.LevelCheckPermission( Level, Permission )
return Granted
end
-- Returns what level is needed for the given permission
function d3stats.GetPermissionLevel( Permission )
local Level
if not d3stats.Permissions[Permission] then
return 1
end
for key, value in pairs( d3stats.Levels ) do
if value.Permissions and value.Permissions[Permission] then
return key
end
end
return nil
end
-- Count the amount of online players who have the permission
if SERVER then
function d3stats.CountPermissionPlayers( Permission, Team )
@ -37,7 +59,7 @@ if SERVER then
local players = player.GetAll()
for key, ply in pairs( players ) do
if Team == nil or pl:Team() == Team then
if Team == nil or ply:Team() == Team then
if d3stats.LevelCheckPermission( ply:D3Stats_GetLevel(), Permission ) == true then
Counter = Counter + 1
end

View File

@ -5,47 +5,48 @@ Settings and level definitions are stored in here
]]
-- Permissions
-- AllowIfLessThan: If the amount of players who have the permission is lower than this number, allow it anyways
-- Team: Reduces count to the specified team. In ZS: TEAM_SURVIVOR = 4
-- Everything not in this list will be allowed by default
-- AllowIfLessThan: If the amount of players who have the permission is lower than this number, allow it anyway
-- Team: Reduces count to the specified team. In ZS: TEAM_SURVIVOR = 4,
d3stats.Permissions = {
["Buy_Hammer"] = { AllowIfLessThan = 2, Team = 4 },
["Use_Hammer"] = { AllowIfLessThan = 2, Team = 4 },
["Buy_Hammer"] = { AllowIfLessThan = 4, Team = 4 },
["Use_Hammer"] = { AllowIfLessThan = 4, Team = 4 },
}
-- Levels, please sort by XP
d3stats.Levels = {
{ XP_needed = 0, Name = "Kleiner" },
{ XP_needed = 500, Name = "Lesser Kleiner" },
{ XP_needed = 1000, Name = "Dayfly" },
{ XP_needed = 2000, Name = "Apprentice", Permissions = { ["Buy_Hammer"] = true, ["Use_Hammer"] = true } },
{ XP_needed = 3000, Name = "Adventurer" },
{ XP_needed = 4000, Name = "Scout" },
{ XP_needed = 5000, Name = "Guardian" },
{ XP_needed = 6000, Name = "Fighter" },
{ XP_needed = 7000, Name = "Brawler" },
{ XP_needed = 8000, Name = "Scrapper" },
{ XP_needed = 9000, Name = "Skirmisher" },
{ XP_needed = 10000, Name = "Battler" },
{ XP_needed = 15000, Name = "Marauder" },
{ XP_needed = 20000, Name = "Slayer" },
{ XP_needed = 25000, Name = "Mercenary" },
{ XP_needed = 30000, Name = "Swordsman" },
{ XP_needed = 35000, Name = "Freelancer" },
{ XP_needed = 40000, Name = "Swashbuckler" },
{ XP_needed = 45000, Name = "Vanquisher" },
{ XP_needed = 50000, Name = "Exemplar" },
{ XP_needed = 60000, Name = "Conqueror" },
{ XP_needed = 70000, Name = "Specialist" },
{ XP_needed = 80000, Name = "Lieutenant" },
{ XP_needed = 90000, Name = "Captain" },
{ XP_needed = 100000, Name = "Major" },
{ XP_needed = 133333, Name = "Colonel" },
{ XP_needed = 166666, Name = "General" },
{ XP_needed = 200000, Name = "Champion" },
{ XP_needed = 250000, Name = "Hero" },
{ XP_needed = 300000, Name = "Legend" },
{ XP_needed = 500000, Name = "Demigod" },
{ XP_needed = 1000000, Name = "God" },
{ XP_needed = 500, Name = "Citizen" },
{ XP_needed = 1370, Name = "Survivor" },
{ XP_needed = 2612, Name = "Rogue" },
{ XP_needed = 4225, Name = "Engineer", Permissions = { ["Buy_Hammer"] = true, ["Use_Hammer"] = true } },
{ XP_needed = 6209, Name = "Scout" },
{ XP_needed = 8564, Name = "Officer" },
{ XP_needed = 11290, Name = "Guardian" },
{ XP_needed = 14387, Name = "Fighter" },
{ XP_needed = 17854, Name = "Brawler" },
{ XP_needed = 21693, Name = "Scrapper" },
{ XP_needed = 25903, Name = "Skirmisher" },
{ XP_needed = 30483, Name = "Battler" },
{ XP_needed = 35435, Name = "Marauder" },
{ XP_needed = 40758, Name = "Slayer" },
{ XP_needed = 46451, Name = "Mercenary" },
{ XP_needed = 52516, Name = "Swordsman" },
{ XP_needed = 58951, Name = "Freelancer" },
{ XP_needed = 65758, Name = "Swashbuckler" },
{ XP_needed = 72935, Name = "Vanquisher" },
{ XP_needed = 80483, Name = "Exemplar" },
{ XP_needed = 88403, Name = "Conqueror" },
{ XP_needed = 96693, Name = "Specialist" },
{ XP_needed = 105354, Name = "Lieutenant" },
{ XP_needed = 114387, Name = "Captain" },
{ XP_needed = 123790, Name = "Major" },
{ XP_needed = 133564, Name = "Colonel" },
{ XP_needed = 143709, Name = "General" },
{ XP_needed = 154225, Name = "Champion" },
{ XP_needed = 165112, Name = "Hero" },
{ XP_needed = 176370, Name = "Legend" },
{ XP_needed = 188000, Name = "Demigod" },
{ XP_needed = 200000, Name = "God" },
}
d3stats.PlayerPointsAdded_Limit = 200 -- Ignore all "PlayerPointsAdded" callbacks above this XP value
@ -56,12 +57,39 @@ d3stats.ZombieKilledHuman_Static = 100 -- Amount of XP a zombie gets for killin
d3stats.ZombieKilledHuman_Max = 1000 -- Upper XP reward clamp
d3stats.ZombieKilledHuman_Min = 0 -- Lower XP reward clamp
-- Fonts
-- Messages TODO: Multilanguage
d3stats.Disallow_Hold_Hammer = "You can't use the hammer until you have reached level %i"
d3stats.MapStats_Zero = "We are playing %s." -- Message to players who just joined
d3stats.MapStats = "We are playing %s. Humans won %i of %i times (%.1f%%)" -- Message to players who just joined (With statistics)
d3stats.MapStats_End = "%s has been won %i of %i times (%.1f%%)" -- Message to all players at the end of the round (With statistics)
if CLIENT then
surface.CreateFont( "D3Stats_OverlayFont", {
font = "Typenoksidi",
extended = true,
size = 16,
-- Overlay positions
d3stats.Overlay_X = 0
d3stats.Overlay_Y = 80 * math.Clamp(ScrH() / 1080, 0.6, 1) -- This needs to be redone
-- Fonts
surface.CreateFont( "D3Stats_OverlayFont_XP", {
font = "Ghoulish Fright AOE",
extended = false,
size = 22,
weight = 0,
blursize = 0,
scanlines = 0,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
} )
surface.CreateFont( "D3Stats_OverlayFont_Level", {
font = "Haunt AOE",
extended = false,
size = 26,
weight = 0,
blursize = 0,
scanlines = 0,
@ -75,7 +103,8 @@ if CLIENT then
additive = false,
outline = true,
} )
d3stats.Font_Overlay = "D3Stats_OverlayFont"
d3stats.Font_TargetID = "D3Stats_OverlayFont"
d3stats.Font_Overlay_XP = "D3Stats_OverlayFont_XP"
d3stats.Font_Overlay_Level = "D3Stats_OverlayFont_Level"
d3stats.Font_TargetID = "ZSHUDFontTiny" -- Use ZS Font
end

33
lua/d3stats/sv_map.lua Normal file
View File

@ -0,0 +1,33 @@
function d3stats.Map_Message( roundend, ply )
local map = game.GetMap()
local count, wins, avg_players = d3stats.Storage.Map_Get( map )
local Message
if count > 0 then
if roundend == true then
Message = string.format( d3stats.MapStats_End, map, wins, count, wins / count * 100 )
else
Message = string.format( d3stats.MapStats, map, wins, count, wins / count * 100 )
end
else
Message = string.format( d3stats.MapStats_Zero, map )
end
if ply then
ply:ChatPrint( Message )
else
PrintMessage( HUD_PRINTTALK, Message )
end
end
function d3stats.Map_End( won )
local map = game.GetMap()
d3stats.Storage.Map_AddOutcome( map, won, #player.GetAll() )
d3stats.Map_Message( true )
end
--d3stats.Map_End( false )
--d3stats.Map_Message( false, player.GetByID(1) )

View File

@ -0,0 +1,53 @@
--[[
Storage stuff
]]
d3stats.Storage = {}
function d3stats.Storage.Initialize()
-- Storage for map data
if not sql.TableExists( "d3stats_maps") then
local result = sql.Query( "CREATE TABLE d3stats_maps ( name varchar(255) PRIMARY KEY, count INT, wins INT, avg_players REAL )" )
end
end
function d3stats.Storage.Map_AddOutcome( name, won, players )
local count = 1
local wins = 0
local avg_players = players
if won == true then wins = 1 end
local result = sql.QueryRow( "SELECT count, wins, avg_players FROM d3stats_maps WHERE name = '" .. name .. "'" )
if result then
if result ~= false then
count = count + tonumber( result.count )
wins = tonumber( result.wins ) + 1 * ( won and 1 or 0 )
avg_players = ( players + tonumber( result.avg_players ) ) / 2
else
Print(sql.LastError())
end
end
local result = sql.Query( "INSERT OR REPLACE INTO d3stats_maps ( name, count, wins, avg_players ) VALUES ( '" .. name .. "', " .. tostring(count) .. ", " .. tostring(wins) .. ", " .. tostring(avg_players) .. " );" )
end
function d3stats.Storage.Map_Get( name )
local count = 0
local wins = 0
local avg_players = 0
local result = sql.QueryRow( "SELECT count, wins, avg_players FROM d3stats_maps WHERE name = '" .. name .. "'" )
if result then
if result ~= false then
count = tonumber( result.count )
wins = tonumber( result.wins )
avg_players = tonumber( result.avg_players )
else
Print(sql.LastError())
end
end
return count, wins, avg_players
end

View File

@ -4,11 +4,21 @@ function PANEL:Init()
self.Progress = vgui.Create( "DProgress", self )
self.Progress:SetPos( 10, 10 )
self.Progress:SetSize( 200, 10 )
self.Progress:SetSize( 200, 20 )
self.Label_XP = vgui.Create( "DLabel", self )
self.Label_XP:SetTextColor( color_black )
self.Label_XP:SetFont( d3stats.Font_Overlay_XP )
self.Label_XP:SetSize( 200, 20 )
self.Label_XP:SetPos( 10, 10 ) -- Set the position of the label
self.Label_XP:SetContentAlignment( 5 )
self.Label_Level = vgui.Create( "DLabel", self )
self.Label_Level:SetFont( d3stats.Font_Overlay_Level )
self.Label_Level:SetPos( 10, 35 ) -- Set the position of the label
self.Label_Level:SetSize( 200, 20 )
self.Label_Level:SetContentAlignment( 5 )
self.Label = vgui.Create( "DLabel", self )
self.Label:SetFont(d3stats.Font_Overlay)
self.Label:SetPos( 10, 25 ) -- Set the position of the label
self:StatsUpdate( 0, 1 )
--self.Label:SetDark( 1 ) -- Set the colour of the text inside the label to a darker one
@ -22,19 +32,25 @@ function PANEL:Paint( aWide, aTall )
end
function PANEL:StatsUpdate( XP, Level )
local Text
local Text_XP
local Text_Level
local Fraction
if d3stats.Levels[Level+1] then
Text = "XP: " .. tostring( XP ) .. " / " .. d3stats.Levels[Level+1].XP_needed .. "\nLevel: " .. tostring( Level ) .. " \"" .. d3stats.Levels[Level].Name .. "\""
Text_XP = "XP: " .. tostring( XP ) .. " / " .. d3stats.Levels[Level+1].XP_needed
Fraction = ( XP - d3stats.Levels[Level].XP_needed ) / ( d3stats.Levels[Level+1].XP_needed - d3stats.Levels[Level].XP_needed )
else
Text = "XP: " .. tostring( XP ) .. "\nLevel: " .. tostring( Level ) .. " \"" .. d3stats.Levels[Level].Name .. "\""
Text_XP = "XP: " .. tostring( XP )
Fraction = 1
end
self.Label:SetText( Text ) -- Set the text of the label
self.Label:SizeToContents() -- Size the label to fit the text in it
Text_Level = "Level: " .. tostring( Level ) .. " \"" .. d3stats.Levels[Level].Name .. "\""
self.Label_XP:SetText( Text_XP ) -- Set the text of the label
--self.Label_XP:SizeToContents() -- Size the label to fit the text in it
self.Label_Level:SetText( Text_Level ) -- Set the text of the label
--self.Label_Level:SizeToContents() -- Size the label to fit the text in it
self.Progress:SetFraction( Fraction )

Binary file not shown.

BIN
resource/fonts/hauntaoe.ttf Normal file

Binary file not shown.

BIN
resource/fonts/nightaoe.ttf Normal file

Binary file not shown.