· 6 years ago · Aug 18, 2019, 10:40 PM
1include("sh_gangs.lua")
2--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3-- Gang Wars & Gang Bases
4util.AddNetworkString("GangBaseDialog")
5util.AddNetworkString("GangWarStartDialog")
6util.AddNetworkString("GangWarOverDialog")
7util.AddNetworkString("ds_gang_points") -- set gang points on the client
8util.AddNetworkString("set_gang_news") -- set gang news msg from client
9util.AddNetworkString("sv_refresh_topgangs")
10GangWars.GangBases = {}
11GangWars.GangWars = {}
12local meta = FindMetaTable("Player")
13
14function meta:GetGangBase()
15 return GangWars.GangBases[self:Gang()]
16end
17
18local function GiveGangMembersXP(gang, xp)
19 for k, v in pairs(player.GetAll()) do
20 if v:Gang() == gang then
21 GangWars.AddXP(v, xp)
22 end
23 end
24end
25
26GangWars.GiveGangMembersXP = GiveGangMembersXP
27
28-- this function will give a % of required XP
29local function GiveGangMembersXPAuto(gang, perc)
30 for k, v in pairs(player.GetAll()) do
31 if v:Gang() == gang then
32 local lvl = GangWars.GetLevel(v) + v:Tier()
33 local xp2l = GangWars.GetXP2L(lvl)
34 local xp = math.floor((xp2l / 100) * (perc or 50))
35 GangWars.AddXP(v, xp, true)
36 end
37 end
38end
39
40GangWars.GiveGangMembersXPAuto = GiveGangMembersXPAuto
41
42local function ServerHasGangVariance()
43 local gangs = {}
44
45 for k, v in pairs(player.GetAll()) do
46 if v:Gang() ~= "" then
47 gangs[v:Gang()] = 1
48 end
49 end
50
51 return table.Count(gangs) > 1
52end
53
54local MIN_TIME_BETWEEN_GANG_BASES = (3600 + 1800)
55
56function GangWars.SetGangBase(ply, base_building)
57 local gang = ply:Gang()
58 local bb = GangWars.FindBuildingByID(base_building)
59
60 -- is gang ok?
61 if gang == "" then
62 Notify(ply, NOTIFY_ERROR, 4, "You are not in a gang")
63
64 return
65 end
66
67 -- is points ok?
68 if not ply.GangInfo or not ply.GangInfo.points or ply.GangInfo.points < 1000 then
69 Notify(ply, NOTIFY_ERROR, 4, "You need at least 1,000 points to make a Gang Base")
70
71 return
72 end
73
74 -- is this building inside a territory owned by our gang?
75 local building_is_in_territory = false
76 local territory = nil
77
78 for k, v in pairs(GangWars.GangTerritories) do
79 if v:ObjectIsInside(bb) and v.owner and v.owner == gang then
80 building_is_in_territory = true
81 territory = v
82 break
83 end
84 end
85
86 if not building_is_in_territory then
87 Notify(ply, NOTIFY_ERROR, 4, "You can only make a gang base within territory you own")
88
89 return
90 end
91
92 -- can we base?
93 isql:QueryValue("SELECT TIME_TO_SEC(TIMEDIFF(NOW(), `last_base`)) FROM `gw_gangs` WHERE `name` = " .. isql:Escape(gang), function(timediff)
94 -- is base ok?
95 if not bb or not bb.bdata or not bb.capture_point then
96 GangNotify(ply, NOTIFY_ERROR, 4, "You can't make a gang base here - " .. base_building)
97 --MsgN("bb = " .. tostring(bb))
98
99 return
100 end
101
102 -- are we at war?
103 if GangWars.GangWars[gang] then
104 GangNotify(ply, NOTIFY_ERROR, 4, "You can't change base while at war!")
105
106 return
107 end
108
109 -- do we have access?
110 if ply:GetNW2Int("gang_rank") > 2 then
111 GangNotify(ply, NOTIFY_ERROR, 4, "Gang Base can only be set by leader & vice leader")
112
113 return
114 end
115
116 -- is there already a base set? compare access levels
117 if GangWars.GangBases[gang] and IsValid(GangWars.GangBases[gang].owner) and GangWars.GangBases[gang].owner:GetNW2Int("gang_rank") < ply:GetNW2Int("gang_rank") then
118 GangNotify(ply, NOTIFY_ERROR, 4, "Your gang already has a base set")
119
120 return
121 end
122
123 -- Cancel / Un-set base
124 if GangWars.GangBases[gang] and GangWars.GangBases[gang].base == base_building then
125 NotifyGang(ply, NOTIFY_ERROR, 4, "Your Gang Base has been un-set. You have no base!")
126
127 -- update building doors
128 for k, v in pairs(bb.doors) do
129 v:SetNW2String("gang", "")
130 end
131
132 -- set data
133 GangWars.GangBases[gang] = nil
134
135 return
136 end
137
138 -- timediff is the number of seconds since we last based. it must be at least 60 mins.
139 -- is time ok?
140 if not timediff or timediff < MIN_TIME_BETWEEN_GANG_BASES then
141 GangNotify(ply, NOTIFY_ERROR, 4, "You can't make a gang base for " .. math.floor((MIN_TIME_BETWEEN_GANG_BASES - (timediff or 60)) / 60) .. " minutes")
142
143 return
144 end
145
146 local newbase = GangWars.GangBases[gang] == nil and false or true
147 -- set database entry for last base
148 isql:Query("UPDATE `gw_gangs` SET `last_base` = NOW() WHERE `name` = " .. isql:Escape(gang))
149
150 -- set base entry
151 GangWars.GangBases[gang] = {
152 owner = ply,
153 gang = gang,
154 base = base_building,
155 territory = territory
156 }
157
158 -- set a gangbase flag here. this is used in UnOwn() in entity.lua to automaticly unset the GangBase entry, capture points use it too.
159 local building = bb
160 building.GangBase = gang
161
162 --[[
163 // create the points tick timer
164 timer.Create("GangBase" .. gang, 60, 0, function()
165 if GangWars.GangBases[gang] then
166
167 // how many points should they earn? 50 base
168 local points = 50
169
170 // launderers, printers, forges boost points by 5
171 local contraband_owned_by_gang = 0;
172 // count contraband which are plugged in, whos owner is in this gang and are a reasonable distance from base
173 local counters = { "money_printer", "money_launderer", "material_forge" }
174 for x, y in pairs(counters) do
175 for k,v in pairs(ents.FindByClass(y) or {}) do
176 if v:GetNW2Bool("connected") and v:GetNWEntity("owning_ent"):Gang() == gang and v:GetPos():DistToSqr( building:GetPos() ) < 1000000 then
177 contraband_owned_by_gang = contraband_owned_by_gang + 1
178 end
179 end
180 end
181
182 // boost points - +5 per contraband
183 points = points + contraband_owned_by_gang * 5
184
185 if table.Count(player.GetAll()) < 10 or not ServerHasGangVariance() then
186 NotifyGang(gang, NOTIFY_ERROR, 4, "No Gang Points with less than 10 people / no other Gangs on the server")
187 else
188 GangWars.DB.AddGangPoints( gang, points, function() end )
189 NotifyGang(gang, NOTIFY_ERROR, 4, "Your base earned +" .. points .. " Gang Points")
190 end
191 else
192 timer.Remove("GangBase" .. gang)
193 end
194 end)
195 ]]
196 -- update clients? not needed because they only need to know this during war?
197 -- update building doors
198 for k, v in pairs(building.doors) do
199 v:SetNW2String("gang", gang)
200 end
201
202 -- tell gang members
203 if newbase then
204 net.Start("GangBaseDialog")
205 net.Send(ply)
206 NotifyGang(gang, 4, 4, "Your Gang Base is set to " .. bb.bdata.name, true)
207 else
208 NotifyGang(gang, 4, 4, "Your Gang Base changed to " .. bb.bdata.name, true)
209 end
210 end)
211end
212
213AddChatCommand("/base", function(ply)
214 local trace = ply:GetEyeTrace()
215
216 if IsValid(trace.Entity) and trace.Entity:IsOwnable() and trace.Entity:IsDoor() and ply:GetPos():Distance(trace.Entity:GetPos()) < 200 then
217 if RPArrestedPlayers[ply:SteamID()] then
218 Notify(ply, 1, 5, "You can't do that while arrested!")
219
220 return ""
221 end
222
223 if trace.Entity:GetNW2Bool("nonOwnable") or trace.Entity:GetNW2Bool("BankerOwnable") then
224 Notify(ply, 1, 5, "This door can not be owned")
225
226 return ""
227 end
228
229 if not trace.Entity:OwnedBy(ply) then
230 Notify(ply, 1, 5, "You don't own this building")
231
232 return ""
233 end
234
235 GangWars.SetGangBase(ply, trace.Entity.building.bdata.id)
236 end
237
238 return ""
239end)
240
241-- This is fking lazy and should be rewritten using a proper net message
242function GangWars.ClientUpdateGangWarData(ply)
243 local war = GangWars.GangWars[ply:Gang()]
244
245 if war then
246 if war.role == "attacking" then
247 local ebase = GangWars.GangBases[war.rival]
248 ply:SendLua("GangWars.GangWar = { role = '" .. war.role .. "', rival = '" .. war.rival .. "', base = '" .. ebase.base .. "', tokens = " .. war.tokens .. " }")
249 else
250 local base = GangWars.GangBases[war.gang]
251
252 -- I've seen here there be no base entry! So we're getting an update on a war where the defense no longer has a base? def should lose?
253 if not base then
254 GangWars.FinishGangWar(war.rival)
255
256 return
257 end
258
259 ply:SendLua("GangWars.GangWar = { role = '" .. war.role .. "', rival = '" .. war.rival .. "', base = '" .. base.base .. "', tokens = " .. GangWars.GangWars[war.rival].tokens .. " }")
260 end
261 else
262 ply:SendLua("GangWars.GangWar = nil")
263 end
264end
265
266--AddChatCommand("/testwar", function(ply, args)
267-- GangWars.StartGangWar( ply, ply:Gang() )
268-- return ""
269--end)
270AddChatCommand("/war", function(ply, args)
271 local trace = ply:GetEyeTrace()
272
273 if IsValid(trace.Entity) and trace.Entity:IsPlayer() then
274 GangWars.StartGangWar(ply, trace.Entity:Gang())
275 elseif IsValid(trace.Entity) and trace.Entity.building and trace.Entity.building.bdata and trace.Entity.building.bdata.id and trace.Entity.building.GangBase then
276 -- search for a gang base at this ID
277 for k, v in pairs(GangWars.GangBases) do
278 if v.base == trace.Entity.building.bdata.id then
279 GangWars.StartGangWar(ply, v.gang)
280
281 return ""
282 end
283 end
284 end
285
286 return ""
287end)
288
289function GangWars.StartGangWar(ply, rival)
290 local gang = ply:Gang()
291 -- TODO: check not fighting ourself
292 if gang == "" or rival == gang then return end --GangNotify(ply, NOTIFY_ERROR, 4, "") -- check not at war
293
294 if GangWars.GangWars[rival] then
295 GangNotify(ply, NOTIFY_ERROR, 4, rival .. " are already at war")
296
297 return
298 end
299
300 -- check if we're already fighting?
301 if GangWars.GangWars[gang] then
302 GangNotify(ply, NOTIFY_ERROR, 4, "You are already fighting " .. GangWars.GangWars[gang].rival .. "")
303
304 return
305 end
306
307 -- do we have access?
308 --if ply:GetNW2Int("gang_rank") > 2 then
309 -- GangNotify(ply, NOTIFY_ERROR, 4, "Gang War can only be started by leader or vice leader")
310 -- return
311 --end
312 -- check we have bases
313 if not GangWars.GangBases[rival] then
314 GangNotify(ply, NOTIFY_ERROR, 4, rival .. " do not have a gang base")
315
316 return
317 end
318
319 -- check their base is not on protection
320 if GangWars.GangBases[rival].protected and GangWars.GangBases[rival].protected > CurTime() then
321 local ptime = math.max(1, math.floor((GangWars.GangBases[rival].protected - CurTime()) / 60))
322 GangNotify(ply, NOTIFY_ERROR, 4, rival .. " cannot be raided! Wait " .. ptime .. " minutes")
323
324 return
325 end
326
327 --if GangWars.GangBases[gang] then
328 -- GangNotify(ply, NOTIFY_ERROR, 4, "You don't have a Gang Base! Buy a building, press F2 on a door and click 'Set Gang Base'" )
329 -- return
330 --end
331 -- check war time limit
332 -- verify time is ok
333 isql:QueryValue("SELECT TIME_TO_SEC(TIMEDIFF(NOW(), time)) FROM `gw_time` WHERE name = " .. isql:Escape("gang_war_" .. ply:Gang()) .. ";", function(time)
334 local war_time = (60 * 60 * 6)
335
336 if time and tonumber(time) < war_time then
337 GangNotify(ply, NOTIFY_ERROR, 4, "You can only start a war once every 3 hours! Wait " .. math.floor((war_time - tonumber(time)) / 60) .. " minutes")
338
339 return
340 end
341
342 isql:Query("UPDATE `gw_time` SET `time` = NOW() WHERE name = " .. isql:Escape("gang_war_" .. ply:Gang()) .. ";", function(d, s, err)
343 -- decide tokens by gang member count
344 local membercount = 0
345
346 for k, v in pairs(player.GetAll()) do
347 if v:Gang() == gang then
348 membercount = membercount + 1
349 end
350 end
351
352 -- add war entires for both gangs
353 GangWars.GangWars[gang] = {
354 gang = gang,
355 rival = rival,
356 role = "attacking",
357 tokens = membercount * 3
358 }
359
360 GangWars.GangWars[rival] = {
361 gang = rival,
362 rival = gang,
363 role = "defending",
364 tokens = membercount * 3
365 }
366
367 -- update all clients in-game that war is active & starting now
368 for k, v in pairs(player.GetAll()) do
369 if v:Gang() == gang then
370 GangWars.ClientUpdateGangWarData(v)
371 TimerNotify(v, 60 * 30, "Attack " .. rival)
372 net.Start("GangWarStartDialog")
373 net.WriteString("attacking")
374 net.WriteString(rival)
375 net.Send(v)
376 end
377
378 if v:Gang() == rival then
379 GangWars.ClientUpdateGangWarData(v)
380 TimerNotify(v, 60 * 30, "Defend from " .. gang)
381 net.Start("GangWarStartDialog")
382 net.WriteString("defending")
383 net.WriteString(gang)
384 net.Send(v)
385 end
386 end
387
388 -- create timer to end the war in favour of the defenders
389 timer.Create("GangWar" .. gang, 60 * 30, 1, function()
390 if GangWars.GangWars[rival] then
391 GangWars.FinishGangWar(rival)
392 end
393 end)
394
395 -- use traditional notify for console message log
396 NotifyGang(gang, 4, 4, ply:Nick() .. " declared war on " .. rival, true)
397 NotifyGang(rival, 4, 4, ply:Nick() .. " of " .. gang .. " declared war on our gang!", true)
398 -- log
399 GangWars.GangLog(gang, rival, "War", ply, ply:Nick() .. " declared war on " .. rival)
400 end)
401 end)
402end
403
404-- catch race conditions
405local FinishWarLimit = {}
406
407function GangWars.FinishGangWar(win)
408 local winner = table.Copy(GangWars.GangWars[win])
409 local loser = table.Copy(GangWars.GangWars[winner.rival])
410
411 if not winner or not loser then
412 MsgN("Error: couldn't find winner or loser in gang war? Winner was '" .. win .. "'")
413 GangWars.Log("error", "", "Couldn't find winner or loser in gang war? Winner was '" .. win .. "'")
414
415 return
416 end
417
418 local wl = winner.gang .. loser.gang
419 if FinishWarLimit[wl] and FinishWarLimit[wl] > CurTime() then return end
420 FinishWarLimit[wl] = CurTime() + 300
421
422 -- determine points
423 GangWars.DB.GetGangPoints(loser.gang, function(points)
424 if not points then
425 MsgN("Error with Gang Points?")
426 GangWars.Log("error", "", "Finishing gang war couldn't find loser points for '" .. loser.gang .. "'")
427
428 return
429 end
430
431 local defenders = GangWars.GangWars[winner.gang].role == "defending" and GangWars.GangWars[winner.gang] or GangWars.GangWars[loser.gang]
432
433 -- DEFENSE LOSES - LOSE 20% of points
434 if GangWars.GangWars[loser.gang].role == "defending" then
435 points = math.floor((points / 100) * 20)
436 local winpoints = math.floor(points / 2)
437 -- change points
438 GangWars.DB.AddGangPoints(winner.gang, winpoints, function() end)
439 GangWars.DB.AddGangPoints(loser.gang, -points, function() end)
440 -- member XP
441 GiveGangMembersXPAuto(winner.gang, 60)
442 -- notify
443 NotifyGang(winner.gang, 4, 4, "You won the war vs " .. loser.gang .. ", winning " .. winpoints .. " points", true)
444 NotifyGang(loser.gang, 4, 4, "You lost the war vs " .. winner.gang .. ", losing " .. points .. " points", true)
445
446 -- defense should lose the base!
447 if GangWars.GangBases[defenders.gang] then
448 -- find base
449 local bb = GangWars.FindBuildingByID(GangWars.GangBases[defenders.gang].base)
450
451 -- update building doors
452 for k, v in pairs(bb.doors) do
453 v:SetNW2String("gang", "")
454 end
455
456 -- set data
457 GangWars.GangBases[defenders.gang] = nil
458 end
459 -- DEFENSE WINS - GAIN BONUS POINTS
460 else
461 points = 25000
462 -- member XP
463 GiveGangMembersXPAuto(winner.gang, 40)
464 -- change points
465 GangWars.DB.AddGangPoints(winner.gang, points, function() end)
466 -- notify
467 NotifyGang(winner.gang, 4, 4, "You defended against " .. loser.gang .. ", and gained +" .. points .. " bonus points", true)
468 NotifyGang(loser.gang, 4, 4, "You lost the war vs " .. winner.gang, true)
469
470 -- set the base of the defense to protected status
471 if GangWars.GangBases[defenders.gang] then
472 GangWars.GangBases[defenders.gang].protected = CurTime() + 60 * 40
473 end
474 end
475
476 -- update wars won status
477 isql:Query("UPDATE `gw_gangs` SET `wars_won` = `wars_won` + 1 WHERE `name` = " .. isql:Escape(winner.gang))
478 isql:Query("UPDATE `gw_gangs` SET `wars_lost` = `wars_lost` + 1 WHERE `name` = " .. isql:Escape(loser.gang))
479
480 -- update wars won status - defending gang lost
481 if GangWars.GangWars[loser.gang].role == "defending" then
482 isql:Query("UPDATE `gw_gangs` SET `att_won` = `att_won` + 1 WHERE `name` = " .. isql:Escape(winner.gang))
483 isql:Query("UPDATE `gw_gangs` SET `def_lost` = `def_lost` + 1 WHERE `name` = " .. isql:Escape(loser.gang))
484 else
485 isql:Query("UPDATE `gw_gangs` SET `def_won` = `def_won` + 1 WHERE `name` = " .. isql:Escape(winner.gang))
486 isql:Query("UPDATE `gw_gangs` SET `att_lost` = `att_lost` + 1 WHERE `name` = " .. isql:Escape(loser.gang))
487 end
488
489 -- log
490 GangWars.Log("gangwar", "", winner.gang .. " won a war vs " .. loser.gang)
491 -- kill timers (only 1 will actually exist here)
492 timer.Remove("GangWar" .. winner.gang)
493 timer.Remove("GangWar" .. loser.gang)
494 FinishWarLimit[wl] = CurTime() + 300
495 -- clear data
496 GangWars.GangWars[winner.gang] = nil
497 GangWars.GangWars[loser.gang] = nil
498
499 -- show dialogs
500 for k, v in pairs(player.GetAll()) do
501 if v:Gang() == winner.gang then
502 net.Start("GangWarOverDialog")
503 net.WriteString(loser.gang)
504 net.WriteString("win")
505 net.WriteInt(points, 32)
506 net.Send(v)
507 TimerNotifyClear(v)
508 v:SendLua("GangWars.GangWar = nil")
509 elseif v:Gang() == loser.gang then
510 net.Start("GangWarOverDialog")
511 net.WriteString(winner.gang)
512 net.WriteString("lose")
513 net.WriteInt(0, 32)
514 net.Send(v)
515 TimerNotifyClear(v)
516 --GangWars.ClientUpdateGangWarData( v )
517 v:SendLua("GangWars.GangWar = nil")
518 end
519 end
520
521 -- log in ganglog
522 GangWars.GangLog(winner.gang, "", "War Won", "none")
523 GangWars.GangLog(loser.gang, "", "War Lost", "none")
524 end)
525end
526
527-- On player spawn, check their gang war info is set
528hook.Add("PlayerSpawn", function(ply)
529 GangWars.ClientUpdateGangWarData(ply)
530end)
531
532--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
533-- Gang News
534net.Receive("set_gang_news", function(len, ply)
535 local gang = ply:Gang()
536 local news = net.ReadString()
537 -- sanitize the news
538 news = string.Replace(news, '<', '<')
539 news = string.Replace(news, '>', '>')
540 news = string.Replace(news, "\\n", '<br/>')
541
542 GangWars.DB.GetPlayerGangRank(ply, function(rank)
543 if rank and rank == 1 then
544 -- Set news
545 isql:Query("UPDATE `gw_gangs` SET `message` = " .. isql:Escape(news) .. " WHERE `name` = " .. isql:Escape(gang), function()
546 -- ensure we're updated
547 Gang.SendInfo(ply, ply:Gang())
548 end)
549 else
550 GangNotify(ply, NOTIFY_ERROR, 4, "Only the leader can set the news")
551 end
552 end)
553end)
554
555--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
556-- Gang Log
557function GangWars.GangLog(gang, log, event, member)
558 event = event or "none"
559
560 if type(member) == "Player" and IsValid(member) then
561 member = member:SteamID()
562 end
563
564 member = member or "none"
565 isql:Query("INSERT INTO `gw_gang_log` (`gang`, `date`, `log`, `event`, `member`) VALUES(" .. isql:Escape(gang) .. ", NOW(), " .. isql:Escape(log) .. ", " .. isql:Escape(event) .. ", " .. isql:Escape(member) .. ")")
566end
567
568function GangWars.GangLogNumber(gang, number, event, member, log)
569 event = event or "none"
570
571 if IsValid(member) and member:IsPlayer() then
572 member = member:SteamID()
573 end
574
575 member = member or "none"
576
577 if log then
578 isql:Query("INSERT INTO `gw_gang_log` (`gang`, `date`, `number`, `event`, `member`, `log`) VALUES(" .. isql:Escape(gang) .. ", NOW(), " .. isql:Escape(number) .. ", " .. isql:Escape(event) .. ", " .. isql:Escape(member) .. ", " .. isql:Escape(log) .. ")")
579 else
580 isql:Query("INSERT INTO `gw_gang_log` (`gang`, `date`, `number`, `event`, `member`) VALUES(" .. isql:Escape(gang) .. ", NOW(), " .. isql:Escape(number) .. ", " .. isql:Escape(event) .. ", " .. isql:Escape(member) .. ")")
581 end
582end
583
584function meta:GangLogRefresh()
585 if not self.GangInfo or not self.GangInfo.name or self.GangInfo.name == "" then
586 self:SetDataset("gang_log", {})
587 else
588 self:SetDatasetQuery("gang_log", "SELECT DATE_FORMAT(`date`, '%D @ %H:%i:%s') AS `date`, `log` FROM `gw_gang_log` WHERE `gang` = " .. isql:Escape(self.GangInfo.name) .. " ORDER BY `date` DESC LIMIT 1000;")
589 end
590end
591
592-- remove older entries than 24*7 hours from the gang log
593timer.Create("PruneGangLogs", 60 * 120, 0, function()
594 isql:Query("DELETE FROM `gw_gang_log` WHERE TIME_TO_SEC(TIMEDIFF(NOW(), `date`)) > 604800")
595end)
596
597--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
598-- Gamemode Hooks
599local doonce = false
600
601local function GangInitTerritories()
602 if doonce then return end
603 doonce = true
604 --[[
605 for _, t in ipairs( GangTerritory ) do
606 if t.map == string.lower(game.GetMap()) then
607 local ter = ents.Create("gang_territory")
608 ter:SetPos(t.pos)
609
610 // Territory network ints
611 ter:SetNW2String("territory_owned", "") // is it owned?
612 ter:SetNW2Int("territory_id", _) // array index: GangTerritory[idx]
613 ter.captime = t.captime
614 ter.master = t.master
615 ter.territory = t
616 GangTerritory[_].ent = ter
617
618 ter:Spawn()
619 end
620 end
621 ]]
622 -- Make the territory map in spawn
623 local tel = ents.Create("gw_territory_map")
624 tel:SetPos(GetNamedSpawn("spawn_map"))
625 tel:Spawn()
626
627 if GetMapName() == "gw_downtown" then
628 tel:SetAngles(Angle(90, 90, 0))
629 else
630 tel:SetAngles(Angle(90, 90, 0))
631 end
632
633 -- Make the top gangs display in spawn
634 local tel = ents.Create("gw_top_gangs")
635 tel:SetPos(GetNamedSpawn("spawn_topgangs"))
636 tel:Spawn()
637 tel:SetAngles(Angle(0, 0, 90))
638 -- HACK NPC's
639 --local tel = ents.Create("npc_gunsmith")
640 --tel:SetPos( GetNamedSpawn("gundealer") )
641 --tel:Spawn()
642 --local tel = ents.Create("npc_blacksmith")
643 --tel:SetPos( GetNamedSpawn("blacksmith") )
644 --tel:SetAngles(Angle(0,270,0))
645 --tel:Spawn()
646 --local tel = ents.Create("npc_armor")
647 --tel:SetPos( GetNamedSpawn("armorsmith") )
648 --tel:SetAngles(Angle(0,270,0))
649 --tel:Spawn()
650 local tel = ents.Create("npc_banker")
651 tel:SetPos(GetNamedSpawn("banker"))
652 tel:SetAngles(Angle(2.007624, -1.220685, 0.000000)) --UPTOWN
653 --tel:SetAngles(Angle(0.160586, -90.368736, 0.000000)) --DOWNTOWN
654 tel:Spawn()
655 --[[
656 local tel = ents.Create("npc_refiner")
657 tel:SetPos( GetNamedSpawn("refiner") )
658 tel:SetAngles(Angle(0,90,0))
659 tel:Spawn()
660 ]]
661 local tel = ents.Create("npc_pothead")
662 tel:SetPos(GetNamedSpawn("pothead"))
663 tel:SetAngles(Angle(1.445511, -134.679184, 0.000000)) --UPTOWN
664 --tel:SetAngles(Angle(-2.007504, 3.501955, 0.000000)) --DOWNTOWN
665 tel:Spawn()
666 local tel = ents.Create("npc_pothead")
667 tel:SetPos(GetNamedSpawn("smackhead"))
668 tel:SetAngles(Angle(0.240853, 178.907089, 0.000000)) --UPTOWN
669 --tel:SetAngles(Angle(-2.007504, 3.501955, 0.000000)) --DOWNTOWN
670 tel:Spawn()
671end
672
673hook.Add("InitPostEntity", "GangEntInit", GangInitTerritories)
674
675-- Handle gang rivalry kills
676local function GangRivalryDeath(victim, weapon, killer)
677 -- if the killer is on a mass murder mission, cancel all affects & knock out
678 if IsValid(victim) and IsValid(killer) and killer.MissionKills then return end
679
680 if victim:IsPlayer() and killer:IsPlayer() and killer ~= victim and GangWars.GetLevel(victim) >= 10 then
681 local vgang = victim:GetNW2String("gang_name")
682 local kgang = killer:GetNW2String("gang_name")
683 if vgang == "" or kgang == "" then return end
684
685 -- see if there is a rivalry between killer and victim
686 isql:QueryValue("SELECT COUNT(*) FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(kgang) .. " AND `rival` = " .. isql:Escape(vgang) .. ";", function(v)
687 if not v or tonumber(v) < 1 then return end
688 -- calculate the fine the other gang will pay
689 local vlvl = GangWars.GetLevel(victim) / 2
690 local fine = (vlvl * vlvl) * 10
691
692 -- upgrade adds to the fine
693 if killer.GangInfo then
694 if killer.GangInfo.rivalboost and killer.GangInfo.rivalboost > 0 then
695 local txt, aff = Gang.GetUpgradeEffect("rivalboost", killer.GangInfo.rivalboost - 1)
696 fine = fine + math.floor((fine / 100) * aff)
697 end
698 end
699
700 fine = math.floor(fine)
701
702 --[[
703 // add cash to gang stash
704 // !!!!!!!!!!!!!!!
705 local stashes = ents.FindByClass("gang_stash")
706 if stashes then
707 for k,v in pairs(stashes) do
708 if v.gang == kgang then
709 v:AddMoney() // adds % to stash
710 end
711 end
712 end
713 // !!!!!!!!!!!!!!!!!!!!
714 ]]
715 -- check they can afford it
716 GangWars.DB.GangCanAfford(vgang, fine, function(canafford)
717 if canafford then
718 -- fine the gang
719 GangWars.DB.AddGangMoney(vgang, -fine, function()
720 NotifyGang(vgang, 4, 4, "Gang lost " .. CUR .. GangWars.FormatMoney(fine) .. " when " .. victim:Nick() .. " died")
721 NotifyGang(kgang, 4, 4, "Gang gained " .. CUR .. GangWars.FormatMoney(fine) .. " for killing " .. victim:Nick())
722 -- update rivalry stats
723 isql:Query("UPDATE `gw_gang_rivals` SET `members_killed` = `members_killed` + 1 WHERE `gang` = " .. isql:Escape(kgang) .. " AND `rival` = " .. isql:Escape(vgang) .. ";")
724 isql:Query("UPDATE `gw_gang_rivals` SET `members_lost` = `members_lost` + 1 WHERE `gang` = " .. isql:Escape(vgang) .. " AND `rival` = " .. isql:Escape(kgang) .. ";")
725
726 -- log
727 if IsValid(killer) then
728 GangWars.GangLog(kgang, IsValid(victim) and victim:Nick() or "unknown", "KillRival", killer)
729 end
730
731 -- add XP and money
732 GangWars.DB.AddGangMoney(kgang, fine)
733 GangWars.DB.AddGangXP(kgang, fine / 10)
734 end)
735 else
736 -- force the bankrupt gang to lose
737 GangWars.DB.RivalryWin(kgang, vgang)
738 end
739 end)
740 end)
741 end
742end
743
744hook.Add("PlayerDeath", "GangRivalryDeath", GangRivalryDeath)
745
746--////////////////////////////////////////////////////////////////////////////
747-- Database
748local function ValidSteam(ply)
749 if not IsValid(ply) then return end
750 local steamID = ply:SteamID()
751 --if steamID == "STEAM_ID_PENDING" or steamID == "STEAM_ID_UNKNOWN" or steamID == "UNKNOWN" or steamID == "PENDING" then
752 -- return
753 --end
754
755 return steamID
756end
757
758-- gets the name of the gang a player is in
759function GangWars.DB.GetPlayerGang(ply, func, show_invites)
760 local steamID = ""
761
762 if type(ply) == "string" then
763 steamID = ply
764 else
765 steamID = ValidSteam(ply)
766 end
767
768 if not steamID then
769 func(nil, "Invalid STEAMID")
770
771 return
772 end
773
774 if show_invites then
775 isql:QueryValue("SELECT `gang` FROM `gw_gang_members` WHERE `steam` = " .. isql:Escape(steamID) .. ";", function(r)
776 if r then
777 func(tostring(r))
778 else
779 func(nil)
780 end
781 end)
782 else
783 isql:QueryValue("SELECT `gang` FROM `gw_gang_members` WHERE `steam` = " .. isql:Escape(steamID) .. " AND `rank` < 6;", function(r)
784 if r then
785 func(tostring(r))
786 else
787 func(nil)
788 end
789 end)
790 end
791end
792
793-- gets a players rank within their gang
794function GangWars.DB.GetPlayerGangRank(ply, func)
795 local steamID = ""
796
797 if type(ply) == "string" then
798 steamID = ply
799 else
800 steamID = ValidSteam(ply)
801 end
802
803 if not steamID then
804 func(nil, "Invalid STEAMID")
805
806 return
807 end
808
809 isql:QueryValue("SELECT `rank` FROM `gw_gang_members` WHERE `steam` = " .. isql:Escape(steamID) .. " AND `rank` < 6;", function(r)
810 if r then
811 func(tonumber(r))
812 else
813 func(nil)
814
815 return
816 end
817 end)
818end
819
820-- returns gang name, xp, level, money
821function GangWars.DB.GetPlayerGangInfo(ply, func)
822 local steamID = ""
823
824 if type(ply) == "string" then
825 steamID = ply
826 else
827 steamID = ValidSteam(ply)
828 end
829
830 if not steamID then
831 func(nil, "Invalid STEAMID")
832
833 return
834 end
835
836 isql:QueryRow("SELECT * FROM `gw_gangs` INNER JOIN `gw_gang_members` ON gw_gang_members.gang = gw_gangs.name WHERE gw_gang_members.steam = " .. isql:Escape(steamID) .. ";", func)
837end
838
839-- returns gang name, xp, level, money
840function GangWars.DB.GetGangInfo(gang_name, func)
841 isql:QueryRow("SELECT * FROM `gw_gangs` WHERE `name` = " .. isql:Escape(gang_name) .. ";", func)
842end
843
844-- gets the list of members of a gang
845function GangWars.DB.GetGangStorage(gang_name, func)
846 isql:Query("SELECT * FROM `view_gang_storage` WHERE `gang` = " .. isql:Escape(gang_name) .. ";", func)
847end
848
849-- gets the list of members of a gang
850function GangWars.DB.GetPlayerGangMemberList(gang_name, func)
851 isql:Query("SELECT `names`.`name` AS `name`, `members`.`rank` AS `rank`, `names`.`steam` AS `steam` FROM `gw_gang_members` `members` INNER JOIN `gw_characters` `names` ON `names`.`name` = `members`.`steam` WHERE `members`.`gang` = " .. isql:Escape(gang_name) .. ";", func)
852end
853
854-- gets the list of members + stats in a gang. takes a unique ID for temp table
855function GangWars.DB.GetGangMemberStats(gang_name, uid, func)
856 local stats = {}
857 local q = "SELECT * FROM `gw_gang_members` WHERE `gang` = " .. isql:Escape(gang_name) .. ";"
858
859 isql:Query(q, function(da, su, er)
860 if su then
861 for k, v in pairs(da or {}) do
862 if not stats[v["steam"]] then
863 stats[v["steam"]] = {}
864 stats[v["steam"]]["rank"] = v["rank"]
865 stats[v["steam"]]["money_donated"] = 0
866 stats[v["steam"]]["money_earned"] = 0
867 stats[v["steam"]]["money_spent"] = 0
868 stats[v["steam"]]["xp_earned"] = 0
869 stats[v["steam"]]["captures"] = 0
870 stats[v["steam"]]["wars"] = 0
871 stats[v["steam"]]["invites"] = 0
872 stats[v["steam"]]["rivals"] = 0
873 end
874 end
875 end
876
877 q = "SELECT * FROM `gw_gang_log` WHERE `date` >= NOW() - INTERVAL 7 DAY and `gang` = " .. isql:Escape(gang_name) .. ";"
878
879 isql:Query(q, function(d, s, e)
880 if s then
881 for k, v in pairs(d or {}) do
882 if not stats[v["member"]] then continue end
883 if v["event"] == "Invite" then
884 stats[v["member"]]["invites"] = stats[v["member"]]["invites"] + 1
885 end
886
887 if v["event"] == "Donate" then
888 stats[v["member"]]["money_donated"] = stats[v["member"]]["money_donated"] + v["number"]
889 end
890
891 if v["event"] == "Buy" then
892 stats[v["member"]]["money_spent"] = stats[v["member"]]["money_spent"] + v["number"]
893 end
894
895 if v["event"] == "Upgrade" then
896 stats[v["member"]]["money_spent"] = stats[v["member"]]["money_spent"] + v["number"]
897 end
898
899 if v["event"] == "Print" then
900 stats[v["member"]]["money_earned"] = stats[v["member"]]["money_earned"] + v["number"]
901 end
902
903 if v["event"] == "XP" then
904 stats[v["member"]]["xp_earned"] = stats[v["member"]]["xp_earned"] + v["number"]
905 end
906
907 if v["event"] == "Capture" then
908 stats[v["member"]]["captures"] = stats[v["member"]]["captures"] + 1
909 end
910
911 if v["event"] == "War" then
912 stats[v["member"]]["wars"] = stats[v["member"]]["wars"] + 1
913 end
914
915 if v["event"] == "KillRival" then
916 stats[v["member"]]["rivals"] = stats[v["member"]]["rivals"] + 1
917 end
918 end
919 end
920
921 func(stats)
922 end)
923 end)
924end
925
926-- gets the list of rivals of a gang
927function GangWars.DB.GetGangRivalList(gang_name, func)
928 isql:Query("SELECT g.name, g.logo, g.color, g.color2, g.level, riv.*, TIME_TO_SEC(TIMEDIFF(NOW(), riv.`started`))/60/60 AS `hours_left` FROM `gw_gang_rivals` riv INNER JOIN `gw_gangs` g ON g.name = riv.rival WHERE riv.gang = " .. isql:Escape(gang_name) .. ";", func)
929end
930
931function GangWars.DB.CreateGang(ply, gang_name, gang_password, gang_logo, gang_color, gang_color2, func)
932 local steamID = ValidSteam(ply)
933
934 if not steamID then
935 func(nil, "Invalid STEAMID")
936
937 return
938 end
939
940 -- reject bad gang names
941 local allowedCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:-1234567890 "
942
943 for i = 1, string.len(gang_name) do
944 local ok = false
945
946 for j = 1, string.len(allowedCharacters) do
947 if string.sub(gang_name, i, i) == string.sub(allowedCharacters, j, j) then
948 ok = true
949 break
950 end
951 end
952
953 if not ok then
954 func(nil, "Gang name contains illegal symbol at character #" .. i)
955
956 return
957 end
958 end
959
960 -- verify time is ok
961 isql:QueryValue("SELECT TIME_TO_SEC(TIMEDIFF(NOW(), time)) FROM `gw_time` WHERE name = " .. isql:Escape("gang_create_" .. ply:RealSteamID()) .. ";", function(time)
962 if time and tonumber(time) < 86400 then
963 func(nil, "You can only make 1 gang per day")
964
965 return
966 end
967
968 isql:Query("UPDATE `gw_time` SET `time` = NOW() WHERE name = " .. isql:Escape("gang_create_" .. ply:RealSteamID()) .. ";", function(d, s, err)
969 -- check gang name doesn't exist
970 isql:QueryValue("SELECT * FROM gw_gangs WHERE name = " .. isql:Escape(gang_name) .. ";", function(r)
971 if r then
972 func(nil, "Gang already exists!")
973
974 return
975 end
976
977 -- check we're not already in a gang
978 local g = GangWars.DB.GetPlayerGang(ply, function(g)
979 if g and g ~= "" then
980 func(nil, "You are already in a gang")
981
982 return
983 end
984
985 -- delete any old invites we had
986 isql:Query("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. ";", function()
987 -- create gang
988 isql:Query("INSERT INTO gw_gangs (`name`, `password`, `logo`, `color`, `color2`, `level`, `xp`, `money`, `creator`, `last_base`) VALUES(" .. isql:Escape(gang_name) .. ", " .. isql:Escape(gang_password) .. ", " .. isql:Escape(gang_logo) .. ", '" .. isql:Escape(gang_color.r) .. " " .. isql:Escape(gang_color.g) .. " " .. isql:Escape(gang_color.b) .. "', '" .. isql:Escape(gang_color2.r) .. " " .. isql:Escape(gang_color2.g) .. " " .. isql:Escape(gang_color2.b) .. "', 1, 0, 0, " .. isql:Escape(steamID) .. ", NOW());", function()
989 -- and owner
990 isql:Query("INSERT INTO gw_gang_members (`gang`, `steam`, `rank`) VALUES(" .. isql:Escape(gang_name) .. ", " .. isql:Escape(steamID) .. ", 1);", function()
991 func(true)
992 net.Start("sv_refresh_topgangs")
993 net.Broadcast()
994 end)
995 end)
996 end)
997 end)
998 end)
999 end)
1000 end)
1001end
1002
1003function GangWars.DB.SetPlayerGangRank(ply, gang, rank, func)
1004 local steamID = ""
1005
1006 if type(ply) == "string" then
1007 steamID = ply
1008 else
1009 steamID = ValidSteam(ply)
1010 end
1011
1012 if not steamID then
1013 func(nil, "Invalid STEAMID")
1014
1015 return
1016 end
1017
1018 if rank < 1 or rank > 5 then
1019 func(nil, nil)
1020
1021 return
1022 end
1023
1024 isql:Query("UPDATE gw_gang_members SET `rank`= " .. isql:Escape(rank) .. " WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(gang) .. ";", function()
1025 func(true)
1026 end)
1027end
1028
1029function GangWars.DB.GetGangMemberLimit(gang_name, func)
1030 func(10)
1031 --[[
1032 // check gang hasn't reached its member limit
1033 isql:Query("SELECT `level`, `boost_members` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) ..";",
1034 function(glevel)
1035 if not glevel then
1036 func()
1037 return
1038 end
1039 glevel = tonumber(glevel.level)
1040 local members = tonumber(glevel.boost_members)
1041
1042 func( Gang.GetMemberLimit(glevel) + members )
1043 end)
1044 ]]
1045end
1046
1047function GangWars.DB.InviteToGang(ply, gang_name, func)
1048 local steamID = ValidSteam(ply)
1049
1050 if not steamID then
1051 func(nil, "Invalid STEAMID")
1052
1053 return
1054 end
1055
1056 -- check they aren't in a gang
1057 isql:QueryValue("SELECT * FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. " AND `rank` < 6;", function(r)
1058 if r then
1059 func(nil, "Player is already in another gang")
1060
1061 return
1062 end
1063
1064 -- check gang hasn't reached its member limit
1065 isql:QueryRow("SELECT `level`, `memberboost` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(glevel)
1066 if not glevel then
1067 func(nil, "Couldn't find gang level or member boost")
1068
1069 return
1070 end
1071
1072 local members = 10 --(tonumber(glevel.memberboost)) + Gang.GetMemberLimit(tonumber(glevel.level))
1073 glevel = tonumber(glevel.level)
1074
1075 isql:QueryValue("SELECT COUNT(*) FROM gw_gang_members WHERE `gang` = " .. isql:Escape(gang_name) .. ";", function(mcount)
1076 mcount = tonumber(mcount)
1077
1078 if not glevel or not mcount or mcount >= members then
1079 func(nil, "Your gang has reached its member limit! (Max " .. members .. " members)")
1080
1081 return
1082 end
1083
1084 -- add them with invited rank
1085 isql:Query("INSERT INTO gw_gang_members (`gang`, `steam`, `rank`) VALUES(" .. isql:Escape(gang_name) .. ", " .. isql:Escape(steamID) .. ", 6);", function()
1086 func(true)
1087 end)
1088 end)
1089 end)
1090 end)
1091end
1092
1093function GangWars.DB.AcceptInvite(ply, gang, func)
1094 local steamID = ValidSteam(ply)
1095
1096 if not steamID then
1097 func(nil, "Invalid STEAMID")
1098
1099 return
1100 end
1101
1102 -- check they are being invited to the gang
1103 isql:QueryValue("SELECT `rank` FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(gang) .. ";", function(r)
1104 if not r or tonumber(r) ~= 6 then
1105 func(nil, "Not invited to that gang!")
1106
1107 return
1108 end
1109
1110 -- add them with basic rank
1111 isql:Query("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` != " .. isql:Escape(gang) .. ";", function()
1112 -- add them with basic rank
1113 isql:Query("UPDATE gw_gang_members SET `rank` = '5' WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(gang) .. ";", function()
1114 func(true)
1115 end)
1116 end)
1117 end)
1118end
1119
1120function GangWars.DB.RejectInvite(ply, gang, func)
1121 local steamID = ValidSteam(ply)
1122
1123 if not steamID then
1124 func(nil, "Invalid STEAMID")
1125
1126 return
1127 end
1128
1129 -- check they are being invited to the gang
1130 isql:QueryValue("SELECT `rank` FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(gang) .. ";", function(r)
1131 if not r or tonumber(r) ~= 6 then
1132 func(nil, "Not invited to that gang!")
1133
1134 return
1135 end
1136
1137 -- remove invite
1138 isql:Query("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(gang) .. ";", function()
1139 func(true)
1140 end)
1141 end)
1142end
1143
1144function GangWars.DB.RemoveFromGangBySteam(steam, gang, func)
1145 isql:QueryRow("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steam) .. " AND `gang` = " .. isql:Escape(gang) .. ";", func)
1146end
1147
1148function GangWars.DB.RemoveFromGangByName(ply_name, gang, func)
1149 -- find the player
1150 isql:QueryRow("SELECT n.name, n.steam, g.gang, g.rank FROM gw_characters n INNER JOIN gw_gang_members g ON g.steam = n.name WHERE n.name LIKE " .. isql:Escape(ply_name) .. ";", function(query)
1151 if not query or not query.name then
1152 func(nil, "Can't find target players name")
1153
1154 return
1155 end
1156
1157 local steamID = query.steam
1158
1159 if not steamID or steamID == "" then
1160 func(nil, "Can't find target players steamID")
1161
1162 return
1163 end
1164
1165 local gang_name = query.gang
1166
1167 if not gang_name or gang_name == "" or gang_name ~= gang then
1168 func(nil, "Can't find target players gang")
1169
1170 return
1171 end
1172
1173 -- remove them
1174 isql:Query("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. ";", function()
1175 func(true)
1176 end)
1177 end)
1178 -- if they were owner, delete gang & all members
1179 --if tonumber(rank) == 1 then
1180 -- isql:Query("DELETE FROM gw_gang_members WHERE `gang` = " .. isql:Escape(gang_name) .. ";")
1181 -- isql:Query("DELETE FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";")
1182 --end
1183end
1184
1185function GangWars.DB.RemoveFromGang(ply, func)
1186 local steamID = ValidSteam(ply)
1187
1188 if not steamID then
1189 func(nil, "Invalid STEAMID")
1190
1191 return
1192 end
1193
1194 local gang_name = GangWars.DB.GetPlayerGang(ply, function(gang_name)
1195 if not gang_name then
1196 func(nil, "Couldn't find gang")
1197
1198 return
1199 end
1200
1201 -- remove them
1202 isql:Query("DELETE FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. ";", function()
1203 func(true)
1204 net.Start("sv_refresh_topgangs")
1205 net.Broadcast()
1206 end)
1207 end)
1208 -- if they were owner, delete gang & all members
1209 --if tonumber(rank) == 1 then
1210 -- isql:Query("DELETE FROM gw_gang_members WHERE gang = " .. isql:Escape(gang_name) .. ";")
1211 -- isql:Query("DELETE FROM gw_gangs WHERE name = " .. isql:Escape(gang_name) .. ";")
1212 --end
1213end
1214
1215function GangWars.DB.RivalryWin(winner, loser, ignoretruce, supressmessage)
1216 local args = loser
1217 local gang = winner
1218
1219 -- see if other gang is our rival
1220 isql:QueryValue("SELECT COUNT(*) FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang) .. ";", function(truce)
1221 if (not truce or tonumber(truce) <= 0) and not ignoretruce then return end --GangNotify(ply, 3, 4, "You don't seem to have a rivalry with " .. args)
1222
1223 -- remove the rivalry
1224 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(gang) .. " AND `rival` = " .. isql:Escape(args) .. ";", function()
1225 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang) .. ";", function()
1226 --MsgN("Deleted rivalry entires")
1227 isql:QueryValue("SELECT `points` FROM `gw_gangs` WHERE `name` = " .. isql:Escape(args) .. ";", function(loser_points)
1228 -- find level difference
1229 --isql:QueryValue("SELECT `level` FROM `gw_gangs` WHERE `name` = " .. isql:Escape(gang) .. ";",
1230 --function(my_level)
1231 --isql:QueryValue("SELECT `level` FROM `gw_gangs` WHERE `name` = " .. isql:Escape(args) .. ";",
1232 --function(their_level)
1233 --[[
1234 if not their_level then
1235 Msg("WARNING: " .. loser .. " requested mercy but can't find level for them\n")
1236 end
1237 if not my_level then
1238 Msg("WARNING: " .. loser .. " requested mercy but can't find level for " .. winner .. "\n")
1239 end
1240 if not their_level or not my_level then
1241 return
1242 end
1243
1244 MsgN("Awarding points")
1245
1246 // find level difference
1247 local lvl_diff = their_level - my_level
1248
1249 // find points
1250 local points = math.max(10000 + (1000 * lvl_diff), 0)
1251 ]]
1252 local points = math.floor(loser_points / 5)
1253 -- award points
1254 GangWars.DB.AddGangPoints(gang, points, function() end)
1255 GangWars.DB.AddGangPoints(args, -points, function() end)
1256
1257 -- refresh their view
1258 if not supressmessage then
1259 NotifyGang(gang, 4, 4, "You gained " .. points .. " points for defeating " .. args)
1260 NotifyGang(args, 4, 4, "You have lost the fight with " .. gang .. " and lost " .. points .. " points")
1261 end
1262
1263 for k, v in pairs(player.GetAll()) do
1264 if IsValid(v) then
1265 if v:Gang() == gang or v:Gang() == args then
1266 InitPlayerGang(v)
1267 end
1268 end
1269 end
1270
1271 -- add norivalry entry (5 days)
1272 -- Modified 03-10-2012 to block the spammy abuse of mercy to increase gang points
1273 isql:Query("INSERT INTO `gw_gang_norival` (`gang`, `rival`, `expires`) VALUES (" .. isql:Escape(gang) .. ", " .. isql:Escape(args) .. ", DATE_ADD(NOW(), INTERVAL 5 DAY));")
1274 -- add norivalry entry for the loser (1 day, to prevent spam)
1275 isql:Query("INSERT INTO `gw_gang_norival` (`gang`, `rival`, `expires`) VALUES (" .. isql:Escape(args) .. ", " .. isql:Escape(gang) .. ", DATE_ADD(NOW(), INTERVAL 1 DAY));")
1276 end)
1277 end)
1278 end)
1279 end)
1280 --end)
1281end
1282
1283-- adds to a gangs XP
1284function GangWars.DB.AddGangXP(gang_name, add_xp)
1285 if not gang_name or gang_name == "" then return end
1286
1287 -- find the gangs xp & level
1288 isql:QueryRow("SELECT `xp`, `level`, `gangxpboost` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(r)
1289 if not r then return end
1290 local xp = tonumber(r['xp'])
1291 local level = tonumber(r['level'])
1292 local boost = tonumber(r['gangxpboost'])
1293 if level >= 20 then return end
1294
1295 -- boost XP
1296 if boost and boost > 0 then
1297 local txt, aff = Gang.GetUpgradeEffect("missionboost", boost - 1)
1298 add_xp = add_xp + math.floor((add_xp / 100) * aff)
1299 end
1300
1301 -- add the XP
1302 xp = xp + add_xp
1303 local levelup = false
1304
1305 -- level up gang
1306 if xp > Gang.XP2Level(level) then
1307 levelup = true
1308 isql:Query("UPDATE gw_gangs SET `xp` = 0, `level` = " .. (level + 1) .. " WHERE `name` = " .. isql:Escape(gang_name) .. ";")
1309 else
1310 isql:Query("UPDATE gw_gangs SET `xp` = `xp` + '" .. add_xp .. "' WHERE `name` = " .. isql:Escape(gang_name) .. ";")
1311 end
1312 end)
1313end
1314
1315-- adds to a gangs money
1316function GangWars.DB.AddGangMoney(gang_name, money, func)
1317 if not gang_name or gang_name == "" then
1318 if func then
1319 func(nil)
1320 end
1321
1322 return
1323 end
1324
1325 isql:Query("UPDATE gw_gangs SET `money` = `money` + " .. isql:Escape(tonumber(money)) .. " WHERE `name` = " .. isql:Escape(gang_name) .. ";", func)
1326end
1327
1328-- adds to a gangs points
1329function GangWars.DB.AddGangPoints(gang_name, points, func)
1330 if not gang_name or gang_name == "" then
1331 if func then
1332 func(nil)
1333 end
1334
1335 return
1336 end
1337
1338 if GangWars.EventActive("doublexp") or GangWars.EventActive("doublepoints") then
1339 points = points * 2
1340 end
1341
1342 isql:Query("UPDATE gw_gangs SET `points` = `points` + " .. isql:Escape(tonumber(points)) .. " WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(d)
1343 -- auto update clients in the gang of their points
1344 GangWars.DB.GetGangPoints(gang_name, function(gp)
1345 for k, v in pairs(player.GetAll()) do
1346 if gp and v:Gang() == gang_name then
1347 net.Start("ds_gang_points")
1348 net.WriteInt(gp, 32)
1349 net.Send(v)
1350 end
1351 end
1352 end)
1353
1354 -- callback
1355 if func then
1356 func(d)
1357 end
1358 end)
1359end
1360
1361-- fetch a gangs points
1362function GangWars.DB.GetGangPoints(gang_name, func)
1363 if not gang_name or gang_name == "" then
1364 if func then
1365 func(nil)
1366 end
1367
1368 return
1369 end
1370
1371 isql:QueryValue("SELECT `points` FROM `gw_gangs` WHERE `name` = " .. isql:Escape(gang_name) .. ";", func)
1372end
1373
1374-- checks gang money
1375function GangWars.DB.GangCanAfford(gang_name, money, func)
1376 if not gang_name or gang_name == "" then return end
1377
1378 isql:QueryValue("SELECT `money` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(mon)
1379 if mon and tonumber(mon) >= money then
1380 func(true)
1381 else
1382 func(false)
1383 end
1384 end)
1385end
1386
1387-- upgrades a gang
1388function GangWars.DB.GangUpgrade(gang_name, upgrade, func)
1389 if not gang_name or gang_name == "" then
1390 func(nil, nil)
1391
1392 return
1393 end
1394
1395 -- check the sql input!
1396 if upgrade ~= "hpboost" and upgrade ~= "regen" and upgrade ~= "extraitems" and upgrade ~= "xpboost" and upgrade ~= "speedboost" and upgrade ~= "printboost" and upgrade ~= "drugboost" and upgrade ~= "dropboost" and upgrade ~= "armorboost" and upgrade ~= "memberboost" and upgrade ~= "shopboost" and upgrade ~= "ppocketboost" and upgrade ~= "bankboost" and upgrade ~= "missionboost" and upgrade ~= "gangxpboost" then
1397 func(nil, "Invalid upgrade")
1398
1399 return
1400 end
1401
1402 -- find the upgrade level
1403 isql:QueryValue("SELECT `" .. upgrade .. "` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(ulevel)
1404 ulevel = tonumber(ulevel)
1405
1406 if not ulevel or ulevel >= 10 then
1407 func(nil, "This is already fully upgraded")
1408
1409 return
1410 end
1411
1412 -- find the gangs money
1413 isql:QueryRow("SELECT `money`, `level` FROM gw_gangs WHERE `name` = " .. isql:Escape(gang_name) .. ";", function(r)
1414 if not r then
1415 func(nil, "Can't find your gang?")
1416
1417 return
1418 end
1419
1420 local amt = tonumber(r['money'])
1421 local glevel = tonumber(r['level'])
1422
1423 -- check gang is high enough level
1424 if glevel <= ulevel then
1425 func(nil, "Gang isn't high enough level", amt)
1426
1427 return
1428 end
1429
1430 -- find upgrade cost
1431 local price = Gang.GetUpgradePrice(ulevel)
1432
1433 -- check we can afford it
1434 if amt < price then
1435 func(nil, "Gang can't afford that", amt)
1436
1437 return
1438 end
1439
1440 -- charge the team
1441 amt = amt - price
1442
1443 -- save and upgrade
1444 isql:Query("UPDATE gw_gangs SET `money` = " .. amt .. ", `" .. upgrade .. "` = " .. (ulevel + 1) .. " WHERE `name` = " .. isql:Escape(gang_name) .. ";", function()
1445 func(true, "", amt)
1446 end)
1447 end)
1448 end)
1449end
1450
1451--////////////////////////////////////////////////////////////////////////////
1452-- Commands
1453-- change logo
1454local function GC_ChangeLogo(len, ply)
1455 local decoded = net.ReadTable()
1456 if not decoded or not decoded.logo then return end
1457 if decoded.logo < 1 then return end
1458 if decoded.logo > 30 then return end
1459 local gname = "extra/" .. decoded.logo
1460 --[[
1461 if not string.find(gname, "extra") then
1462 GangNotify(ply, 3, 4, "Invalid logo... you've been logged, thank you!")
1463 GangWars.Log("cheat", ply, ply:Nick() .. " tried to set gang logo to '" .. gname .. "'")
1464 return
1465 end
1466 ]]
1467 local steamID = ValidSteam(ply)
1468 if not steamID then return end
1469 local gang = ply:GetNW2String("gang_name")
1470
1471 -- find gang info
1472 GangWars.DB.GetGangInfo(gang, function(info)
1473 if not info then
1474 Msg("GC_ChangeLogo: GangWars.DB.GetGangInfo returned nil")
1475
1476 return
1477 end
1478
1479 -- find our rank
1480 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1481 if not my_rank or tonumber(my_rank) > 1 then
1482 GangNotify(ply, 3, 4, "Only leaders can buy logos")
1483
1484 return
1485 end
1486
1487 local gangmoney = tonumber(info.money)
1488 local ganglevel = tonumber(info.level)
1489 local logoprice = 500000 + tonumber(decoded.logo) * 200000
1490 --local logolevel = 5 + math.floor(tonumber(decoded.logo) / 10) * 5
1491 local logolevel = math.min(10 + math.floor(tonumber(decoded.logo) / 10) * 5, 20)
1492
1493 -- abandon if we're not high enough level
1494 if logolevel > ganglevel then
1495 GangNotify(ply, 3, 4, "Your gang must be level " .. logolevel .. " to buy that logo!")
1496
1497 return
1498 end
1499
1500 -- abandon if we can't afford it
1501 if gangmoney < logoprice then
1502 GangNotify(ply, 1, 4, "Your gang can not afford this logo!")
1503
1504 return
1505 end
1506
1507 -- charge gang
1508 GangWars.DB.AddGangMoney(gang, -logoprice, function()
1509 -- create gang
1510 isql:Query("UPDATE gw_gangs SET `logo` = " .. isql:Escape(gname) .. " WHERE `name` = " .. isql:Escape(info.name) .. ";", function()
1511 GangNotify(ply, 3, 4, "You successfully changed your gangs logo!")
1512 GangWars.GangLog(gang, ply:Nick() .. " changed the gang logo", "Logo Change", ply)
1513 InitPlayerGang(ply)
1514 end)
1515 end)
1516 end)
1517 end)
1518end
1519
1520net.Receive("ChangeGangLogo", GC_ChangeLogo)
1521
1522-- change password
1523local function GC_ChangePassword(len, ply)
1524 local decoded = net.ReadTable()
1525 local steamID = ValidSteam(ply)
1526 if not steamID then return end
1527 if decoded and not decoded.old or not decoded.new then return end
1528
1529 -- find ranks
1530 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1531 if not my_rank or my_rank ~= 1 then
1532 GangNotify(ply, 3, 4, "You must be gang leader to change the password")
1533
1534 return
1535 end
1536
1537 -- find gang info
1538 GangWars.DB.GetGangInfo(ply:GetNW2String("gang_name"), function(info)
1539 if not info then
1540 Msg("GC_ChangePassword: GangWars.DB.GetGangInfo returned nil")
1541
1542 return
1543 end
1544
1545 local gangpass = info.password
1546
1547 -- abandon if old password does not match
1548 if tostring(gangpass) ~= tostring(util.CRC(decoded.old)) then
1549 GangNotify(ply, 3, 4, "Old password was incorrect!")
1550
1551 return
1552 end
1553
1554 -- charge gang
1555 --GangWars.DB.AddGangMoney(gang, -500000,
1556 --function()
1557 -- create gang
1558 isql:Query("UPDATE gw_gangs SET `password` = " .. isql:Escape(util.CRC(decoded.new)) .. " WHERE `name` = " .. isql:Escape(info.name) .. ";", function()
1559 GangNotify(ply, 3, 4, "You successfully changed your gangs password!")
1560 GangWars.GangLog(gang, ply:Nick() .. " changed the gang password", "Password Change", ply)
1561 end)
1562 end)
1563 end)
1564 --end)
1565end
1566
1567net.Receive("ChangeGangPassword", GC_ChangePassword)
1568
1569-- recover gang
1570local function GC_Recover(len, ply)
1571 local decoded = net.ReadTable()
1572 local steamID = ValidSteam(ply)
1573 if not steamID then return end
1574 if decoded and not decoded.name or not decoded.password then return end
1575
1576 -- find gang info
1577 GangWars.DB.GetGangInfo(decoded.name, function(info)
1578 if not info then
1579 Msg("GC_Recover: GangWars.DB.GetGangInfo returned nil")
1580
1581 return
1582 end
1583
1584 local gangpass = info.password
1585
1586 -- abandon if old password does not match
1587 if tostring(gangpass) ~= tostring(util.CRC(decoded.password)) then
1588 GangNotify(ply, 3, 4, "The password was incorrect! This action has been logged and sent to the admin team.")
1589 GangWars.Log("gang_recover", ply, ply:Nick() .. " tried to recover the gang '" .. decoded.name .. "' with a bad password")
1590
1591 return
1592 end
1593
1594 -- Remove all members. Set us as the only member/leader.
1595 isql:QueryValue("SELECT COUNT(*) FROM `gw_gang_members` WHERE `gang` = " .. isql:Escape(info.name) .. " AND `rank` = 1;", function(row)
1596 if tonumber(row) and tonumber(row) > 0 then
1597 GangNotify(ply, 3, 4, "The gang already has a leader! This action has been logged and sent to the admin team.")
1598 GangWars.Log("gang_recover", ply, ply:Nick() .. " tried to recover the gang '" .. decoded.name .. "' but it already has a leader")
1599
1600 return
1601 end
1602
1603 -- create gang
1604 isql:Query("INSERT INTO `gw_gang_members` (`steam`, `gang`, `rank`) VALUES(" .. isql:Escape(steamID) .. ", " .. isql:Escape(info.name) .. ", 1);", function()
1605 InitPlayerGang(ply)
1606 ply:GangStorageRefresh()
1607 GangNotify(ply, 3, 4, "You successfully recovered the " .. info.name .. " gang!")
1608 GangWars.Log("gang_recover", ply, ply:Nick() .. " successfully recovered the gang '" .. decoded.name .. "'")
1609 end)
1610 end)
1611 end)
1612end
1613
1614net.Receive("RecoverGang", GC_Recover)
1615
1616-- /create <gang name>
1617local function GC_Create(len, ply)
1618 local decoded = net.ReadTable()
1619 local gname = decoded.name
1620
1621 if string.len(gname) > 20 then
1622 GangNotify(ply, 3, 4, "Gang name must not exceed 20 characters!")
1623
1624 return ""
1625 end
1626
1627 local price = 100000
1628
1629 if GangWars.GetLevel(ply) >= 10 and ply:CanAfford(price) and tonumber(decoded.logo) <= 25 then
1630 GangWars.DB.CreateGang(ply, gname, decoded.password, decoded.logo, decoded.color, decoded.color2, function(q, msg)
1631 if q then
1632 ply:AddMoney(-price, "Gang creation")
1633 InitPlayerGang(ply)
1634 ply:GangStorageRefresh()
1635 GangNotify(ply, 3, 4, "Congratulations! You have started the " .. gname .. " gang!")
1636 else
1637 if msg then
1638 GangNotify(ply, 3, 4, "Could not create gang. " .. msg)
1639 else
1640 GangNotify(ply, 3, 4, "Could not create gang.")
1641 end
1642 end
1643 end)
1644 else
1645 GangNotify(ply, 3, 4, "You must be level 10 and have " .. CUR .. "100,000 to create a gang")
1646 end
1647end
1648
1649net.Receive("CreateGang", GC_Create)
1650
1651-- /leave gang
1652local function GC_Leave(ply, args)
1653 -- find our gang name
1654 GangWars.DB.GetPlayerGang(ply, function(gang)
1655 if not gang then return end
1656
1657 GangWars.DB.RemoveFromGang(ply, function(q)
1658 --timer.Simple(1, function () InitPlayerGang(ply) end )
1659 --timer.Simple(1, function() UpdateClientGangInfo(gang) end)
1660 --timer.Simple(1, function() UpdateClientGangMembers(gang) end)
1661 if q then
1662 ply.GangInfo = nil
1663 GangNotify(ply, 3, 4, "You have left the " .. gang .. " gang")
1664 GangWars.GangLog(gang, ply:Nick() .. " left the gang", "Leave", ply)
1665 InitPlayerGang(ply)
1666 end
1667 end)
1668 end)
1669
1670 return ""
1671end
1672
1673AddChatCommand("/gang_leave", GC_Leave)
1674
1675local function GC_Donate(ply, args)
1676 -- find our gang name
1677 GangWars.DB.GetPlayerGang(ply, function(gang)
1678 if not gang then return "" end
1679 local money = math.floor(tonumber(args))
1680 if money <= 0 then return "" end
1681
1682 if not ply:CanAfford(money) then
1683 GangNotify(ply, 4, 4, "You don't have that much to donate!")
1684
1685 return ""
1686 end
1687
1688 -- swap money
1689 GangWars.DB.AddGangMoney(gang, money, function()
1690 InitPlayerGang(ply)
1691 ply:AddMoney(-money, "Gang donation")
1692 GangWars.GangLogNumber(gang, money, "Donate", ply)
1693 GangNotify(ply, 3, 4, "You have donated " .. CUR .. GangWars.FormatMoney(money) .. " to your gang")
1694 end)
1695 end)
1696
1697 return ""
1698end
1699
1700AddChatCommand("/gang_donate", GC_Donate)
1701
1702-- upgrade gang
1703local function GC_Upgrade(ply, args)
1704 -- find our gang name
1705 GangWars.DB.GetPlayerGang(ply, function(gang)
1706 if not gang then return end
1707
1708 -- find ranks
1709 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1710 if not my_rank or my_rank > 2 then
1711 GangNotify(ply, 3, 4, "You must be at least vice leader to purchase upgrades")
1712
1713 return
1714 end
1715
1716 -- do upgrade
1717 GangWars.DB.GangUpgrade(gang, args, function(q, msg, amnt)
1718 if q then
1719 --timer.Simple(2, function() UpdateClientGangInfo(gang) end)
1720 InitPlayerGang(ply)
1721 GangNotify(ply, 3, 4, "You have upgraded your gang")
1722 GangWars.GangLogNumber(gang, amnt, "Upgrade", ply, ply:Nick() .. " upgraded " .. args .. " for $" .. string.Comma(amnt))
1723 else
1724 if msg then
1725 GangNotify(ply, 3, 4, "You can't purchase that upgrade. " .. msg)
1726 else
1727 GangNotify(ply, 3, 4, "You can't purchase that upgrade")
1728 end
1729 end
1730 end)
1731 end)
1732 end)
1733
1734 return ""
1735end
1736
1737AddChatCommand("/gang_upgrade", GC_Upgrade)
1738
1739-- /invite <player>
1740local function GC_Invite(ply, args)
1741 -- find our gang
1742 GangWars.DB.GetPlayerGang(ply, function(gang)
1743 if not gang then
1744 GangNotify(ply, 3, 4, "You aren't in a gang!")
1745
1746 return
1747 end
1748
1749 -- find our target
1750 local target = FindPlayer(args)
1751
1752 if not target then
1753 GangNotify(ply, 3, 4, "Can't find that player to invite")
1754
1755 return ""
1756 end
1757
1758 -- find ranks
1759 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1760 if not my_rank or my_rank > 2 then
1761 GangNotify(ply, 3, 4, "You must be leader or vice leader to invite")
1762
1763 return ""
1764 end
1765
1766 -- invite them
1767 GangWars.DB.InviteToGang(target, gang, function(q, msg)
1768 if q then
1769 --timer.Simple(2, function () InitPlayerGang(target) end )
1770 --timer.Simple(2, function() UpdateClientGangInfo(gang) end)
1771 --timer.Simple(2, function() UpdateClientGangMembers(gang) end)
1772 unet.Start("gang_invite", target)
1773 net.WriteString(gang)
1774 unet.Send(target)
1775 InitPlayerGang(ply)
1776 InitPlayerGang(target)
1777 GangWars.GangLog(gang, ply:Nick() .. " invited " .. target:Nick(), "Invite", ply)
1778 GangNotify(ply, 3, 4, "You have invited " .. target:Nick() .. " to join " .. gang)
1779 GangNotify(target, 4, 4, "You have been invited to join " .. gang)
1780 else
1781 if msg then
1782 GangNotify(ply, 3, 4, "Invite failed. " .. msg)
1783 else
1784 GangNotify(ply, 3, 4, "Invite failed.")
1785 end
1786 end
1787 end)
1788 end)
1789 end)
1790
1791 return ""
1792end
1793
1794AddChatCommand("/gang_invite", GC_Invite)
1795
1796-- /kick <player>
1797local function GC_Kick(ply, cmd, args)
1798 -- find our gang name
1799 GangWars.DB.GetPlayerGang(ply, function(gang)
1800 if not gang then return end
1801 -- find our target
1802 local target = args[1]
1803 if target == "" then return end
1804 local reason = args[2] or ""
1805
1806 if target == ply:SteamID() then
1807 GangNotify(ply, 3, 4, "You can't kick yourself")
1808
1809 return ""
1810 end
1811
1812 -- check they're in our gang
1813 GangWars.DB.GetPlayerGang(target, function(tgang)
1814 if not tgang or tgang ~= gang then return "" end
1815
1816 -- find our rank
1817 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1818 if not my_rank then return end
1819
1820 -- check other guys rank
1821 -- AND `rank` < 6
1822 isql:QueryValue("SELECT `rank` FROM gw_gang_members WHERE `steam` = " .. isql:Escape(target) .. ";", function(other_rank)
1823 if not other_rank then return end
1824 local rank_ok = false
1825
1826 -- rank setting permissions. leaders can always kick
1827 if my_rank <= 1 then
1828 rank_ok = true
1829 -- vice leaders can kick captains
1830 elseif my_rank == 2 and other_rank > 2 then
1831 rank_ok = true
1832 elseif my_rank == 3 and other_rank > 3 then
1833 -- captains can kick vices
1834 rank_ok = true
1835 end
1836
1837 -- check the target isn't higher ranking than us if we're not leader
1838 if my_rank > 1 and other_rank <= my_rank then
1839 rank_ok = false
1840 end
1841
1842 -- invites can only be kicked by leaders and vice
1843 if other_rank >= 6 and my_rank > 2 then
1844 rank_ok = false
1845 end
1846
1847 if not rank_ok then
1848 GangNotify(ply, 3, 4, "You don't have the rank to do that")
1849
1850 return
1851 end
1852
1853 -- remove them
1854 GangWars.DB.RemoveFromGangBySteam(target, gang, function()
1855 net.Start("sv_refresh_topgangs")
1856 net.Broadcast()
1857 InitPlayerGang(ply)
1858 GangNotify(ply, 3, 4, "You have kicked " .. target .. " from the gang")
1859 GangWars.GangLog(gang, ply:Nick() .. " kicked " .. target .. " (" .. reason .. ")", "Kick", ply)
1860 local tply = FindPlayer(target)
1861
1862 if tply then
1863 InitPlayerGang(tply)
1864 GangNotify(tply, 4, 4, "You have been kicked from the " .. gang .. " gang")
1865 end
1866 end)
1867 end)
1868 end)
1869 end, true)
1870 end)
1871
1872 return ""
1873end
1874
1875--AddChatCommand("/gang_kick", GC_Kick)
1876concommand.Add("gang_kick", GC_Kick)
1877
1878-- /promote <rank> <player>
1879local function GC_Promote(ply, cmd, args)
1880 -- find our gang name
1881 GangWars.DB.GetPlayerGang(ply, function(gang)
1882 if not gang then return "" end
1883 --local words = string.Explode(" ", args)
1884 --if #words ~= 2 then return "" end
1885 local ptype = args[1]
1886 -- find our target
1887 local target = args[2]
1888
1889 if target == ply:SteamID() then
1890 GangNotify(ply, 3, 4, "You can't change your own rank")
1891
1892 return ""
1893 end
1894
1895 -- check they're in our gang
1896 GangWars.DB.GetPlayerGang(target, function(tgang)
1897 if not tgang or tgang ~= gang then return "" end
1898
1899 -- check our rank
1900 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1901 if not my_rank then return "" end
1902
1903 -- check other guys rank
1904 GangWars.DB.GetPlayerGangRank(target, function(other_rank)
1905 if not other_rank then return "" end
1906 local target_rank = tonumber(ptype)
1907 local rank_ok = false
1908
1909 -- rank setting permissions. leaders can set all ranks
1910 if my_rank <= 1 then
1911 rank_ok = true
1912 -- vice leaders can set up to captain
1913 elseif my_rank == 2 and target_rank > 2 then
1914 rank_ok = true
1915 elseif my_rank == 3 and target_rank > 3 then
1916 -- captains can set vices
1917 rank_ok = true
1918 end
1919
1920 -- check the target isn't higher ranking than us if we're not leader
1921 if my_rank > 1 and other_rank <= my_rank then
1922 rank_ok = false
1923 end
1924
1925 -- abandon setting the same rank
1926 if target_rank == other_rank then
1927 rank_ok = false
1928 end
1929
1930 if not rank_ok then
1931 GangNotify(ply, 3, 4, "You don't have the rank to do that")
1932
1933 return ""
1934 end
1935
1936 -- is it a promotion or demotion?
1937 local promotion = target_rank < other_rank
1938
1939 -- set targets rank
1940 GangWars.DB.SetPlayerGangRank(target, gang, target_rank, function(q)
1941 if q then
1942 local text = "promoted"
1943
1944 if not promotion then
1945 text = "demoted"
1946 end
1947
1948 InitPlayerGang(ply)
1949 local target = FindPlayer(args[2])
1950
1951 if IsValid(target) then
1952 InitPlayerGang(target)
1953 GangNotify(target, 4, 4, "You have been " .. text .. " within the gang")
1954 GangNotify(ply, 3, 4, "You " .. text .. " " .. target:Nick())
1955 GangWars.GangLog(gang, ply:Nick() .. " " .. text .. " " .. target:Nick(), "Promote", ply)
1956 else
1957 GangNotify(ply, 3, 4, "You " .. text .. " " .. args[2])
1958 GangWars.GangLog(gang, ply:Nick() .. " " .. text .. " " .. args[2], "Promote", ply)
1959 end
1960 end
1961 end)
1962 end)
1963 end)
1964 end)
1965 end)
1966
1967 return ""
1968end
1969
1970--AddChatCommand("/gang_promote", GC_Promote)
1971concommand.Add("gang_promote", GC_Promote)
1972
1973-- /add rival
1974local function GC_AddRival(ply, args)
1975 -- find our gang name
1976 GangWars.DB.GetPlayerGangInfo(ply, function(gang)
1977 if not gang then return "" end
1978
1979 -- check we're not naming ourself
1980 if gang.name == args then
1981 GangNotify(ply, 3, 4, "You can't name your own gang as a rival")
1982
1983 return
1984 end
1985
1986 if tonumber(gang.points) <= 0 then
1987 GangNotify(ply, 3, 4, args .. " can't be rivalled because your gang has no gang points")
1988
1989 return
1990 end
1991
1992 -- check rank
1993 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
1994 if not my_rank or tonumber(my_rank) > 2 then
1995 GangNotify(ply, 3, 4, "Only leaders and vice leaders can add rivals")
1996
1997 return
1998 end
1999
2000 -- check the other gang exists
2001 isql:QueryRow("SELECT `level`, `points` FROM `gw_gangs` WHERE `name` = " .. isql:Escape(args) .. ";", function(q)
2002 if not q or tonumber(q.level) < (ply:GetNW2Int("gang_level") - 5) then
2003 GangNotify(ply, 3, 4, args .. " are too low level to be your rival")
2004
2005 return
2006 end
2007
2008 if tonumber(q.points) <= 0 then
2009 GangNotify(ply, 3, 4, args .. " can't be rivalled because they have no gang points")
2010
2011 return
2012 end
2013
2014 -- check they aren't already our rival
2015 isql:QueryValue("SELECT COUNT(*) FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(gang.name) .. " AND `rival` = " .. isql:Escape(args) .. ";", function(q)
2016 if q and tonumber(q) > 0 then
2017 GangNotify(ply, 3, 4, "You are already rivals with that gang")
2018
2019 return
2020 end
2021
2022 -- and the other way around
2023 isql:QueryValue("SELECT COUNT(*) FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang.name) .. ";", function(q)
2024 if q and tonumber(q) > 0 then
2025 GangNotify(ply, 3, 4, "You are already rivals with that gang")
2026
2027 return
2028 end
2029
2030 -- check the rivalry is allowed
2031 isql:QueryValue("SELECT DATEDIFF(`expires`, NOW()) AS diff FROM `gw_gang_norival` WHERE `gang` = " .. isql:Escape(gang.name) .. " AND `rival` = " .. isql:Escape(args) .. " AND DATEDIFF(`expires`, NOW()) > 0;", function(rcount)
2032 if rcount and tonumber(rcount) > 0 then
2033 GangNotify(ply, 3, 4, "You are not allowed to rival that gang for " .. rcount .. " more days")
2034
2035 return
2036 end
2037
2038 -- delete any norival entry for this gang
2039 isql:Query("DELETE FROM `gw_gang_norival` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang.name) .. ";", function()
2040 -- add rival relationship
2041 isql:Query("INSERT INTO `gw_gang_rivals` (`gang`, `rival`, `started`) VALUES(" .. isql:Escape(gang.name) .. ", " .. isql:Escape(args) .. ", NOW());", function()
2042 isql:Query("INSERT INTO `gw_gang_rivals` (`gang`, `rival`, `started`) VALUES(" .. isql:Escape(args) .. ", " .. isql:Escape(gang.name) .. ", NOW());", function()
2043 -- add them
2044 --InitPlayerGang(ply)
2045 --GangNotify(ply, 3, 4, "You have named " .. args .. " as a rival gang")
2046 NotifyGang(gang.name, 4, 4, "A gang rivalry has been started against " .. args .. "!")
2047 NotifyGang(args, 4, 4, gang.name .. " have declared a gang rivalry has against you!")
2048
2049 for k, v in pairs(player.GetAll()) do
2050 if IsValid(v) then
2051 if v:Gang() == gang.name or v:Gang() == args then
2052 InitPlayerGang(v)
2053 end
2054 end
2055 end
2056 end)
2057 end)
2058 end)
2059 end)
2060 end)
2061 end)
2062 end)
2063 end)
2064 end)
2065
2066 return ""
2067end
2068
2069AddChatCommand("/gang_addrival", GC_AddRival)
2070-- request mercy
2071local BlockMercySpam = {}
2072
2073local function GC_ReqMercy(ply, args)
2074 if not IsValid(ply) then return end
2075 if BlockMercySpam[ply:SteamID()] and BlockMercySpam[ply:SteamID()] > CurTime() then return end
2076 BlockMercySpam[ply:SteamID()] = CurTime() + 5
2077
2078 -- find our gang name
2079 GangWars.DB.GetPlayerGang(ply, function(gang)
2080 if not gang then return "" end
2081
2082 -- find our rank
2083 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
2084 if not my_rank or tonumber(my_rank) > 2 then
2085 GangNotify(ply, 3, 4, "Only leaders and co-leaders can request mercy")
2086
2087 return
2088 end
2089
2090 -- try and make them win
2091 GangWars.DB.RivalryWin(args, gang)
2092 end)
2093 end)
2094
2095 return ""
2096end
2097
2098AddChatCommand("/gang_mercy", GC_ReqMercy)
2099
2100-- request truce
2101local function GC_ReqTruce(ply, args)
2102 -- find our gang name
2103 GangWars.DB.GetPlayerGang(ply, function(gang)
2104 if not gang then return "" end
2105
2106 -- find our rank
2107 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
2108 if not my_rank or tonumber(my_rank) > 2 then
2109 GangNotify(ply, 3, 4, "Only leaders and co-leaders can request a truce")
2110
2111 return
2112 end
2113
2114 -- see if other gang is requesting a truce
2115 isql:QueryValue("SELECT `truce` FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang) .. ";", function(truce)
2116 if not truce then
2117 GangNotify(ply, 3, 4, "You don't seem to have a rivalry with " .. args)
2118
2119 return
2120 end
2121
2122 if tonumber(truce) == 1 then
2123 -- truce is agreed. remove the rivalry
2124 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(gang) .. " AND `rival` = " .. isql:Escape(args) .. ";", function()
2125 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang) .. ";", function()
2126 -- refresh their view
2127 InitPlayerGang(ply)
2128 NotifyGang(gang, 4, 4, "A truce with " .. args .. " has been agreed!")
2129 NotifyGang(args, 4, 4, "A truce with " .. gang .. " has been agreed!")
2130 end)
2131 end)
2132 else
2133 -- set truce request
2134 isql:Query("UPDATE `gw_gang_rivals` SET `truce` = '1' WHERE `gang` = " .. isql:Escape(gang) .. " AND `rival` = " .. isql:Escape(args) .. ";", function()
2135 -- refresh their view
2136 InitPlayerGang(ply)
2137 --GangNotify(ply, 3, 4, "You have requested a truce with " .. args)
2138 NotifyGang(gang, 4, 4, "You have requested a truce with " .. args)
2139 NotifyGang(args, 4, 4, gang .. " have requested a truce!")
2140 end)
2141 end
2142 end)
2143 end)
2144 end)
2145
2146 return ""
2147end
2148
2149AddChatCommand("/gang_truce", GC_ReqTruce)
2150
2151-- cancel truce
2152local function GC_CancelTruce(ply, args)
2153 -- find our gang name
2154 GangWars.DB.GetPlayerGang(ply, function(gang)
2155 if not gang then return "" end
2156
2157 -- find our rank
2158 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
2159 if not my_rank or tonumber(my_rank) > 2 then
2160 GangNotify(ply, 3, 4, "Only leaders and co-leaders can cancel a truce")
2161
2162 return
2163 end
2164
2165 -- just check they exist
2166 isql:Query("SELECT `truce` FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(args) .. " AND `rival` = " .. isql:Escape(gang) .. ";", function(truce)
2167 if truce then
2168 -- set truce request
2169 isql:Query("UPDATE `gw_gang_rivals` SET `truce` = '0' WHERE `gang` = " .. isql:Escape(gang) .. " AND `rival` = " .. isql:Escape(args) .. ";", function()
2170 -- refresh their view
2171 InitPlayerGang(ply)
2172 GangNotify(ply, 3, 4, "You have cancelled the truce request with " .. args)
2173 end)
2174 end
2175 end)
2176 end)
2177 end)
2178
2179 return ""
2180end
2181
2182AddChatCommand("/gang_canceltruce", GC_CancelTruce)
2183
2184-- /accept
2185local function GC_AcceptInvite(ply, args)
2186 GangWars.DB.AcceptInvite(ply, args, function(q)
2187 if q then
2188 InitPlayerGang(ply, function()
2189 ply:GangStorageRefresh()
2190 ply:GangLogRefresh()
2191 GangNotify(ply, 3, 4, "You accepted the gang invite from " .. args)
2192 GangWars.GangLog(args, ply:Nick() .. " joined the gang", "Join", ply)
2193 end)
2194 end
2195 end)
2196
2197 return ""
2198end
2199
2200AddChatCommand("/gang_accept", GC_AcceptInvite)
2201
2202-- /reject
2203local function GC_RejectInvite(ply, args)
2204 GangWars.DB.RejectInvite(ply, args, function(q)
2205 if q then
2206 InitPlayerGang(ply)
2207 GangNotify(ply, 3, 4, "You rejected the gang invite from " .. args)
2208 GangWars.GangLog(args, ply:Nick() .. " rejected our gang invite", "Reject", ply)
2209 end
2210 end)
2211
2212 return ""
2213end
2214
2215AddChatCommand("/gang_reject", GC_RejectInvite)
2216
2217-- set item purchase permission
2218local function GC_SetBuyPermission(ply, cmd, args)
2219 --Msg("GC_SetBuyPermission\n")
2220 -- find our gang name
2221 GangWars.DB.GetPlayerGang(ply, function(gang)
2222 if not gang then return "" end
2223
2224 --Msg("GetPlayerGang\n")
2225 -- find our rank
2226 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
2227 --Msg("GetPlayerGangRank check\n")
2228 if not my_rank or tonumber(my_rank) > 2 then return end
2229 --Msg("GetPlayerGangRank ok\n")
2230 local itemid = args[1]
2231 local perms = args[2]
2232
2233 -- delete any existing permissions
2234 isql:Query("DELETE FROM`gw_gang_permissions` WHERE `gang` = " .. isql:Escape(gang) .. " AND `item` = " .. isql:Escape(itemid) .. ";", function()
2235 --Msg("DELETE FROM`gw_gang_permissions`\n")
2236 -- insert new permissions
2237 isql:Query("INSERT INTO `gw_gang_permissions` (`gang`, `item`, `permission`) VALUES(" .. isql:Escape(gang) .. ", " .. isql:Escape(itemid) .. ", " .. isql:Escape(perms) .. ");", function() end) --Msg("done!\n")
2238 end)
2239 end)
2240 end)
2241end
2242
2243concommand.Add("gang_permission", GC_SetBuyPermission)
2244
2245-- gang buy
2246local function GC_BuyItem(ply, args)
2247 -- Can't buy gang stuff as a cop
2248 if ply:GetProfession().police then
2249 Notify(ply, 4, 4, "You cant buy gang stuff when working as AnkhTek Security!")
2250
2251 return ""
2252 end
2253
2254 -- find our gang name
2255 GangWars.DB.GetPlayerGang(ply, function(gang)
2256 if not gang then
2257 Msg("Warning: /gang_buy player had no gang?\n")
2258
2259 return
2260 end
2261
2262 -- find our rank
2263 GangWars.DB.GetPlayerGangRank(ply, function(my_rank)
2264 if not my_rank then
2265 Msg("Warning: /gang_buy player had no rank?\n")
2266
2267 return
2268 end
2269
2270 -- find permissions for the item
2271 isql:QueryValue("SELECT `permission` FROM `gw_gang_permissions` WHERE `gang` = " .. isql:Escape(gang) .. " AND `item` = " .. isql:Escape(args) .. ";", function(perm)
2272 if not perm then
2273 --Msg("Warning: /gang_buy " .. args .. ": couldn't find a permission entry for this item\n")
2274 --return
2275 -- no permissions = default. nobody can buy.
2276 perm = 0
2277 end
2278
2279 -- check our rank has permission to buy
2280 local function HasItemPerm(perms, rank)
2281 local d = 16
2282 local pms = {0, 0, 0, 0, 0}
2283 local r = 5
2284
2285 while perms > 0 do
2286 if perms - d >= 0 then
2287 perms = perms - d
2288 pms[r] = 1
2289 end
2290
2291 d = d / 2
2292 r = r - 1
2293 end
2294
2295 return pms[rank] == 1
2296 end
2297
2298 -- check our rank has permission to buy
2299 if not HasItemPerm(perm, my_rank) then
2300 GangNotify(ply, 3, 4, "You don't have permission to buy that!")
2301
2302 return
2303 end
2304
2305 -- find gang info
2306 GangWars.DB.GetGangInfo(gang, function(info)
2307 if not info then
2308 Msg("GC_BuyItem: GangWars.DB.GetGangInfo returned nil")
2309
2310 return
2311 end
2312
2313 local gangmoney = tonumber(info.money)
2314 local ganglevel = tonumber(info.level)
2315 local found = false
2316
2317 -- find item in gang shop
2318 for k, v in pairs(Gang.GangShop) do
2319 if v.id == args then
2320 found = v
2321 break
2322 end
2323 end
2324
2325 -- abandon if item not found
2326 if not found then
2327 GangNotify(ply, 3, 4, "Item not found in gang shop")
2328
2329 return
2330 end
2331
2332 -- abandon if we're not high enough level
2333 if found.level > ganglevel then
2334 GangNotify(ply, 3, 4, "Your gang must be level " .. found.level .. " to spawn that!")
2335
2336 return
2337 end
2338
2339 -- fix the price
2340 local item_price = found.price
2341
2342 -- discount upgrade
2343 if ply.GangInfo and found.entity ~= "gang_stash" then
2344 if ply.GangInfo.shopboost and ply.GangInfo.shopboost > 0 then
2345 local txt, aff = Gang.GetUpgradeEffect("shopboost", ply.GangInfo.shopboost - 1)
2346 item_price = item_price - math.floor((item_price / 100) * aff)
2347 end
2348 end
2349
2350 -- abandon if we can't afford it
2351 if gangmoney < item_price then
2352 GangNotify(ply, 1, 4, "Your gang can not afford this!")
2353
2354 return
2355 end
2356
2357 -- abandon if gang is past its stash limit
2358 if found.entity == "gang_stash" then
2359 local stashes = {}
2360
2361 for k, v in pairs(ents.FindByClass(found.entity)) do
2362 if v.gang == gang then
2363 table.insert(stashes, v)
2364 end
2365 end
2366
2367 if #stashes >= math.min(ganglevel, 4) then
2368 GangNotify(ply, 1, 4, "You already have the max of " .. math.min(ganglevel, 4) .. " stashes")
2369
2370 return
2371 end
2372 end
2373
2374 -- abandon if gang is past its generator limit
2375 if found.entity == "base_generator" then
2376 local stashes = {}
2377
2378 for k, v in pairs(ents.FindByClass(found.entity)) do
2379 if v.gang == gang then
2380 table.insert(stashes, v)
2381 end
2382 end
2383
2384 if #stashes >= 2 then
2385 GangNotify(ply, 1, 4, "Your gang already have the max of 2 generators")
2386
2387 return
2388 end
2389 end
2390
2391 -- abandon if gang is past its printer limit
2392 if found.entity == "gang_printer" then
2393 local stashes = {}
2394
2395 for k, v in pairs(ents.FindByClass(found.entity)) do
2396 if v.gang == gang then
2397 table.insert(stashes, v)
2398 end
2399 end
2400
2401 --MsgN("checking gang printers. search is for '" .. found.entity .."', initial count is " .. #ents.FindByClass(found.entity) .. ", actual is " .. #stashes)
2402 if #stashes >= 4 then
2403 GangNotify(ply, 1, 4, "You already have the max of 4 gang printers")
2404
2405 return
2406 end
2407 end
2408
2409 -- abandon if gang is past its printer limit
2410 if found.entity == "orb_forge" then
2411 local stashes = {}
2412
2413 for k, v in pairs(ents.FindByClass(found.entity)) do
2414 if v.gang == gang then
2415 table.insert(stashes, v)
2416 end
2417 end
2418
2419 if #stashes >= 1 then
2420 GangNotify(ply, 1, 4, "You already have the max of 1 gang orb forge!")
2421
2422 return
2423 end
2424 end
2425
2426 -- abandon if gang is past its overclocker limit
2427 if found.entity == "overclocker_forge" then
2428 local stashes = {}
2429
2430 for k, v in pairs(ents.FindByClass(found.entity)) do
2431 if v.gang == gang then
2432 table.insert(stashes, v)
2433 end
2434 end
2435
2436 if #stashes >= 4 then
2437 GangNotify(ply, 1, 4, "You already have the max of 4 overclocker forges!")
2438
2439 return
2440 end
2441 end
2442
2443 -- charge gang
2444 GangWars.DB.AddGangMoney(gang, -item_price, function()
2445 GangNotify(ply, 1, 4, "You have bought a " .. found.name .. " for " .. CUR .. GangWars.FormatMoney(item_price))
2446 GangWars.GangLogNumber(gang, item_price, "Buy", ply, found.name)
2447 local trace = {}
2448 trace.start = ply:EyePos()
2449 trace.endpos = trace.start + ply:GetAimVector() * 85
2450 trace.filter = ply
2451 local tr = util.TraceLine(trace)
2452 -- create the item
2453 local spawnitem
2454 spawnitem = ents.Create(found.entity)
2455 spawnitem.SID = ply.SID
2456 spawnitem.gang = gang
2457 spawnitem:SetNWEntity("owning_ent", ply)
2458 spawnitem:SetNW2String("Owner", "Shared")
2459 spawnitem:SetNW2String("gang", gang)
2460 spawnitem.Owner = ply
2461 spawnitem.OwnerID = ply:SteamID()
2462 spawnitem:SetNW2Int("original_cost", item_price)
2463 spawnitem:SetPos(tr.HitPos)
2464 spawnitem.onlyremover = true
2465 spawnitem.nodupe = true
2466
2467 if found.model then
2468 spawnitem.weaponclass = found.subclass
2469 spawnitem:SetModel(found.model)
2470 end
2471
2472 -- create CII data
2473 local ciidata = {}
2474 ciidata.class = "item"
2475 ciidata.subclass = found.subclass
2476 ciidata.ent = found.entity
2477 ciidata.name = found.name or ""
2478 ciidata.model = found.model or ""
2479 ciidata.icon = found.icon
2480 ciidata.value = item_price or 0
2481 ciidata.level_lock = found.level or 0
2482 ciidata.quantity = 0
2483 ciidata.level = 1
2484 ciidata.entityex = found.subclass
2485
2486 -- See if the item supports the CII interface
2487 if spawnitem.CIILoad then
2488 spawnitem:CIILoad(ciidata)
2489 end
2490
2491 -- See if the item supports the newer LoadItem interface (it must have a ref)
2492 if spawnitem.LoadItem then
2493 local ref = GangWars.Item.FindByName(found.name)
2494 spawnitem:LoadItem(ref)
2495 end
2496
2497 -- Else try the subclass interface
2498 if spawnitem.SetSubclass then
2499 spawnitem:SetSubclass(found.subclass)
2500 end
2501
2502 spawnitem:Spawn()
2503
2504 -- do it twice for the benefit of gang coolers etc (badly coded ents)
2505 if spawnitem.SetSubclass then
2506 spawnitem:SetSubclass(found.subclass)
2507 end
2508 spawnitem:CPPISetOwner(ply)
2509 end)
2510 end)
2511 end)
2512 end)
2513 end)
2514
2515 return ""
2516end
2517
2518AddChatCommand("/gang_buy", GC_BuyItem)
2519
2520--////////////////////////////////////////////////////////////////////////////
2521-- Util
2522function Gang.SendRivalList(rp, my_gang)
2523 if not my_gang then return end
2524
2525 -- send full member list
2526 GangWars.DB.GetGangRivalList(my_gang, function(members)
2527 if not members then return end
2528
2529 for k, v in pairs(members) do
2530 local col = string.Explode(" ", v.color)
2531
2532 if #col == 3 then
2533 v.color = Color(tonumber(col[1]), tonumber(col[2]), tonumber(col[3]), 255)
2534 end
2535
2536 local col = string.Explode(" ", v.color2)
2537
2538 if #col == 3 then
2539 v.color2 = Color(tonumber(col[1]), tonumber(col[2]), tonumber(col[3]), 255)
2540 end
2541 end
2542
2543 -- store the list - we use this to decide wether to drop evidence in sv_gamemode_functions.lua
2544 local tmp = {}
2545
2546 for k, v in pairs(members) do
2547 table.insert(tmp, v.name)
2548 end
2549
2550 rp.GangRivals = tmp
2551 net.Start("ds_gang_rivals")
2552 net.WriteTable(members)
2553 net.Send(rp)
2554 end)
2555end
2556
2557function Gang.SendMemberList(rp, my_gang)
2558 if not my_gang then return end
2559
2560 -- send full member list
2561 --[[
2562 GangWars.DB.GetPlayerGangMemberList(my_gang,
2563 function(members)
2564 if not members then return end
2565 net.Start("ds_gang_members")
2566 net.WriteTable(members)
2567 net.Send(rp)
2568 end)
2569 ]]
2570 GangWars.DB.GetGangMemberStats(my_gang, rp:SteamID(), function(members)
2571 if not members then return end
2572 net.Start("ds_gang_members")
2573 net.WriteTable(members)
2574 net.Send(rp)
2575 end)
2576end
2577
2578function Gang.SendInfo(rp, my_gang)
2579 if not my_gang then return end
2580
2581 -- set gang info
2582 GangWars.DB.GetGangInfo(my_gang, function(info)
2583 -- get members for count
2584 GangWars.DB.GetPlayerGangMemberList(my_gang, function(members)
2585 -- get shop permissions
2586 isql:Query("SELECT * FROM `gw_gang_permissions` WHERE `gang` = " .. isql:Escape(my_gang) .. ";", function(perms)
2587 local shop_permissions = {}
2588
2589 if perms then
2590 for k, v in ipairs(perms) do
2591 shop_permissions[tostring(v.item)] = v.permission
2592 end
2593 end
2594--[[
2595 local col = string.Explode(" ", info.color)
2596
2597 if #col == 3 then
2598 col = Color(tonumber(col[1]), tonumber(col[2]), tonumber(col[3]), 255)
2599 end
2600
2601 local col2 = string.Explode(" ", info.color2)
2602
2603 if #col2 == 3 then
2604 col2 = Color(tonumber(col2[1]), tonumber(col2[2]), tonumber(col2[3]), 255)
2605 end
2606]]
2607 -- this is pretty pointless, but could save copying over unwanted data (eg password)
2608 local MyGang = {}
2609 MyGang.name = info['name']
2610 MyGang.logo = info['logo']
2611 MyGang.message = info['message']
2612 MyGang.points = tonumber(info['points'])
2613 MyGang.color = Color(0, 0, 0)
2614 MyGang.color2 = Color(255, 0, 0)
2615 MyGang.xp = tonumber(info['xp'])
2616 MyGang.level = tonumber(info['level'])
2617 MyGang.money = tonumber(info['money'])
2618 MyGang.hpboost = tonumber(info['hpboost'])
2619 MyGang.regen = tonumber(info['regen'])
2620 MyGang.extraitems = tonumber(info['extraitems'])
2621 MyGang.xpboost = tonumber(info['xpboost'])
2622 MyGang.speedboost = tonumber(info['speedboost'])
2623 MyGang.printboost = tonumber(info['printboost'])
2624 MyGang.drugboost = tonumber(info['drugboost'])
2625 MyGang.dropboost = tonumber(info['dropboost'])
2626 -- gang patch
2627 MyGang.armorboost = tonumber(info['armorboost'])
2628 --MyGang.memberboost = tonumber(info['memberboost'])
2629 --MyGang.rivalboost = tonumber(info['rivalboost'])
2630 MyGang.shopboost = tonumber(info['shopboost'])
2631 --MyGang.ghostboost = tonumber(info['ghostboost'])
2632 MyGang.ppocketboost = tonumber(info['ppocketboost'])
2633 MyGang.bankboost = tonumber(info['bankboost'])
2634 MyGang.missionboost = tonumber(info['missionboost'])
2635 MyGang.gangxpboost = tonumber(info['gangxpboost'])
2636 --MyGang.capboost = tonumber(info['capboost'])
2637 MyGang.shop_permissions = shop_permissions
2638 MyGang.members = table.Count(members)
2639 net.Start("ds_gang_info")
2640 net.WriteTable(MyGang)
2641 net.Send(rp)
2642 end)
2643 end)
2644 end)
2645end
2646
2647--[[
2648// Refreshes a gangs info for all online players in the gang
2649function UpdateClientGangInfo(gang_name)
2650 local RP = RecipientFilter()
2651
2652 // Find all gangmembers
2653 GangWars.DB.GetPlayerGangMemberList(gang_name,
2654 function(mlist)
2655 if not mlist then return false end
2656
2657 // Find gangmembers who are on the server
2658 for id, row in pairs(mlist) do
2659 local p = FindPlayer(row['name'])
2660 if p and IsValid(p) and p:IsPlayer() then
2661 RP:AddPlayer(p)
2662 end
2663 end
2664
2665 // Send updates
2666 Gang.SendInfo(RP, gang_name)
2667 end)
2668end
2669
2670// Refreshes a gangs player list for all online players in the gang
2671function UpdateClientGangMembers(gang_name)
2672 local RP = RecipientFilter()
2673
2674 // Find all gangmembers
2675 GangWars.DB.GetPlayerGangMemberList(gang_name,
2676 function(mlist)
2677 if not mlist then return false end
2678
2679 // Find gangmembers who are on the server
2680 for id, row in pairs(mlist) do
2681 local p = FindPlayer(row['name'])
2682 if p and IsValid(p) and p:IsPlayer() then
2683 RP:AddPlayer(p)
2684 end
2685 end
2686
2687 // Send updates
2688 Gang.SendMemberList(RP, gang_name)
2689 end)
2690end
2691]]
2692-- Updates a single players gang info
2693function InitPlayerGang(ply, func)
2694 if not ply or not IsValid(ply) then return false end
2695 local steamID = ply:SteamID()
2696
2697 -- find gang status
2698 isql:QueryRow("SELECT `gang`, `rank` FROM `gw_gang_members` WHERE `steam` = " .. isql:Escape(steamID) .. " ORDER BY `rank` ASC;", function(info)
2699 if not info or not info.gang or not info.rank then
2700 -- set no gang
2701 ply:SetNW2String("gang_name", "")
2702 ply:SetNW2Int("gang_rank", 0)
2703 ply:SetNW2Int("gang_level", 0)
2704 ply:SetNW2String("gang_logo", "")
2705 ply:SetNW2String("gang_color", "")
2706 ply:SetNW2String("gang_color2", "")
2707 ply.GangInfo = nil
2708 unet.Start("gang_clear", ply)
2709 unet.Send(ply)
2710
2711 if func then
2712 func(false)
2713 end
2714
2715 return
2716 elseif tonumber(info.rank) == 6 then
2717 -- set invited
2718 ply:SetNW2String("gang_name", "")
2719 ply:SetNW2Int("gang_rank", 0)
2720 ply:SetNW2Int("gang_level", 0)
2721 ply:SetNW2String("gang_logo", "")
2722 ply:SetNW2String("gang_color", "")
2723 ply:SetNW2String("gang_color2", "")
2724 ply.GangInfo = nil
2725 unet.Start("gang_clear", ply)
2726 unet.Send(ply)
2727 ply:SetNW2Int("gang_invited", true)
2728
2729 isql:Query("SELECT `gang` FROM gw_gang_members WHERE `steam` = " .. isql:Escape(steamID) .. ";", function(members)
2730 if members then
2731 net.Start("ds_gang_invites")
2732 net.WriteTable(members)
2733 net.Send(ply)
2734 end
2735 end)
2736
2737 if func then
2738 func(false)
2739 end
2740
2741 return
2742 else
2743 -- set member
2744 GangWars.DB.GetGangInfo(info.gang, function(ginfo)
2745 if ginfo then
2746 -- convert ints
2747 ginfo.level = tonumber(ginfo.level)
2748 ginfo.rank = tonumber(ginfo.rank)
2749
2750 for k, v in pairs(ginfo) do
2751 if tonumber(v) ~= nil then
2752 ginfo[k] = tonumber(v)
2753 end
2754 end
2755
2756 -- set network vars
2757 ply:SetNW2String("gang_name", info.gang)
2758 ply:SetNW2Int("gang_rank", info.rank)
2759 ply:SetNW2Int("gang_level", ginfo.level)
2760 ply:SetNW2String("gang_logo", ginfo.logo)
2761 --ply:SetNW2String("gang_color", ginfo.color)
2762 --ply:SetNW2String("gang_color2", ginfo.color2)
2763 ply:SetNW2String("gang_color", "0 0 0")
2764 ply:SetNW2String("gang_color2", "255 0 0")
2765 -- attach gang info data to player
2766 ply.GangInfo = ginfo
2767 Gang.SendRivalList(ply, info.gang)
2768 Gang.SendMemberList(ply, info.gang)
2769 Gang.SendInfo(ply, info.gang)
2770 ply:GangLogRefresh()
2771
2772 if func then
2773 func(true)
2774 end
2775 else
2776 if func then
2777 func(false)
2778 end
2779 end
2780 end)
2781 end
2782 end)
2783
2784 return ""
2785end
2786
2787local function DoRefresh(ply, args)
2788 InitPlayerGang(ply, function()
2789 ply:GangStorageRefresh()
2790 end)
2791
2792 return ""
2793end
2794
2795AddChatCommand("/gang_refresh", DoRefresh)
2796
2797hook.Add("PlayerPickedCharacter", "InitGang", function(ply)
2798 InitPlayerGang(ply, function()
2799 ply:GangStorageRefresh()
2800 ply:GangLogRefresh()
2801
2802 --MsgN("SELECT `rival`, `members_killed` FROM gw_gang_rivals WHERE `gang` = " .. isql:Escape(ply:Gang()) .. " AND TIME_TO_SEC(TIMEDIFF(NOW(), started))/60/60 > 72;")
2803 isql:Query("SELECT `rival`, `members_killed` FROM gw_gang_rivals WHERE `gang` = " .. isql:Escape(ply:Gang()) .. " AND TIME_TO_SEC(TIMEDIFF(NOW(), started))/60/60 > 72;", function(q)
2804 if not q then return end
2805
2806 --MsgN("looping")
2807 for k, v in pairs(q) do
2808 --MsgN("SELECT `members_killed` FROM gw_gang_rivals WHERE `gang` = " .. isql:Escape(v.rival) .. " AND `rival` = " .. isql:Escape(ply:Gang()) .. " AND TIME_TO_SEC(TIMEDIFF(NOW(), started))/60/60 > 72;")
2809 -- we've found a finished war. check who had more kills
2810 local our_kills = v.members_killed
2811 local our_gang = ply:Gang()
2812
2813 isql:QueryValue("SELECT `members_killed` FROM gw_gang_rivals WHERE `gang` = " .. isql:Escape(v.rival) .. " AND `rival` = " .. isql:Escape(ply:Gang()) .. " AND TIME_TO_SEC(TIMEDIFF(NOW(), started))/60/60 > 72;", function(q2)
2814 --MsgN("result = " .. tostring(q2))
2815 if not q2 then return end
2816 local enemy_kills = q2
2817 local enemy_gang = v.rival
2818
2819 --MsgN("fin")
2820 -- if either team has less than 10 kills?
2821 if our_kills == enemy_kills then
2822 NotifyGang(enemy_gang, 4, 4, "The rivalry with " .. our_gang .. " ended in a draw because you both had " .. our_kills .. " kills")
2823 NotifyGang(our_gang, 4, 4, "The rivalry with " .. enemy_gang .. " ended in a draw because you both had " .. our_kills .. " kills")
2824 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(our_gang) .. " AND `rival` = " .. isql:Escape(enemy_gang) .. ";")
2825 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(enemy_gang) .. " AND `rival` = " .. isql:Escape(our_gang) .. ";")
2826 elseif our_kills > enemy_kills then
2827 if our_kills < 30 then
2828 NotifyGang(enemy_gang, 4, 4, "The rivalry with " .. our_gang .. " ended with less than 30 kills. Nobody won!")
2829 NotifyGang(our_gang, 4, 4, "The rivalry with " .. enemy_gang .. " ended with less than 30 kills. Nobody won!")
2830 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(our_gang) .. " AND `rival` = " .. isql:Escape(enemy_gang) .. ";")
2831 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(enemy_gang) .. " AND `rival` = " .. isql:Escape(our_gang) .. ";")
2832 else
2833 NotifyGang(enemy_gang, 4, 4, "You lost the rivalry vs " .. our_gang .. " after 3 days, with " .. enemy_kills .. " kills")
2834 NotifyGang(our_gang, 4, 4, "You won the rivalry with " .. enemy_gang .. " after 3 days, with " .. our_kills .. " kills")
2835 GangWars.DB.RivalryWin(our_gang, enemy_gang, true)
2836 end
2837 else
2838 if enemy_kills < 30 then
2839 NotifyGang(enemy_gang, 4, 4, "The rivalry with " .. our_gang .. " ended with less than 30 kills. Nobody won!")
2840 NotifyGang(our_gang, 4, 4, "The rivalry with " .. enemy_gang .. " ended with less than 30 kills. Nobody won!")
2841 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(our_gang) .. " AND `rival` = " .. isql:Escape(enemy_gang) .. ";")
2842 isql:Query("DELETE FROM `gw_gang_rivals` WHERE `gang` = " .. isql:Escape(enemy_gang) .. " AND `rival` = " .. isql:Escape(our_gang) .. ";")
2843 else
2844 NotifyGang(enemy_gang, 4, 4, "You won the rivalry vs " .. our_gang .. " after 3 days, with " .. enemy_kills .. " kills")
2845 NotifyGang(our_gang, 4, 4, "You lost the rivalry with " .. enemy_gang .. " after 3 days, with " .. our_kills .. " kills")
2846 GangWars.DB.RivalryWin(enemy_gang, our_gang, true)
2847 end
2848 end
2849 end)
2850 end
2851 end)
2852 end)
2853end)
2854
2855-- gang search
2856local function GC_Search(ply, args)
2857 if string.len(args) < 2 or string.len(args) > 32 then
2858 GangNotify(ply, 3, 4, "Invalid Search")
2859
2860 return ""
2861 end
2862
2863 isql:Query("SELECT `name`, `logo`, `color`, `color2`, `level` FROM gw_gangs WHERE `name` LIKE " .. isql:Escape("%" .. args .. "%") .. " LIMIT 15;", function(q)
2864 if q then
2865 for k, v in pairs(q) do
2866 local col = string.Explode(" ", v.color)
2867
2868 if #col == 3 then
2869 v.color = Color(tonumber(col[1]), tonumber(col[2]), tonumber(col[3]), 255)
2870 end
2871
2872 local col = string.Explode(" ", v.color2)
2873
2874 if #col == 3 then
2875 v.color2 = Color(tonumber(col[1]), tonumber(col[2]), tonumber(col[3]), 255)
2876 end
2877 end
2878
2879 net.Start("ds_gang_search")
2880 net.WriteTable(q)
2881 net.Send(ply)
2882 end
2883 end)
2884
2885 return ""
2886end
2887
2888AddChatCommand("/gang_search", GC_Search)
2889--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2890-- Gang Storage
2891local meta = FindMetaTable("Player")
2892
2893function meta:GangStorageRefresh()
2894 if not self.GangInfo or not self.GangInfo.name or self.GangInfo.name == "" then
2895 self:SetDataset("gang_storage", {})
2896 else
2897 self:SetDatasetQueryKeyed("gang_storage", "slot", "SELECT * FROM `view_gang_storage` WHERE `gang` = " .. isql:Escape(self.GangInfo.name) .. ";")
2898 end
2899end
2900
2901function meta:AllGangStorageRefresh()
2902 if not self.GangInfo or not self.GangInfo.name or self.GangInfo.name == "" then return end
2903
2904 for k, v in pairs(player.GetAll()) do
2905 if v.GangInfo and v.GangInfo.name and v.GangInfo.name == self.GangInfo.name then
2906 v:SetDatasetQueryKeyed("gang_storage", "slot", "SELECT * FROM `view_gang_storage` WHERE `gang` = " .. isql:Escape(self.GangInfo.name) .. ";")
2907 end
2908 end
2909end
2910
2911--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2912function GangWars.DBX.GangStorageAdd(ply, itemid, slotid, func)
2913 if not IsValid(ply) or not ply.GangInfo then
2914 func(nil)
2915
2916 return
2917 end
2918
2919 local steamID = ply:SteamID()
2920
2921 -- stop exploit where you drop an item & drop from storage
2922 if ply.DroppingItem or ply.upgrading then
2923 GangWars.Log("cheat", ply, "JIMMYS Gang Storage Exploit (GSTADD)") -- log jimmy lol
2924 ply:GangStorageRefresh()
2925 ply:InvRefresh()
2926 -- timer.Simple(1, function()
2927 -- ply:InvRefresh()
2928 -- end)
2929
2930 return
2931 end
2932
2933 if ply.trade then
2934 Notify(ply, 3, 4, "You can't do this while trading")
2935 ply:InvRefresh()
2936 ply:GangStorageRefresh()
2937
2938 return
2939 end
2940
2941 -- race condition exploits
2942 if ply.RCExploit and ply.RCExploit > CurTime() then
2943 GangWars.Log("cheat", ply, "Blocked RC (GSADD)")
2944 ply:GangStorageRefresh()
2945 ply:InvRefresh()
2946 -- timer.Simple(1, function()
2947 -- ply:InvRefresh()
2948 -- end)
2949
2950 return
2951 end
2952
2953 ply.RCExploit = CurTime() + 2
2954
2955 -- no storage until level 5
2956 if ply.GangInfo.level < 5 then
2957 Notify(ply, 3, 4, "You can't use gang storage until your gang is level 5")
2958 ply:GangStorageRefresh()
2959 ply:InvRefresh()
2960 -- timer.Simple(1, function()
2961 -- ply:InvRefresh()
2962 -- end)
2963
2964 return
2965 end
2966
2967 -- Note the player is dropping something
2968 ply.DroppingItem = true
2969 ply.trade = true
2970
2971 -- Find the item
2972 GangWars.DBX.GetInventoryItem(ply, itemid, function(checkitem)
2973 if not checkitem then
2974 ply.DroppingItem = false
2975 ply.trade = false
2976
2977 return
2978 end
2979
2980 -- Can't drop credit items
2981 if checkitem.glon ~= "" and checkitem.glon ~= "nil" then
2982 local tmp = util.JSONToTable(checkitem.glon)
2983
2984 if tmp.bound or tmp.superbound then
2985 Notify(ply, 4, 4, "You can't put bound items in storage!")
2986 ply:GangStorageRefresh()
2987 ply:InvRefresh()
2988 -- timer.Simple(1, function()
2989 -- ply:InvRefresh()
2990 -- end)
2991 ply.DroppingItem = false
2992 ply.trade = false
2993
2994 return
2995 end
2996 end
2997
2998 -- do we have permission?
2999 local gang = ply.GangInfo.name
3000 local rank = ply:GetNW2Int("gang_rank")
3001
3002 -- find permissions for the item
3003 isql:QueryValue("SELECT `permission` FROM `gw_gang_permissions` WHERE `gang` = " .. isql:Escape(gang) .. " AND `item` = 'storage_add';", function(perm)
3004 if not perm then
3005 perm = 0
3006 end
3007
3008 -- check our rank has permission to buy
3009 local function HasItemPerm(perms, rank)
3010 local d = 16
3011 local pms = {0, 0, 0, 0, 0}
3012 local r = 5
3013
3014 while perms > 0 do
3015 if perms - d >= 0 then
3016 perms = perms - d
3017 pms[r] = 1
3018 end
3019
3020 d = d / 2
3021 r = r - 1
3022 end
3023
3024 return pms[rank] == 1
3025 end
3026
3027 -- check our rank has permission to buy
3028 if not HasItemPerm(perm, rank) then
3029 GangNotify(ply, 3, 4, "You don't have permission to add items to storage!")
3030 ply:GangStorageRefresh()
3031 ply:InvRefresh()
3032 -- timer.Simple(1, function()
3033 -- ply:InvRefresh()
3034 -- end)
3035 ply.DroppingItem = false
3036 ply.trade = false
3037
3038 return
3039 end
3040
3041 -- add item
3042 isql:Query("SELECT * FROM `gw_items` WHERE `steam` = " .. isql:Escape(steamID) .. " AND `id` = " .. isql:Escape(itemid), function(d, s, err)
3043 d = d[1]
3044
3045 if not d then
3046 ply:GangStorageRefresh()
3047 ply:InvRefresh()
3048 -- timer.Simple(1, function()
3049 -- ply:InvRefresh()
3050 -- end)
3051 ply.DroppingItem = false
3052 ply.trade = false
3053
3054 return
3055 end
3056
3057 isql:Query("INSERT INTO `view_gang_storage` (`id`,`steam`, `class`,`ent`,`subclass`,`name`,`model`,`icon`,`value`,`quantity`,`level_lock`,`level`,`glon`,`slot`, `gang`) VALUES(" .. isql:Escape(d.id) .. "," .. isql:Escape(steamID) .. "," .. isql:Escape(d.class) .. "," .. isql:Escape(d.ent) .. "," .. isql:Escape(d.subclass) .. "," .. isql:Escape(d.name) .. "," .. isql:Escape(d.model) .. "," .. isql:Escape(d.icon) .. "," .. isql:Escape(d.value) .. "," .. isql:Escape(d.quantity) .. "," .. isql:Escape(d.level_lock) .. "," .. isql:Escape(d.level) .. "," .. isql:Escape(d.glon or {}) .. "," .. isql:Escape(slotid) .. "," .. isql:Escape(ply.GangInfo.name) .. ")", function(d, s, e)
3058 isql:Query("DELETE FROM `gw_items` WHERE `steam` = " .. isql:Escape(steamID) .. " AND `id` = " .. isql:Escape(itemid), function(d, s, e)
3059 GangWars.Log("gangstorage", ply, "{" .. ply:Gang() .. "} Added " .. checkitem.quantity .. "x" .. checkitem.name .. " [" .. checkitem.id .. "]")
3060 ply:InvRefresh()
3061 ply:AllGangStorageRefresh()
3062 ply.DroppingItem = false
3063 ply.trade = false
3064
3065 if not s then
3066 Msg("GangWars.DBX.GangStorageAdd: Failed: " .. err .. "\n")
3067 end
3068 end)
3069 end)
3070 end)
3071 end)
3072 end)
3073end
3074
3075function GangWars.DBX.GangStorageRemove(ply, itemid, slot)
3076 if not IsValid(ply) or not ply.GangInfo then
3077 func(nil)
3078
3079 return
3080 end
3081
3082 local steamID = ply:SteamID()
3083
3084 -- stop exploit where you drop an item & drop from storage
3085 if ply.DroppingItem or ply.upgrading then
3086 GangWars.Log("cheat", ply, "JIMMYS Gang Storage Exploit (GSTREM)") -- log jimmy lol
3087 ply:GangStorageRefresh()
3088 ply:InvRefresh()
3089 -- timer.Simple(1, function()
3090 -- ply:InvRefresh()
3091 -- end)
3092
3093 return
3094 end
3095
3096 if ply.trade then
3097 Notify(ply, 3, 4, "You can't do this while trading")
3098 ply:GangStorageRefresh()
3099 ply:InvRefresh()
3100 -- timer.Simple(1, function()
3101 -- ply:InvRefresh()
3102 -- end)
3103
3104 return
3105 end
3106
3107 -- race condition exploits
3108 if ply.RCExploit and ply.RCExploit > CurTime() then
3109 GangWars.Log("cheat", ply, "Blocked RC (GSREM)")
3110 ply:GangStorageRefresh()
3111 ply:InvRefresh()
3112 -- timer.Simple(1, function()
3113 -- ply:InvRefresh()
3114 -- end)
3115
3116 return
3117 end
3118
3119 ply.RCExploit = CurTime() + 2
3120 -- Note the player is dropping something
3121 ply.DroppingItem = true
3122 ply.trade = true
3123 -- do we have permission?
3124 local gang = ply.GangInfo.name
3125 local rank = ply:GetNW2Int("gang_rank")
3126
3127 -- find permissions for the item
3128 isql:QueryValue("SELECT `permission` FROM `gw_gang_permissions` WHERE `gang` = " .. isql:Escape(gang) .. " AND `item` = 'storage_remove';", function(perm)
3129 if not perm then
3130 perm = 0
3131 end
3132
3133 -- check our rank has permission to buy
3134 local function HasItemPerm(perms, rank)
3135 local d = 16
3136 local pms = {0, 0, 0, 0, 0}
3137 local r = 5
3138
3139 while perms > 0 do
3140 if perms - d >= 0 then
3141 perms = perms - d
3142 pms[r] = 1
3143 end
3144
3145 d = d / 2
3146 r = r - 1
3147 end
3148
3149 return pms[rank] == 1
3150 end
3151
3152 -- check our rank has permission to buy
3153 if not HasItemPerm(perm, rank) then
3154 GangNotify(ply, 3, 4, "You don't have permission to take items from storage!")
3155 ply:InvRefresh()
3156 ply:GangStorageRefresh()
3157 ply.DroppingItem = false
3158 ply.trade = false
3159
3160 return
3161 end
3162
3163 -- Check for inventory space
3164 if not ply:HasInvSpace() then
3165 Notify(ply, 3, 4, "Your inventory is full!")
3166 ply:InvRefresh()
3167 ply:GangStorageRefresh()
3168 ply.DroppingItem = false
3169 ply.trade = false
3170
3171 return
3172 end
3173
3174 -- Switch item to inventory
3175 isql:Query("SELECT * FROM `view_gang_storage` WHERE `id` = " .. isql:Escape(itemid) .. " AND `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(ply.GangInfo.name), function(d, s, err)
3176 d = d[1]
3177 local ciidata = GangWars.Item.FindByName(d.name):CreateCII()
3178 ciidata.glon = util.JSONToTable(d.glon)
3179 ciidata.value = d.value
3180 ciidata.quantity = d.quantity
3181 ciidata.level_lock = d.level_lock
3182 ciidata.level = d.level
3183
3184 GangWars.DBX.AddInventoryItemCII(ply, ciidata, function(s)
3185 if s then
3186 isql:Query("DELETE FROM `view_gang_storage` WHERE `steam` = " .. isql:Escape(steamID) .. " AND `id` = " .. isql:Escape(itemid) .. " AND `gang` = " .. isql:Escape(ply.GangInfo.name), function(d, s, e)
3187 ply:InvRefresh()
3188 ply:AllGangStorageRefresh()
3189 ply.DroppingItem = false
3190 ply.trade = false
3191
3192 if not s then
3193 Msg("GangWars.DBX.GangStorageRemove: Failed: " .. err .. "\n")
3194 end
3195 end)
3196 end
3197 end, slot, false, true)
3198 end)
3199 end)
3200end
3201
3202function GangWars.DBX.GangStorageMove(ply, itemid, slotid)
3203 if not IsValid(ply) or not ply.GangInfo then
3204 func(nil)
3205
3206 return
3207 end
3208
3209 local steamID = ply:SteamID()
3210
3211 if ply.trade then
3212 Notify(ply, 3, 4, "You can't do this while trading")
3213 ply:GangStorageRefresh()
3214 ply:InvRefresh()
3215 -- timer.Simple(1, function()
3216 -- ply:InvRefresh()
3217 -- end)
3218
3219 return
3220 end
3221
3222 -- Switch item
3223 isql:Query("UPDATE `view_gang_storage` SET `slot` = " .. isql:Escape(slotid) .. " WHERE `id` = " .. isql:Escape(itemid) .. " AND `steam` = " .. isql:Escape(steamID) .. " AND `gang` = " .. isql:Escape(ply.GangInfo.name), function(d, s, err)
3224 ply:AllGangStorageRefresh()
3225
3226 if not s then
3227 Msg("GangWars.DBX.GangStorageMove: Failed: " .. err .. "\n")
3228 end
3229 end)
3230end
3231
3232--///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3233-- Gang Storage Console Commands
3234local function DoStorageRefresh(ply, cmd, args)
3235 ply:GangStorageRefresh()
3236
3237 return ""
3238end
3239
3240concommand.Add("gang_storage_refresh", DoStorageRefresh)
3241
3242local function DoStorageAdd(ply, cmd, args)
3243 local id = tonumber(args[1])
3244 local slot = tonumber(args[2])
3245 GangWars.DBX.GangStorageAdd(ply, id, slot)
3246
3247 return ""
3248end
3249
3250concommand.Add("gang_storage_add", DoStorageAdd)
3251
3252local function DoStorageRemove(ply, cmd, args)
3253 local id = tonumber(args[1])
3254 local slot = tonumber(args[2])
3255 GangWars.DBX.GangStorageRemove(ply, id, slot)
3256
3257 return ""
3258end
3259
3260concommand.Add("gang_storage_remove", DoStorageRemove)
3261
3262local function DoStorageMove(ply, cmd, args)
3263 local id = tonumber(args[1])
3264 local slot = tonumber(args[2])
3265 GangWars.DBX.GangStorageMove(ply, id, slot)
3266
3267 return ""
3268end
3269
3270concommand.Add("gang_storage_move", DoStorageMove)
3271util.AddNetworkString("gw_tg_request")
3272util.AddNetworkString("gw_tg_send")
3273
3274net.Receive("gw_tg_request", function(l, p)
3275 local gdata = {}
3276 local cache = {}
3277 if p.LastGangScoreboardRequest and p.LastGangScoreboardRequest < CurTime() then return end
3278
3279 isql:Query("SELECT `color`, `color2`, `name`, `level`, `points`, `money` FROM `gw_gangs` ORDER BY `points` DESC LIMIT 10", function(d, s, e)
3280 if s then
3281 table.insert(gdata, d)
3282
3283 isql:Query("SELECT * FROM `gw_gang_members`", function(d2, s2, e2)
3284 if s2 then
3285 table.insert(cache, d2)
3286
3287 for index, gang in pairs(gdata) do
3288 for ind, data in pairs(cache) do
3289 if data.gang == gang.name then
3290 if not gdata[index]["players"] then
3291 gdata[index]["players"] = {}
3292 end
3293
3294 table.insert(gdata[index]["players"], data)
3295 end
3296 end
3297
3298 if not gdata[index]["players"] then
3299 gdata[index]["players"] = {}
3300 end
3301 end
3302 end
3303
3304 net.Start("gw_tg_send")
3305 net.WriteTable(gdata)
3306 net.Send(p)
3307 end)
3308 end
3309 end)
3310
3311 p.LastGangScoreboardRequest = CurTime() + 290
3312end)