Advertisement
Guest User

server

a guest
May 22nd, 2015
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.10 KB | None | 0 0
  1. Db = require 'db'
  2. Plugin = require 'plugin'
  3. Timer = require 'timer'
  4. Event = require 'event'
  5.  
  6. # Global constants, use .peek()
  7. global = {
  8. pointsTime: 3600000
  9. pointsTimeSec: 3600
  10. }
  11.  
  12. # ==================== Events ====================
  13. # Game install
  14. exports.onInstall = ->
  15. initializeColors()
  16. initializeGame()
  17. # Game update
  18. exports.onUpgrade = ->
  19. # Check if the color array is defined correctly
  20. if not Db.shared.peek('colors', '-1', 'name')?
  21. log 'Initialized colors again'
  22. initializeColors()
  23.  
  24. # Check version number and upgrade if required
  25. version = Db.shared.peek('version')
  26. newVersion = version
  27. if not version?
  28. version = 0
  29. # Version checking
  30. if version < 1 # Initialize deviceId, fixes inRange system
  31. newVersion = 1
  32. Db.shared.set 'maxDeviceId', 0
  33. if version < 2 # Clean team neutral from the scores list and clean event about team neutral (got there because of a bug)
  34. newVersion = 2
  35. Db.shared.remove 'game', 'teams', -1
  36. Db.shared.iterate 'game', 'eventlist', (e) ->
  37. if (e.peek('conqueror')? and e.peek('conqueror') == -1) or (e.peek('leading')? and e.peek('leading') == -1)
  38. Db.shared.remove 'game', 'eventlist', e.key()
  39. if version < 3 # Change yellow color
  40. newVersion = 3
  41. initializeColors()
  42. # Write new version to the database
  43. if newVersion isnt version
  44. log '[onUpgrade] Upgraded from version '+version+' to '+newVersion+'.'
  45. Db.shared.set 'version', newVersion
  46. # Config changes (by admin or plugin adder)
  47. exports.onConfig = (config) ->
  48. if config.restart
  49. log '[onConfig()] Restarting game'
  50. initializeGame()
  51. # Get background location from player.
  52. exports.onGeoloc = (userId, geoloc) ->
  53. log '[onGeoloc()] Geoloc from ' + Plugin.userName(userId) + '('+userId+'): ', JSON.stringify(geoloc)
  54. recieved = new Date()/1000
  55. if Db.shared.peek('gameState') is 1 and (recieved - (Db.shared.peek('lastNotification', userId) || 0))> 30*60
  56. beacons = Db.shared.ref('game', 'beacons')
  57. beaconRadius = Db.shared.peek('game', 'beaconRadius')
  58. found=false;
  59. #Check if user is in range of an enemy beacon, opening the app will capture the beacon
  60. beacons.iterate (beacon) ->
  61. if beacon.peek('owner') isnt getTeamOfUser(userId) and !found
  62. #log distance(geoloc.latitude, geoloc.longitude, beacon.peek('location', 'lat'), beacon.peek('location', 'lng'))
  63. if distance(geoloc.latitude, geoloc.longitude, beacon.peek('location', 'lat'), beacon.peek('location', 'lng')) < beaconRadius
  64. #send notifcation
  65. Event.create
  66. unit: 'inRange'
  67. include: userId
  68. text: 'You are in range of an enemy beacon, capture it now!'
  69. found=true;
  70. #Check if user is nearby an enemy beacon.
  71. if !found
  72. beacons.iterate (beacon) ->
  73. if beacon.peek('owner') isnt getTeamOfUser(userId) and !found
  74. dist = distance(geoloc.latitude, geoloc.longitude, beacon.peek('location','lat'), beacon.peek('location','lng'))
  75. if dist < beaconRadius *2.5
  76. #send notifcation
  77. Event.create
  78. unit: 'nearby'
  79. include: userId
  80. text: 'You are ' + parseInt(dist,10)+ ' m away from an enemy beacon, capture it now!'
  81. found=true;
  82. #Last notification send, so that the user will not be spammed with notifications
  83. if found
  84. Db.shared.set('lastNotification', userId, recieved)
  85. # Handle new users joining the happening
  86. exports.onJoin = (userId) ->
  87. log '[onJoin()] Player ' + Plugin.userName(userId) + ' is joining the Happening'
  88. if Db.shared.peek 'gameState' == 1
  89. # Find teams with lowest number of members
  90. min = 99999
  91. lowest = []
  92. Db.shared.iterate 'game', 'teams', (team) !->
  93. if team.count() < min
  94. min = team.count()
  95. lowest = []
  96. lowest.push team.key()
  97. else if team.count() == min
  98. lowest.push team.key()
  99. # Draw a random team from those
  100. randomNumber = Math.floor(Math.random() * lowest.length)
  101. team = lowest[randomNumber]
  102. # Add player to team
  103. Db.shared.set 'game', 'teams', team, 'users', userId, 'userScore', 0
  104. Db.shared.set 'game', 'teams', team, 'users', userId, 'captured', 0
  105. Db.shared.set 'game', 'teams', team, 'users', userId, 'neutralized', 0
  106. Db.shared.set 'game', 'teams', team, 'users', userId, 'userName', Plugin.userName(userId)
  107. log '[onJoin()] Added to team ' + team
  108.  
  109. #==================== Client calls ====================
  110. # Add a beacon (during setup phase)
  111. exports.client_addMarker = (client, location) ->
  112. if Db.shared.peek('gameState') isnt 0
  113. log '[addMarker()] '+Plugin.userName(client), ' (id=', client, ') tried to add a marker while game is not in setup phase!'
  114. else
  115. log '[addMarker()] Adding marker: lat=', location.lat, ', lng=', location.lng
  116. nextNumber = 0
  117. while Db.shared.peek('game', 'beacons', nextNumber)?
  118. nextNumber++
  119.  
  120. Db.shared.set 'game', 'beacons', nextNumber, {location: location}
  121. Db.shared.set 'game', 'beacons', nextNumber, 'owner', -1
  122. Db.shared.set 'game', 'beacons', nextNumber, 'nextOwner', -1
  123. Db.shared.set 'game', 'beacons', nextNumber, 'percentage', 0
  124. Db.shared.set 'game', 'beacons', nextNumber, 'captureValue', 10
  125. Db.shared.set 'game', 'beacons', nextNumber, 'action', "none"
  126. exports.client_deleteBeacon = (client, location) ->
  127. #Finding the right beacon
  128. if Db.shared.peek('gameState') isnt 0
  129. log '[deleteBeacon()] '+Plugin.userName(client), ' (id=', client, ') tried to delete a beacon while game is not in setup phase!'
  130. else
  131. Db.shared.iterate 'game', 'beacons', (beacon) !->
  132. if beacon.peek('location', 'lat') == location.lat and beacon.peek('location', 'lng') == location.lng
  133. log '[deleteBeacon()] Deleted beacon: key='+beacon.key()+', lat=', location.lat, ', lng=', location.lng
  134. Db.shared.remove 'game', 'beacons', beacon.key()
  135. # Set the round time unit and number
  136. exports.client_setRoundTime = (roundTimeNumber, roundTimeUnit) ->
  137. log '[setRoundTime()] RoundTime set to: ' + roundTimeNumber + ' ' + roundTimeUnit
  138. Db.shared.set 'game', 'roundTimeNumber', roundTimeNumber
  139. Db.shared.set 'game', 'roundTimeUnit', roundTimeUnit
  140. # Set the number of teams
  141. exports.client_setTeams = (teams) ->
  142. log '[setTeams()] Teams set to: ', teams
  143. Db.shared.set 'game', 'numberOfTeams', teams
  144. # Set the game boundaries
  145. exports.client_setBounds = (one, two) ->
  146. Db.shared.set 'game', 'bounds', {one: one, two: two}
  147. # Get clients ingame user ID
  148. # exports.client_getIngameUserId = (client) ->
  149. # client.reply
  150. exports.client_getNewDeviceId = (client, result) ->
  151. newId = (Db.shared.peek('maxDeviceId'))+1
  152. log '[getDeviceId()] newId ' + newId + ' send to ' + Plugin.userName(client) + " (" + client + ")"
  153. Db.shared.set 'maxDeviceId', newId
  154. result.reply newId
  155. exports.client_log = (userId, message) ->
  156. log '[log()] Client:'+Plugin.userName(userId)+":"+userId+": "+message
  157. # Start the game
  158. exports.client_startGame = ->
  159. setTimer()
  160. userIds = Plugin.userIds()
  161. teams = Db.shared.peek('game','numberOfTeams')
  162. team = 0
  163. while(userIds.length > 0)
  164. randomNumber = Math.floor(Math.random() * userIds.length)
  165. Db.shared.set 'game', 'teams', team, 'users', userIds[randomNumber], 'userScore', 0
  166. Db.shared.set 'game', 'teams', team, 'users', userIds[randomNumber], 'captured', 0
  167. Db.shared.set 'game', 'teams', team, 'users', userIds[randomNumber], 'neutralized', 0
  168. Db.shared.set 'game', 'teams', team, 'users', userIds[randomNumber], 'userName', Plugin.userName(userIds[randomNumber])
  169. log '[startGame()] Team', team, 'has player', Plugin.userName(userIds[randomNumber])
  170. userIds.splice(randomNumber,1)
  171. team++
  172. team = 0 if team >= teams
  173. Db.shared.iterate 'game', 'teams', (team) !->
  174. Db.shared.set 'game', 'teams', team.key(), 'teamScore', 0
  175. Db.shared.set 'game', 'teams', team.key(), 'captured', 0
  176. Db.shared.set 'game', 'teams', team.key(), 'neutralized', 0
  177. Db.shared.set 'gameState', 1 # Set gameState at the end, because this triggers a repaint at the client so we want all data prepared before that
  178. Event.create
  179. unit: 'startGame'
  180. text: "The game has started!"
  181. # Checkin location for capturing a beacon
  182. exports.client_checkinLocation = (client, location, device, accuracy) ->
  183. if Db.shared.peek 'gameState' is not 1
  184. log '[checkinLocation()] Client ', client, ' (', Plugin.userName(client), ') tried to capture beacon while game is not running!'
  185. else
  186. log '[checkinLocation()] client: ', client, ', location: lat=', location.lat, ', lng=', location.lng
  187. beacons = Db.shared.ref('game', 'beacons')
  188. beaconRadius = Db.shared.peek('game', 'beaconRadius')
  189. beacons.iterate (beacon) ->
  190. current = beacon.peek('inRange', client)?
  191. beaconDistance = distance(location.lat, location.lng, beacon.peek('location', 'lat'), beacon.peek('location', 'lng'))
  192. newStatus = beaconDistance < beaconRadius
  193. if newStatus != current
  194. # Cancel timers of ongoing caputes/neutralizes (new ones will be set below if required)
  195. Timer.cancel 'onCapture', {beacon: beacon.key(), players: getInrangePlayers(beacon.key())}
  196. Timer.cancel 'onNeutralize', {beacon: beacon.key(), players: getInrangePlayers(beacon.key())}
  197. removed = undefined;
  198. if newStatus
  199. if not device? # Deal with old clients by denying them to be added to inRange
  200. log '[checkinLocation()] Denied adding to inRange, no deviceId provided: id=' + client + ', name=' + Plugin.userName(client)
  201. return
  202. if accuracy > beaconRadius
  203. log '[checkinLocation()] Denied adding to inRange of '+Plugin.userName(client)+' ('+client+'), accuracy too low: '+accuracy+'m'
  204. return
  205. owner = beacon.peek 'owner'
  206. log '[checkinLocation()] Added to inRange: id=' + client + ', name=' + Plugin.userName(client) + ', deviceId=' + device
  207. beacon.set 'inRange', client, device
  208. # Start takeover
  209. else
  210. inRangeValue = beacon.peek('inRange', client)
  211. if inRangeValue == 'true' || inRangeValue == device
  212. log '[checkinLocation()] Removed from inRange: id=' + client + ', name=' + Plugin.userName(client) + ', deviceId=' + device
  213. # clean takeover
  214. beacon.remove 'inRange', client
  215. removed = client
  216. else
  217. log '[checkinLocation()] Denied removing from inRange, deviceId does not match: id=' + client + ', name=' + Plugin.userName(client) + ', deviceId=' + device, ', inRangeValue=' + inRangeValue
  218. #log 'removed=', removed
  219. # ========== Handle changes for inRange players ==========
  220. # Determine members per team
  221. teamMembers = (0 for team in [0..5])
  222. beacon.iterate 'inRange', (player) !->
  223. if parseInt(player.key(), 10) != parseInt(removed, 10)
  224. team = getTeamOfUser(player.key())
  225. teamMembers[team] = teamMembers[team]+1
  226. #log 'teamMembers count: ', teamMembers
  227.  
  228. # Determine who is competing
  229. max = 0
  230. competing = []
  231. for team in [0..5]
  232. if teamMembers[team] > max
  233. max = teamMembers[team]
  234. competing = []
  235. competing.push team
  236. else if teamMembers[team] == max
  237. competing.push team
  238. # Update percentage taken for current time
  239. log '[checkinLocation()] Competing teams=', competing
  240. updateBeaconPercentage(beacon)
  241.  
  242. # Check if there should be progress
  243. if competing.length == 1
  244. # Team will capture the flag
  245. activeTeam = competing[0]
  246. if activeTeam != owner
  247. beacon.set 'nextOwner', activeTeam
  248. percentage = beacon.peek 'percentage'
  249. if owner == -1
  250. # Capturing
  251. log '[checkinLocation()] Team ', activeTeam, ' is capturing beacon ', beacon.key()
  252. beacon.set 'actionStarted', new Date()/1000
  253. beacon.set 'action', 'capture'
  254. # Set timer for capturing
  255. Timer.set (100-percentage)*10*30, 'onCapture', {beacon: beacon.key()}
  256. else
  257. # Neutralizing
  258. log '[checkinLocation()] Team ', activeTeam, ' is neutralizing beacon ', beacon.key()
  259. beacon.set 'actionStarted', new Date()/1000
  260. beacon.set 'action', 'neutralize'
  261. Timer.set percentage*10*30, 'onNeutralize', {beacon: beacon.key()}
  262. else
  263. log '[checkinLocation()] Active team already has the beacon, ', activeTeam, '=', owner
  264.  
  265. else
  266. # No progess, stand-off
  267. beacon.set 'actionStarted', new Date()/1000
  268. beacon.set 'action', 'none'
  269. if competing.length > 1
  270. log '[checkinLocation()] Capture of beacon ', beacon.key(), ' on hold, competing teams: ', competing
  271. else
  272. log '[checkinLocation()] Capture of beacon ', beacon.key(), ' stopped, left the area'
  273. # Update the takeover percentage of a beacon depening on current action and the passed time
  274. updateBeaconPercentage = (beacon) ->
  275. currentPercentage = beacon.peek 'percentage'
  276. action = beacon.peek 'action'
  277. actionStarted = beacon.peek 'actionStarted'
  278. if action is 'capture'
  279. time = (new Date()/1000)-actionStarted
  280. newPercentage = currentPercentage+(time/30*100)
  281. newPercentage = 100 if newPercentage>100
  282. beacon.set 'percentage', newPercentage
  283. else if action is 'neutralize'
  284. time = (new Date()/1000)-actionStarted
  285. newPercentage = currentPercentage-(time/30*100)
  286. newPercentage = 0 if newPercentage<0
  287. beacon.set 'percentage', newPercentage
  288.  
  289. #==================== Functions called by timers ====================
  290. #Function called when the game ends
  291. exports.endGame = (args) ->
  292. # End game and activate end game screen
  293. Db.shared.modify 'gameState', (v) -> 2
  294. log "[endGame()] The game ended! gameState: " + Db.shared.peek('gameState') + " "
  295. # Set winning team
  296. Db.shared.set 'game', 'firstTeam', getFirstTeam()
  297. # Cancel timers
  298. Db.shared.iterate 'game', 'beacons', (beacon) ->
  299. Timer.cancel 'onCapture', {beacon: beacon.key()}
  300. Timer.cancel 'onNeutralize', {beacon: beacon.key()}
  301. Timer.cancel 'overtimeScore', {beacon: beacon.key()}
  302.  
  303. # Geen punten per tijdseenheid
  304. # Pushbericht winnaar en verliezer
  305. # Knop voor herstarten voor admins en game owners
  306.  
  307. # Called by the beacon capture timer
  308. # args.beacon: beacon key
  309. exports.onCapture = (args) ->
  310. beacon = Db.shared.ref 'game', 'beacons', args.beacon
  311. nextOwner = beacon.peek('nextOwner')
  312. inRangeOfTeam = getInrangePlayersOfTeamArray(args.beacon, nextOwner)
  313. log '[onCapture()] Team ', nextOwner, ' has captured beacon ', beacon.key(), ', inRange players of team: '+inRangeOfTeam
  314. beacon.set 'percentage', 100
  315. beacon.set 'owner', nextOwner
  316. beacon.set 'actionStarted', new Date()/1000
  317. beacon.set 'action', 'none'
  318.  
  319. # Set a timer to gain teamscore overtime
  320. log '[onCapture()] pointsTime: '+global.pointsTime
  321. Timer.set global.pointsTime, 'overtimeScore', {beacon: beacon.key()}
  322.  
  323. # Add event log entrie(s)
  324. maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
  325. Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
  326. Db.shared.set 'game', 'eventlist', maxId, 'type', "capture"
  327. Db.shared.set 'game', 'eventlist', maxId, 'beacon', beacon.key()
  328. Db.shared.set 'game', 'eventlist', maxId, 'conqueror', nextOwner
  329.  
  330. # Handle push notifications
  331. # TODO: Personalize for team members or dubed players
  332. Event.create
  333. unit: 'capture'
  334. text: "Team " + Db.shared.peek('colors', nextOwner , 'name') + " captured a beacon"
  335.  
  336. # Give 1 person of the team the individual points
  337. modifyScore inRangeOfTeam[0], beacon.peek('captureValue')
  338.  
  339. # Increment captures per team and per capturer
  340. for player in inRangeOfTeam
  341. Db.shared.modify 'game', 'teams', getTeamOfUser(player) , 'users', player, 'captured', (v) -> v+1
  342. #log player + " from team " + getTeamOfUser(player) + " captured " + Db.shared.peek('game', 'teams', getTeamOfUser(player), 'users', player, 'captured') + " beacons"
  343. Db.shared.modify 'game', 'teams', nextOwner, 'captured', (v) -> v+1
  344. # Modify beacon value
  345. beacon.modify 'captureValue', (v) -> v - 1 if beacon.peek('captureValue') > 1
  346.  
  347. # The game will end in 1 hour if all the beacons are captured by one team
  348. capOwner = Db.shared.peek('game', 'beacons', '0', 'owner')
  349. log 'capOwner', capOwner
  350. allBeaconsCaptured = true
  351. Db.shared.iterate 'game', 'beacons', (beacon) ->
  352. if capOwner isnt beacon.peek('owner')
  353. log 'capOwner2', beacon.peek('owner')
  354. allBeaconsCaptured = false
  355. log 'capturedBeaconState', allBeaconsCaptured
  356. log 'allbeaconscapturedFinal', allBeaconsCaptured
  357. endTime=Db.shared.peek('game', 'endTime')
  358. if allBeaconsCaptured and endTime-Plugin.time()>global.pointsTimeSec
  359. owner = Db.shared.peek('colors', nextOwner , 'name')
  360. Event.create
  361. unit: 'captureAll'
  362. text: "Team " + Db.shared.peek('colors', beacon.get('owner'), 'name') + " has captured all beacons, the game will end in 1 hour if you don't reconquer!!"
  363. end = Plugin.time()+global.pointsTimeSec #in seconds
  364. log 'end', end
  365. Db.shared.set 'game', 'newEndTime', end
  366. Timer.cancel 'endGame'
  367. Timer.set global.pointsTime, 'endGame', args
  368.  
  369. endGame() # Debug endGame()
  370. # Called by the beacon neutralize timer
  371. exports.onNeutralize = (args) ->
  372. beacon = Db.shared.ref 'game', 'beacons', args.beacon
  373. neutralizer = beacon.peek('nextOwner')
  374. inRangeOfTeam = getInrangePlayersOfTeamArray(args.beacon, nextOwner)
  375. log '[onNeutralize()] Team ', neutralizer, ' has neutralized beacon ', beacon.key(), ', players: '+inRangeOfTeam
  376. beacon.set 'percentage', 0
  377. beacon.set 'owner', -1
  378.  
  379. #cancel gain teamscore overtime
  380. Timer.cancel 'overtimeScore', {beacon: beacon.key()}
  381.  
  382. #Call the timer to reset the time in the correct endtime in the database
  383. end = Db.shared.peek 'game', 'endTime'
  384. Db.shared.modify 'game', 'newEndTime', (v) -> 0
  385. Timer.cancel 'endGame'
  386. Timer.set (end-Plugin.time())*1000, 'endGame'
  387.  
  388. # Increment neutralizes per team and per capturer
  389. for player in inRangeOfTeam
  390. Db.shared.modify 'game', 'teams', getTeamOfUser(player), 'users', player, 'neutralized', (v) -> v+1
  391. Db.shared.modify 'game', 'teams', neutralizer, 'neutralized', (v) -> v+1
  392.  
  393. # Handle capturing
  394. updateBeaconPercentage(beacon)
  395. percentage = beacon.peek 'percentage'
  396. log '[onNeutralize()] Team ', neutralizer, ' is capturing beacon ', beacon.key(), ' (after neutralize)'
  397.  
  398. beacon.set 'action', 'capture'
  399. beacon.set 'actionStarted', new Date()/1000
  400. # Set timer for capturing
  401. Timer.set (100-percentage)*10*30, 'onCapture', args
  402.  
  403. # Modify teamscore for possessing a beacon for a certain amount of time
  404. exports.overtimeScore = (args) ->
  405. owner = Db.shared.peek 'game', 'beacons', args.beacon, 'owner'
  406. Db.shared.modify 'game', 'teams', owner, 'teamScore', (v) -> v + 1
  407. Timer.set global.pointsTime, 'overtimeScore', args # Every hour
  408.  
  409. # ==================== Functions ====================
  410. # Get a string of the players that are inRange of a beacon
  411. getInrangePlayers = (beacon) ->
  412. playersStr = undefined;
  413. Db.shared.iterate 'game', 'beacons', beacon, 'inRange', (player) !->
  414. if playersStr?
  415. playersStr = playersStr + ', ' + player.key()
  416. else
  417. playersStr = player.key()
  418. return playersStr
  419. getInrangePlayersOfTeam = (beacon, team) ->
  420. playersStr = undefined;
  421. Db.shared.iterate 'game', 'beacons', beacon, 'inRange', (player) !->
  422. if getTeamOfUser(player.key()) == team
  423. if playersStr?
  424. playersStr = playersStr + ', ' + player.key()
  425. else
  426. playersStr = player.key()
  427. return playersStr
  428. getInrangePlayersOfTeamArray = (beacon, team) ->
  429. players = [];
  430. Db.shared.iterate 'game', 'beacons', beacon, 'inRange', (player) !->
  431. if parseInt(getTeamOfUser(player.key()), 10) == parseInt(team, 10)
  432. players.push(player.key())
  433. return players
  434. # Setup an empty game
  435. initializeGame = ->
  436. # Stop all timers from the previous game
  437. Db.shared.iterate 'game', 'beacons', (beacon) ->
  438. Timer.cancel 'onCapture', {beacon: beacon.key()}
  439. Timer.cancel 'onNeutralize', {beacon: beacon.key()}
  440. Timer.cancel 'overtimeScore', {beacon: beacon.key()}
  441. # Reset database to defaults
  442. Db.shared.set 'game', {}
  443. #Db.shared.set 'game', 'bounds', {one: {lat: 52.249822176849, lng: 6.8396973609924}, two: {lat: 52.236578295702, lng: 6.8598246574402}} # TOOD remove
  444. Db.shared.set 'game', 'numberOfTeams', 2
  445. Db.shared.set 'game', 'beaconRadius', 200
  446. Db.shared.set 'game', 'roundTimeUnit', 'Days'
  447. Db.shared.set 'game', 'roundTimeNumber', 7
  448. Db.shared.set 'game', 'eventlist', 'maxId', 0
  449.  
  450. Db.shared.set 'gameState', 0
  451. Db.shared.modify 'gameNumber', (v) -> (0||v)+1
  452. initializeColors = ->
  453. Db.shared.set 'colors',
  454. {
  455. '-1': {name: 'neutral', capitalizedName: 'Neutral', hex: '#999999'},
  456. 0: {name: 'blue', capitalizedName: 'Blue', hex: '#3882b6'},
  457. 1: {name: 'red', capitalizedName: 'Red', hex: '#FF3C00'},
  458. 2: {name: 'green', capitalizedName: 'Green', hex: '#009F22'},
  459. 3: {name: 'yellow', capitalizedName: 'Yellow', hex: '#E8E03F'},
  460. 4: {name: 'orange', capitalizedName: 'Orange', hex: '#FFB400'},
  461. 5: {name: 'purple', capitalizedName: 'Purple', hex: '#E700D4'}
  462. }
  463. # Game timer
  464. setTimer = ->
  465. if Db.shared.peek('game', 'roundTimeUnit') is 'Months'
  466. seconds = Db.shared.peek('game', 'roundTimeNumber')*2592000
  467. else if Db.shared.peek('game', 'roundTimeUnit') is 'Days'
  468. seconds = Db.shared.peek('game', 'roundTimeNumber')*86400
  469. else if Db.shared.peek('game', 'roundTimeUnit') is 'Hours'
  470. seconds = Db.shared.peek('game', 'roundTimeNumber')*3600
  471. end = Plugin.time()+seconds #in seconds
  472. Db.shared.set 'game', 'endTime', end
  473. Timer.cancel
  474. Timer.set seconds*1000, 'endGame' #endGame is the function called when the timer ends
  475. # Calculate distance
  476. distance = (inputLat1, inputLng1, inputLat2, inputLng2) ->
  477. r = 6378137
  478. rad = Math.PI / 180
  479. lat1 = inputLat1 * rad
  480. lat2 = inputLat2 * rad
  481. a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((inputLng2 - inputLng1) * rad);
  482. return r * Math.acos(Math.min(a, 1));
  483. # Get the team id the user is added to
  484. getTeamOfUser = (userId) ->
  485. result = undefined
  486. Db.shared.iterate 'game', 'teams', (team) !->
  487. if team.peek('users', userId, 'userName')?
  488. result = team.key()
  489. #if result is -1
  490. # log 'Warning: Did not find team for userId=', userId
  491. return result
  492. # Returns team with the highest score
  493. getFirstTeam = ->
  494. teamMax = -1
  495. maxScore = -1
  496. Db.shared.iterate 'game', 'teams', (team) !->
  497. if maxScore < team.peek('teamScore')
  498. teamMax = team.key()
  499. maxScore = team.peek('teamScore')
  500. log "[getFirstTeam()] teamMax: " + teamMax
  501. return teamMax
  502. # Modify user and team scores by adding "points" to the current value
  503. modifyScore = (client, points) !->
  504. log "[modifyScore()] client: " + client + " team: " + getTeamOfUser(client) + " points: " + points
  505. # calculate old number one
  506. teamMax = getFirstTeam()
  507. newLead = false
  508.  
  509. # modify user and team scores
  510.  
  511. teamClient = getTeamOfUser(client)
  512. Db.shared.modify 'game', 'teams', teamClient, 'users', client, 'userScore', (v) -> v + points
  513. Db.shared.modify 'game', 'teams', teamClient, 'teamScore', (v) -> v + points
  514.  
  515. newLead = getFirstTeam() isnt teamMax
  516.  
  517. log "[modifyScore()] TeamMax: " + teamMax + " newLead: " + newLead + " (2)"
  518.  
  519. # create score event
  520. # To Do: personalize for team members or dubed players
  521. if newLead
  522. maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
  523. Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
  524. Db.shared.set 'game', 'eventlist', maxId, 'type', "score"
  525. Db.shared.set 'game', 'eventlist', maxId, 'leading', teamClient
  526. log "[modifyScore()] Team " + Db.shared.peek('colors', teamMax, 'name') + " took the lead!"
  527. Event.create
  528. unit: 'score'
  529. text: "Team " + Db.shared.peek('colors', teamMax, 'name') + " took the lead!"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement