1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace Smr; |
4
|
|
|
|
5
|
|
|
use SmrGame; |
6
|
|
|
use SmrPlayer; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Collection of functions to help with Lotto processing. |
10
|
|
|
*/ |
11
|
|
|
class Lotto { |
12
|
|
|
|
13
|
|
|
public const TICKET_COST = 1000000; // cost of 1 ticket |
14
|
|
|
public const WIN_FRAC = 0.9; // fraction of ticket sales returned to winner |
15
|
|
|
|
16
|
|
|
public static function checkForLottoWinner(int $gameID): void { |
17
|
|
|
|
18
|
|
|
// No more lotto winners after the game has ended |
19
|
|
|
if (SmrGame::getGame($gameID)->hasEnded()) { |
20
|
|
|
return; |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
// we check for a lotto winner... |
24
|
|
|
$db = Database::getInstance(); |
25
|
|
|
$db->lockTable('player_has_ticket'); |
26
|
|
|
$lottoInfo = self::getLottoInfo($gameID); |
27
|
|
|
|
28
|
|
|
if ($lottoInfo['TimeRemaining'] > 0) { |
29
|
|
|
// Drawing is not closed yet |
30
|
|
|
$db->unlock(); |
31
|
|
|
return; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
//we need to pick a winner |
35
|
|
|
$dbResult = $db->read('SELECT * FROM player_has_ticket WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND time > 0 ORDER BY rand() LIMIT 1'); |
36
|
|
|
$winner_id = $dbResult->record()->getInt('account_id'); |
37
|
|
|
|
38
|
|
|
// Any unclaimed prizes get merged into this prize |
39
|
|
|
$dbResult = $db->read('SELECT IFNULL(SUM(prize), 0) AS total_prize FROM player_has_ticket WHERE time = 0 AND game_id = ' . $db->escapeNumber($gameID)); |
40
|
|
|
$lottoInfo['Prize'] += $dbResult->record()->getInt('total_prize'); |
41
|
|
|
|
42
|
|
|
// Delete all tickets and re-insert the winning ticket |
43
|
|
|
$db->write('DELETE FROM player_has_ticket WHERE game_id = ' . $db->escapeNumber($gameID)); |
44
|
|
|
$db->insert('player_has_ticket', [ |
45
|
|
|
'game_id' => $db->escapeNumber($gameID), |
46
|
|
|
'account_id' => $db->escapeNumber($winner_id), |
47
|
|
|
'time' => 0, |
48
|
|
|
'prize' => $db->escapeNumber($lottoInfo['Prize']), |
49
|
|
|
]); |
50
|
|
|
$db->unlock(); |
51
|
|
|
|
52
|
|
|
// create news msg |
53
|
|
|
$winner = SmrPlayer::getPlayer($winner_id, $gameID); |
54
|
|
|
$winner->increaseHOF($lottoInfo['Prize'], ['Bar', 'Lotto', 'Money', 'Winnings'], HOF_PUBLIC); |
55
|
|
|
$winner->increaseHOF(1, ['Bar', 'Lotto', 'Results', 'Wins'], HOF_PUBLIC); |
56
|
|
|
$news_message = $winner->getBBLink() . ' has won the lotto! The jackpot was ' . number_format($lottoInfo['Prize']) . '. ' . $winner->getBBLink() . ' can report to any bar to claim their prize before the next drawing!'; |
57
|
|
|
// insert the news entry |
58
|
|
|
$db->write('DELETE FROM news WHERE type = \'lotto\' AND game_id = ' . $db->escapeNumber($gameID)); |
59
|
|
|
$db->insert('news', [ |
60
|
|
|
'game_id' => $db->escapeNumber($gameID), |
61
|
|
|
'time' => $db->escapeNumber(Epoch::time()), |
62
|
|
|
'news_message' => $db->escapeString($news_message), |
63
|
|
|
'type' => $db->escapeString('lotto'), |
64
|
|
|
'dead_id' => $db->escapeNumber($winner->getAccountID()), |
65
|
|
|
'dead_alliance' => $db->escapeNumber($winner->getAllianceID()), |
66
|
|
|
]); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @return array<string, int> |
71
|
|
|
*/ |
72
|
|
|
public static function getLottoInfo(int $gameID): array { |
73
|
|
|
$amount = self::TICKET_COST; // pot starts with 1 ticket value |
74
|
|
|
$firstBuy = Epoch::time(); |
75
|
|
|
|
76
|
|
|
$db = Database::getInstance(); |
77
|
|
|
$dbResult = $db->read('SELECT count(*) as num, min(time) as time FROM player_has_ticket |
78
|
|
|
WHERE game_id = ' . $db->escapeNumber($gameID) . ' AND time > 0'); |
79
|
|
|
$dbRecord = $dbResult->record(); |
80
|
|
|
if ($dbRecord->getInt('num') > 0) { |
81
|
|
|
$amount += $dbRecord->getInt('num') * IFloor(self::TICKET_COST * self::WIN_FRAC); |
|
|
|
|
82
|
|
|
$firstBuy = $dbRecord->getInt('time'); |
83
|
|
|
} |
84
|
|
|
//find the time remaining in this jackpot. (which is 2 days from the first purchased ticket) |
85
|
|
|
return ['Prize' => $amount, 'TimeRemaining' => $firstBuy + TIME_LOTTO - Epoch::time()]; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
} |
89
|
|
|
|