stats.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. local love = require("compat")
  2. local stats = {}
  3. local list = {}
  4. local STAT_WIDTH = love.graphics.getWidth()/2
  5. local STAT_X = (love.graphics.getWidth() - STAT_WIDTH)/2
  6. local STAT_HEIGHT = 300 --math.min(love.graphics.getHeight()/3, 300)
  7. local STAT_Y = (love.graphics.getHeight() - STAT_HEIGHT)/2
  8. local PAD = 20
  9. local STAT_SWITCH_TIME = 5
  10. local panel = require( "panel" )
  11. function stats:clear()
  12. list = {}
  13. STAT_WIDTH = love.graphics.getWidth()/2
  14. STAT_X = (love.graphics.getWidth() - STAT_WIDTH)/2
  15. STAT_HEIGHT = 300 --math.min(love.graphics.getHeight()/3, 300)
  16. STAT_Y = (love.graphics.getHeight() - STAT_HEIGHT)/2 - PAD*4
  17. self.panel = panel:new( STAT_X - PAD, STAT_Y - 2*PAD,
  18. STAT_WIDTH + 3*PAD, STAT_HEIGHT + 6*PAD )
  19. -- Stat to be displayed:
  20. self.current = nil
  21. self.nextStatTimer = STAT_SWITCH_TIME
  22. end
  23. function stats:show()
  24. if #list > 1 then
  25. self.display = true
  26. self.nextStatTimer = STAT_SWITCH_TIME
  27. self.current = 1
  28. if list[self.current] then
  29. list[self.current].timer = 0
  30. end
  31. end
  32. end
  33. function stats:hide()
  34. stats.display = false
  35. end
  36. -- Called for every statistic sent from the server:
  37. function stats:add( str )
  38. local name, unit, data = str:match( "(.-)|(.-)|(.*)" )
  39. if name and unit and data then
  40. local stat = {
  41. name = name,
  42. unit = unit,
  43. timer = 0,
  44. data = {},
  45. }
  46. local users = network:getUsers()
  47. local max = -math.huge
  48. for id, value in data:gmatch( "(%S-)%s(%S-)|" ) do
  49. id = tonumber(id)
  50. if id and users[id] then
  51. local entry = {}
  52. entry.val = tonumber(value)
  53. entry.id = id
  54. entry.displayStr = " " .. users[id].playerName .. ": " .. entry.val .. " " .. unit
  55. table.insert( stat.data, entry )
  56. max = math.max( entry.val, max )
  57. end
  58. end
  59. -- Calculate the height (relative to the maximum):
  60. for k, u in ipairs( stat.data ) do
  61. if max ~= 0 then
  62. u.relHeight = u.val/max
  63. -- Display at least a few pixels, even if u.val is zero:
  64. u.relHeight = math.max( 0.02, u.relHeight )
  65. else
  66. u.relHeight = 0.02
  67. end
  68. end
  69. table.insert( list, stat )
  70. end
  71. end
  72. function stats:draw()
  73. if self.display and self.current and list[self.current] then
  74. love.graphics.setLineWidth( 2 )
  75. local fontHeight = love.graphics.getFont():getHeight()
  76. local users = network:getUsers()
  77. local stat = list[self.current]
  78. --[[love.graphics.setColor( 0, 0, 0, 200 )
  79. love.graphics.rectangle( "fill", STAT_X - PAD, STAT_Y - PAD*2,
  80. STAT_WIDTH + 2*PAD, STAT_HEIGHT + 4*PAD )]]
  81. self.panel:draw()
  82. local statNameWidth = STAT_WIDTH/(#list)
  83. for k, s in ipairs( list ) do
  84. -- Print stat titles:
  85. if s == stat then
  86. love.graphics.setColor( 255, 255, 255, 255 )
  87. else
  88. love.graphics.setColor( 255, 255, 255, 64 )
  89. end
  90. love.graphics.printf( s.name, STAT_X + statNameWidth*(k-1),
  91. STAT_Y - PAD, statNameWidth, "center" )
  92. end
  93. local slotWidth = STAT_WIDTH/(#stat.data+1)
  94. local barWidth = math.min( 30, slotWidth + 10 )
  95. for k, u in ipairs( stat.data ) do
  96. if users[u.id] then
  97. local barHeight = math.min(stat.timer,u.relHeight)*STAT_HEIGHT
  98. love.graphics.setColor( users[u.id].customData.red,
  99. users[u.id].customData.green,
  100. users[u.id].customData.blue,
  101. 128 )
  102. love.graphics.rectangle( "fill", STAT_X + k*slotWidth - barWidth/2,
  103. STAT_Y + STAT_HEIGHT - barHeight, barWidth, barHeight )
  104. love.graphics.setColor( 0, 0, 0, 255 )
  105. love.graphics.rectangle( "line", STAT_X + k*slotWidth - barWidth/2,
  106. STAT_Y + STAT_HEIGHT - barHeight, barWidth, barHeight )
  107. love.graphics.setColor( 255, 255, 255, 255 )
  108. --love.graphics.setColor( 0, 0, 0, 255 )
  109. love.graphics.printf( u.displayStr,
  110. STAT_X + k*slotWidth - fontHeight/2, STAT_Y + STAT_HEIGHT - 5,
  111. 500, "left", -math.pi/2 )
  112. if map:getCar( u.id ) then
  113. map:getCar( u.id ):drawOnUI( STAT_X + k*slotWidth,
  114. STAT_Y + STAT_HEIGHT + 40, 0.3 )
  115. end
  116. end
  117. end
  118. end
  119. end
  120. function stats:update( dt )
  121. if self.display then
  122. if not self.current or not list[self.current] then
  123. self.current = 1
  124. if list[self.current] then
  125. list[self.current].timer = 0
  126. end
  127. self.nextStatTimer = STAT_SWITCH_TIME
  128. else
  129. if list[self.current] then
  130. if list[self.current].timer < 1 then
  131. list[self.current].timer = math.min( list[self.current].timer + dt*0.5, 1 )
  132. end
  133. self.nextStatTimer = self.nextStatTimer - dt
  134. if self.nextStatTimer < 0 then
  135. self.current = self.current + 1
  136. self.nextStatTimer = STAT_SWITCH_TIME
  137. if list[self.current] then
  138. list[self.current].timer = 0
  139. end
  140. end
  141. end
  142. end
  143. end
  144. end
  145. function stats:removeUser( id )
  146. for i, stat in pairs( list ) do
  147. for k, u in ipairs( stat.data ) do
  148. if u.id == id then
  149. table.remove( stat.data, k )
  150. break
  151. end
  152. end
  153. end
  154. end
  155. return stats