· 9 years ago · Dec 18, 2016, 02:38 PM
1--[[
2 Name: sv_economy.lua
3 For: TalosLife
4 By: TalosLife
5]]--
6
7hook.Add( "GamemodePlayerSelectCharacter", "NetworkEconData", function( pPlayer )
8 timer.Simple( 30, function()
9 if not IsValid( pPlayer ) then return end
10 GAMEMODE.Net:SendPlayerBills( pPlayer )
11 GAMEMODE.Net:SendTaxFullUpdate( pPlayer )
12 end )
13
14 timer.Simple( 5, function()
15 if not IsValid( pPlayer ) then return end
16 for k, v in pairs( GAMEMODE.Econ.m_tblBills ) do
17 if GAMEMODE.Econ:PlayerHasUnpaidBillsOfType( pPlayer, k ) then
18 pPlayer:AddNote( "Du har ubetalte regninger. Husk at betale dem i banken.", NOTIFY_ERROR, 20 )
19 break
20 end
21 end
22 end )
23end )
24
25-- Taxes
26-- ----------------------------------------------------------------
27function GM.Econ:SetTaxRate( strTaxID, intRate, bNoNetwork )
28 local data = self.m_tblTaxes[strTaxID]
29 if not data then return false end
30
31 intRate = math.Clamp( intRate, data.MinValue, data.MaxValue )
32 local oldValue = data.Value or 0
33 data.Value = intRate
34
35 if not bNoNetwork then
36 GAMEMODE.Net:SendTaxUpdate( nil, strTaxID )
37 self:CommitTaxData()
38 end
39
40 self:OnTaxRateChanged( strTaxID, oldValue, data.Value )
41 return true
42end
43
44function GM.Econ:OnTaxRateChanged( strTaxID, intOldValue, intNewValue )
45 hook.Call( "GamemodeOnTaxRateChanged", GAMEMODE, strTaxID, intOldValue, intNewValue )
46end
47
48function GM.Econ:CommitTaxData()
49 local num, done = table.Count( self.m_tblTaxes ), 0
50 local callback = function( tblData, q )
51 done = done +1
52 if done == num then
53 GAMEMODE.ServerNet:BroadcastTaxesChanged()
54 end
55 end
56
57 for k, v in pairs( self.m_tblTaxes ) do
58 GAMEMODE.SQL:PooledQueryWrite( 2, ([[INSERT INTO gamemode_taxes (`key`, value) VALUES ('%s', %1.2f) ON DUPLICATE KEY UPDATE value=%1.2f]]):format(
59 k,
60 v.Value,
61 v.Value
62 ), callback )
63 end
64end
65
66function GM.Econ:LoadSavedTaxData()
67 GAMEMODE.SQL:QueryReadOnly( [[SELECT * FROM gamemode_taxes]], function( tblData, q )
68 for k, row in pairs( tblData ) do
69 GAMEMODE.Econ:SetTaxRate( row.key, row.value, true )
70 end
71
72 GAMEMODE.Net:SendTaxFullUpdate()
73 end )
74end
75
76-- Bills
77-- ----------------------------------------------------------------
78--intTimeToPay = 0 for a bill that never expires
79GM.Econ.m_tblAutoBills = (GAMEMODE or GM).Econ.m_tblAutoBills or {}
80
81function GM.Econ:RegisterAutoBill( strUID, intDuration, funcBillPlayer )
82 self.m_tblAutoBills[strUID] = { Length = intDuration, BillPlayer = funcBillPlayer }
83end
84
85function GM.Econ:LoadAutoBills()
86 self:RegisterAutoBill( "bill_cars", GM.Config.CarInsuranceTaxInterval, function( pPlayer )
87 if not pPlayer:GetCharacter() then return end
88 local bill = false
89 for k, v in pairs( pPlayer:GetCharacter().Vehicles ) do
90 local data = GAMEMODE.Cars:GetCarByUID( k )
91 if not data then continue end
92 local billCost = math.ceil( GAMEMODE.CarShop:GetRepairCost(data.Price, 0, 100) *GAMEMODE.Config.CarInsuranceBillScale )
93 self:IssuePlayerBill(
94 pPlayer,
95 "car_insurance",
96 "Vehicle Insurance: ".. data.Name,
97 billCost,
98 GAMEMODE.Config.CarInsuranceBillTime,
99 { Shared = {CarID = k} }
100 )
101 bill = true
102 end
103
104 if bill then pPlayer:AddNote( "Du har ny bilforsikrings regning, betal dem i banken." ) end
105 end )
106
107 self:RegisterAutoBill( "bill_property", GM.Config.PropertyTaxInterval, function( pPlayer )
108 if not pPlayer:GetCharacter() then return end
109 local bill = false
110 for k, v in pairs( GAMEMODE.Property:GetPropertiesByOwner(pPlayer) ) do
111 local data = GAMEMODE.Property.m_tblRegister[GAMEMODE.Property:GetPropertyByName(v).ID]
112 if not data or not data.Price or not data.Cat then continue end
113 local billCost = GAMEMODE.Econ:ApplyTaxToSum( "prop_".. data.Cat, data.Price *GAMEMODE.Config.PropertyTaxScale )
114 self:IssuePlayerBill(
115 pPlayer,
116 "property",
117 "Property Tax: ".. data.Name,
118 billCost,
119 0,
120 { Shared = {PropertyID = v} }
121 )
122 bill = true
123 end
124
125 if bill then pPlayer:AddNote( "Du har ny husleje regning, betal dem i banken" ) end
126 end )
127end
128
129function GM.Econ:IssuePlayerBill( pPlayer, strBillID, strBillName, intBillCost, intTimeToPay, tblMetaData )
130 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
131 if not saveTable then return false end
132 saveTable.Bills = saveTable.Bills or {}
133
134 local bill = {
135 Type = strBillID,
136 Name = strBillName,
137 Cost = intBillCost,
138 LifeTime = intTimeToPay,
139 IssueTime = os.time(),
140 MetaData = tblMetaData
141 }
142 local billUID = table.insert( saveTable.Bills, bill )
143 GAMEMODE.SQL:MarkDiffDirty( pPlayer, "data_store", "Bills" )
144 GAMEMODE.Net:SendPlayerBills( pPlayer )
145
146 return billUID
147end
148
149function GM.Econ:PlayerPayBill( pPlayer, intBillIDX )
150 --intBillIDX is the key of the bill being paid in the save table
151 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
152 if not saveTable or not saveTable.Bills then return false end
153
154 local billData = saveTable.Bills[intBillIDX]
155 if not billData then return false end
156
157 local typeData = self:GetBillData( billData.Type )
158 if not typeData then return false end
159
160 if not pPlayer:CanAfford( billData.Cost ) then
161 pPlayer:AddNote( "Du har ikke råd til at betale alle dine regninger" )
162 return false
163 end
164
165 pPlayer:TakeMoney( billData.Cost )
166 typeData.OnPay( pPlayer, billData, billData.MetaData, intBillIDX )
167 table.remove( saveTable.Bills, intBillIDX )
168 GAMEMODE.SQL:MarkDiffDirty( pPlayer, "data_store", "Bills" )
169 GAMEMODE.Net:SendPlayerBills( pPlayer )
170 pPlayer:AddNote( "You paid off a bill for $".. string.Comma(billData.Cost).. "!" )
171 return true
172end
173
174function GM.Econ:PlayerPayAllBills( pPlayer )
175 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
176 if not saveTable or not saveTable.Bills then return false end
177
178 local total = 0
179 for k, v in pairs( saveTable.Bills ) do
180 total = total +v.Cost
181 end
182 if total <= 0 then return end
183
184 if not pPlayer:CanAfford( total ) then
185 pPlayer:AddNote( "Du har ikke råd til at betale alle dine regninger!" )
186 return false
187 end
188
189 pPlayer:TakeMoney( total )
190 for k, v in pairs( saveTable.Bills ) do
191 if not self:GetBillData( v.Type ) then continue end
192 self:GetBillData( v.Type ).OnPay( pPlayer, v, v.MetaData, k )
193 end
194
195 saveTable.Bills = {}
196 GAMEMODE.SQL:MarkDiffDirty( pPlayer, "data_store", "Bills" )
197 GAMEMODE.Net:SendPlayerBills( pPlayer )
198 pPlayer:AddNote( "Du har betalt alle dine regninger på $".. string.Comma(total).. "!" )
199 return true
200end
201
202function GM.Econ:OnPlayerBillExpired( pPlayer, intBillIDX )
203 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
204 if not saveTable or not saveTable.Bills then return false end
205
206 local billData = saveTable.Bills[intBillIDX]
207 if not billData then return false end
208
209 local typeData = self:GetBillData( billData.Type )
210 if not typeData then return false end
211
212 typeData.OnDefault( pPlayer, billData, billData.MetaData, intBillIDX )
213 table.remove( saveTable.Bills, intBillIDX )
214 GAMEMODE.SQL:MarkDiffDirty( pPlayer, "data_store", "Bills" )
215 GAMEMODE.Net:SendPlayerBills( pPlayer )
216
217 return true
218end
219
220function GM.Econ:TickPlayerBills( pPlayer )
221 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
222 if not saveTable or not saveTable.Bills then return end
223
224 local time = os.time()
225 for uid, billData in pairs( saveTable.Bills ) do
226 local data = self.m_tblBills[billData.Type]
227 if not data then continue end
228
229 if data.Update then
230 if time > (billData.LastUpdate or 0) then
231 billData.LastUpdate = time +5
232 data.Update( pPlayer, billData, billData.MetaData, uid )
233 end
234 end
235
236 if billData.LifeTime <= 0 then continue end --This bill never expires until paid
237 if time > (billData.IssueTime +billData.LifeTime) then --This bill has passed the expiry point!
238 self:OnPlayerBillExpired( pPlayer, uid )
239 end
240 end
241end
242
243function GM.Econ:TickAutoBills( pPlayer )
244 local saveTable = GAMEMODE.Char:GetCurrentSaveTable( pPlayer )
245 if not saveTable then return end
246
247 local dirty = not saveTable.AutoBills
248 saveTable.AutoBills = saveTable.AutoBills or {}
249 local playTime = GAMEMODE.Jobs:GetTotalSavedPlayTime( pPlayer )
250
251 for billID, v in pairs( self.m_tblAutoBills ) do
252 if not saveTable.AutoBills[billID] then
253 saveTable.AutoBills[billID] = playTime
254 dirty = true
255 continue
256 end
257
258 if playTime >= saveTable.AutoBills[billID] +v.Length then
259 saveTable.AutoBills[billID] = playTime
260 dirty = true
261 v.BillPlayer( pPlayer )
262 end
263 end
264
265 if dirty then
266 GAMEMODE.SQL:MarkDiffDirty( pPlayer, "data_store", "AutoBills" )
267 end
268end
269
270hook.Add( "GamemodeCanPlayerBuyProperty", "Bills_UnpiadBlockPurchase", function( pPlayer, strPropName )
271 if GAMEMODE.Econ:PlayerHasUnpaidBillsOfType( pPlayer, "property" ) then
272 pPlayer:AddNote( "Du har ubetalte husleje regninger!" )
273 pPlayer:AddNote( "Du skal betale dem før du kan købe en ny ejendom." )
274 return false
275 end
276end )
277
278hook.Add( "GamemodeInitSQLTables", "DefineLoadEconData", function()
279 GAMEMODE.SQL:PooledQueryWrite( 1, [[CREATE TABLE IF NOT EXISTS `gamemode_taxes` (
280 `key` VARCHAR(255) NOT NULL,
281 `value` FLOAT NULL,
282 UNIQUE INDEX `key` (`key`)
283 ) ENGINE=InnoDB;]], function()
284 GAMEMODE.Econ:LoadSavedTaxData()
285 end )
286end )