· 8 years ago · Jan 05, 2018, 08:56 PM
1if (!GANG.GroupList) then
2 GANG.GroupList = {}
3 GANG.GroupMembers = {}
4 GANG.GroupPlayers = {}
5 GANG.GroupNameIndex = {}
6 GANG.GroupCount = 0
7end
8
9util.AddNetworkString("gang_syncgroup")
10util.AddNetworkString("gang_grouplist")
11util.AddNetworkString("gang_chat")
12util.AddNetworkString("gang_group_motd_change")
13util.AddNetworkString("gang_group_names")
14util.AddNetworkString("gang_playernames")
15util.AddNetworkString("gang_invite")
16
17local defPlayerColor = Vector(0.243137, 0.345098, 0.415686)
18
19local function DoQuery(q, args, callback)
20 local query = q
21
22 if (args and table.Count(args) > 0) then
23 for key, value in pairs (args) do
24 local esc = "" -- The stuff to replace :key with
25 if (type(value) == "number") then
26 esc = value
27 elseif (type(value) == "boolean") then
28 esc = "'" .. (value and 1 or 0) .. "'"
29 elseif (type(value) == "string") then
30 esc = "'" .. sql.SQLStr(value, true) .. "'"
31 end
32
33 query = string.gsub(query, ":" .. key, esc)
34 end
35 end
36
37 -- local res = sql.Query(query)
38 -- if (callback) then
39 -- callback(query, res)
40 -- end
41 RPI.QueueQuery(query, {
42 onSuccess = function(q)
43 if (callback) then
44 callback(query, q:getData())
45 end
46 end,
47 onFailure = function(q, err)
48 print("FAILED QUERY!", err)
49 end
50 })
51end
52
53function GANG:DropTables()
54 -- sql.Query([[
55 -- DROP TABLE gang_list;
56 -- DROP TABLE gang_members;
57 -- DROP TABLE gang_spawn
58 -- ]])
59end
60
61function GANG:InitGroups()
62 self.GroupList = {}
63 self.GroupMembers = {}
64
65 -- if (!sql.TableExists("gang_list")) then
66 -- sql.Query([[
67 -- CREATE TABLE gang_list ( id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(32), motd varchar(2048), leader varchar(32), color varchar(32), creationdate int(32), disabled int(2) DEFAULT 0, relations varchar(65536), friendlyfire int(2) DEFAULT 0 );
68 -- CREATE TABLE gang_members ( id INTEGER PRIMARY KEY, steamid varchar(]] .. GANG.GroupNameMax .. [[), partyid int(32) DEFAULT 0, officer int(2) DEFAULT 0 );
69 -- CREATE TABLE gang_spawn ( id INTEGER, x int(32), y int(32), z int(32) );
70 -- ]])
71 -- end
72
73 DoQuery("SELECT COUNT(*) FROM gang_list", nil, function(q, data)
74 self.GroupCount = tonumber(data[1]["COUNT(*)"])
75 end)
76
77 DoQuery("SELECT id, name, motd, leader, coleader, color, relations, friendlyfire FROM gang_list WHERE disabled != 1", nil, function(q, data)
78 if (!data or !data[1]) then
79 return
80 end
81
82 for _, g in pairs (data) do
83 local c = string.ToColor(g.color .. " 255")
84 local col = Vector(c.r / 255, c.g / 255, c.b / 255)
85
86 local t = {
87 name = g.name,
88 motd = g.motd or "",
89 leader = g.leader,
90 coleader = util.JSONToTable(g.coleader) == nil and {g.coleader} or util.JSONToTable(g.coleader),
91 color = col,
92 members = {},
93 membercount = 0,
94 relstr = g.relations,
95 relations = {
96 [true] = {},
97 [false] = {},
98 },
99 friendlyfire = tonumber(g.friendlyfire) == 1
100 }
101
102 if (g.motd == "NULL") then
103 g.motd = ""
104 end
105
106 local relstr = g.relations or ""
107 local expl = string.Explode(",", relstr)
108 for __, v in ipairs (expl) do
109 local expl2 = string.Explode(":", v)
110 local groupid = tonumber(expl2[1])
111 local ally = tobool(tonumber(expl2[2]))
112
113 table.insert(t.relations[ally], groupid)
114 end
115
116 GANG.GroupList[tonumber(g.id)] = t
117 GANG.GroupNameIndex[g.name] = t
118 end
119
120 DoQuery("SELECT id, x, y, z FROM gang_spawn", nil, function(q, data)
121 if (!data or !data[1]) then
122 return end
123
124 for _, m in pairs (data) do
125 m.id = tonumber(m.id)
126 if (!GANG.GroupList[m.id]) then
127 continue end
128
129 GANG.GroupList[m.id].spawn = Vector(tonumber(m.x), tonumber(m.y), tonumber(m.z))
130 SetGlobalVector("SquadSpawn" .. m.id, GANG.GroupList[m.id].spawn)
131 end
132 end)
133
134 DoQuery("SELECT steamid, partyid, officer FROM gang_members WHERE partyid != 0", nil, function(q, data)
135 if (!data or !data[1]) then
136 return end
137
138 for _, m in pairs (data) do
139 m.partyid = tonumber(m.partyid)
140 if (!GANG.GroupList[m.partyid]) then
141 continue end
142
143 GANG.GroupMembers[m.steamid] = m.partyid
144 GANG.GroupList[m.partyid].members[m.steamid] = tonumber(m.officer)
145 GANG.GroupList[m.partyid].membercount = GANG.GroupList[m.partyid].membercount + 1
146 end
147 end)
148 end)
149end
150
151function GANG:GetGroup(id)
152 return self.GroupList[id]
153end
154
155function GANG:GetGroupByName(name)
156 return self.GroupNameIndex[name]
157end
158
159function GANG:GetGroupBySteamID(steamid)
160 return self.GroupMembers[steamid] or 0
161end
162
163function GANG:IsValidName(name, prevname)
164 local len = name:len()
165 if (len < self.GroupNameMin) then
166 return false, "Name must be at least " .. self.GroupNameMin .. " characters long."
167 elseif (len > self.GroupNameMax) then
168 return false, "Name exceeds max length of " .. self.GroupNameMax .. " characters."
169 end
170
171 if (string.find(name, "#") or string.find(name, "%(") or string.find(name, "%)")) then
172 return false, "Unallowed characters found."
173 end
174
175 if (name == prevname) then
176 return false, "Names are identical."
177 end
178
179 return true
180end
181
182function GANG:CreateGroup(ply, name, cs)
183 for gname in pairs (self.GroupNameIndex) do
184 if (gname:lower() == name:lower()) then
185 ply:ChatPrint("A squad with this name already exists.")
186 return
187 end
188 end
189
190 if (ply:IsInGroup()) then
191 local s = "Leave your squad to create one."
192 if (ply:IsGroupLeader()) then
193 s = "Disband your squad or give the leadership to someone else then leave to create one."
194 end
195
196 ply:ChatPrint("You're already in a squad! " .. s)
197 return
198 end
199
200 local okname, reason = self:IsValidName(name)
201 if (!okname) then
202 ply:ChatPrint(reason)
203 return
204 end
205
206 local color = string.ToColor(cs)
207 if (!color or (!color.r or !color.g or !color.b)) then
208 if (IsValid(ply)) then
209 ply:ChatPrint("Invalid color code.")
210 end
211
212 return
213 end
214
215 local steamid = ply:SteamID()
216
217 local t = {
218 name = name,
219 leader = steamid,
220 coleader = {},
221 members = {
222 [steamid] = 0,
223 },
224 membercount = 1,
225 color = cs,
226 motd = "",
227 relstr = "",
228 relations = {[true] = {}, [false] = {}},
229 friendlyfire = false,
230 }
231
232 DoQuery("INSERT INTO gang_list (name, leader, coleader, creationdate, color) VALUES (:name, :leader, '[]', " .. os.time() .. ", :color)", t, function(q, data, result)
233 local id = GANG.GroupCount + 1
234 t.color = color:ToVector()
235
236 GANG.GroupNameIndex[name] = t
237 GANG.GroupList[id] = t
238 GANG.GroupCount = id
239
240 local t = {
241 steamid = steamid,
242 partyid = id,
243 officer = "0",
244 }
245
246 DoQuery("UPDATE gang_members SET partyid = :partyid, officer = :officer WHERE steamid = :steamid", t, function(q, data, result)
247 GANG.GroupMembers[steamid] = id
248 ply:ChatPrint("You have created the squad: " .. name)
249 ply:SetGroupID(id)
250 ply:SetGroupColor(Vector(color.r / 255, color.g / 255, color.b / 255))
251 ply:SetGroupName(name)
252 ply:SetGroupRank(4)
253
254 if (self.GroupPlayers[id]) then
255 table.insert(self.GroupPlayers[id], ply)
256 else
257 self.GroupPlayers[id] = {ply}
258 end
259 end)
260 end)
261end
262
263function GANG:DisbandGroup(id, ply)
264 local group = self:GetGroup(id)
265 if (!group) then return end
266
267 if (IsValid(ply)) then
268 if (!ply:IsInGroup(id)) then
269 ply:ChatPrint("You aren't even in this squad.")
270 return
271 end
272
273 if (!ply:IsGroupLeader(id)) then
274 ply:ChatPrint("You can't disband a squad if you aren't the leader.")
275 return
276 end
277 end
278
279 DoQuery("UPDATE gang_list SET disabled = 1 WHERE id = :id", {id = id}, function(q, data, result)
280 if (IsValid(ply)) then
281 ply:ChatPrint("You have disbanded your squad.")
282 ply:SetGroupID(0)
283 end
284
285 for _, v in pairs (self:GetGangMembers(id)) do
286 if (IsValid(v)) then
287 if (v ~= ply) then
288 v:ChatPrint("Your squad was disbanded!")
289 v:SetGroupID(0)
290 GANG.GroupMembers[v:SteamID()] = nil
291 end
292
293 v:SetGroupColor(defPlayerColor)
294 v:SetGroupRank(0)
295 end
296 end
297
298 DoQuery("UPDATE gang_members SET partyid = 0, officer = 0 WHERE partyid = :partyid", {partyid = id})
299
300 GANG.GroupList[id] = nil
301 GANG.GroupNameIndex[group.name] = nil
302
303 for member, gid in pairs (GANG.GroupMembers) do
304 if (gid == id) then
305 GANG.GroupMembers[member] = nil
306 end
307 end
308
309 self.GroupPlayers[id] = nil
310 end)
311end
312
313function GANG:RenameGroup(id, ply, name)
314 local group = self:GetGroup(id)
315 if (!group) then return end
316
317 local prevname = group.name
318
319 local okname, reason = self:IsValidName(name, prevname)
320 local already = self:GetGroup(name) ~= nil
321
322 if (IsValid(ply)) then
323 if (!ply:IsInGroup(id)) then
324 ply:ChatPrint("You aren't even in this squad.")
325 return
326 end
327
328 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id)) then
329 ply:ChatPrint("You can't rename a squad if you aren't the leader or co-leader.")
330 return
331 end
332
333 if (!okname) then
334 ply:ChatPrint(reason)
335 return
336 end
337
338 if (already) then
339 ply:ChatPrint("A squad with this name already exists.")
340 return
341 end
342 end
343
344 if (!okname or already) then return end
345
346 DoQuery("UPDATE gang_list SET name = :name WHERE id = :id", {id = id, name = name}, function(q, data, result)
347 if (IsValid(ply)) then
348 ply:ChatPrint("You have renamed your squad to: " .. name)
349 end
350
351 for _, v in pairs (self:GetGangMembers(id)) do
352 if (IsValid(v) and v ~= ply) then
353 v:ChatPrint("Your squad was renamed to: " .. name)
354 end
355 end
356
357 group.name = name
358 GANG.GroupNameIndex[prevname] = nil
359 GANG.GroupNameIndex[name] = group
360 GANG:SyncGroup(id, true)
361 end)
362end
363
364function GANG:LeaveGroup(id, ply)
365 local group = self:GetGroup(id)
366 if (!group) then return end
367
368 if (!ply:IsInGroup(id)) then
369 ply:ChatPrint("You aren't even in this squad.")
370 return
371 end
372
373 if (ply:IsGroupLeader(id)) then
374 ply:ChatPrint("As leader you can't leave your squad. Disband your squad or give the leadership to someone else.")
375 return
376 end
377
378 local steamid = ply:SteamID()
379
380 if (ply:IsGroupCoLeader()) then
381 table.RemoveByValue(group.coleader, ply:SteamID())
382 DoQuery("UPDATE gang_list SET coleader = '" .. util.TableToJSON(group.coleader) .. "' WHERE id = :id", {id = id})
383 end
384
385 DoQuery("UPDATE gang_members SET partyid = 0, officer = 0 WHERE steamid = :steamid", {steamid = steamid}, function(q, data, result)
386 if (IsValid(ply)) then
387 ply:ChatPrint("You have left your squad.")
388 ply:SetGroupID(0)
389 ply:SetGroupColor(defPlayerColor)
390 ply:SetGroupName("")
391 ply:SetGroupRank(0)
392 ply:SetNWString("GANG_Allies", "")
393 GANG.GroupMembers[ply:SteamID()] = nil
394
395 if (self.GroupPlayers[id]) then
396 for _, v in pairs (self:GetGangMembers(id)) do
397 if (IsValid(v) and v ~= ply) then
398 v:ChatPrint(ply:Nick() .. " has left the squad.")
399 end
400 end
401
402 table.RemoveByValue(self.GroupPlayers[id], ply)
403 end
404 end
405
406 group.members[steamid] = nil
407 group.membercount = group.membercount - 1
408 GANG.GroupMembers[steamid] = nil
409 GANG:SyncGroup(id, true)
410 end)
411end
412
413function GANG:JoinGroup(id, ply)
414 local group = self:GetGroup(id)
415 if (!group) then return end
416
417 if (ply:IsInGroup()) then
418 ply:ChatPrint("You're already in a squad.")
419 return
420 end
421
422 local steamid = ply:SteamID()
423
424 DoQuery("UPDATE gang_members SET partyid = :partyid, officer = :officer WHERE steamid = :steamid", {steamid = steamid, partyid = id, officer = 0}, function(q, data, result)
425 if (IsValid(ply)) then
426 ply:ChatPrint("You have joined the squad: " .. group.name)
427 ply:SetGroupID(id)
428 ply:SetGroupColor(group.color)
429 ply:SetGroupName(group.name)
430 ply:SetGroupRank(0)
431 ply:SetNWString("GANG_Allies", table.concat(group.relations[true], ","))
432
433 for _, v in pairs (self:GetGangMembers(id)) do
434 if (IsValid(v) and v ~= ply) then
435 v:ChatPrint(ply:Nick() .. " joined the squad!")
436 end
437 end
438
439 if (self.GroupPlayers[id]) then
440 table.insert(self.GroupPlayers[id], ply)
441 else
442 self.GroupPlayers[id] = {ply}
443 end
444 end
445
446 group.members[steamid] = "0"
447 group.membercount = group.membercount + 1
448 GANG.GroupMembers[steamid] = id
449 GANG:SyncGroup(id, true)
450 end)
451end
452
453function GANG:InviteToGroup(ply, target)
454 local id = ply:GetGroupID()
455 local group = self:GetGroup(id)
456 if (!group) then return end
457
458 if (!ply:IsGroupOfficer() and !ply:IsGroupLeader() and !ply:IsGroupCoLeader()) then
459 ply:ChatPrint("You must be an officer or higher to invite players into your squad.")
460 return
461 end
462
463 if (target:IsInGroup()) then
464 if (target:GetGroupID() == id) then
465 ply:ChatPrint("They're already in your squad.")
466 else
467 ply:ChatPrint("They're already in a squad.")
468 end
469
470 return
471 end
472
473 if (target._groupinvite) then
474 ply:ChatPrint("They already have a squad invite pending.")
475 return
476 end
477
478 if (ply.m_fLastSquadInvite and CurTime() - ply.m_fLastSquadInvite <= 10) then
479 ply:ChatPrint("You have recently invited a player to your squad. Please Wait.")
480 return
481 end
482
483 target._groupinvite = {
484 id = id,
485 inviter = ply,
486 expires = CurTime() + 30,
487 }
488
489 ply.m_fLastSquadInvite = CurTime()
490 ply:ChatPrint("Invitation to join squad sent.")
491 -- target:ChatPrint("You have been invited by " .. ply:Nick() .. " to join their squad: " .. group.name)
492 -- target:ChatPrint("Type /saccept to join the squad or /sdeny to deny the invitation.")
493
494 net.Start("gang_invite")
495 net.WriteString(ply:Nick())
496 net.WriteString(group.name)
497 net.Send(target)
498end
499
500function GANG:KickFromGroup(id, ply, target)
501 local group = self:GetGroup(id)
502 if (!group) then return end
503
504 local ingroup = self:GetGroupBySteamID(target) == id
505
506 if (IsValid(ply)) then
507 if (!ply:IsInGroup(id)) then
508 ply:ChatPrint("You aren't even in this squad.")
509 return
510 end
511
512 if (!ply:IsGroupOfficer() and !ply:IsGroupLeader() and !ply:IsGroupCoLeader() and !ply:IsGroupSergeant()) then
513 ply:ChatPrint("You can't kick someone from a squad if you aren't an officer or higher.")
514 return
515 end
516
517 if (target == ply:SteamID()) then
518 ply:ChatPrint("You can't kick yourself.")
519 return
520 end
521
522 if (group.leader == target) then
523 if (ply:IsGroupLeader()) then
524 ply:ChatPrint("You can't kick yourself. Disband your squad or give the leadership to someone else.")
525 else
526 ply:ChatPrint("You can't kick the squad's leader.")
527 end
528
529 return
530 elseif (table.HasValue(group.coleader, target)) then
531 if (!ply:IsGroupLeader()) then
532 ply:ChatPrint("Only the squad leader may kick the co-leader.")
533 return
534 end
535 elseif (group.members[target] == 1 and !ply:IsGroupLeader() and !ply:IsGroupCoLeader() and !ply:IsGroupSergeant()) then
536 ply:ChatPrint("Only the squad leader, co-leader or a sergeant can kick officers.")
537 return
538 elseif (group.members[target] == 2 and !ply:IsGroupLeader() and !ply:IsGroupCoLeader()) then
539 ply:ChatPrint("Only the squad leader and co-leader can kick sergeants.")
540 return
541 end
542
543 if (!ingroup) then
544 ply:ChatPrint("They aren't in your squad.")
545 return
546 end
547 end
548
549 if (!ingroup) then return end
550
551 if (table.HasValue(group.coleader, target)) then
552 table.RemoveByValue(group.coleader, target)
553 DoQuery("UPDATE gang_list SET coleader = '" .. util.TableToJSON(group.coleader) .. "' WHERE id = :id", {id = id})
554 end
555
556 DoQuery("UPDATE gang_members SET partyid = 0, officer = 0 WHERE steamid = :steamid", {steamid = target}, function(q, data, result)
557 local pl
558 for _, v in pairs (self:GetGangMembers(id)) do
559 if (IsValid(v) and v:SteamID() == target) then
560 v:ChatPrint("You were kicked from your squad!")
561 v:SetGroupID(0)
562 v:SetGroupColor(defPlayerColor)
563 v:SetGroupName("")
564 v:SetGroupRank(0)
565 v:SendLua([[if (IsValid(pGangMenu)) then pGangMenu:Remove() end]])
566 v:SetNWString("GANG_Allies", "")
567
568 pl = v
569
570 break
571 end
572 end
573
574 if (self.GroupPlayers[id]) then
575 local msg
576 if (pl) then
577 msg = pl:Nick() .. " was kicked from your squad."
578
579 table.RemoveByValue(self.GroupPlayers[id], pl)
580 else
581 msg = "A player (" .. target .. ") was kicked from your squad."
582
583 GANG:GetRPName(target, function(data)
584 if (!data) then
585 return end
586
587 msg = data[1].rpname .. " was kicked from your squad."
588 end)
589 end
590
591 for _, v in pairs (self:GetGangMembers(id)) do
592 if (!IsValid(v) or v == pl) then
593 continue end
594
595 v:ChatPrint(msg)
596 end
597 end
598
599 group.members[target] = nil
600 group.membercount = group.membercount - 1
601 GANG.GroupMembers[target] = nil
602 GANG:SyncGroup(id, true)
603 end)
604end
605
606function GANG:ChangeGroupRelation(id, ply, groupid, ally)
607 local group = self:GetGroup(id)
608 if (!group) then
609 return end
610
611 local targetgroup = self:GetGroup(groupid)
612 if (!targetgroup) then
613 ply:ChatPrint("That squad doesn't exist.")
614 return
615 end
616
617 if (group.relations[ally] and #group.relations[ally] > 3) then return end
618
619 if (table.HasValue(group.relations[ally], groupid)) then
620 return end
621
622 if (IsValid(ply)) then
623 if (!ply:IsInGroup(id)) then
624 ply:ChatPrint("You aren't even in this squad.")
625 return
626 end
627
628 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id)) then
629 ply:ChatPrint("You can't do this if you aren't the leader.")
630 return
631 end
632 end
633
634 table.insert(group.relations[ally], groupid)
635 table.RemoveByValue(group.relations[!ally], groupid)
636
637 local t = {}
638 local alliedto = {}
639 for _, v in pairs (group.relations[true]) do
640 table.insert(t, v .. ":1")
641 table.insert(alliedto, v)
642 end
643
644 local allystr = table.concat(alliedto, ",")
645
646 for _, v in pairs (group.relations[false]) do
647 table.insert(t, v .. ":0")
648 end
649
650 local relations = table.concat(t, ",")
651 group.relstr = relations
652
653 DoQuery("UPDATE gang_list SET relations = :relations WHERE id = :id", {id = id, relations = relations}, function(q, data, result)
654 for _, v in pairs (self:GetGangMembers(id)) do
655 if (IsValid(v)) then
656 v:SetNWString("GANG_Allies", allystr)
657 v:ChatPrint("Your squad now considers the " .. targetgroup.name .. " squad as an " .. (ally and "ally" or "enemy") .. ".")
658 end
659 end
660
661 for _, v in pairs (self:GetGangMembers(groupid)) do
662 if (IsValid(v)) then
663 v:ChatPrint("The " .. group.name .. " squad now considers your squad as an " .. (ally and "ally" or "enemy") .. ".")
664 end
665 end
666
667 GANG:SyncGroup(id, true)
668 end)
669end
670
671function GANG:ChangeGroupRelationNeutral(id, ply, groupid)
672 local group = self:GetGroup(id)
673 if (!group) then
674 return end
675
676 local targetgroup = self:GetGroup(groupid)
677 if (!targetgroup) then
678 ply:ChatPrint("That squad doesn't exist.")
679 return
680 end
681
682 if (!table.HasValue(group.relations[true], groupid) and !table.HasValue(group.relations[false], groupid)) then
683 return end
684
685 if (IsValid(ply)) then
686 if (!ply:IsInGroup(id)) then
687 ply:ChatPrint("You aren't even in this squad.")
688 return
689 end
690
691 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id)) then
692 ply:ChatPrint("You can't do this if you aren't the leader.")
693 return
694 end
695 end
696
697 table.RemoveByValue(group.relations[true], groupid)
698 table.RemoveByValue(group.relations[false], groupid)
699
700 local t = {}
701 local alliedto = {}
702 for _, v in pairs (group.relations[true]) do
703 table.insert(t, v .. ":1")
704 table.insert(alliedto, v)
705 end
706
707 local allystr = table.concat(alliedto, ",")
708
709 for _, v in pairs (group.relations[false]) do
710 table.insert(t, v .. ":0")
711 end
712
713 local relations = table.concat(t, ",")
714 group.relstr = relations
715
716 DoQuery("UPDATE gang_list SET relations = :relations WHERE id = :id", {id = id, relations = relations}, function(q, data, result)
717 for _, v in pairs (self:GetGangMembers(id)) do
718 if (IsValid(v)) then
719 v:SetNWString("GANG_Allies", allystr)
720 v:ChatPrint("Your squad now considers the " .. targetgroup.name .. " squad as neutral.")
721 end
722 end
723
724 GANG:SyncGroup(id, true)
725 end)
726end
727
728function GANG:SetGroupLeader(id, ply, target)
729 local group = self:GetGroup(id)
730 if (!group) then return end
731
732 local ingroup = self:GetGroupBySteamID(target) == id
733
734 if (IsValid(ply)) then
735 if (!ply:IsInGroup(id)) then
736 ply:ChatPrint("You aren't even in this squad.")
737 return
738 end
739
740 if (!ply:IsGroupLeader(id)) then
741 ply:ChatPrint("You can't make someone leader if you aren't the leader yourself.")
742 return
743 end
744
745 if (group.leader == target) then
746 ply:ChatPrint("You're already the leader.")
747 return
748 end
749
750 if (!ingroup) then
751 ply:ChatPrint("They aren't in your squad.")
752 return
753 end
754 end
755
756 if (!ingroup) then return end
757
758 DoQuery("UPDATE gang_list AS g, gang_members AS m SET g.leader = :leader, m.officer = 0 WHERE g.id = :partyid AND m.partyid = :partyid", {leader = target, partyid = id}, function(q, data, result)
759 GANG:GetRPName(target, function(data)
760 if (!data) then
761 return end
762
763 for _, v in pairs (self:GetGangMembers(id)) do
764 if (IsValid(v)) then
765 v:ChatPrint("Your squad has a new leader (" .. data[1].rpname .. ")")
766 end
767 end
768 end)
769
770 for _, v in pairs (player.GetAll()) do
771 if (v:SteamID() == target) then
772 v:SetGroupRank(4)
773 break
774 end
775 end
776 ply:SetGroupRank(0)
777
778 group.leader = target
779 group.members[target] = 0
780 group.members[ply:SteamID()] = 0
781 GANG:SyncGroup(id, true)
782 end)
783end
784
785function GANG:SetGroupCoLeader(id, ply, target)
786 local group = self:GetGroup(id)
787 if (!group) then MsgN("No group found") return end
788
789 local ingroup = self:GetGroupBySteamID(target) == id
790
791 if (IsValid(ply)) then
792 if (!ply:IsInGroup(id)) then
793 ply:ChatPrint("You aren't even in this squad.")
794 return
795 end
796
797 if (!ply:IsGroupLeader(id)) then
798 ply:ChatPrint("You can't make someone co-leader if you aren't the leader yourself.")
799 return
800 end
801
802 if (group.leader == target) then
803 ply:ChatPrint("You are the leader; can't make yourself co-leader.")
804 return
805 end
806
807 if (!ingroup) then
808 ply:ChatPrint("They aren't in your squad.")
809 return
810 end
811 end
812
813 if (!ingroup) then MsgN("Wait?") return end
814
815 table.insert(group.coleader, target)
816
817 DoQuery("UPDATE gang_list AS g, gang_members AS m SET g.coleader = '" .. util.TableToJSON(group.coleader) .. "', m.officer = 0 WHERE g.id = " .. id .. " AND m.partyid = " .. id .. ";", {}, function(q, data, result)
818
819 GANG:GetRPName(target, function(data)
820 if (!data) then
821 return end
822
823 for _, v in pairs (self:GetGangMembers(id)) do
824 if (IsValid(v)) then
825 v:ChatPrint("Your squad has a new co-leader (" .. data[1].rpname .. ")")
826 end
827 end
828 end)
829
830 for _, v in pairs (player.GetAll()) do
831 if (v:SteamID() == target) then
832 v:SetGroupRank(3)
833 end
834 end
835
836 group.members[target] = 0
837 GANG:SyncGroup(id, true)
838 end)
839end
840
841function GANG:UnsetGroupCoLeader(id, ply, target, nick)
842 local group = self:GetGroup(id)
843 if (!group) then return end
844
845 if (IsValid(ply)) then
846 if (!ply:IsInGroup(id)) then
847 ply:ChatPrint("You aren't even in this squad.")
848 return
849 end
850
851 if (group.coleader == {}) then
852 ply:ChatPrint("Your squad doesn't have any co-leaders.")
853 return
854 end
855
856 if (!ply:IsGroupLeader(id)) then
857 ply:ChatPrint("You can't make demote the co-leader if you aren't leader.")
858 return
859 end
860 end
861
862 table.RemoveByValue(group.coleader, target)
863
864 DoQuery("UPDATE gang_list SET coleader = '" .. util.TableToJSON(group.coleader) .. "' WHERE id = " .. id, {}, function(q, data, result)
865 local name = ""
866 for _, v in pairs (self:GetGangMembers(id)) do
867 if (v:SteamID() == id) then
868 name = v:Nick()
869 v:SetGroupRank(0)
870 end
871 end
872 for _, v in pairs (self:GetGangMembers(id)) do
873 if (IsValid(v)) then
874 v:SetGroupRank(0)
875 v:ChatPrint(nick .. " is no longer your co-leader.")
876 end
877 end
878
879 GANG:SyncGroup(id, true)
880 end)
881end
882
883function GANG:ChangeOfficerRank(id, ply, target, promote)
884 local group = self:GetGroup(id)
885 if (!group) then return end
886
887 local ingroup = self:GetGroupBySteamID(target) == id
888 local alreadyofficer = promote and group.members[target] == 1
889 local alreadymember = !promote and group.members[target] == 0
890
891 if (IsValid(ply)) then
892 if (!ply:IsInGroup(id)) then
893 ply:ChatPrint("You aren't even in this squad.")
894 return
895 end
896
897 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id) and !ply:IsGroupSergeant()) then
898 ply:ChatPrint("You can't promote a squad member if you aren't sergeant or higher.")
899 return
900 end
901
902 if (group.leader == target) then
903 ply:ChatPrint("You can't promote or demote yourself. Give the leadership to someone else.")
904 return
905 end
906
907 if (!ingroup) then
908 ply:ChatPrint("They aren't in your squad.")
909 return
910 end
911
912 if (alreadyofficer) then
913 ply:ChatPrint("They're already an officer.")
914 return
915 end
916
917 if (alreadymember) then
918 ply:ChatPrint("They're already a member.")
919 return
920 end
921 end
922
923 if (!ingroup or alreadyofficer or alreadymember) then return end
924
925 DoQuery("UPDATE gang_members SET officer = :rank WHERE steamid = :steamid", {steamid = target, rank = promote and "1" or "0"}, function(q, data, result)
926 local s = promote and "promoted to officer" or "demoted to member"
927
928 GANG:GetRPName(target, function(data)
929 local name = data and data[1].rpname or target
930
931 for _, v in pairs (self:GetGangMembers(id)) do
932 if (IsValid(v)) then
933 if (v:SteamID() == target) then
934 v:SetGroupRank(promote and 1 or 0)
935 v:ChatPrint("You were " .. s .. "!")
936 else
937 v:ChatPrint("A squad member (" .. name .. ") was " .. s .. ".") -- no name for now...
938 end
939 end
940 end
941 end)
942
943 group.members[target] = promote and 1 or 0
944 GANG:SyncGroup(id, true)
945 end)
946end
947
948function GANG:ChangeSergeantRank(id, ply, target, promote)
949 local group = self:GetGroup(id)
950 if (!group) then return end
951
952 local ingroup = self:GetGroupBySteamID(target) == id
953 local alreadysergeant = promote and group.members[target] == 2
954 local alreadymember = !promote and group.members[target] < 2
955
956 if (IsValid(ply)) then
957 if (!ply:IsInGroup(id)) then
958 ply:ChatPrint("You aren't even in this squad.")
959 return
960 end
961
962 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader()) then
963 ply:ChatPrint("You can't promote a squad member if you aren't the leader or co-leader.")
964 return
965 end
966
967 if (group.leader == target) then
968 ply:ChatPrint("You can't promote or demote yourself. Give the leadership to someone else.")
969 return
970 end
971
972 if (!ingroup) then
973 ply:ChatPrint("They aren't in your squad.")
974 return
975 end
976
977 if (alreadysergeant) then
978 ply:ChatPrint("They're already a sergeant.")
979 return
980 end
981
982 if (alreadymember) then
983 ply:ChatPrint("They're already a member or officer.")
984 return
985 end
986
987 if (promote) then
988 local ser = 0
989 for id, rank in pairs (group.members) do
990 if (rank == 2) then
991 ser = ser + 1
992 end
993 end
994
995 if (ser >= 5) then
996 ply:ChatPrint("Your squad has reached the maximum amount of Sergeants it can have.")
997 return
998 end
999 end
1000 end
1001
1002 if (!ingroup or alreadysergeant or alreadymember) then return end
1003
1004 DoQuery("UPDATE gang_members SET officer = :rank WHERE steamid = :steamid", {steamid = target, rank = promote and "2" or "0"}, function(q, data, result)
1005 local s = promote and "promoted to sergeant" or "demoted to officer"
1006
1007 GANG:GetRPName(target, function(data)
1008 local name = data and data[1].rpname or target
1009
1010 for _, v in pairs (self:GetGangMembers(id)) do
1011 if (IsValid(v)) then
1012 if (v:SteamID() == target) then
1013 v:SetGroupRank(promote and 2 or 1)
1014 v:ChatPrint("You were " .. s .. "!")
1015 else
1016 v:ChatPrint("A squad member (" .. name .. ") was " .. s .. ".") -- no name for now...
1017 end
1018 end
1019 end
1020 end)
1021
1022 group.members[target] = promote and 2 or 1
1023 GANG:SyncGroup(id, true)
1024 end)
1025end
1026
1027function GANG:ChangeGroupMOTD(id, ply, text)
1028 local group = self:GetGroup(id)
1029 if (!group) then
1030 return end
1031
1032 if (IsValid(ply)) then
1033 if (!ply:IsInGroup(id)) then
1034 ply:ChatPrint("You aren't even in this squad.")
1035 return
1036 end
1037
1038 if (!ply:IsGroupOfficer() and !ply:IsGroupLeader() and !ply:IsGroupCoLeader()) then
1039 ply:ChatPrint("You must be an officer or higher to change your squad's bulletin.")
1040 return
1041 end
1042 end
1043
1044 if (group.motd == "NULL" and text == "" or group.motd == text) then
1045 return end
1046
1047 DoQuery("UPDATE gang_list SET motd = :motd WHERE id = :id", {id = id, motd = text}, function(q, data, result)
1048 for _, v in pairs (self:GetGangMembers(id)) do
1049 if (IsValid(v)) then
1050 v:ChatPrint("Your squad's bulletin was updated by " .. ply:Nick() .. "!")
1051 end
1052 end
1053
1054 group.motd = text
1055 GANG:SyncGroup(id, true)
1056 end)
1057end
1058
1059function GANG:CheckGroupInvite(ply, ct)
1060 local inv = ply._groupinvite
1061 if (!inv) then return end
1062
1063 if (ct >= inv.expires) then
1064 if (IsValid(inv.inviter)) then
1065 inv.inviter:ChatPrint("Group invite to " .. ply:Nick() .. " expired.")
1066 end
1067
1068 ply._groupinvite = nil
1069 end
1070end
1071
1072function GANG:SyncGroup(ply, justupdate, id)
1073 local group
1074 if (id) then
1075 group = self:GetGroup(id)
1076 else
1077 if (type(ply) == "number") then -- update to all group members
1078 group = self:GetGroup(ply)
1079 ply = self:GetGangMembers(ply)
1080 elseif (type(ply) == "Player") then
1081 if (!justupdate and (ply._lastgroupupdate and ply._lastgroupupdate + 1 > CurTime())) then
1082 return
1083 end
1084
1085 ply._lastgroupupdate = CurTime()
1086
1087 group = self:GetGroup(ply:GetGroupID())
1088 end
1089 end
1090
1091 if (!group) then
1092 return end
1093
1094 local groupnames = {}
1095
1096 local t = {}
1097 for _, v in pairs (group.relations[true]) do
1098 if (!self.GroupList[v]) then
1099 continue end
1100
1101 table.insert(t, v .. ":1")
1102 table.insert(groupnames, v)
1103 end
1104
1105 for _, v in pairs (group.relations[false]) do
1106 if (!self.GroupList[v]) then
1107 continue end
1108
1109 table.insert(t, v .. ":0")
1110 table.insert(groupnames, v)
1111 end
1112
1113 local relations = table.concat(t, ",")
1114 group.relstr = relations
1115
1116 for k,v in pairs(player.GetAll()) do
1117 if(group.leader == v:SteamID()) then
1118 v:SetGroupRank(4)
1119 elseif(isnumber(tonumber(group.members[v:SteamID()]))) then
1120 v:SetGroupRank(tonumber(group.members[v:SteamID()]))
1121 end
1122 end
1123
1124 -- Transmit general group info
1125 net.Start("gang_syncgroup")
1126 net.WriteString(group.name)
1127 net.WriteString(group.leader)
1128 net.WriteTable(group.coleader)
1129 net.WriteUInt(table.Count(group.members), 16)
1130
1131 for steamid, rank in pairs (group.members) do
1132 net.WriteString(steamid)
1133 net.WriteUInt(rank, 4)
1134 end
1135
1136 net.WriteVector(group.color)
1137 net.WriteString(group.motd or "")
1138 net.WriteString(group.relstr or "")
1139 net.WriteBool(group.friendlyfire or false)
1140
1141 net.WriteBool(justupdate)
1142 net.WriteBool(id ~= nil)
1143 net.Send(ply)
1144
1145 -- Transmit ally/enemy group names
1146 self:SendGroupNames(ply, groupnames)
1147
1148 -- Transmit RPNames of group members
1149 local names = {}
1150
1151 for steamid in pairs (group.members) do
1152 GANG:GetRPName(steamid, function(data)
1153 if (!data) then
1154 return end
1155
1156 names[steamid] = data[1].rpname
1157
1158 net.Start("gang_playernames")
1159 net.WriteUInt(1, 16)
1160
1161 net.WriteString(steamid)
1162 net.WriteString(data[1].rpname)
1163 net.Send(ply)
1164 end)
1165 end
1166end
1167
1168function GANG:SendGroupNames(ply, tbl)
1169 local sent = {}
1170
1171 for _, id in ipairs (tbl) do
1172 if (sent[id] or !self.GroupList[id]) then
1173 continue end
1174
1175 sent[id] = self.GroupList[id].name
1176 end
1177
1178 net.Start("gang_group_names")
1179 net.WriteUInt(table.Count(sent), 16)
1180
1181 for id, name in pairs (sent) do
1182 net.WriteUInt(id, 32)
1183 net.WriteString(name)
1184 end
1185 net.Send(ply)
1186end
1187
1188function GANG:GroupShowList(ply)
1189 if (!ply:IsInGroup()) then
1190 return end
1191
1192 local plyid = ply:GetGroupID()
1193
1194 local available = {}
1195 for _, v in pairs (player.GetAll()) do
1196 local gid = v:GetGroupID()
1197 if (gid == 0 or available[gid]) then
1198 continue end
1199
1200 local group = self.GroupList[gid]
1201 if (group) then
1202 available[gid] = group
1203 end
1204 end
1205
1206 local cnt = table.Count(available)
1207
1208 net.Start("gang_grouplist")
1209 net.WriteUInt(cnt, 16)
1210
1211 for id, s in pairs (available) do
1212 net.WriteUInt(id, 32)
1213 net.WriteString(s.name)
1214 end
1215 net.Send(ply)
1216end
1217
1218function GANG:GroupSay(ply, realtext, bteam)
1219 local text = realtext:lower():Replace("!", "/")
1220
1221 if (text == "/group" or text == "/party" or text == "/gang" or text == "/squad") then
1222 if (ply:IsInGroup()) then
1223 self:SyncGroup(ply)
1224 else
1225 ply:SendLua("GANG:ShowCreationMenu()")
1226 end
1227
1228 return ""
1229 end
1230
1231 if (ply:IsInGroup() and (ply:IsGroupLeader() or ply:IsGroupOfficer() or ply:IsGroupCoLeader())) then
1232 local id = ply:GetGroupID()
1233 local gang = GANG:GetGroup(id)
1234 if (!gang) then
1235 return end
1236
1237 if (text == "/squadspawn" or text == "/partyspawn" or text == "/sspawn") then
1238 if (ply.InSafeZone and ply:InSafeZone()) then
1239 ply:ChatPrint("You cannot set your squad's spawn point in the Safe Zone.")
1240 return ""
1241 end
1242
1243 local pos = ply:GetPos()
1244 local queryarg = {id = id, x = pos.x, y = pos.y, z = pos.z}
1245
1246 local function ApplyChanges()
1247 for _, v in pairs (GANG:GetGangMembers(id)) do
1248 if (IsValid(v)) then
1249 v:ChatPrint("Your squad's spawn point was updated by " .. ply:Nick() .. "!")
1250 end
1251 end
1252
1253 gang.spawn = pos
1254 end
1255
1256 SetGlobalVector("SquadSpawn" .. id, pos)
1257
1258 if (gang.spawn) then
1259 DoQuery("UPDATE gang_spawn SET x = :x, y = :y, z = :z WHERE id = :id", queryarg, ApplyChanges)
1260 else
1261 DoQuery("INSERT INTO gang_spawn (id, x, y, z) VALUES (:id, :x, :y, :z)", queryarg, ApplyChanges)
1262 end
1263
1264 return ""
1265 elseif (text == "/removesquadspawn" or text == "/resetsquadspawn" or text == "/removepartyspawn" or text == "/resetpartyspawn" or text == "/rss") then
1266 if (!gang.spawn) then
1267 ply:ChatPrint("Your squad does not have a spawn point set.")
1268 return ""
1269 end
1270
1271 SetGlobalVector("SquadSpawn" .. id, nil)
1272
1273 DoQuery("DELETE FROM gang_spawn WHERE id = :id", {id = id}, function()
1274 for _, v in pairs (GANG:GetGangMembers(id)) do
1275 if (IsValid(v)) then
1276 v:ChatPrint("Your squad's spawn point was reset by " .. ply:Nick() .. "!")
1277 end
1278 end
1279
1280 gang.spawn = nil
1281 end)
1282
1283 return ""
1284 end
1285 elseif (text == "/squadspawn" or text == "/partyspawn" or text == "/removesquadspawn" or text == "/resetsquadspawn" or text == "/removepartyspawn" or text == "/resetpartyspawn") then
1286 local id = ply:GetGroupID()
1287 SetGlobalVector("SquadSpawn" .. id, nil)
1288 return ""
1289 end
1290
1291 if (ply:IsInGroup() and (bteam or text:StartWith("/sc ")) and !text:StartWith("//")) then
1292 local gangmembers = {}
1293
1294 if (ply._isforeveralone) then
1295 table.insert(gangmembers, ply)
1296 else
1297 for _, v in pairs (player.GetAll()) do
1298 if (v:IsInGroup(ply:GetGroupID())) then
1299 table.insert(gangmembers, v)
1300 end
1301 end
1302 end
1303
1304 net.Start("gang_chat")
1305 net.WriteEntity(ply)
1306 net.WriteString(bteam and realtext or realtext:sub(5))
1307 net.Send(gangmembers)
1308
1309 return ""
1310 elseif (text == "/saccept") then
1311 if (!ply._groupinvite) then
1312 ply:ChatPrint("You don't have any invitation pending.")
1313 else
1314 self:JoinGroup(ply._groupinvite.id, ply)
1315 ply._groupinvite = nil
1316 end
1317
1318 return ""
1319 elseif (text == "/sdeny") then
1320 if (!ply._groupinvite) then
1321 ply:ChatPrint("You don't have any invitation pending.")
1322 else
1323 if (IsValid(ply._groupinvite.inviter)) then
1324 ply:ChatPrint("You have rejected " .. ply._groupinvite.inviter:Nick() .. "'s invitation.")
1325 ply._groupinvite.inviter:ChatPrint(ply:Nick() .. " rejected your invitation to join your squad.")
1326 end
1327
1328 ply._groupinvite = nil
1329 end
1330
1331 return ""
1332 end
1333end
1334
1335function GANG:GetGangMembers(id)
1336 return self.GroupPlayers[id] or {}
1337end
1338
1339function GANG:ChangeGroupColor(id, ply, cs)
1340 local group = self:GetGroup(id)
1341 if (!group) then return end
1342
1343 if (IsValid(ply)) then
1344 if (!ply:IsInGroup(id)) then
1345 ply:ChatPrint("You aren't even in this squad.")
1346 return
1347 end
1348
1349 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id)) then
1350 ply:ChatPrint("You can't change a squad's color if you aren't the leader or co-leader.")
1351 return
1352 end
1353 end
1354
1355 local color = string.ToColor(cs)
1356 if (!color or (!color.r or !color.g or !color.b)) then
1357 if (IsValid(ply)) then
1358 ply:ChatPrint("Invalid color code.")
1359 end
1360
1361 return
1362 end
1363
1364 color.r = math.Clamp(color.r, 0, 255)
1365 color.g = math.Clamp(color.g, 0, 255)
1366 color.b = math.Clamp(color.b, 0, 255)
1367
1368 local col = Vector(color.r / 255, color.g / 255, color.b / 255)
1369
1370 if (group.color == col) then
1371 if (IsValid(ply)) then
1372 ply:ChatPrint("Squad color is identical.")
1373 end
1374
1375 return
1376 end
1377
1378 DoQuery("UPDATE gang_list SET color = :color WHERE id = :id", {id = id, color = tostring(color):sub(1, -5)}, function(q, data, result)
1379 group.color = col
1380
1381 local msg = "Your squad's color was updated."
1382 if (IsValid(ply)) then
1383 msg = ply:Nick() .. " has updated your squad's color."
1384 end
1385
1386 for _, v in pairs (self:GetGangMembers(id)) do
1387 if (IsValid(v)) then
1388 v:ChatPrint(msg)
1389 v:SetGroupColor(Vector(group.color.r / 255, group.color.g / 255, group.color.b / 255))
1390 end
1391 end
1392
1393 GANG:SyncGroup(id, true)
1394 end)
1395end
1396
1397function GANG:ToggleFriendlyFire(id, ply)
1398 local group = self:GetGroup(id)
1399 if (!group) then
1400 return end
1401
1402 if (IsValid(ply)) then
1403 if (!ply:IsInGroup(id)) then
1404 ply:ChatPrint("You aren't even in this squad.")
1405 return
1406 end
1407
1408 if (!ply:IsGroupLeader(id) and !ply:IsGroupCoLeader(id)) then
1409 ply:ChatPrint("You can't do that if you aren't the leader or co-leader.")
1410 return
1411 end
1412 end
1413
1414 local toggle = !group.friendlyfire
1415
1416 DoQuery("UPDATE gang_list SET friendlyfire = :friendlyfire WHERE id = :id", {id = id, friendlyfire = toggle and 1 or 0}, function(q, data, result)
1417 group.friendlyfire = toggle
1418
1419 local msg = "Your squad's friendly fire is now " .. (toggle and "ON" or "OFF") .. "."
1420
1421 for _, v in pairs (self:GetGangMembers(id)) do
1422 if (IsValid(v)) then
1423 v:ChatPrint(msg)
1424 end
1425 end
1426
1427 GANG:SyncGroup(id, true)
1428 end)
1429end
1430
1431GANG.NameCache = {}
1432
1433function GANG:GetRPName(steamid, callback)
1434 if (type(steamid) == "Player") then
1435 steamid = steamid:SteamID64()
1436 elseif (isstring(steamid) and steamid:StartWith("STEAM_")) then
1437 steamid = util.SteamIDTo64(steamid)
1438 end
1439
1440 local cached = self.NameCache[steamid]
1441 if (cached and cached.expire > CurTime()) then
1442 callback({
1443 {rpname = cached.name}
1444 })
1445
1446 return
1447 end
1448
1449 http.Fetch("http://steamcommunity.com/profiles/" .. steamid .. "/?xml=1&time=" .. os.time(), function(body)
1450 pcall(function()
1451 local tbl = XMLToTable(body)
1452 if (!tbl or !tbl.profile or !tbl.profile.steamID) then
1453 return end
1454
1455 local nick = tbl.profile.steamID
1456 GANG.NameCache[steamid] = {
1457 name = nick,
1458 expire = CurTime() + 300,
1459 }
1460
1461 callback({
1462 {rpname = nick}
1463 })
1464 end)
1465 end)
1466end
1467
1468hook.Add("InitPostEntity", "gang_load", function()
1469 GANG:InitGroups()
1470end)
1471
1472hook.Add("PlayerSay", "GANG_PlayerSay", function(ply, say, team)
1473 local s = GANG:GroupSay(ply, say, team)
1474 if (s ~= nil) then
1475 return s
1476 end
1477end)
1478
1479hook.Add("PlayerInitialSpawn", "gang_load_player", function(ply)
1480 local gid = GANG.GroupMembers[ply:SteamID()]
1481 local gang = GANG.GroupList[gid]
1482 if (gid and gang) then
1483 ply:SetGroupID(gid)
1484 ply:SetGroupName(gang.name)
1485 ply:SetGroupColor(gang.color)
1486 ply:SetNWString("GANG_Allies", table.concat(gang.relations[true], ","))
1487
1488 local rank = 0
1489 if (gang.leader == ply:SteamID()) then
1490 rank = 4
1491 elseif (table.HasValue(gang.coleader, ply:SteamID())) then
1492 rank = 3
1493 elseif (gang.members[ply:SteamID()] == 2) then
1494 rank = 2
1495 elseif (gang.members[ply:SteamID()] == 1) then
1496 rank = 1
1497 end
1498 ply:SetGroupRank(rank)
1499
1500 if (GANG.GroupPlayers[gid]) then
1501 table.insert(GANG.GroupPlayers[gid], ply)
1502 else
1503 GANG.GroupPlayers[gid] = {ply}
1504 end
1505 else
1506 local sid = ply:SteamID()
1507
1508 DoQuery("SELECT * FROM gang_members WHERE steamid = :steamid", {steamid = sid}, function(q, data)
1509 if (!data or !data[1]) then
1510 DoQuery("INSERT INTO gang_members (steamid, partyid, officer) VALUES (:steamid, 0, 0)", {steamid = sid}, function(q, data)
1511 GANG.GroupMembers[sid] = GANG.GroupMembers[sid] or 0
1512 end)
1513 end
1514 end)
1515 end
1516end)
1517
1518hook.Add("PlayerDisconnected", "gang_disconnect_player", function(ply)
1519 local gid = GANG.GroupMembers[ply:SteamID()]
1520 if (gid and GANG.GroupList[gid]) then
1521 if (GANG.GroupPlayers[gid]) then
1522 table.RemoveByValue(GANG.GroupPlayers[gid], ply)
1523 end
1524 end
1525end)
1526
1527hook.Add("PlayerShouldTakeDamage", "gang_friendly_fire", function(ply, attacker)
1528 if (!IsValid(attacker) or !attacker:IsPlayer() or attacker == ply or attacker:GetGroupID() <= 0) then
1529 return end
1530
1531 local mygang = GANG.GroupList[attacker:GetGroupID()]
1532 if (attacker:GetGroupID() == ply:GetGroupID()) then
1533 if (mygang) then
1534 return mygang.friendlyfire or false
1535 end
1536 else
1537 local theirgang = GANG.GroupList[ply:GetGroupID()]
1538 if (theirgang) then
1539 if (table.HasValue(theirgang.relations[true], attacker:GetGroupID()) and table.HasValue(mygang.relations[true], ply:GetGroupID())) then
1540 return false
1541 end
1542 end
1543 end
1544end)
1545
1546hook.Add("SetupPlayerVisibility", "gang_pvs", function(ply, view)
1547 local myorg = ply:GetGroupID()
1548 if (myorg > 0) then
1549 for _, v in ipairs (player.GetAll()) do
1550 if (v == ply) then
1551 continue end
1552
1553 local theirorg = v:GetGroupID()
1554 if (theirorg == myorg) then
1555 AddOriginToPVS(v:GetPos())
1556 end
1557 end
1558 end
1559end)
1560
1561concommand.Add("gang_group_create", function(ply, cmd, args)
1562 local name = args[1]
1563 local color = args[2]
1564 if (!name or !color) then return end
1565
1566 GANG:CreateGroup(ply, string.Trim(name), color)
1567end)
1568
1569concommand.Add("gang_group_disband", function(ply, cmd, args)
1570 GANG:DisbandGroup(ply:GetGroupID(), ply)
1571end)
1572
1573-- concommand.Add("gang_group_rename", function(ply, cmd, args)
1574 -- local name = args[1]
1575 -- if (!name) then return end
1576
1577 -- GANG:RenameGroup(ply:GetGroupID(), ply, name)
1578-- end)
1579
1580concommand.Add("gang_group_leave", function(ply, cmd, args)
1581 GANG:LeaveGroup(ply:GetGroupID(), ply)
1582end)
1583
1584concommand.Add("gang_group_invite", function(ply, cmd, args)
1585 local targetid = tonumber(args[1])
1586 if (!targetid) then return end
1587
1588 local target = Player(targetid)
1589 if (!IsValid(target)) then
1590 ply:ChatPrint("Invalid target.")
1591 return
1592 end
1593
1594 GANG:InviteToGroup(ply, target)
1595end)
1596
1597concommand.Add("gang_group_leader", function(ply, cmd, args)
1598 local steamid = args[1]
1599 if (!steamid) then
1600 return end
1601
1602 GANG:SetGroupLeader(ply:GetGroupID(), ply, steamid)
1603end)
1604
1605concommand.Add("gang_group_coleader", function(ply, cmd, args)
1606 local steamid = args[1]
1607 if (!steamid) then
1608 return end
1609
1610 GANG:SetGroupCoLeader(ply:GetGroupID(), ply, steamid)
1611end)
1612
1613concommand.Add("gang_group_coleader_unset", function(ply, cmd, args)
1614 GANG:UnsetGroupCoLeader(ply:GetGroupID(), ply, args[1], args[2])
1615end)
1616
1617concommand.Add("gang_group_kick", function(ply, cmd, args)
1618 local steamid = args[1]
1619 if (!steamid) then
1620 return end
1621
1622 GANG:KickFromGroup(ply:GetGroupID(), ply, steamid)
1623end)
1624
1625concommand.Add("gang_group_relation", function(ply, cmd, args)
1626 local groupid = tonumber(args[1])
1627 if (!groupid) then
1628 return end
1629
1630 local ally = tobool(tonumber(args[2]) or 0)
1631
1632 GANG:ChangeGroupRelation(ply:GetGroupID(), ply, groupid, ally)
1633end)
1634
1635concommand.Add("gang_group_relation_neutral", function(ply, cmd, args)
1636 local groupid = tonumber(args[1])
1637 if (!groupid) then
1638 return end
1639
1640 GANG:ChangeGroupRelationNeutral(ply:GetGroupID(), ply, groupid)
1641end)
1642
1643concommand.Add("gang_group_rank", function(ply, cmd, args)
1644 local steamid = args[1]
1645 if (!steamid) then
1646 return end
1647
1648 GANG:ChangeOfficerRank(ply:GetGroupID(), ply, steamid, tobool(tonumber(args[2])))
1649end)
1650
1651concommand.Add("gang_group_sergeant", function(ply, cmd, args)
1652 local steamid = args[1]
1653 if (!steamid) then
1654 return end
1655
1656 GANG:ChangeSergeantRank(ply:GetGroupID(), ply, steamid, tobool(tonumber(args[2])))
1657end)
1658
1659concommand.Add("gang_group_relation_list", function(ply, cmd, args)
1660 GANG:GroupShowList(ply)
1661end)
1662
1663net.Receive("gang_group_motd_change", function(len, ply)
1664 local text = net.ReadString()
1665 text = text:sub(1, 2048)
1666
1667 GANG:ChangeGroupMOTD(ply:GetGroupID(), ply, text)
1668end)
1669
1670-- concommand.Add("gang_group_color", function(ply, cmd, args)
1671 -- local cs = tostring(args[1])
1672 -- if (!cs) then return end
1673
1674 -- GANG:ChangeGroupColor(ply:GetGroupID(), ply, cs)
1675-- end)
1676
1677concommand.Add("gang_group_view", function(ply, cmd, args)
1678 local id = tonumber(args[1])
1679 if (!id or id < 0) then return end
1680
1681 GANG:SyncGroup(ply, false, id ~= ply:GetGroupID() and id or nil)
1682end)
1683
1684concommand.Add("gang_group_friendlyfire", function(ply, cmd, args)
1685 GANG:ToggleFriendlyFire(ply:GetGroupID(), ply)
1686end)
1687
1688concommand.Add("gang_admin_become_officer", function(ply, cmd, args)
1689 if (!ply:IsAdmin()) then
1690 return end
1691
1692 local id = ply:GetGroupID()
1693 local group = GANG:GetGroup(id)
1694 if (!group) then
1695 return end
1696
1697 if (ply:IsGroupLeader(id) or ply:IsGroupCoLeader(id)) then
1698 ply:ChatPrint("Can't do that as Leader or Co-Leader.")
1699 return
1700 end
1701
1702 local target = ply:SteamID()
1703 if (group.members[target] == 1) then
1704 ply:ChatPrint("You're already an officer.")
1705 return
1706 end
1707
1708 DoQuery("UPDATE gang_members SET officer = :rank WHERE steamid = :steamid", {steamid = target, rank = "1"}, function(q, data, result)
1709 local s = "promoted to officer"
1710
1711 GANG:GetRPName(target, function(data)
1712 local name = data and data[1].rpname or target
1713
1714 for _, v in pairs (GANG:GetGangMembers(id)) do
1715 if (IsValid(v)) then
1716 if (v:SteamID() == target) then
1717 v:SetGroupRank(1)
1718 v:ChatPrint("You were " .. s .. "!")
1719 else
1720 v:ChatPrint("A squad member (" .. name .. ") was " .. s .. ".") -- no name for now...
1721 end
1722 end
1723 end
1724 end)
1725
1726 group.members[target] = 1
1727 GANG:SyncGroup(id, true)
1728 end)
1729end)