· 8 years ago · Apr 27, 2018, 07:50 PM
1--[[
2Name: "init.lua".
3Product: "Cider (Roleplay)".
4--]]
5local player2 = player
6require("tmysql");
7
8-- Include the shared gamemode file.
9include("sh_init.lua");
10
11-- Add the Lua files that we need to send to the client.
12AddCSLuaFile("cl_init.lua");
13AddCSLuaFile("sh_init.lua");
14AddCSLuaFile("core/sh_configuration.lua");
15AddCSLuaFile("core/sh_enumerations.lua");
16AddCSLuaFile("core/scoreboard/admin_buttons.lua");
17AddCSLuaFile("core/scoreboard/player_frame.lua");
18AddCSLuaFile("core/scoreboard/player_infocard.lua");
19AddCSLuaFile("core/scoreboard/player_row.lua");
20AddCSLuaFile("core/scoreboard/scoreboard.lua");
21AddCSLuaFile("core/scoreboard/vote_button.lua");
22
23-- Add our red glow to the download list.
24resource.AddFile("materials/sprites/redglow8.vmt");
25
26-- Enable realistic fall damage for this gamemode.
27game.ConsoleCommand("mp_falldamage 1\n");
28game.ConsoleCommand("sbox_godmode 0\n");
29game.ConsoleCommand("sbox_plpldamage 0\n");
30
31
32-- Some useful ConVars that can be changed in game.
33CreateConVar("cider_ooc", 1);
34
35-- Store the old hook.Call function.
36hookCall = hook.Call;
37
38-- Overwrite the hook.Call function.
39function hook.Call(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
40 if (a == "PlayerSay") then d = string.Replace(d, "$q", "\""); end;
41
42 -- Call the original hook.Call function.
43 return hookCall(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z);
44end;
45
46-- A table that will hold entities that were there when the map started.
47GM.entities = {};
48
49-- Called when the server initializes.
50function GM:Initialize()
51 local host = cider.configuration["MySQL Host"];
52 local username = cider.configuration["MySQL Username"];
53 local password = cider.configuration["MySQL Password"];
54 local database = cider.configuration["MySQL Database"];
55
56 -- Initialize a connection to the MySQL database.
57 tmysql.initialize(host, username, password, database, 3306, 5, 5);
58
59 -- Call the base class function.
60 return self.BaseClass:Initialize();
61end;
62
63-- Called when a player switches their flashlight on or off.
64function GM:PlayerSwitchFlashlight(player, on)
65 if (player.cider._Arrested or player._KnockedOut or player.cider._Hostaged) then
66 return false;
67 else
68 return true;
69 end;
70end;
71
72function GM.UpdateDatabase()
73 for k, v in pairs(player.GetAll()) do
74 cider.player.saveData(v);
75 end
76end
77timer.Create('cider_update_database', 60, 0, GM.UpdateDatabase);
78
79-- Called when a player attempts to use an entity.
80function GM:PlayerUse(player, entity)
81 if (player._KnockedOut) then
82 return false;
83 elseif (player.cider._Arrested or player._Hostaged) then
84 if ( !player._NextNotify or player._NextNotify < CurTime() ) then
85 cider.player.notify(player, "You cannot do that in this state!", 1);
86
87 -- Set their next notify so that they don't get spammed with the message.
88 player._NextNotify = CurTime() + 2;
89 end;
90
91 -- Return false because they are arrested.
92 return false;
93 elseif (cider.entity.isDoor(entity) or entity:GetClass() == "prop_dynamic") then
94 if ( hook.Call("PlayerCanUseDoor", GAMEMODE, player, entity) ) then
95 cider.entity.openDoor(entity, 0);
96 end;
97 end;
98
99 -- Call the base class function.
100 return self.BaseClass:PlayerUse(player, entity);
101end;
102
103-- Called when a player's warrant has expired.
104function GM:PlayerWarrantExpired(player, class) end;
105
106-- Called when a player demotes another player.
107function GM:PlayerDemote(player, target, team) end;
108
109-- Called when a player knocks out another player.
110function GM:PlayerKnockOut(player, target) end;
111
112-- Called when a player wakes up another player.
113function GM:PlayerWakeUp(player, target) end;
114
115-- Called when a player arrests another player.
116function GM:PlayerArrest(player, target) end;
117
118-- Called when a player hostage another player.
119function GM:PlayerHostage(player, target) end;
120
121-- Called when a player unarrests another player.
122function GM:PlayerUnarrest(player, target) end;
123
124-- Called when a player warrants another player.
125function GM:PlayerWarrant(player, target, class) end;
126
127-- Called when a player unwarrants another player.
128function GM:PlayerUnwarrant(player, target) end;
129
130-- Called when a player attempts to own a door.
131function GM:PlayerCanOwnDoor(player, door) return true; end;
132
133-- Called when a player attempts to view a door.
134function GM:PlayerCanViewDoor(player, door) return true; end;
135
136-- Called when a player attempts to holster a weapon.
137function GM:PlayerCanHolster(player, weapon, silent) return true; end;
138
139-- Called when a player attempts to drop a weapon.
140function GM:PlayerCanDrop(player, weapon, silent, attacker) return true; end;
141
142-- Called when a player attempts to use an item.
143function GM:PlayerCanUseItem(player, item, silent) return true; end;
144
145-- Called when a player attempts to knock out a player.
146function GM:PlayerCanKnockOut(player, target) return true; end;
147
148-- Called when a player attempts to warrant a player.
149function GM:PlayerCanWarrant(player, target) return true; end;
150
151-- Called when a player attempts to wake up another player.
152function GM:PlayerCanWakeUp(player, target) return true; end;
153
154-- Called when a player attempts to ram a door.
155function GM:PlayerCanRamDoor(player, door, silent)
156 if ( ValidEntity(door._Owner) ) then
157 if (!door._Owner._Warranted and !door._Owner.cider._Arrested and door._Owner != player) then
158 cider.player.notify(player, "This player does not have a search warrant!", 1);
159
160 -- Return false because the player requires a warrant.
161 return false;
162 end;
163 end;
164
165 -- Return true because we can ram this door.
166 return true;
167end;
168
169-- Called when a player attempts to use a door.
170function GM:PlayerCanUseDoor(player, door)
171 if ( ValidEntity(door._Owner) ) then
172 if (!door._Owner._Warranted and door._Owner != player) then
173 return false;
174 end;
175 end;
176
177 -- Return true because we can use this door.
178 return true;
179end;
180
181-- Called when a player enters a vehicle.
182function GM:PlayerEnteredVehicle(player, vehicle, role)
183 timer.Simple(FrameTime() * 0.5, function()
184 if ( ValidEntity(player) ) then player:SetCollisionGroup(COLLISION_GROUP_PLAYER); end;
185 end);
186end;
187
188-- Called when a player attempts to join a team.
189function GM:PlayerCanJoinTeam(player, team)
190 team = cider.team.get(team);
191
192 -- Check if this is a valid team.
193 if (team) then
194 if (player._NextChangeTeam[team.index]) then
195 if ( player._NextChangeTeam[team.index] > CurTime() ) then
196 local seconds = math.floor( player._NextChangeTeam[team.index] - CurTime() );
197
198 -- Notify them that they cannot change to this team yet.
199 cider.player.notify(player, "Wait "..seconds.." second(s) to become a "..team.name.."!", 1);
200
201 -- Return here because they can't become this team.
202 return false;
203 end;
204 end;
205 end;
206
207 -- Check if the player is warranted.
208 if (player._Warranted) then
209 cider.player.notify(player, "You cannot do that while you are warranted!", 1);
210
211 -- Return here because they can't become this team.
212 return false;
213 end;
214
215 -- Check if the player is knocked out.
216 if (player._KnockedOut or player._Hostaged) then
217 cider.player.notify(player, "You cannot do that in this state!", 1);
218
219 -- Return here because they can't become this team.
220 return false;
221 end;
222
223 -- Return true because they can join this team.
224 return true;
225end;
226
227-- Called when a player earns contraband money.
228function GM:PlayerCanEarnContraband(player) return true; end;
229
230-- Called when a player attempts to unwarrant a player.
231function GM:PlayerCanUnwarrant(player, target)
232 if ( !player:IsAdmin() ) then
233 return true;
234 else
235 cider.player.notify(player, "You do not have access to unwarrant this player!", 1);
236
237 -- Return false because they cannot unwarrant this player.
238 return false;
239 end;
240end;
241
242
243-- Called when a player attempts to demote another player.
244function GM:PlayerCanDemote(player, target)
245 if ( !player:IsAdmin() ) then
246 cider.player.notify(player, "You do not have access to demote this player!", 1);
247
248 -- Return false because they cannot demote this player.
249 return false;
250 else
251 return true;
252 end;
253end;
254
255-- Called when a player attempts to promote another player.
256function GM:PlayerCanPromote(player, target)
257 if ( !player:IsAdmin() ) then
258 cider.player.notify(player, "You do not have access to promote this player!", 1);
259
260 -- Return false because they cannot promote this player.
261 return false;
262 else
263 return true;
264 end;
265end;
266
267-- Called when all of the map entities have been initialized.
268function GM:InitPostEntity()
269 for k, v in pairs( ents.GetAll() ) do self.entities[v] = v; end;
270
271 -- Call the base class function.
272 return self.BaseClass:InitPostEntity();
273end;
274
275-- Called when a player attempts to say something in-character.
276function GM:PlayerCanSayIC(player, text)
277 if (!player:Alive() or player._KnockedOut) then
278 cider.player.notify(player, "You cannot talk in this state!", 1);
279
280 -- Return false because we can't say anything.
281 return false;
282 else
283 return true;
284 end;
285end;
286
287-- Called when a player attempts to say something in OOC.
288function GM:PlayerCanSayOOC(player, text)
289 if ( player:IsAdmin() ) then
290 return true;
291
292 elseif (player:GetNetworkedBool("CanOOC") == true) then
293 player:SetNetworkedBool("CanOOC", false);
294
295 -- Set their chat time.
296 player:GetTable()._ChatTime = cider.configuration["OOC Delay"] + CurTime();
297
298 -- Create the timer so it sets them able to speak again in a set time.
299 timer.Create("ChatOOC"..player:UniqueID(), cider.configuration["OOC Delay"], 1, function()
300 player:SetNetworkedBool("CanOOC", true);
301
302 end);
303
304 -- Return true to say we have chatted.
305 return true;
306 else
307 local chatTime = math.Round(player:GetTable()._ChatTime - CurTime());
308 cider.player.notify(player, "Please wait "..tostring(chatTime).." seconds to talk OOC again.", 1)
309 return false;
310 end;
311end;
312
313-- Called when a player attempts to say something in local OOC.
314function GM:PlayerCanSayLOOC(player, text) return true; end;
315
316-- Called when attempts to use a command.
317function GM:PlayerCanUseCommand(player, command, arguments)
318 if (command == "sleep" and player:Alive() and !player.cider._Arrested and player._Sleeping) then
319 return true;
320 else
321 if (!player:Alive() or player._KnockedOut or player.cider._Arrested or player.cider._Hostaged) then
322 cider.player.notify(player, "You cannot do that in this state!", 1);
323
324 -- Return false because we can't say anything.
325 return false;
326 else
327 return true;
328 end;
329 end;
330end;
331
332-- Called when a player says something.
333function GM:PlayerSay(player, text, public)
334 text = string.Replace(text, " ' ", "'");
335 text = string.Replace(text, " : ", ":");
336
337 -- Check if we're speaking on OOC.
338 if (string.sub(text, 1, 2) == "//") then
339 if (string.Trim( string.sub(text, 3) ) != "") then
340 if ( hook.Call("PlayerCanSayOOC", GAMEMODE, player, text) ) then
341 cider.chatBox.add( nil, player, "ooc", string.Trim( string.sub(text, 3) ) );
342 end;
343 end;
344 elseif (string.sub(text, 1, 3) == ".//") then
345 if (string.Trim( string.sub(text, 4) ) != "") then
346 if ( hook.Call("PlayerCanSayLOOC", GAMEMODE, player, text) ) then
347 cider.chatBox.addInRadius(player, "looc", string.Trim( string.sub(text, 4) ), player:GetPos(), cider.configuration["Talk Radius"]);
348 end;
349 end;
350 elseif( string.sub(text, 1, 7) == "/cradio" and player._RadioFrequency) then
351 if (string.Trim( string.sub(text,8) ) != "") then
352 for k, v in pairs(player2.GetAll()) do
353 if(v:IsValid()) then
354 if(v._RadioFrequency == player._RadioFrequency) then
355 cider.chatBox.add(v, player, "cradio", string.Trim(string.sub(text,8)))
356 end
357 end
358 end
359 return ""
360 end
361 else
362 if ( string.sub(text, 1, 1) == cider.configuration["Command Prefix"] ) then
363 local arguments = string.Explode(" ", text);
364
365 -- Get the command from the arguments.
366 local command = string.sub(arguments[1], string.len(cider.configuration["Command Prefix"]) + 1);
367 local quote = false;
368
369 -- Loop through the arguments that we specified.
370 for k, v in pairs(arguments) do
371 if (!quote and string.sub(v, 1, 1) == '"') then quote = true; end
372
373 -- Check if the key is greater than 1 so that we don't affect the command.
374 if (k > 1) then if (!quote) then arguments[k] = "\""..arguments[k].."\""; end; end;
375
376 -- Check if we are quoting and the last character is a quote.
377 if (quote and string.sub(v, -1) == '"') then quote = false; end;
378 end;
379
380 -- Run the console command on the player so that we can handle quoted arguments.
381 player:ConCommand("cider "..command.." "..table.concat(arguments, " ", 2).."\n");
382 else
383 if ( hook.Call("PlayerCanSayIC", GAMEMODE, player, text) ) then
384 if (player.cider._Arrested) then
385 cider.chatBox.addInRadius(player, "arrested", text, player:GetPos(), cider.configuration["Talk Radius"]);
386 elseif (player.cider._Hostaged) then
387 cider.chatBox.addInRadius(player, "hostaged", text, player:GetPos(), cider.configuration["Talk Radius"]);
388 else
389 cider.chatBox.addInRadius(player, "ic", text, player:GetPos(), cider.configuration["Talk Radius"]);
390 end;
391 end;
392 end;
393 end;
394
395 -- Return an empty string so the text doesn't show.
396 return "";
397end;
398
399-- Called when a player attempts suicide.
400function GM:CanPlayerSuicide(player) return false; end;
401
402-- Called when a player attempts to punt an entity with the gravity gun.
403function GM:GravGunPunt(player, entity) return false; end;
404
405-- Called when a player attempts to pick up an entity with the physics gun.
406function GM:PhysgunPickup(player, entity)
407 if (self.entities[entity]) then return false; end;
408
409 -- Check if the player is an administrator.
410 if ( player:IsAdmin() ) then
411 if ( entity:IsPlayer() ) then
412 if ( !entity:InVehicle() ) then
413 entity:SetMoveType(MOVETYPE_NOCLIP);
414 else
415 return false;
416 end;
417 end;
418
419 -- Return true because administrators can pickup any entity.
420 return true;
421 end;
422
423 -- Check if this entity is a player's ragdoll.
424 if ( ValidEntity(entity._Player) ) then return false; end;
425
426 -- Check if the entity is a forbidden class.
427 if ( string.find(entity:GetClass(), "npc_")
428 or string.find(entity:GetClass(), "cider_")
429 or string.find(entity:GetClass(), "prop_dynamic") ) then
430 return false;
431 end;
432
433 -- Call the base class function.
434 return self.BaseClass:PhysgunPickup(player, entity);
435end;
436
437-- Called when a player attempts to drop an entity with the physics gun.
438function GM:PhysgunDrop(player, entity)
439 if ( entity:IsPlayer() ) then entity:SetMoveType(MOVETYPE_WALK); end;
440end;
441
442-- Called when a player attempts to arrest another player.
443function GM:PlayerCanArrest(player, target)
444 if (target._Warranted == "arrest") then
445 return true;
446 else
447 cider.player.notify(player, target:Name().." does not have an arrest warrant!", 1);
448
449 -- Return false because the target does not have a warrant.
450 return false;
451 end;
452end;
453
454-- Called when a player attempts to unarrest a player.
455function GM:PlayerCanUnarrest(player, target)
456 if ( !player:IsAdmin() ) then
457 return true;
458 else
459 cider.player.notify(player, "You do not have access to unarrest this player!", 1);
460
461 -- Return false because we cannot unarrest this player.
462 return false;
463 end;
464end;
465
466-- Called when a player attempts to spawn an NPC.
467function GM:PlayerSpawnNPC(player, model)
468 if (!player:Alive() or player.cider._Arrested or player._KnockedOut or player.cider._Hostaged) then
469 cider.player.notify(player, "You cannot do that in this state!", 1);
470
471 -- Return false because we cannot spawn it.
472 return false;
473 end;
474
475 -- Check if the player is an administrator.
476 if ( !player:IsAdmin() ) then
477 return false;
478 else
479 return true;
480 end;
481end;
482
483-- Called when a player attempts to spawn a prop.
484function GM:PlayerSpawnProp(player, model)
485 if ( !cider.player.hasAccess(player, "e") ) then return false; end;
486
487 -- Check if the player can spawn this prop.
488 if (!player:Alive() or player.cider._Arrested or player._KnockedOut or player._Hostaged) then
489 cider.player.notify(player, "You cannot do that in this state!", 1);
490
491 -- Return false because we cannot spawn it.
492 return false;
493 end;
494
495 -- Check if the player is an administrator.
496 if ( player:IsAdmin() ) then return true; end;
497
498 -- Escape the bad characters from the model.
499 model = string.Replace(model, "\\", "/");
500 model = string.Replace(model, "//", "/");
501
502 -- Loop through our banned props to see if this one is banned.
503 for k, v in pairs(cider.configuration["Banned Props"]) do
504 if ( string.lower(v) == string.lower(model) ) then
505 cider.player.notify(player, "You cannot spawn banned props!", 1);
506
507 -- Return false because we cannot spawn it.
508 return false;
509 end;
510 end;
511
512
513 -- Call the base class function.
514 return self.BaseClass:PlayerSpawnProp(player, model);
515end;
516
517-- Called when a player attempts to spawn a ragdoll.
518function GM:PlayerSpawnRagdoll(player, model)
519 if (!player:Alive() or player.cider._Arrested or player._KnockedOut or player.cider._Hostaged) then
520 cider.player.notify(player, "You cannot do that in this state!", 1);
521
522 -- Return false because we cannot spawn it.
523 return false;
524 end;
525
526 -- Check if the player is an administrator.
527 if ( !player:IsAdmin() ) then
528 return false;
529 else
530 return true;
531 end;
532end;
533
534-- Called when a player attempts to spawn an effect.
535function GM:PlayerSpawnEffect(player, model)
536 if (!player:Alive() or player.cider._Arrested or player._KnockedOut or player.cider._Hostaged) then
537 cider.player.notify(player, "You cannot do that in this state!", 1);
538
539 -- Return false because we cannot spawn it.
540 return false;
541 end;
542
543 -- Check if the player is an administrator.
544 if ( !player:IsAdmin() ) then
545 return false;
546 else
547 return true;
548 end;
549end;
550
551-- Called when a player attempts to spawn a vehicle.
552function GM:PlayerSpawnVehicle(player, model)
553 if ( !cider.player.hasAccess(player, "e") ) then return false; end;
554
555 -- Check if the model is a chair.
556 if ( !string.find(model, "chair") and !string.find(model, "seat") ) then
557 return false;
558 end;
559
560 -- Check if the player can spawn this vehicle.
561 if (!player:Alive() or player.cider._Arrested or player._KnockedOut or player._Hostaged) then
562 cider.player.notify(player, "You cannot do that in this state!", 1);
563
564 -- Return false because we cannot spawn it.
565 return false;
566 end;
567
568 -- Check if the player is an administrator.
569 if ( player:IsAdmin() ) then return true; end;
570
571 -- Call the base class function.
572 return self.BaseClass:PlayerSpawnVehicle(player, model);
573end;
574
575-- A function to check whether we're running on a listen server.
576function GM:IsListenServer()
577 for k, v in pairs( g_Player.GetAll() ) do
578 if ( v:IsListenServerHost() ) then return true; end;
579 end;
580
581 -- Check if we're running on single player.
582 if ( SinglePlayer() ) then return true; end;
583
584 -- Return false because there is no listen server host and it isn't single player.
585 return false;
586end;
587
588-- Called when a player attempts to use a tool.
589function GM:CanTool(player, trace, tool)
590 if ( player:IsAdmin() ) then return true; end;
591
592 -- Check if the trace entity is valid.
593 if ( ValidEntity(trace.Entity) ) then
594 if (tool == "nail") then
595 local line = {};
596
597 -- Set the information for the trace line.
598 line.start = trace.HitPos;
599 line.endpos = trace.HitPos + player:GetAimVector() * 16;
600 line.filter = {player, trace.Entity};
601
602 -- Perform the trace line.
603 line = util.TraceLine(line);
604
605 -- Check if the trace entity is valid.
606 if ( ValidEntity(line.Entity) ) then
607 if (self.entities[line.Entity]) then return false; end;
608 end;
609 end
610
611 -- Check if we're using the remover tool and we're trying to remove constrained entities.
612 if ( tool == "remover" and player:KeyDown(IN_ATTACK2) and !player:KeyDownLast(IN_ATTACK2) ) then
613 local entities = constraint.GetAllConstrainedEntities(trace.Entity);
614
615 -- Loop through the constained entities.
616 for k, v in pairs(entities) do
617 if (self.entities[v]) then return false; end;
618 end
619 end
620
621 -- Check if this entity cannot be used by the tool.
622 if (self.entities[trace.Entity]) then return false; end;
623
624 -- Check if this entity is a player's ragdoll.
625 if ( ValidEntity(trace.Entity._Player) ) then return false; end;
626 end;
627
628 -- Call the base class function.
629 return self.BaseClass:CanTool(player, trace, tool);
630end;
631
632-- Called when a player attempts to noclip.
633function GM:PlayerNoClip(player)
634 if (player.cider._Arrested or player._KnockedOut or player.cider._Hostaged) then
635 return false;
636 else
637 if ( player:IsAdmin() ) then
638 return true;
639 else
640 return false;
641 end;
642 end;
643end;
644
645-- Called when the player has initialized.
646function GM:PlayerInitialized(player)
647 local uniqueID = player:UniqueID();
648
649 -- Create a timer to give this player their salary.
650 timer.Create("Give Salary: "..uniqueID, cider.configuration["Salary Interval"], 0, function()
651 if ( ValidEntity(player) ) then
652 if (player:Alive() and !player.cider._Arrested) then
653 cider.player.giveMoney(player, player._Salary);
654
655 -- Print a message to the player letting them know they received their salary.
656 cider.player.notify(player, "You received $"..player._Salary.." salary.", 0);
657 end;
658
659 else
660 timer.Remove("Give Salary: "..uniqueID);
661 end;
662 end);
663end;
664
665-- Called when a player's data is loaded.
666function GM:PlayerDataLoaded(player, success)
667 player._Job = cider.configuration["Default Job"];
668 player._Ammo = {};
669 player._Gender = "Male";
670 player._Salary = 0;
671 player._Ragdoll = {};
672 player._Sleeping = false;
673 player._Warranted = false;
674 player._LightSpawn = false;
675 player._ScaleDamage = false;
676 player._Initialized = true;
677 player._ChangeTeam = false;
678 player._NextChangeTeam = {};
679 player._NextSpawnGender = "";
680 player._HideHealthEffects = false;
681 player._CannotBeWarranted = 0;
682
683 -- Some player variables based on configuration.
684 player._SpawnTime = cider.configuration["Spawn Time"];
685 player._ArrestTime = cider.configuration["Arrest Time"];
686 player._KnockOutTime = cider.configuration["Knock Out Time"];
687 player._TranqKnockOutTime = cider.configuration["Tranq Knock Out Time"];
688
689 -- Call a hook for the gamemode.
690 hook.Call("PlayerInitialized", GAMEMODE, player);
691
692 -- Respawn them now that they have initialized and then freeze them.
693 player:Spawn();
694 player:Freeze(true);
695
696 -- Unfreeze them in a few seconds from now.
697 timer.Simple(0.7, function()
698 if ( ValidEntity(player) ) then
699 player:Freeze(false);
700 player:SetNetworkedBool("CanOOC", true)
701
702 -- We can now start updating the player's data.
703 player._UpdateData = true;
704
705 -- Send a user message to remove the loading screen.
706 umsg.Start("cider.player.initialized", player); umsg.End();
707 end;
708 end);
709
710 -- Check if the player is arrested.
711 if (player.cider._Arrested) then cider.player.arrest(player, true, true); end;
712end;
713
714-- Called when a player initially spawns.
715function GM:PlayerInitialSpawn(player)
716 if ( ValidEntity(player) ) then
717 player.cider = {};
718
719 -- Create a timer to load my data.
720 timer.Create("LoadData:"..player:UniqueID(), 0.5, 1, function()
721 cider.player.loadData(player);
722 end);
723
724 -- A table of valid door classes.
725 local doorClasses = {
726 "func_door",
727 "func_door_rotating",
728 "prop_door_rotating"
729 };
730
731 -- Loop through our table of valid door classes.
732 for k, v in pairs(doorClasses) do
733 for k2, v2 in pairs( ents.FindByClass(v) ) do
734 if ( cider.entity.isDoor(v2) ) then
735 if (player:UniqueID() == v2._UniqueID) then
736 v2._Owner = player;
737
738 -- Set the networked owner so that the client can get it.
739 v2:SetNetworkedEntity("cider_Owner", player);
740 end;
741 end;
742 end;
743 end;
744
745 -- A table to store every contraband entity.
746 local contraband = {};
747
748 -- Loop through each contraband class.
749 for k, v in pairs( cider.configuration["Contraband"] ) do
750 table.Add( contraband, ents.FindByClass(k) );
751 end;
752
753 -- Loop through all of the contraband.
754 for k, v in pairs(contraband) do
755 if (player:UniqueID() == v._UniqueID) then v:SetPlayer(player); end;
756 end;
757
758 -- Kill them silently until we've loaded the data.
759 player:KillSilent();
760 end;
761end
762
763-- Called every frame that a player is dead.
764function GM:PlayerDeathThink(player)
765 if (!player._Initialized) then return true; end;
766
767 -- Check if the player is a bot.
768 if (player:SteamID() == "BOT") then
769 if (player.NextSpawnTime and CurTime() >= player.NextSpawnTime) then player:Spawn(); end;
770 end;
771
772 -- Return the base class function.
773 return self.BaseClass:PlayerDeathThink(player);
774end;
775
776-- Called when a player's salary should be adjusted.
777function GM:PlayerAdjustSalary(player) end;
778
779-- Called when a player's radio recipients should be adjusted.
780function GM:PlayerAdjustRadioRecipients(player, text, recipients) end;
781
782-- Called when a player should gain a frag.
783function GM:PlayerCanGainFrag(player, victim) return true; end;
784
785-- Called when a player's model should be set.
786function GM:PlayerSetModel(player)
787 local models = cider.team.query(player:Team(), "models");
788
789 -- Check if the models table exists.
790 if (models) then
791 models = models[ string.lower(player._Gender) ];
792
793 -- Check if the models table exists for this gender.
794 if (models) then
795 local model = models[ math.random(1, #models) ];
796
797 -- Set the player's model to the we got.
798 player:SetModel(model);
799 end;
800 end;
801end;
802
803-- Called when a player spawns.
804function GM:PlayerSpawn(player)
805 if (player._Initialized) then
806 if (player._NextSpawnGender != "") then
807 player._Gender = player._NextSpawnGender; player._NextSpawnGender = "";
808 end;
809
810 -- Set it so that the player does not drop weapons.
811 player:ShouldDropWeapon(false);
812
813 -- Check if we're not doing a light spawn.
814 if (!player._LightSpawn) then
815 player:SetRunSpeed( cider.configuration["Run Speed"] );
816 player:SetWalkSpeed( cider.configuration["Walk Speed"] );
817
818 -- Set some of the player's variables.
819 player._Ammo = {};
820 player._Sleeping = false;
821 player._ScaleDamage = false;
822 player._HideHealthEffects = false;
823 player._CannotBeWarranted = CurTime() + 15;
824
825 -- Make the player become conscious again.
826 cider.player.knockOut(player, false, nil, true);
827
828 -- Set the player's model and give them their loadout.
829 self:PlayerSetModel(player);
830 self:PlayerLoadout(player);
831 end;
832
833 -- Call a gamemode hook for when the player has finished spawning.
834 hook.Call("PostPlayerSpawn", GAMEMODE, player, player._LightSpawn, player._ChangeTeam);
835
836 -- Set some of the player's variables.
837 player._LightSpawn = false;
838 player._ChangeTeam = false;
839 else
840 player:KillSilent();
841 end;
842end;
843
844-- Called when a player should take damage.
845function GM:PlayerShouldTakeDamage(player, attacker) return true; end;
846
847-- Called when a player is attacked by a trace.
848function GM:PlayerTraceAttack(player, damageInfo, direction, trace)
849 player._LastHitGroup = trace.HitGroup;
850
851 -- Return false so that we don't override internals.
852 return false;
853end;
854
855-- Called just before a player dies.
856function GM:DoPlayerDeath(player, attacker, damageInfo)
857 for k, v in pairs( player:GetWeapons() ) do
858 local class = v:GetClass();
859
860 -- Check if this is a valid item.
861 if (cider.item.stored[class]) then
862 if ( hook.Call("PlayerCanDrop", GAMEMODE, player, class, true, attacker) ) then
863 cider.item.make( class, player:GetPos() );
864 end;
865 end;
866 end;
867
868 -- Unwarrant them, unarrest them and stop them from bleeding, etc.
869 player._Hostaged = false;
870 player._Stoned = false;
871 cider.player.warrant(player, false);
872 cider.player.arrest(player, false, true);
873 cider.player.bleed(player, false);
874
875 -- Strip the player's weapons and ammo.
876 player:StripWeapons();
877 player:StripAmmo();
878
879 -- Add a death to the player's death count.
880 player:AddDeaths(1);
881
882 -- Death message NLR
883 player:ConCommand("DrawDeathMsg")
884
885 -- Check it the attacker is a valid entity and is a player.
886 if ( ValidEntity(attacker) and attacker:IsPlayer() ) then
887 if (player != attacker) then
888 if ( hook.Call("PlayerCanGainFrag", GAMEMODE, attacker, player) ) then
889 attacker:AddFrags(1);
890 end;
891 end;
892 end;
893end;
894
895-- Called when a player dies.
896function GM:PlayerDeath(player, inflictor, attacker, ragdoll)
897 -- Set their next spawn time.
898 player.NextSpawnTime = CurTime() + player._SpawnTime;
899
900 -- Set it so that we can the next spawn time client side.
901 cider.player.setLocalPlayerVariable(player, CLASS_LONG, "_NextSpawnTime", player.NextSpawnTime);
902
903 -- Check if the attacker is a player.
904 if ( attacker:IsPlayer() ) then
905 if ( ValidEntity( attacker:GetActiveWeapon() ) ) then
906 cider.player.printConsoleAccess(attacker:Name().." killed "..player:Name().." with "..attacker:GetActiveWeapon():GetClass()..".", "a");
907 else
908 cider.player.printConsoleAccess(attacker:Name().." killed "..player:Name()..".", "a");
909 end;
910 else
911 cider.player.printConsoleAccess(attacker:GetClass().." killed "..player:Name()..".", "a");
912 end;
913
914 if (!player._Sleeping) or (!player._KnockedOut == true) then
915 player:CreateRagdoll();
916 end
917end;
918
919-- Called when a player's weapons should be given.
920function GM:PlayerLoadout(player)
921 if ( cider.player.hasAccess(player, "t") ) then player:Give("gmod_tool"); end
922 if ( cider.player.hasAccess(player, "p") ) then player:Give("weapon_physgun"); end
923
924 -- Give the player the camera, the hands and the physics cannon.
925 player:Give("gmod_camera");
926 player:Give("cider_keys");
927
928 -- Call the player loadout hook.
929 cider.plugin.call("playerLoadout", player);
930
931 -- Select the hands by default.
932 player:SelectWeapon("cider_keys");
933end
934
935-- Called when the server shuts down or the map changes.
936function GM:ShutDown()
937 for k, v in pairs( g_Player.GetAll() ) do
938 cider.player.holsterAll(v2);
939
940 -- Save the player's data.
941 cider.player.saveData(v);
942 end;
943end;
944
945-- Called when a player presses F1.
946function GM:ShowHelp(player) umsg.Start("cider_Menu", player); umsg.End(); end;
947
948-- Called when a player presses F2.
949function GM:ShowTeam(player)
950 local door = player:GetEyeTrace().Entity;
951
952 -- Check if the player is aiming at a door.
953 if ( ValidEntity(door) and cider.entity.isDoor(door) ) then
954 if (door:GetPos():Distance( player:GetPos() ) <= 128) then
955 if ( hook.Call("PlayerCanViewDoor", GAMEMODE, player, door) ) then
956 umsg.Start("cider_Door", player);
957 umsg.Bool(door._Unsellable or false);
958
959 -- Check if the owner is a valid entity.
960 if ( ValidEntity(door._Owner) ) then
961 umsg.Entity(door._Owner);
962 else
963 umsg.Entity(NULL);
964 end;
965
966 -- Send the door as an entity and unsellable as a bool.
967 umsg.Entity(door);
968
969 -- Check if the door has access.
970 if (door._Access) then
971 for k, v in pairs( g_Player.GetAll() ) do
972 if (v != door._Owner) then
973 local uniqueID = v:UniqueID();
974
975 -- Check if they have access.
976 if (door._Access[uniqueID]) then
977 umsg.Short( v:EntIndex() );
978 umsg.Short(1);
979 else
980 umsg.Short( v:EntIndex() );
981 umsg.Short(0);
982 end;
983 end;
984 end;
985 end;
986 umsg.End();
987 end;
988 end;
989 end;
990end;
991
992-- Called when an entity takes damage.
993function GM:EntityTakeDamage(entity, inflictor, attacker, amount, damageInfo)
994 if (attacker:IsPlayer() and ValidEntity( attacker:GetActiveWeapon() )
995 and attacker:GetActiveWeapon():GetClass() == "weapon_stunstick") then
996 damageInfo:SetDamage(10);
997 elseif (attacker:IsPlayer() and ValidEntity( attacker:GetActiveWeapon() )
998 and attacker:GetActiveWeapon():GetClass() == "cider_hands") then
999 damageInfo:ScaleDamage(1);
1000 end;
1001
1002 -- Check if the entity that got damaged is a player.
1003 if ( entity:IsPlayer() ) then
1004 if (entity:InVehicle()) then
1005 damageInfo:SetDamage(10);
1006 end;
1007
1008 if (entity._KnockedOut) then
1009 if ( ValidEntity(entity._Ragdoll.entity) ) then
1010 hook.Call("EntityTakeDamage", GAMEMODE, entity._Ragdoll.entity, inflictor, attacker, damageInfo:GetDamage(), damageInfo);
1011 end;
1012 else
1013 if ( entity:InVehicle() and damageInfo:IsExplosionDamage() ) then
1014 if (!damageInfo:GetDamage() or damageInfo:GetDamage() == 0) then
1015 damageInfo:SetDamage(100);
1016 end;
1017 end;
1018
1019 -- Check if the player has a last hit group defined.
1020 if (entity._LastHitGroup) then
1021 if (entity._LastHitGroup == HITGROUP_HEAD) then
1022 damageInfo:ScaleDamage( cider.configuration["Scale Head Damage"] );
1023 elseif (entity._LastHitGroup == HITGROUP_CHEST or entity._LastHitGroup == HITGROUP_GENERIC) then
1024 damageInfo:ScaleDamage( cider.configuration["Scale Chest Damage"] );
1025 elseif (entity._LastHitGroup == HITGROUP_LEFTARM or
1026 entity._LastHitGroup == HITGROUP_RIGHTARM or
1027 entity._LastHitGroup == HITGROUP_LEFTLEG or
1028 entity._LastHitGroup == HITGROUP_RIGHTLEG or
1029 entity._LastHitGroup == HITGROUP_GEAR) then
1030 damageInfo:ScaleDamage( cider.configuration["Scale Limb Damage"] );
1031 end;
1032
1033 -- Set the last hit group to nil so that we don't use it again.
1034 entity._LastHitGroup = nil;
1035 end;
1036
1037 -- Check if the player is supposed to scale damage.
1038 if (entity._ScaleDamage) then damageInfo:ScaleDamage(entity._ScaleDamage); end;
1039
1040 -- Make the player bleed.
1041 cider.player.bleed( entity, true, cider.configuration["Bleed Time"] );
1042 end;
1043 elseif ( entity:IsNPC() ) then
1044 if (attacker:IsPlayer() and ValidEntity( attacker:GetActiveWeapon() )
1045 and attacker:GetActiveWeapon():GetClass() == "weapon_crowbar") then
1046 damageInfo:SetDamage(10);
1047 end;
1048 end;
1049
1050 -- Check if the entity is a knocked out player.
1051 if ( ValidEntity(entity._Player) ) then
1052 local player = entity._Player;
1053
1054 -- Set the damage to the amount we're given.
1055 damageInfo:SetDamage(amount);
1056
1057 -- Check if the attacker is not a player.
1058 if ( !attacker:IsPlayer() ) then
1059 if ( attacker == GetWorldEntity() ) then
1060 if ( ( entity._NextWorldDamage and entity._NextWorldDamage > CurTime() )
1061 or damageInfo:GetDamage() <= 10 ) then return; end;
1062
1063 -- Set the next world damage to be 1 second from now.
1064 entity._NextWorldDamage = CurTime() + 1;
1065 else
1066 if (damageInfo:GetDamage() <= 10) then return; end;
1067 end;
1068 else
1069 damageInfo:ScaleDamage( cider.configuration["Scale Ragdoll Damage"] );
1070 end;
1071
1072 -- Check if the player is supposed to scale damage.
1073 if (entity._Player._ScaleDamage) then damageInfo:ScaleDamage(entity._Player._ScaleDamage); end;
1074
1075 -- Take the damage from the player's health.
1076 player:SetHealth( math.max(player:Health() - damageInfo:GetDamage(), 0) );
1077
1078 -- Set the player's conscious health.
1079 player._Ragdoll.health = player:Health();
1080
1081 -- Create new effect data so that we can create a blood impact at the damage position.
1082 local effectData = EffectData();
1083 effectData:SetOrigin( damageInfo:GetDamagePosition() );
1084 util.Effect("BloodImpact", effectData);
1085
1086 -- Loop from 1 to 4 so that we can draw some blood decals around the ragdoll.
1087 for i = 1, 2 do
1088 local trace = {};
1089
1090 -- Set some settings and information for the trace.
1091 trace.start = damageInfo:GetDamagePosition();
1092 trace.endpos = trace.start + (damageInfo:GetDamageForce() + (VectorRand() * 16) * 128);
1093 trace.filter = entity;
1094
1095 -- Create the trace line from the set information.
1096 trace = util.TraceLine(trace);
1097
1098 -- Draw a blood decal at the hit position.
1099 util.Decal("Blood", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal);
1100 end;
1101
1102 -- Check to see if the player's health is less than 0 and that the player is alive.
1103 if ( player:Health() <= 0 and player:Alive() ) then
1104 player:KillSilent();
1105
1106 -- Call some gamemode hooks to fake the player's death.
1107 hook.Call("DoPlayerDeath", GAMEMODE, player, attacker, damageInfo);
1108 hook.Call("PlayerDeath", GAMEMODE, player, inflictor, attacker, false);
1109 end;
1110 end;
1111end;
1112
1113-- Called when a player has disconnected.
1114function GM:PlayerDisconnected(player)
1115
1116 -- Remove the players knockout to give them their weapons back.
1117 cider.player.knockOut(player, false, nil, true);
1118
1119 -- Holster all their weapons so it saves.
1120 cider.player.holsterAll(player);
1121
1122 -- Remove the players cars and items.
1123 for k,v in pairs(ents.GetAll()) do
1124 if (!cider.entity.isDoor(v)) then
1125 if (v:GetTable()._Owner == player) then
1126 if (v:GetTable()._UniqueID == player:UniqueID()) then
1127 v:Remove()
1128 end;
1129 end;
1130 end;
1131 end;
1132
1133 -- Save the player's data.
1134 cider.player.saveData(player);
1135
1136 -- Call the base class function.
1137 self.BaseClass:PlayerDisconnected(player);
1138end;
1139
1140-- Called when a player attempts to spawn a SWEP.
1141function GM:PlayerSpawnSWEP(player, class, weapon)
1142 if ( !player:IsSuperAdmin() ) then
1143 return false;
1144 else
1145 return true;
1146 end;
1147end;
1148
1149-- Called when a player is given a SWEP.
1150function GM:PlayerGiveSWEP(player, class, weapon)
1151 if ( !player:IsSuperAdmin() ) then
1152 return false;
1153 else
1154 return true;
1155 end;
1156end;
1157
1158-- Called when attempts to spawn a SENT.
1159function GM:PlayerSpawnSENT(player, class)
1160 if ( !player:IsSuperAdmin() ) then
1161 return false;
1162 else
1163 return true;
1164 end;
1165end;
1166
1167-- Called when a player presses a key.
1168function GM:KeyPress(player, key)
1169 if (key == IN_JUMP and player._StuckInWorld) then
1170 cider.player.holsterAll(player);
1171
1172 -- Spawn them lightly now that we holstered their weapons.
1173 cider.player.lightSpawn(player);
1174 end;
1175end;
1176
1177-- Create a timer to automatically clean up decals.
1178timer.Create("Cleanup Decals", 60, 0, function()
1179 for k, v in pairs( player.GetAll() ) do v:ConCommand("r_cleardecals\n"); end;
1180end);
1181
1182-- Create a timer to give players money for their contraband.
1183timer.Create("Contraband", cider.configuration["Contraband Interval"], 0, function()
1184 local players = {};
1185 local contraband = {};
1186
1187 -- Loop through each contraband class.
1188 for k, v in pairs( cider.configuration["Contraband"] ) do
1189 table.Add( contraband, ents.FindByClass(k) );
1190 end;
1191
1192 -- Loop through all of the contraband.
1193 for k, v in pairs(contraband) do
1194 local player = v:GetPlayer();
1195
1196 -- Check if the player is a valid entity,
1197 if ( ValidEntity(player) ) then
1198 players[player] = players[player] or {refill = 0, money = 0};
1199 local amount = cider.configuration["Contraband"][v:GetClass()].money
1200 local money = ents.Create("cider_money")
1201 money:SetPos(v:GetPos() + Vector(0,0,30))
1202 money:Spawn()
1203 money:SetAmount(amount)
1204
1205 -- Decrease the energy of the contraband.
1206 v._Energy = math.Clamp(v._Energy - 1, 0, 5);
1207
1208 -- Set the networked variable so that the client can use it.
1209 v:SetNetworkedInt("cider_Energy3", v._Energy);
1210
1211
1212
1213 -- Check the energy of the contraband.
1214 if (v._Energy == 0) then
1215 players[player].refill = players[player].refill + 1;
1216 else
1217 players[player].money = players[player].money + cider.configuration["Contraband"][ v:GetClass() ].money;
1218 end;
1219 end;
1220 end;
1221
1222 -- Loop through our players list.
1223 for k, v in pairs(players) do
1224 if ( hook.Call("PlayerCanEarnContraband", GAMEMODE, k) ) then
1225 if (v.refill > 0) then
1226 cider.player.notify(k, v.refill.." of your contraband need refilling!", 1);
1227 elseif (v.money > 0) then
1228 -- cider.player.notify(k, "You earned $"..v.money.." from contraband.", 0);
1229
1230 -- Give the player their money.
1231 -- cider.player.giveMoney(k, v.money);
1232
1233
1234
1235
1236 end;
1237 end;
1238 end;
1239end);
1240
1241-- CHRISTMAS
1242
1243-- function spawnHat(player)
1244-- local eyes = player:LookupAttachment("eyes");
1245-- if (eyes == 0) then return; end;
1246
1247-- local santaHat = ents.Create("santa");
1248-- santaHat:SetOwner(player);
1249-- santaHat:SetParent(player);
1250-- santaHat:SetModel("models/santa/santa.mdl");
1251-- santaHat:Spawn();
1252-- santaHat:Activate();
1253-- santaHat:SetMoveType(MOVETYPE_NONE);
1254-- santaHat:SetSolid(SOLID_NONE);
1255-- santaHat:SetCollisionGroup(COLLISION_GROUP_NONE);
1256-- santaHat:DrawShadow(false);
1257
1258-- return santaHat;
1259-- end;
1260
1261-- function spawnHatPlayer(player)
1262-- timer.Create("santahat", 1, 1, function()
1263-- spawnHat(player);
1264-- end);
1265-- end;
1266-- hook.Add("PlayerInitialSpawn", "spawnHatPlayer", spawnHatPlayer);
1267
1268function setStringPlayer()
1269 for k, v in pairs(player.GetAll()) do
1270 v:SetNWString("PModel", v:GetModel());
1271 end;
1272end;
1273hook.Add("Think", "setStringPlayer", setStringPlayer)