Guest User

Untitled

a guest
Jun 30th, 2017
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 348.41 KB | None | 0 0
  1. --[[
  2. Name: "sh_core.lua".
  3. Product: "Nexus".
  4. --]]
  5.  
  6. NEXUS.Timers = {};
  7. NEXUS.DataStreamHooks = {};
  8. NEXUS.GlobalSharedVars = {};
  9.  
  10. function ScaleToWideScreen(size)
  11.     return math.min(math.max( ScreenScale(size /--[[
  12. Name: "sv_auto.lua".
  13. Product: "Nexus".
  14. --]]
  15.  
  16. for k, v in pairs( file.Find("../materials/decals/flesh/blood*") ) do
  17.     resource.AddFile("materials/decals/flesh/"..v);
  18. end;
  19.  
  20. for k, v in pairs( file.Find("../materials/decals/blood*") ) do
  21.     resource.AddFile("materials/decals/"..v);
  22. end;
  23.  
  24. for k, v in pairs( file.Find("../materials/effects/blood*") ) do
  25.     resource.AddFile("materials/effects/"..v);
  26. end;
  27.  
  28. for k, v in pairs( file.Find("../materials/sprites/blood*") ) do
  29.     resource.AddFile("materials/sprites/"..v);
  30. end;
  31.  
  32. resource.AddFile("materials/gui/silkicons/information.vtf");
  33. resource.AddFile("materials/gui/silkicons/information.vmt");
  34. resource.AddFile("materials/gui/silkicons/user_delete.vtf");
  35. resource.AddFile("materials/gui/silkicons/user_delete.vmt");
  36. resource.AddFile("materials/gui/silkicons/newspaper.vtf");
  37. resource.AddFile("materials/gui/silkicons/newspaper.vmt");
  38. resource.AddFile("materials/gui/silkicons/user_add.vtf");
  39. resource.AddFile("materials/gui/silkicons/user_add.vmt");
  40. resource.AddFile("materials/gui/silkicons/comment.vtf");
  41. resource.AddFile("materials/gui/silkicons/comment.vmt");
  42. resource.AddFile("materials/gui/silkicons/error.vtf");
  43. resource.AddFile("materials/gui/silkicons/error.vmt");
  44. resource.AddFile("materials/gui/silkicons/help.vtf");
  45. resource.AddFile("materials/gui/silkicons/help.vmt");
  46. resource.AddFile("models/humans/female_gestures.ani");
  47. resource.AddFile("models/humans/female_gestures.mdl");
  48. resource.AddFile("models/humans/female_postures.ani");
  49. resource.AddFile("models/humans/female_postures.mdl");
  50. resource.AddFile("models/combine_soldier_anims.ani");
  51. resource.AddFile("models/combine_soldier_anims.mdl");
  52. resource.AddFile("models/humans/female_shared.ani");
  53. resource.AddFile("models/humans/female_shared.mdl");
  54. resource.AddFile("models/humans/male_gestures.ani");
  55. resource.AddFile("models/humans/male_gestures.mdl");
  56. resource.AddFile("models/humans/male_postures.ani");
  57. resource.AddFile("models/humans/male_postures.mdl");
  58. resource.AddFile("models/humans/male_shared.ani");
  59. resource.AddFile("models/humans/male_shared.mdl");
  60. resource.AddFile("materials/nexus/xhlogo.vtf");
  61. resource.AddFile("materials/nexus/xhlogo.vmt");
  62. resource.AddFile("models/police_animations.ani");
  63. resource.AddFile("models/police_animations.mdl");
  64. resource.AddFile("models/humans/female_ss.ani");
  65. resource.AddFile("models/humans/female_ss.mdl");
  66. resource.AddFile("materials/nexus/unknown.vtf");
  67. resource.AddFile("materials/nexus/unknown.vmt");
  68. resource.AddFile("models/humans/male_ss.ani");
  69. resource.AddFile("models/humans/male_ss.mdl");
  70. resource.AddFile("models/police_ss.ani");
  71. resource.AddFile("models/police_ss.mdl");
  72.  
  73. CreateConVar("npc_thinknow", 1);
  74.  
  75. AddCSLuaFile("sh_enums.lua");
  76. AddCSLuaFile("sh_core.lua");
  77. AddCSLuaFile("sh_auto.lua");
  78. AddCSLuaFile("cl_auto.lua");
  79.  
  80. include("sh_auto.lua");
  81.  
  82. local gradientTexture = nexus.schema.GetOption("gradient");
  83. local introImage = nexus.schema.GetOption("intro_image");
  84. local CurTime = CurTime;
  85. local hook = hook;
  86.  
  87. if (gradientTexture != "gui/gradient_up") then
  88.     resource.AddFile("materials/"..gradientTexture..".vtf");
  89.     resource.AddFile("materials/"..gradientTexture..".vmt");
  90. end;
  91.  
  92. if (introImage != "") then
  93.     resource.AddFile("materials/"..introImage..".vtf");
  94.     resource.AddFile("materials/"..introImage..".vmt");
  95. end;
  96.  
  97. _R["CRecipientFilter"].IsValid = function()
  98.     return true;
  99. end;
  100.  
  101. hook.NexusCall = hook.Call;
  102.  
  103. -- A function to call a hook.
  104. function hook.Call(name, gamemode, ...)
  105.     local callCachedHook = nexus.mount.CallCachedHook;
  106.     local arguments = {...};
  107.     local hookCall = hook.NexusCall;
  108.    
  109.     if (!gamemode) then
  110.         gamemode = NEXUS;
  111.     end;
  112.    
  113.     if (name == "EntityTakeDamage") then
  114.         if ( NEXUS:DoEntityTakeDamageHook(gamemode, arguments) ) then
  115.             return;
  116.         end;
  117.     end;
  118.    
  119.     if (name == "PlayerDisconnected") then
  120.         if ( !IsValid( arguments[1] ) ) then
  121.             return;
  122.         end;
  123.     end;
  124.    
  125.     if (name == "PlayerSay") then
  126.         arguments[2] = string.Replace(arguments[2], "~", "\"");
  127.     end;
  128.    
  129.     local value = callCachedHook(name, arguments);
  130.    
  131.     if (value == nil) then
  132.         return hookCall( name, gamemode, unpack(arguments) );
  133.     else
  134.         return value;
  135.     end;
  136. end;
  137.  
  138. -- Called when the server initializes.
  139. function NEXUS:Initialize()
  140.     local useLocalMachineDate = nexus.config.Get("use_local_machine_date"):Get();
  141.     local useLocalMachineTime = nexus.config.Get("use_local_machine_time"):Get();
  142.     local defaultDate = nexus.schema.GetOption("default_date");
  143.     local defaultTime = nexus.schema.GetOption("default_time");
  144.     local defaultDays = nexus.schema.GetOption("default_days");
  145.     local username = nexus.config.Get("mysql_username"):Get();
  146.     local password = nexus.config.Get("mysql_password"):Get();
  147.     local database = nexus.config.Get("mysql_database"):Get();
  148.     local dateInfo = os.date("*t");
  149.     local host = nexus.config.Get("mysql_host"):Get();
  150.    
  151.     local success, value = pcall(tmysql.initialize, host, username, password, database, 3306, 6, 6);
  152.         NEXUS.NoMySQL = !success;
  153.        
  154.     if (useLocalMachineTime) then
  155.         nexus.config.Get("minute_time"):Set(60);
  156.     end;
  157.    
  158.     nexus.config.SetInitialized(true);
  159.    
  160.     table.Merge(nexus.time, defaultTime);
  161.     table.Merge(nexus.date, defaultDate);
  162.    
  163.     math.randomseed( os.time() );
  164.    
  165.     if (useLocalMachineTime) then
  166.         local realDay = dateInfo.wday - 1;
  167.        
  168.         if (realDay == 0) then
  169.             realDay = #defaultDays;
  170.         end;
  171.        
  172.         table.Merge( nexus.time, {
  173.             minute = dateInfo.min,
  174.             hour = dateInfo.hour,
  175.             day = realDay
  176.         } );
  177.        
  178.         self.NextDateTimeThink = SysTime() + (60 - dateInfo.sec);
  179.     else
  180.         table.Merge( nexus.time, self:RestoreSchemaData("time") );
  181.     end;
  182.    
  183.     if (useLocalMachineDate) then
  184.         dateInfo.year = dateInfo.year + (defaultDate.year - dateInfo.year);
  185.        
  186.         table.Merge( nexus.time, {
  187.             month = dateInfo.month,
  188.             year = dateInfo.year,
  189.             day = dateInfo.yday
  190.         } );
  191.     else
  192.         table.Merge( nexus.date, self:RestoreSchemaData("date") );
  193.     end;
  194.    
  195.     NX_CONVAR_DEBUG = self:CreateConVar("nx_debug", 1);
  196.     NX_CONVAR_LOG = self:CreateConVar("nx_log", 1)
  197.    
  198.     for k, v in pairs(nexus.config.stored) do
  199.         nexus.mount.Call("NexusConfigInitialized", k, v.value);
  200.     end;
  201.    
  202.     RunConsoleCommand("sv_usermessage_maxsize", "1024");
  203.         nexus.mount.Call("NexusInitialized");
  204.     self:LoadBans();
  205. end;
  206.  
  207. -- Called when a player has disconnected.
  208. function NEXUS:PlayerDisconnected(player)
  209.     local tempData = player:CreateTempData();
  210.    
  211.     if ( player:HasInitialized() ) then
  212.         if (nexus.mount.Call("PlayerCharacterUnloaded", player) != true) then
  213.             player:SaveCharacter();
  214.         end;
  215.        
  216.         if (tempData) then
  217.             nexus.mount.Call("PlayerSaveTempData", player, tempData);
  218.         end;
  219.        
  220.         nexus.chatBox.Add(nil, nil, "disconnect", player:SteamName().." has disconnected from the server.");
  221.        
  222.         self:PrintDebug(player:SteamName().." ("..player:SteamID().."|"..player:IPAddress()..") has disconnected from the server.");
  223.     end;
  224. end;
  225.  
  226. -- Called when the Nexus core has loaded.
  227. function NEXUS:NexusCoreLoaded()
  228.     nexus.config.Import("nexus/mysql.cfg");
  229. end;
  230.  
  231. -- Called when Nexus has initialized.
  232. function NEXUS:NexusInitialized()
  233.     local cashName = nexus.schema.GetOption("name_cash");
  234.    
  235.     if ( !nexus.config.Get("cash_enabled"):Get() ) then
  236.         nexus.command.SetHidden(string.gsub(cashName, "%s", "").."Give", true);
  237.         nexus.command.SetHidden(string.gsub(cashName, "%s", "").."Drop", true);
  238.         nexus.command.SetHidden("StorageTakeCash", true);
  239.         nexus.command.SetHidden("StorageGiveCash", true);
  240.        
  241.         nexus.config.Get("scale_prop_cost"):Set(0, nil, true, true);
  242.         nexus.config.Get("door_cost"):Set(0, nil, true, true);
  243.     end;
  244. end;
  245.  
  246. -- Called when a player is banned.
  247. function NEXUS:PlayerBanned(player, duration, reason) end;
  248.  
  249. -- Called when a player's model has changed.
  250. function NEXUS:PlayerModelChanged(player, model) end;
  251.  
  252. -- Called when a player's inventory string is needed.
  253. function NEXUS:PlayerGetInventoryString(player, character, inventory)
  254.     if ( player:IsRagdolled() ) then
  255.         for k, v in pairs( player:GetRagdollWeapons() ) do
  256.             if (v.canHolster) then
  257.                 local class = v.weaponData["class"];
  258.                 local uniqueID = v.weaponData["uniqueID"];
  259.                 local itemTable = nexus.item.GetWeapon(class, uniqueID);
  260.                
  261.                 if (itemTable) then
  262.                     if ( !nexus.player.GetSpawnWeapon(player, class) ) then
  263.                         if ( inventory[itemTable.uniqueID] ) then
  264.                             inventory[itemTable.uniqueID] = inventory[itemTable.uniqueID] + 1;
  265.                         else
  266.                             inventory[itemTable.uniqueID] = 1;
  267.                         end;
  268.                     end;
  269.                 end;
  270.             end;
  271.         end;
  272.     end;
  273.    
  274.     for k, v in pairs( player:GetWeapons() ) do
  275.         local class = v:GetClass();
  276.         local itemTable = nexus.item.GetWeapon(v);
  277.        
  278.         if (itemTable) then
  279.             if ( !nexus.player.GetSpawnWeapon(player, class) ) then
  280.                 if ( inventory[itemTable.uniqueID] ) then
  281.                     inventory[itemTable.uniqueID] = inventory[itemTable.uniqueID] + 1;
  282.                 else
  283.                     inventory[itemTable.uniqueID] = 1;
  284.                 end;
  285.             end;
  286.         end;
  287.     end;
  288. end;
  289.  
  290. -- Called when a player's unlock info is needed.
  291. function NEXUS:PlayerGetUnlockInfo(player, entity)
  292.     if ( nexus.entity.IsDoor(entity) ) then
  293.         return {
  294.             duration = nexus.config.Get("unlock_time"):Get(),
  295.             Callback = function(player, entity)
  296.                 entity:Fire("unlock", "", 0);
  297.             end
  298.         };
  299.     end;
  300. end;
  301.  
  302. -- Called when a player's lock info is needed.
  303. function NEXUS:PlayerGetLockInfo(player, entity)
  304.     if ( nexus.entity.IsDoor(entity) ) then
  305.         return {
  306.             duration = nexus.config.Get("lock_time"):Get(),
  307.             Callback = function(player, entity)
  308.                 entity:Fire("lock", "", 0);
  309.             end
  310.         };
  311.     end;
  312. end;
  313.  
  314. -- Called when data should be saved.
  315. function NEXUS:SaveData()
  316.     for k, v in ipairs( g_Player.GetAll() ) do
  317.         if ( v:HasInitialized() ) then
  318.             v:SaveCharacter();
  319.         end;
  320.     end;
  321.    
  322.     if ( !nexus.config.Get("use_local_machine_time"):Get() ) then
  323.         self:SaveSchemaData( "time", nexus.time.GetSaveData() );
  324.     end;
  325.    
  326.     if ( !nexus.config.Get("use_local_machine_date"):Get() ) then
  327.         self:SaveSchemaData( "date", nexus.date.GetSaveData() );
  328.     end;
  329. end;
  330.  
  331. -- Called when a player attempts to fire a weapon.
  332. function NEXUS:PlayerCanFireWeapon(player, raised, weapon, secondary)
  333.     local canShootTime = player.canShootTime;
  334.     local curTime = CurTime();
  335.    
  336.     if (nexus.config.Get("raised_weapon_system"):Get() and !raised) then
  337.         if ( !nexus.mount.Call("PlayerCanUseLoweredWeapon", player, weapon, secondary) ) then
  338.             return false;
  339.         end;
  340.     end;
  341.    
  342.     if (canShootTime and canShootTime > curTime) then
  343.         return false;
  344.     end;
  345.    
  346.     return true;
  347. end;
  348.  
  349. -- Called when a player attempts to use a lowered weapon.
  350. function NEXUS:PlayerCanUseLoweredWeapon(player, weapon, secondary)
  351.     if (secondary) then
  352.         return weapon.NeverRaised or (weapon.Secondary and weapon.Secondary.NeverRaised);
  353.     else
  354.         return weapon.NeverRaised or (weapon.Primary and weapon.Primary.NeverRaised);
  355.     end;
  356. end;
  357.  
  358. -- Called when a player's recognised names have been cleared.
  359. function NEXUS:PlayerRecognisedNamesCleared(player, status, simple) end;
  360.  
  361. -- Called when a player's name has been cleared.
  362. function NEXUS:PlayerNameCleared(player, status, simple) end;
  363.  
  364. -- Called when an offline player has been given property.
  365. function NEXUS:PlayerPropertyGivenOffline(key, uniqueID, entity, networked, removeDelay) end;
  366.  
  367. -- Called when an offline player has had property taken.
  368. function NEXUS:PlayerPropertyTakenOffline(key, uniqueID, entity) end;
  369.  
  370. -- Called when a player has been given property.
  371. function NEXUS:PlayerPropertyGiven(player, entity, networked, removeDelay) end;
  372.  
  373. -- Called when a player has had property taken.
  374. function NEXUS:PlayerPropertyTaken(player, entity) end;
  375.  
  376. -- Called when a player's visibility should be set up.
  377. function NEXUS:SetupPlayerVisibility(player)
  378.     local ragdollEntity = player:GetRagdollEntity();
  379.     local curTime = CurTime();
  380.    
  381.     if (ragdollEntity) then
  382.         AddOriginToPVS( ragdollEntity:GetPos() );
  383.     end;
  384.    
  385.     if ( player:HasInitialized() ) then
  386.         if (!player.nextThink) then
  387.             player.nextThink = curTime + 0.5;
  388.         end;
  389.        
  390.         if (!player.nextSetSharedVars) then
  391.             player.nextSetSharedVars = curTime + 3;
  392.         end;
  393.        
  394.         if (curTime >= player.nextThink) then
  395.             nexus.player.CallThinkHook(player, (curTime >= player.nextSetSharedVars), {}, curTime);
  396.         end;
  397.     end;
  398. end;
  399.  
  400. -- Called when a player has been given flags.
  401. function NEXUS:PlayerFlagsGiven(player, flags)
  402.     if ( string.find(flags, "p") and player:Alive() ) then
  403.         nexus.player.GiveSpawnWeapon(player, "weapon_physgun");
  404.     end;
  405.    
  406.     if ( string.find(flags, "t") and player:Alive() ) then
  407.         nexus.player.GiveSpawnWeapon(player, "gmod_tool");
  408.     end;
  409.    
  410.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  411. end;
  412.  
  413. -- Called when a player has had flags taken.
  414. function NEXUS:PlayerFlagsTaken(player, flags)
  415.     if ( string.find(flags, "p") and player:Alive() ) then
  416.         if ( !nexus.player.HasFlags(player, "p") ) then
  417.             nexus.player.TakeSpawnWeapon(player, "weapon_physgun");
  418.         end;
  419.     end;
  420.    
  421.     if ( string.find(flags, "t") and player:Alive() ) then
  422.         if ( !nexus.player.HasFlags(player, "t") ) then
  423.             nexus.player.TakeSpawnWeapon(player, "gmod_tool");
  424.         end;
  425.     end;
  426.    
  427.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  428. end;
  429.  
  430. -- Called when the game description is needed.
  431. function NEXUS:GetGameDescription()
  432.     if (SCHEMA and SCHEMA.name != "Base") then
  433.         return SCHEMA.name;
  434.     else
  435.         return self.Name;
  436.     end;
  437. end;
  438.  
  439. -- Called when a player's phys desc override is needed.
  440. function NEXUS:GetPlayerPhysDescOverride(player, physDesc) end;
  441.  
  442. -- Called when a player's default skin is needed.
  443. function NEXUS:GetPlayerDefaultSkin(player)
  444.     local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
  445.    
  446.     return skin;
  447. end;
  448.  
  449. -- Called when a player's default model is needed.
  450. function NEXUS:GetPlayerDefaultModel(player)
  451.     local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
  452.    
  453.     return model;
  454. end;
  455.  
  456. -- Called when a player's default inventory is needed.
  457. function NEXUS:GetPlayerDefaultInventory(player, character, inventory) end;
  458.  
  459. -- Called to get whether a player's weapon is raised.
  460. function NEXUS:GetPlayerWeaponRaised(player, class, weapon)
  461.     if (class == "weapon_physgun" or class == "weapon_physcannon" or class == "gmod_tool") then
  462.         return true;
  463.     end;
  464.    
  465.     if ( weapon:GetNetworkedBool("Ironsights") ) then
  466.         return true;
  467.     end;
  468.    
  469.     if (weapon:GetNetworkedInt("Zoom") != 0) then
  470.         return true;
  471.     end;
  472.    
  473.     if ( weapon:GetNetworkedBool("Scope") ) then
  474.         return true;
  475.     end;
  476.    
  477.     if (player.toggleWeaponRaised == class) then
  478.         return true;
  479.     else
  480.         player.toggleWeaponRaised = nil;
  481.     end;
  482.    
  483.     if (player.autoWeaponRaised == class) then
  484.         return true;
  485.     else
  486.         player.autoWeaponRaised = nil;
  487.     end;
  488. end;
  489.  
  490. -- Called when a player's attribute has been updated.
  491. function NEXUS:PlayerAttributeUpdated(player, attributeTable, amount) end;
  492.  
  493. -- Called when a player's inventory item has been updated.
  494. function NEXUS:PlayerInventoryItemUpdated(player, itemTable, amount, force)
  495.     nexus.player.UpdateStorageForPlayer(player, itemTable.uniqueID);
  496. end;
  497.  
  498. -- Called when a player's cash has been updated.
  499. function NEXUS:PlayerCashUpdated(player, amount, reason, noMessage)
  500.     nexus.player.UpdateStorageForPlayer(player);
  501. end;
  502.  
  503. -- A function to scale damage by hit group.
  504. function NEXUS:PlayerScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, baseDamage)
  505.     if ( attacker:IsVehicle() or ( attacker:IsPlayer() and attacker:InVehicle() ) ) then
  506.         damageInfo:ScaleDamage(0.25);
  507.     end;
  508. end;
  509.  
  510. -- Called when a player switches their flashlight on or off.
  511. function NEXUS:PlayerSwitchFlashlight(player, on)
  512.     if (player:HasInitialized() and on) then
  513.         if ( player:IsRagdolled() ) then
  514.             return false;
  515.         else
  516.             return true;
  517.         end;
  518.     else
  519.         return true;
  520.     end;
  521. end;
  522.  
  523. -- Called when time has passed.
  524. function NEXUS:TimePassed(quantity) end;
  525.  
  526. -- Called when Nexus config has initialized.
  527. function NEXUS:NexusConfigInitialized(key, value)
  528.     if (key == "cash_enabled" and !value) then
  529.         for k, v in pairs( nexus.item.GetAll() ) do
  530.             v.cost = 0;
  531.         end;
  532.     elseif (key == "local_voice") then
  533.         if (value) then
  534.             RunConsoleCommand("sv_alltalk", "0");
  535.         end;
  536.     elseif (key == "use_optimised_rates") then
  537.         if (value) then
  538.             RunConsoleCommand("sv_maxupdaterate", "66");
  539.             RunConsoleCommand("sv_minupdaterate", "0");
  540.             RunConsoleCommand("sv_maxcmdrate", "66");
  541.             RunConsoleCommand("sv_mincmdrate", "0");
  542.             RunConsoleCommand("sv_maxrate", "25000");
  543.             RunConsoleCommand("sv_minrate", "0");
  544.         end;
  545.     end;
  546. end;
  547.  
  548. -- Called when a Nexus ConVar has changed.
  549. function NEXUS:NexusConVarChanged(name, previousValue, newValue)
  550.     if (name == "local_voice" and newValue) then
  551.         RunConsoleCommand("sv_alltalk", "1");
  552.     end;
  553. end;
  554.  
  555. -- Called when Nexus config has changed.
  556. function NEXUS:NexusConfigChanged(key, data, previousValue, newValue)
  557.     if (key == "default_flags") then
  558.         for k, v in ipairs( g_Player.GetAll() ) do
  559.             if ( v:HasInitialized() and v:Alive() ) then
  560.                 if ( string.find(previousValue, "p") ) then
  561.                     if ( !string.find(newValue, "p") ) then
  562.                         if ( !nexus.player.HasFlags(v, "p") ) then
  563.                             nexus.player.TakeSpawnWeapon(v, "weapon_physgun");
  564.                         end;
  565.                     end;
  566.                 elseif ( !string.find(previousValue, "p") ) then
  567.                     if ( string.find(newValue, "p") ) then
  568.                         nexus.player.GiveSpawnWeapon(v, "weapon_physgun");
  569.                     end;
  570.                 end;
  571.                
  572.                 if ( string.find(previousValue, "t") ) then
  573.                     if ( !string.find(newValue, "t") ) then
  574.                         if ( !nexus.player.HasFlags(v, "t") ) then
  575.                             nexus.player.TakeSpawnWeapon(v, "gmod_tool");
  576.                         end;
  577.                     end;
  578.                 elseif ( !string.find(previousValue, "t") ) then
  579.                     if ( string.find(newValue, "t") ) then
  580.                         nexus.player.GiveSpawnWeapon(v, "gmod_tool");
  581.                     end;
  582.                 end;
  583.             end;
  584.         end;
  585.     elseif (key == "crouched_speed") then
  586.         for k, v in ipairs( g_Player.GetAll() ) do
  587.             v:SetCrouchedWalkSpeed(newValue);
  588.         end;
  589.     elseif (key == "ooc_interval") then
  590.         for k, v in ipairs( g_Player.GetAll() ) do
  591.             v.nextTalkOOC = nil;
  592.         end;
  593.     elseif (key == "jump_power") then
  594.         for k, v in ipairs( g_Player.GetAll() ) do
  595.             v:SetJumpPower(newValue);
  596.         end;
  597.     elseif (key == "walk_speed") then
  598.         for k, v in ipairs( g_Player.GetAll() ) do
  599.             v:SetWalkSpeed(newValue);
  600.         end;
  601.     elseif (key == "run_speed") then
  602.         for k, v in ipairs( g_Player.GetAll() ) do
  603.             v:SetRunSpeed(newValue);
  604.         end;
  605.     end;
  606. end;
  607.  
  608. -- Called when a player's name has changed.
  609. function NEXUS:PlayerNameChanged(player, previousName, newName) end;
  610.  
  611. -- Called when a player attempts to sprays their tag.
  612. function NEXUS:PlayerSpray(player)
  613.     if ( !player:Alive() or player:IsRagdolled() ) then
  614.         return true;
  615.     else
  616.         return nexus.config.Get("disable_sprays"):Get();
  617.     end;
  618. end;
  619.  
  620. -- Called when a player attempts to use an entity.
  621. function NEXUS:PlayerUse(player, entity)
  622.     if ( player:IsRagdolled(RAGDOLL_FALLENOVER) ) then
  623.         return false;
  624.     else
  625.         return true;
  626.     end;
  627. end;
  628.  
  629. -- Called when a player's move data is set up.
  630. function NEXUS:SetupMove(player, moveData)
  631.     if ( player:Alive() and !player:IsRagdolled() ) then
  632.         local frameTime = FrameTime();
  633.         local curTime = CurTime();
  634.         local drunk = nexus.player.GetDrunk(player);
  635.        
  636.         if (drunk and player.drunkSwerve) then
  637.             player.drunkSwerve = math.Clamp( player.drunkSwerve + frameTime, 0, math.min(drunk * 2, 16) );
  638.            
  639.             moveData:SetMoveAngles( moveData:GetMoveAngles() + Angle(0, math.cos(curTime) * player.drunkSwerve, 0) );
  640.         elseif (player.drunkSwerve and player.drunkSwerve > 1) then
  641.             player.drunkSwerve = math.max(player.drunkSwerve - frameTime, 0);
  642.            
  643.             moveData:SetMoveAngles( moveData:GetMoveAngles() + Angle(0, math.cos(curTime) * player.drunkSwerve, 0) );
  644.         elseif (player.drunkSwerve != 1) then
  645.             player.drunkSwerve = 1;
  646.         end;
  647.     end;
  648. end;
  649.  
  650. -- Called when a player throws a punch.
  651. function NEXUS:PlayerPunchThrown(player) end;
  652.  
  653. -- Called when a player knocks on a door.
  654. function NEXUS:PlayerKnockOnDoor(player, door) end;
  655.  
  656. -- Called when a player attempts to knock on a door.
  657. function NEXUS:PlayerCanKnockOnDoor(player, door) return true; end;
  658.  
  659. -- Called when a player punches an entity.
  660. function NEXUS:PlayerPunchEntity(player, entity) end;
  661.  
  662. -- Called when a player orders an item shipment.
  663. function NEXUS:PlayerOrderShipment(player, itemTable, entity) end;
  664.  
  665. -- Called when a player holsters a weapon.
  666. function NEXUS:PlayerHolsterWeapon(player, itemTable, forced)
  667.     if (itemTable.OnHolster) then
  668.         itemTable:OnHolster(player, forced);
  669.     end;
  670. end;
  671.  
  672. -- Called when a player attempts to save a recognised name.
  673. function NEXUS:PlayerCanSaveRecognisedName(player, target)
  674.     if (player != target) then return true; end;
  675. end;
  676.  
  677. -- Called when a player attempts to restore a recognised name.
  678. function NEXUS:PlayerCanRestoreRecognisedName(player, target)
  679.     if (player != target) then return true; end;
  680. end;
  681.  
  682. -- Called when a player attempts to order an item shipment.
  683. function NEXUS:PlayerCanOrderShipment(player, itemTable)
  684.     return true;
  685. end;
  686.  
  687. -- Called when a player attempts to get up.
  688. function NEXUS:PlayerCanGetUp(player) return true; end;
  689.  
  690. -- Called when a player knocks out a player with a punch.
  691. function NEXUS:PlayerPunchKnockout(player, target) end;
  692.  
  693. -- Called when a player attempts to throw a punch.
  694. function NEXUS:PlayerCanThrowPunch(player) return true; end;
  695.  
  696. -- Called when a player attempts to punch an entity.
  697. function NEXUS:PlayerCanPunchEntity(player, entity) return true; end;
  698.  
  699. -- Called when a player attempts to knock a player out with a punch.
  700. function NEXUS:PlayerCanPunchKnockout(player, target) return true; end;
  701.  
  702. -- Called when a player attempts to bypass the faction limit.
  703. function NEXUS:PlayerCanBypassFactionLimit(player, character) return false; end;
  704.  
  705. -- Called when a player attempts to bypass the class limit.
  706. function NEXUS:PlayerCanBypassClassLimit(player, class) return false; end;
  707.  
  708. -- Called when a player's pain sound should be played.
  709. function NEXUS:PlayerPlayPainSound(player, gender, damageInfo, hitGroup)
  710.     if (damageInfo:IsBulletDamage() and math.random() <= 0.5) then
  711.         if (hitGroup == HITGROUP_HEAD) then
  712.             return "vo/npc/"..gender.."01/ow0"..math.random(1, 2)..".wav";
  713.         elseif (hitGroup == HITGROUP_CHEST or hitGroup == HITGROUP_GENERIC) then
  714.             return "vo/npc/"..gender.."01/hitingut0"..math.random(1, 2)..".wav";
  715.         elseif (hitGroup == HITGROUP_LEFTLEG or hitGroup == HITGROUP_RIGHTLEG) then
  716.             return "vo/npc/"..gender.."01/myleg0"..math.random(1, 2)..".wav";
  717.         elseif (hitGroup == HITGROUP_LEFTARM or hitGroup == HITGROUP_RIGHTARM) then
  718.             return "vo/npc/"..gender.."01/myarm0"..math.random(1, 2)..".wav";
  719.         elseif (hitGroup == HITGROUP_GEAR) then
  720.             return "vo/npc/"..gender.."01/startle0"..math.random(1, 2)..".wav";
  721.         end;
  722.     end;
  723.    
  724.     return "vo/npc/"..gender.."01/pain0"..math.random(1, 9)..".wav";
  725. end;
  726.  
  727. -- Called when a player's data has loaded.
  728. function NEXUS:PlayerDataLoaded(player)
  729.     if ( nexus.config.Get("nexus_intro_enabled"):Get() ) then
  730.         if ( !player:GetData("nexus_intro") ) then
  731.             umsg.Start("nx_NexusIntro", player);
  732.             umsg.End();
  733.            
  734.             player:SetData("nexus_intro", true);
  735.         end;
  736.     end;
  737. end;
  738.  
  739. -- Called when a player attempts to be given a weapon.
  740. function NEXUS:PlayerCanBeGivenWeapon(player, class, uniqueID, forceReturn)
  741.     return true;
  742. end;
  743.  
  744. -- Called when a player has been given a weapon.
  745. function NEXUS:PlayerGivenWeapon(player, class, uniqueID, forceReturn)
  746.     nexus.inventory.Rebuild(player);
  747. end;
  748.  
  749. -- Called when a player attempts to create a character.
  750. function NEXUS:PlayerCanCreateCharacter(player, character, characterID)
  751.     if ( nexus.quiz.GetEnabled() and !nexus.quiz.GetCompleted(player) ) then
  752.         return false, "You have not completed the quiz!";
  753.     else
  754.         return true;
  755.     end;
  756. end;
  757.  
  758. -- Called when a player attempts to interact with a character.
  759. function NEXUS:PlayerCanInteractCharacter(player, action, character)
  760.     if ( nexus.quiz.GetEnabled() and !nexus.quiz.GetCompleted(player) ) then
  761.         return false, "You have not completed the quiz!";
  762.     else
  763.         return true;
  764.     end;
  765. end;
  766.  
  767. -- Called when a player's fall damage is needed.
  768. function NEXUS:GetFallDamage(player, velocity)
  769.     local ragdollEntity = nil;
  770.     local position = player:GetPos();
  771.     local damage = math.max( (velocity - 464) * 0.225225225, 0 ) * nexus.config.Get("scale_fall_damage"):Get();
  772.     local filter = {player};
  773.    
  774.     if ( nexus.config.Get("wood_breaks_fall"):Get() ) then
  775.         if ( player:IsRagdolled() ) then
  776.             ragdollEntity = player:GetRagdollEntity();
  777.             position = ragdollEntity:GetPos();
  778.             filter = {player, ragdollEntity};
  779.         end;
  780.        
  781.         local trace = util.TraceLine( {
  782.             endpos = position - Vector(0, 0, 64),
  783.             start = position,
  784.             filter = filter
  785.         } );
  786.  
  787.         if (IsValid(trace.Entity) and trace.MatType == MAT_WOOD) then
  788.             if ( string.find(trace.Entity:GetClass(), "prop_physics") ) then
  789.                 trace.Entity:Fire("Break", "", 0);
  790.                
  791.                 damage = damage * 0.25;
  792.             end;
  793.         end;
  794.     end;
  795.    
  796.     return damage;
  797. end;
  798.  
  799. -- Called when a player's data stream info has been sent.
  800. function NEXUS:PlayerDataStreamInfoSent(player)
  801.     if ( player:IsBot() ) then
  802.         nexus.player.LoadData(player, function(player)
  803.             nexus.mount.Call("PlayerDataLoaded", player);
  804.            
  805.             local factions = table.ClearKeys(nexus.faction.stored, true);
  806.             local faction = factions[ math.random(1, #factions) ];
  807.            
  808.             if (faction) then
  809.                 local genders = {GENDER_MALE, GENDER_FEMALE};
  810.                 local gender = faction.singleGender or genders[ math.random(1, #genders) ];
  811.                 local models = faction.models[ string.lower(gender) ];
  812.                 local model = models[ math.random(1, #models) ];
  813.                
  814.                 nexus.player.LoadCharacter( player, 1, {
  815.                     faction = faction.name,
  816.                     gender = gender,
  817.                     model = model,
  818.                     name = player:Name(),
  819.                     data = {}
  820.                 }, function()
  821.                     nexus.player.LoadCharacter(player, 1);
  822.                 end);
  823.             end;
  824.         end);
  825.     elseif (table.Count(nexus.faction.stored) > 0) then
  826.         nexus.player.LoadData(player, function()
  827.             nexus.mount.Call("PlayerDataLoaded", player);
  828.            
  829.             local whitelisted = player:GetData("whitelisted");
  830.             local steamName = player:SteamName();
  831.             local unixTime = os.time();
  832.            
  833.             nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_OPEN);
  834.            
  835.             for k, v in pairs(whitelisted) do
  836.                 if ( nexus.faction.stored[v] ) then
  837.                     self:StartDataStream( player, "SetWhitelisted", {v, true} );
  838.                 else
  839.                     whitelisted[k] = nil;
  840.                 end;
  841.             end;
  842.            
  843.             nexus.player.GetCharacters(player, function(characters)
  844.                 if (characters) then
  845.                     for k, v in pairs(characters) do
  846.                         nexus.player.ConvertCharacterMySQL(v);
  847.                        
  848.                         player.characters[v.characterID] = {};
  849.                        
  850.                         for k2, v2 in pairs(v.inventory) do
  851.                             if ( !nexus.item.GetAll()[k2] ) then
  852.                                 if ( !nexus.mount.Call("PlayerHasUnknownInventoryItem", player, v.inventory, k2, v2) ) then
  853.                                     v.inventory[k2] = nil;
  854.                                 end;
  855.                             end;
  856.                         end;
  857.                        
  858.                         for k2, v2 in pairs(v.attributes) do
  859.                             if ( !nexus.attribute.GetAll()[k2] ) then
  860.                                 if ( !nexus.mount.Call("PlayerHasUnknownAttribute", player, v.attributes, k2, v2.amount, v2.progress) ) then
  861.                                     v.attributes[k2] = nil;
  862.                                 end;
  863.                             end;
  864.                         end;
  865.                        
  866.                         for k2, v2 in pairs(v) do
  867.                             if (k2 == "timeCreated") then
  868.                                 if (v2 == "") then
  869.                                     player.characters[v.characterID][k2] = unixTime;
  870.                                 else
  871.                                     player.characters[v.characterID][k2] = v2;
  872.                                 end;
  873.                             elseif (k2 == "lastPlayed") then
  874.                                 player.characters[v.characterID][k2] = unixTime;
  875.                             elseif (k2 == "steamName") then
  876.                                 player.characters[v.characterID][k2] = steamName;
  877.                             else
  878.                                 player.characters[v.characterID][k2] = v2;
  879.                             end;
  880.                         end;
  881.                     end;
  882.                    
  883.                     for k, v in pairs(player.characters) do
  884.                         local delete = nexus.mount.Call("PlayerAdjustCharacterTable", player, v);
  885.                        
  886.                         if (!delete) then
  887.                             nexus.player.CharacterScreenAdd(player, v);
  888.                         else
  889.                             nexus.player.ForceDeleteCharacter(player, k);
  890.                         end;
  891.                     end;
  892.                 end;
  893.                
  894.                 nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_LOADED);
  895.             end);
  896.         end);
  897.     end;
  898. end;
  899.  
  900. -- Called when a player's data stream info should be sent.
  901. function NEXUS:PlayerSendDataStreamInfo(player) end;
  902.  
  903. -- Called when a player's death sound should be played.
  904. function NEXUS:PlayerPlayDeathSound(player, gender)
  905.     return "vo/npc/"..string.lower(gender).."01/pain0"..math.random(1, 9)..".wav";
  906. end;
  907.  
  908. -- Called when a player's character data should be restored.
  909. function NEXUS:PlayerRestoreCharacterData(player, data)
  910.     if ( data["physdesc"] ) then
  911.         data["physdesc"] = self:ModifyPhysDesc( data["physdesc"] );
  912.     end;
  913. end;
  914.  
  915. -- Called when a player's character data should be saved.
  916. function NEXUS:PlayerSaveCharacterData(player, data)
  917.     if ( nexus.config.Get("save_attribute_boosts"):Get() ) then
  918.         self:SavePlayerAttributeBoosts(player, data);
  919.     end;
  920.    
  921.     data["health"] = player:Health();
  922.     data["armor"] = player:Armor();
  923.    
  924.     if (data["health"] <= 1) then
  925.         data["health"] = nil;
  926.     end;
  927.    
  928.     if (data["armor"] <= 1) then
  929.         data["armor"] = nil;
  930.     end;
  931. end;
  932.  
  933. -- Called when a player's data should be saved.
  934. function NEXUS:PlayerSaveData(player, data)
  935.     if (data["whitelisted"] and #data["whitelisted"] == 0) then
  936.         data["whitelisted"] = nil;
  937.     end;
  938. end;
  939.  
  940. -- Called when a player's storage should close.
  941. function NEXUS:PlayerStorageShouldClose(player, storageTable)
  942.     local entity = player:GetStorageEntity();
  943.    
  944.     if ( player:IsRagdolled() or !player:Alive() or !entity or (storageTable.distance and player:GetShootPos():Distance( entity:GetPos() ) > storageTable.distance) ) then
  945.         return true;
  946.     elseif ( storageTable.ShouldClose and storageTable.ShouldClose(player, storageTable) ) then
  947.         return true;
  948.     end;
  949. end;
  950.  
  951. -- Called when a player attempts to pickup a weapon.
  952. function NEXUS:PlayerCanPickupWeapon(player, weapon)
  953.     if ( player.forceGive or ( player:GetEyeTraceNoCursor().Entity == weapon and player:KeyDown(IN_USE) ) ) then
  954.         return true;
  955.     else
  956.         return false;
  957.     end;
  958. end;
  959.  
  960. -- Called each tick.
  961. function NEXUS:Tick()
  962.     if (NEXUS_TICK) then
  963.         local sysTime = SysTime();
  964.         local curTime = CurTime();
  965.        
  966.         if (!self.NextHint or curTime >= self.NextHint) then
  967.             nexus.hint.Distribute();
  968.            
  969.             self.NextHint = curTime + nexus.config.Get("hint_interval"):Get();
  970.         end;
  971.        
  972.         if (!self.NextWagesTime or curTime >= self.NextWagesTime) then
  973.             self:DistributeWagesCash();
  974.             self.NextWagesTime = curTime + nexus.config.Get("wages_interval"):Get();
  975.         end;
  976.        
  977.         if (!self.NextGeneratorTime or curTime >= self.NextGeneratorTime) then
  978.             self:DistributeGeneratorCash();
  979.             self.NextGeneratorTime = curTime + nexus.config.Get("generator_interval"):Get();
  980.         end;
  981.        
  982.         if (!self.NextDateTimeThink or sysTime >= self.NextDateTimeThink) then
  983.             self:PerformDateTimeThink();
  984.             self.NextDateTimeThink = sysTime + nexus.config.Get("minute_time"):Get();
  985.         end;
  986.        
  987.         if (!self.NextSaveData or sysTime >= self.NextSaveData) then
  988.             nexus.mount.Call("PreSaveData");
  989.                 nexus.mount.Call("SaveData");
  990.             nexus.mount.Call("PostSaveData");
  991.            
  992.             self.NextSaveData = sysTime + nexus.config.Get("save_data_interval"):Get();
  993.         end;
  994.        
  995.         if (!self.NextCheckEmpty) then
  996.             self.NextCheckEmpty = sysTime + 1200;
  997.         end;
  998.        
  999.         if (sysTime >= self.NextCheckEmpty) then
  1000.             self.NextCheckEmpty = nil;
  1001.            
  1002.             if (#g_Player.GetAll() == 0) then
  1003.                 RunConsoleCommand( "changelevel", game.GetMap() );
  1004.             end;
  1005.         end;
  1006.     end;
  1007. end;
  1008.  
  1009. -- Called each frame.
  1010. function NEXUS:Think()
  1011.     self:CallTimerThink( CurTime() );
  1012. end;
  1013.  
  1014. -- Called when a player's shared variables should be set.
  1015. function NEXUS:PlayerSetSharedVars(player, curTime)
  1016.     local weaponClass = nexus.player.GetWeaponClass(player);
  1017.     local r, g, b, a = player:GetColor();
  1018.     local drunk = nexus.player.GetDrunk(player);
  1019.    
  1020.     player:HandleAttributeProgress(curTime);
  1021.     player:HandleAttributeBoosts(curTime);
  1022.    
  1023.     player:SetSharedVar( "sh_PhysDesc", player:GetCharacterData("physdesc") );
  1024.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  1025.     player:SetSharedVar( "sh_Model", player:QueryCharacter("model") );
  1026.     player:SetSharedVar( "sh_Name", player:QueryCharacter("name") );
  1027.     player:SetSharedVar( "sh_Cash", nexus.player.GetCash(player) );
  1028.    
  1029.     if ( nexus.config.Get("enable_temporary_damage"):Get() ) then
  1030.         local maxHealth = player:GetMaxHealth();
  1031.         local health = player:Health();
  1032.        
  1033.         if ( player:Alive() ) then
  1034.             if ( health >= (maxHealth / 2) ) then
  1035.                 if (health < maxHealth) then
  1036.                     player:SetHealth( math.Clamp(health + 1, 0, maxHealth) );
  1037.                 end;
  1038.             elseif (health > 0) then
  1039.                 if (!player.nextSlowRegeneration) then
  1040.                     player.nextSlowRegeneration = curTime + 6;
  1041.                 end;
  1042.                
  1043.                 if (curTime >= player.nextSlowRegeneration) then
  1044.                     player.nextSlowRegeneration = nil;
  1045.                     player:SetHealth( math.Clamp(health + 1, 0, maxHealth) );
  1046.                 end;
  1047.             end;
  1048.         end;
  1049.     end;
  1050.    
  1051.     if (r == 255 and g == 0 and b == 0 and a == 0) then
  1052.         player:SetColor(255, 255, 255, 255);
  1053.     end;
  1054.    
  1055.     if (player.drunk) then
  1056.         for k, v in pairs(player.drunk) do
  1057.             if (curTime >= v) then
  1058.                 table.remove(player.drunk, k);
  1059.             end;
  1060.         end;
  1061.     end;
  1062.    
  1063.     if (drunk) then
  1064.         player:SetSharedVar("sh_Drunk", drunk);
  1065.     else
  1066.         player:SetSharedVar("sh_Drunk", 0);
  1067.     end;
  1068. end;
  1069.  
  1070. -- Called at an interval while a player is connected.
  1071. function NEXUS:PlayerThink(player, curTime, infoTable)
  1072.     local storageTable = player:GetStorageTable();
  1073.    
  1074.     if ( !nexus.config.Get("cash_enabled"):Get() ) then
  1075.         player:SetCharacterData("cash", 0, true);
  1076.        
  1077.         infoTable.wages = 0;
  1078.     end;
  1079.    
  1080.     if (player.reloadHoldTime and curTime >= player.reloadHoldTime) then
  1081.         nexus.player.ToggleWeaponRaised(player);
  1082.        
  1083.         player.reloadHoldTime = nil;
  1084.         player.canShootTime = curTime + nexus.config.Get("shoot_after_raise_time"):Get();
  1085.     end;
  1086.    
  1087.     if ( player:IsRagdolled() ) then
  1088.         player:SetMoveType(MOVETYPE_OBSERVER);
  1089.     end;
  1090.    
  1091.     if (storageTable) then
  1092.         if (hook.Call( "PlayerStorageShouldClose", self, player, storageTable) ) then
  1093.             nexus.player.CloseStorage(player);
  1094.         end;
  1095.     end;
  1096.    
  1097.     player:SetSharedVar( "sh_InventoryWeight", math.ceil(infoTable.inventoryWeight) );
  1098.     player:SetSharedVar( "sh_Wages", math.ceil(infoTable.wages) );
  1099.    
  1100.     if (infoTable.running == false or infoTable.runSpeed < infoTable.walkSpeed) then
  1101.         infoTable.runSpeed = infoTable.walkSpeed;
  1102.     end;
  1103.    
  1104.     if (infoTable.jogging) then
  1105.         infoTable.walkSpeed = infoTable.walkSpeed * 1.75;
  1106.     end;
  1107.    
  1108.     player:UpdateWeaponRaised();
  1109.     player:SetCrouchedWalkSpeed(math.max(infoTable.crouchedSpeed, 0), true);
  1110.     player:SetWalkSpeed(math.max(infoTable.walkSpeed, 0), true);
  1111.     player:SetJumpPower(math.max(infoTable.jumpPower, 0), true);
  1112.     player:SetRunSpeed(math.max(infoTable.runSpeed, 0), true);
  1113. end;
  1114.  
  1115. -- Called when a player uses an item.
  1116. function NEXUS:PlayerUseItem(player, itemTable, itemEntity) end;
  1117.  
  1118. -- Called when a player drops an item.
  1119. function NEXUS:PlayerDropItem(player, itemTable, position, entity)
  1120.     if ( IsValid(entity) and nexus.item.IsWeapon(itemTable) ) then
  1121.         local secondaryAmmo = nexus.player.TakeSecondaryAmmo(player, itemTable.weaponClass);
  1122.         local primaryAmmo = nexus.player.TakePrimaryAmmo(player, itemTable.weaponClass);
  1123.        
  1124.         if (secondaryAmmo > 0) then
  1125.             entity.data.sClip = secondaryAmmo;
  1126.         end;
  1127.        
  1128.         if (primaryAmmo > 0) then
  1129.             entity.data.pClip = primaryAmmo;
  1130.         end;
  1131.     end;
  1132. end;
  1133.  
  1134. -- Called when a player destroys an item.
  1135. function NEXUS:PlayerDestroyItem(player, itemTable) end;
  1136.  
  1137. -- Called when a player drops a weapon.
  1138. function NEXUS:PlayerDropWeapon(player, itemTable, entity)
  1139.     if ( IsValid(entity) ) then
  1140.         local secondaryAmmo = nexus.player.TakeSecondaryAmmo(player, itemTable.weaponClass);
  1141.         local primaryAmmo = nexus.player.TakePrimaryAmmo(player, itemTable.weaponClass);
  1142.        
  1143.         if (secondaryAmmo > 0) then
  1144.             entity.data.sClip = secondaryAmmo;
  1145.         end;
  1146.        
  1147.         if (primaryAmmo > 0) then
  1148.             entity.data.pClip = primaryAmmo;
  1149.         end;
  1150.     end;
  1151. end;
  1152.  
  1153. -- Called when a player charges generator.
  1154. function NEXUS:PlayerChargeGenerator(player, entity, generator) end;
  1155.  
  1156. -- Called when a player destroys generator.
  1157. function NEXUS:PlayerDestroyGenerator(player, entity, generator) end;
  1158.  
  1159. -- Called when a player's data should be restored.
  1160. function NEXUS:PlayerRestoreData(player, data)
  1161.     if ( !data["whitelisted"] ) then
  1162.         data["whitelisted"] = {};
  1163.     end;
  1164. end;
  1165.  
  1166. -- Called when a player's temporary info should be saved.
  1167. function NEXUS:PlayerSaveTempData(player, tempData) end;
  1168.  
  1169. -- Called when a player's temporary info should be restored.
  1170. function NEXUS:PlayerRestoreTempData(player, tempData) end;
  1171.  
  1172. -- Called when a player selects a custom character option.
  1173. function NEXUS:PlayerSelectCharacterOption(player, character, option) end;
  1174.  
  1175. -- Called when a player attempts to see another player's status.
  1176. function NEXUS:PlayerCanSeeStatus(player, target)
  1177.     return "# "..target:UserID().." | "..target:Name().." | "..target:SteamName().." | "..target:SteamID().." | "..target:IPAddress();
  1178. end;
  1179.  
  1180. -- Called when a player attempts to see a player's chat.
  1181. function NEXUS:PlayerCanSeePlayersChat(text, teamOnly, listener, speaker)
  1182.     return true;
  1183. end;
  1184.  
  1185. -- Called when a player attempts to hear another player's voice.
  1186. function NEXUS:PlayerCanHearPlayersVoice(listener, speaker)
  1187.     if ( nexus.config.Get("local_voice"):Get() ) then
  1188.         if ( listener:IsRagdolled(RAGDOLL_FALLENOVER) or !listener:Alive() ) then
  1189.             return false;
  1190.         elseif ( speaker:IsRagdolled(RAGDOLL_FALLENOVER) or !speaker:Alive() ) then
  1191.             return false;
  1192.         elseif ( listener:GetPos():Distance( speaker:GetPos() ) > nexus.config.Get("talk_radius"):Get() ) then
  1193.             return false;
  1194.         end;
  1195.     end;
  1196.    
  1197.     return true;
  1198. end;
  1199.  
  1200. -- Called when a player attempts to delete a character.
  1201. function NEXUS:PlayerCanDeleteCharacter(player, character)
  1202.     if ( nexus.config.Get("cash_enabled"):Get() ) then
  1203.         if ( character.cash < nexus.config.Get("default_cash"):Get() ) then
  1204.             if ( !character.data["banned"] ) then
  1205.                 return "You cannot delete characters with less than "..FORMAT_CASH(nexus.config.Get("default_cash"):Get(), nil, true)..".";
  1206.             end;
  1207.         end;
  1208.     end;
  1209. end;
  1210.  
  1211. -- Called when a player attempts to switch to a character.
  1212. function NEXUS:PlayerCanSwitchCharacter(player, character)
  1213.     local fault = nexus.mount.Call("PlayerCanUseCharacter", player, character);
  1214.     local canUse = false;
  1215.    
  1216.     if (fault == nil or fault == true) then
  1217.         canUse = true;
  1218.     end;
  1219.    
  1220.     if (!player:Alive() and canUse) then
  1221.         return "You cannot switch characters when you are dead!";
  1222.     else
  1223.         return true;
  1224.     end;
  1225. end;
  1226.  
  1227. -- Called when a player attempts to use a character.
  1228. function NEXUS:PlayerCanUseCharacter(player, character)
  1229.     if ( character.data["banned"] ) then
  1230.         return character.name.." is banned and cannot be used!";
  1231.     end;
  1232. end;
  1233.  
  1234. -- Called when a player's weapons should be given.
  1235. function NEXUS:PlayerGiveWeapons(player) end;
  1236.  
  1237. -- Called when a player deletes a character.
  1238. function NEXUS:PlayerDeleteCharacter(player, character) end;
  1239.  
  1240. -- Called when a player's armor is set.
  1241. function NEXUS:PlayerArmorSet(player, armor)
  1242.     if ( player:IsRagdolled() ) then
  1243.         player:GetRagdollTable().armor = armor;
  1244.     end;
  1245. end;
  1246.  
  1247. -- Called when a player's health is set.
  1248. function NEXUS:PlayerHealthSet(player, health)
  1249.     if ( player:IsRagdolled() ) then
  1250.         player:GetRagdollTable().health = health;
  1251.     end;
  1252. end;
  1253.  
  1254. -- Called when a player attempts to own a door.
  1255. function NEXUS:PlayerCanOwnDoor(player, door)
  1256.     if ( nexus.entity.IsDoorUnownable(door) ) then
  1257.         return false;
  1258.     else
  1259.         return true;
  1260.     end;
  1261. end;
  1262.  
  1263. -- Called when a player attempts to view a door.
  1264. function NEXUS:PlayerCanViewDoor(player, door)
  1265.     if ( nexus.entity.IsDoorUnownable(door) ) then
  1266.         return false;
  1267.     end;
  1268.    
  1269.     return true;
  1270. end;
  1271.  
  1272. -- Called when a player attempts to holster a weapon.
  1273. function NEXUS:PlayerCanHolsterWeapon(player, itemTable, forceHolster, noMessage)
  1274.     if ( nexus.player.GetSpawnWeapon(player, itemTable.weaponClass) ) then
  1275.         if (!noMessage) then
  1276.             nexus.player.Notify(player, "You cannot holster this weapon!");
  1277.         end;
  1278.        
  1279.         return false;
  1280.     elseif (itemTable.CanHolsterWeapon) then
  1281.         return itemTable:CanHolsterWeapon(player, forceHolster, noMessage);
  1282.     else
  1283.         return true;
  1284.     end;
  1285. end;
  1286.  
  1287. -- Called when a player attempts to drop a weapon.
  1288. function NEXUS:PlayerCanDropWeapon(player, itemTable, noMessage)
  1289.     if ( nexus.player.GetSpawnWeapon(player, itemTable.weaponClass) ) then
  1290.         if (!noMessage) then
  1291.             nexus.player.Notify(player, "You cannot drop this weapon!");
  1292.         end;
  1293.        
  1294.         return false;
  1295.     elseif (itemTable.CanDropWeapon) then
  1296.         return itemTable:CanDropWeapon(player, noMessage);
  1297.     else
  1298.         return true;
  1299.     end;
  1300. end;
  1301.  
  1302. -- Called when a player attempts to use an item.
  1303. function NEXUS:PlayerCanUseItem(player, itemTable, noMessage)
  1304.     if ( nexus.item.IsWeapon(itemTable) and nexus.player.GetSpawnWeapon( player, itemTable.weaponClass ) ) then
  1305.         if (!noMessage) then
  1306.             nexus.player.Notify(player, "You cannot use this weapon!");
  1307.         end;
  1308.        
  1309.         return false;
  1310.     else
  1311.         return true;
  1312.     end;
  1313. end;
  1314.  
  1315. -- Called when a player attempts to drop an item.
  1316. function NEXUS:PlayerCanDropItem(player, itemTable, noMessage) return true; end;
  1317.  
  1318. -- Called when a player attempts to destroy an item.
  1319. function NEXUS:PlayerCanDestroyItem(player, itemTable, noMessage) return true; end;
  1320.  
  1321. -- Called when a player attempts to destroy generator.
  1322. function NEXUS:PlayerCanDestroyGenerator(player, entity, generator) return true; end;
  1323.  
  1324. -- Called when a player attempts to knockout a player.
  1325. function NEXUS:PlayerCanKnockout(player, target) return true; end;
  1326.  
  1327. -- Called when a player attempts to use the radio.
  1328. function NEXUS:PlayerCanRadio(player, text, listeners, eavesdroppers) return true; end;
  1329.  
  1330. -- Called when death attempts to clear a player's name.
  1331. function NEXUS:PlayerCanDeathClearName(player, attacker, damageInfo) return false; end;
  1332.  
  1333. -- Called when death attempts to clear a player's recognised names.
  1334. function NEXUS:PlayerCanDeathClearRecognisedNames(player, attacker, damageInfo) return false; end;
  1335.  
  1336. -- Called when a player's ragdoll attempts to take damage.
  1337. function NEXUS:PlayerRagdollCanTakeDamage(player, ragdoll, inflictor, attacker, hitGroup, damageInfo)
  1338.     if (!attacker:IsPlayer() and player:GetRagdollTable().immunity) then
  1339.         if (CurTime() <= player:GetRagdollTable().immunity) then
  1340.             return false;
  1341.         end;
  1342.     end;
  1343.    
  1344.     return true;
  1345. end;
  1346.  
  1347. -- Called when a player has been authenticated.
  1348. function NEXUS:PlayerAuthed(player, steamID)
  1349.     local banTable = self.BanList[ player:IPAddress() ] or self.BanList[steamID];
  1350.    
  1351.     if (banTable) then
  1352.         local unixTime = os.time();
  1353.         local timeLeft = banTable.unbanTime - unixTime;
  1354.         local hoursLeft = math.Round( math.max(timeLeft / 3600, 0) );
  1355.         local minutesLeft = math.Round( math.max(timeLeft / 60, 0) );
  1356.        
  1357.         if (banTable.unbanTime > 0 and unixTime < banTable.unbanTime) then
  1358.             local bannedMessage = nexus.config.Get("banned_message"):Get();
  1359.            
  1360.             if (hoursLeft >= 1) then
  1361.                 hoursLeft = tostring(hoursLeft);
  1362.                
  1363.                 bannedMessage = string.gsub(bannedMessage, "!t", hoursLeft);
  1364.                 bannedMessage = string.gsub(bannedMessage, "!f", "hour(s)");
  1365.             elseif (minutesLeft >= 1) then
  1366.                 minutesLeft = tostring(minutesLeft);
  1367.                
  1368.                 bannedMessage = string.gsub(bannedMessage, "!t", minutesLeft);
  1369.                 bannedMessage = string.gsub(bannedMessage, "!f", "minutes(s)");
  1370.             else
  1371.                 timeLeft = tostring(timeLeft);
  1372.                
  1373.                 bannedMessage = string.gsub(bannedMessage, "!t", timeLeft);
  1374.                 bannedMessage = string.gsub(bannedMessage, "!f", "second(s)");
  1375.             end;
  1376.            
  1377.             player:Kick(bannedMessage);
  1378.         elseif (banTable.unbanTime == 0) then
  1379.             player:Kick(banTable.reason);
  1380.         else
  1381.             self:RemoveBan(ipAddress);
  1382.             self:RemoveBan(steamID);
  1383.         end;
  1384.     end;
  1385. end;
  1386.  
  1387. -- Called when the player attempts to be ragdolled.
  1388. function NEXUS:PlayerCanRagdoll(player, state, delay, decay, ragdoll)
  1389.     return true;
  1390. end;
  1391.  
  1392. -- Called when the player attempts to be unragdolled.
  1393. function NEXUS:PlayerCanUnragdoll(player, state, ragdoll)
  1394.     return true;
  1395. end;
  1396.  
  1397. -- Called when a player has been ragdolled.
  1398. function NEXUS:PlayerRagdolled(player, state, ragdoll)
  1399.     player:SetSharedVar("sh_FallenOver", false);
  1400. end;
  1401.  
  1402. -- Called when a player has been unragdolled.
  1403. function NEXUS:PlayerUnragdolled(player, state, ragdoll)
  1404.     player:SetSharedVar("sh_FallenOver", false);
  1405. end;
  1406.  
  1407. -- Called to check if a player does have an flag.
  1408. function NEXUS:PlayerDoesHaveFlag(player, flag)
  1409.     if ( string.find(nexus.config.Get("default_flags"):Get(), flag) ) then
  1410.         return true;
  1411.     end;
  1412. end;
  1413.  
  1414. -- Called to check if a player does have door access.
  1415. function NEXUS:PlayerDoesHaveDoorAccess(player, door, access, simple)
  1416.     if (nexus.entity.GetOwner(door) == player) then
  1417.         return true;
  1418.     else
  1419.         local key = player:QueryCharacter("key");
  1420.        
  1421.         if ( door.accessList and door.accessList[key] ) then
  1422.             if (simple) then
  1423.                 return door.accessList[key] == access;
  1424.             else
  1425.                 return door.accessList[key] >= access;
  1426.             end;
  1427.         end;
  1428.     end;
  1429.    
  1430.     return false;
  1431. end;
  1432.  
  1433. -- Called to check if a player does know another player.
  1434. function NEXUS:PlayerDoesRecognisePlayer(player, target, status, simple, default)
  1435.     return default;
  1436. end;
  1437.  
  1438. -- Called to check if a player does have an item.
  1439. function NEXUS:PlayerDoesHaveItem(player, itemTable) return false; end;
  1440.  
  1441. -- Called when a player attempts to lock an entity.
  1442. function NEXUS:PlayerCanLockEntity(player, entity)
  1443.     if ( nexus.entity.IsDoor(entity) ) then
  1444.         return nexus.player.HasDoorAccess(player, entity);
  1445.     else
  1446.         return true;
  1447.     end;
  1448. end;
  1449.  
  1450. -- Called when a player's class has been set.
  1451. function NEXUS:PlayerClassSet(player, newClass, oldClass, noRespawn, addDelay, noModelChange) end;
  1452.  
  1453. -- Called when a player attempts to unlock an entity.
  1454. function NEXUS:PlayerCanUnlockEntity(player, entity)
  1455.     if ( nexus.entity.IsDoor(entity) ) then
  1456.         return nexus.player.HasDoorAccess(player, entity);
  1457.     else
  1458.         return true;
  1459.     end;
  1460. end;
  1461.  
  1462. -- Called when a player attempts to use a door.
  1463. function NEXUS:PlayerCanUseDoor(player, door)
  1464.     if ( nexus.entity.GetOwner(door) and !nexus.player.HasDoorAccess(player, door) ) then
  1465.         return false;
  1466.     end;
  1467.    
  1468.     if ( nexus.entity.IsDoorFalse(door) ) then
  1469.         return false;
  1470.     end;
  1471.    
  1472.     return true;
  1473. end;
  1474.  
  1475. -- Called when a player uses a door.
  1476. function NEXUS:PlayerUseDoor(player, door) end;
  1477.  
  1478. -- Called when a player attempts to use an entity in a vehicle.
  1479. function NEXUS:PlayerCanUseEntityInVehicle(player, entity, vehicle)
  1480.     if ( entity.UsableInVehicle or nexus.entity.IsDoor(entity) ) then
  1481.         return true;
  1482.     end;
  1483. end;
  1484.  
  1485. -- Called when a player's ragdoll attempts to decay.
  1486. function NEXUS:PlayerCanRagdollDecay(player, ragdoll, seconds)
  1487.     return true;
  1488. end;
  1489.  
  1490. -- Called when a player attempts to exit a vehicle.
  1491. function NEXUS:CanExitVehicle(vehicle, player)
  1492.     if ( player.nextExitVehicle and player.nextExitVehicle > CurTime() ) then
  1493.         return false;
  1494.     end;
  1495.    
  1496.     if ( IsValid(player) and player:IsPlayer() ) then
  1497.         local trace = player:GetEyeTraceNoCursor();
  1498.        
  1499.         if ( IsValid(trace.Entity) and !trace.Entity:IsVehicle() ) then
  1500.             if ( nexus.mount.Call("PlayerCanUseEntityInVehicle", player, trace.Entity, vehicle) ) then
  1501.                 return false;
  1502.             end;
  1503.         end;
  1504.     end;
  1505.    
  1506.     if ( nexus.entity.IsChairEntity(vehicle) and !IsValid( vehicle:GetParent() ) ) then
  1507.         local trace = player:GetEyeTraceNoCursor();
  1508.        
  1509.         if (trace.HitPos:Distance( player:GetShootPos() ) <= 192) then
  1510.             trace = {
  1511.                 start = trace.HitPos,
  1512.                 endpos = trace.HitPos - Vector(0, 0, 1024),
  1513.                 filter = {player, vehicle}
  1514.             };
  1515.            
  1516.             player.exitVehicle = util.TraceLine(trace).HitPos;
  1517.            
  1518.             player:SetMoveType(MOVETYPE_NOCLIP);
  1519.         else
  1520.             return false;
  1521.         end;
  1522.     end;
  1523.    
  1524.     return true;
  1525. end;
  1526.  
  1527. -- Called when a player leaves a vehicle.
  1528. function NEXUS:PlayerLeaveVehicle(player, vehicle)
  1529.     timer.Simple(FrameTime() * 0.5, function()
  1530.         if ( IsValid(player) and !player:InVehicle() ) then
  1531.             if ( IsValid(vehicle) ) then
  1532.                 if ( nexus.entity.IsChairEntity(vehicle) ) then
  1533.                     local position = player.exitVehicle or vehicle:GetPos();
  1534.                     local targetPosition = nexus.player.GetSafePosition(player, position, vehicle);
  1535.                    
  1536.                     if (targetPosition) then
  1537.                         player:SetMoveType(MOVETYPE_NOCLIP);
  1538.                         player:SetPos(targetPosition);
  1539.                     end;
  1540.                    
  1541.                     player:SetMoveType(MOVETYPE_WALK);
  1542.                    
  1543.                     player.exitVehicle = nil;
  1544.                 end;
  1545.             end;
  1546.         end;
  1547.     end);
  1548. end;
  1549.  
  1550. -- Called when a player enters a vehicle.
  1551. function NEXUS:PlayerEnteredVehicle(player, vehicle, class)
  1552.     timer.Simple(FrameTime() * 0.5, function()
  1553.         if ( IsValid(player) ) then
  1554.             local model = player:GetModel();
  1555.             local class = nexus.animation.GetModelClass(model);
  1556.            
  1557.             if ( IsValid(vehicle) and !string.find(model, "/player/") ) then
  1558.                 if (class == "maleHuman" or class == "femaleHuman") then
  1559.                     if ( nexus.entity.IsChairEntity(vehicle) ) then
  1560.                         player:SetLocalPos( Vector(16.5438, -0.1642, -20.5493) );
  1561.                     else
  1562.                         player:SetLocalPos( Vector(30.1880, 4.2020, -6.6476) );
  1563.                     end;
  1564.                 end;
  1565.             end;
  1566.            
  1567.             player:SetCollisionGroup(COLLISION_GROUP_PLAYER);
  1568.         end;
  1569.     end);
  1570. end;
  1571.  
  1572. -- Called when a player attempts to change class.
  1573. function NEXUS:PlayerCanChangeClass(player, class)
  1574.     local curTime = CurTime();
  1575.    
  1576.     if (player.nextChangeClass and curTime < player.nextChangeClass) then
  1577.         nexus.player.Notify(player, "You cannot change class for another "..math.ceil(player.nextChangeClass - curTime).." second(s)!");
  1578.        
  1579.         return false;
  1580.     else
  1581.         return true;
  1582.     end;
  1583. end;
  1584.  
  1585. -- Called when a player attempts to earn generator cash.
  1586. function NEXUS:PlayerCanEarnGeneratorCash(player, info, cash)
  1587.     return true;
  1588. end;
  1589.  
  1590. -- Called when a player earns generator cash.
  1591. function NEXUS:PlayerEarnGeneratorCash(player, info, cash) end;
  1592.  
  1593. -- Called when a player attempts to earn wages cash.
  1594. function NEXUS:PlayerCanEarnWagesCash(player, cash)
  1595.     return true;
  1596. end;
  1597.  
  1598. -- Called when a player is given wages cash.
  1599. function NEXUS:PlayerGiveWagesCash(player, cash, wagesName)
  1600.     return true;
  1601. end;
  1602.  
  1603. -- Called when a player earns wages cash.
  1604. function NEXUS:PlayerEarnWagesCash(player, cash) end;
  1605.  
  1606. -- Called when Nexus has loaded all of the entities.
  1607. function NEXUS:NexusInitPostEntity() end;
  1608.  
  1609. -- Called when the map has loaded all the entities.
  1610. function NEXUS:InitPostEntity()
  1611.     for k, v in ipairs( ents.GetAll() ) do
  1612.         if ( IsValid(v) and v:GetModel() ) then
  1613.             nexus.entity.SetMapEntity(v, true);
  1614.             nexus.entity.SetStartAngles( v, v:GetAngles() );
  1615.             nexus.entity.SetStartPosition( v, v:GetPos() );
  1616.            
  1617.             if ( nexus.entity.SetChairAnimations(v) ) then
  1618.                 v:SetCollisionGroup(COLLISION_GROUP_WEAPON);
  1619.                
  1620.                 local physicsObject = v:GetPhysicsObject();
  1621.                
  1622.                 if ( IsValid(physicsObject) ) then
  1623.                     physicsObject:EnableMotion(false);
  1624.                 end;
  1625.             end;
  1626.         end;
  1627.     end;
  1628.    
  1629.     nexus.entity.RegisterSharedVars(GetWorldEntity(), self.GlobalSharedVars);
  1630.         NEXUS:SetSharedVar("sh_NoMySQL", self.NoMySQL);
  1631.     nexus.mount.Call("NexusInitPostEntity");
  1632.    
  1633.     NEXUS_TICK = true;
  1634. end;
  1635.  
  1636. -- Called when a player attempts to say something in-character.
  1637. function NEXUS:PlayerCanSayIC(player, text)
  1638.     if ( ( !player:Alive() or player:IsRagdolled(RAGDOLL_FALLENOVER) ) and !nexus.player.GetDeathCode(player, true) ) then
  1639.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  1640.        
  1641.         return false;
  1642.     else
  1643.         return true;
  1644.     end;
  1645. end;
  1646.  
  1647. -- Called when a player attempts to say something out-of-character.
  1648. function NEXUS:PlayerCanSayOOC(player, text) return true; end;
  1649.  
  1650. -- Called when a player attempts to say something locally out-of-character.
  1651. function NEXUS:PlayerCanSayLOOC(player, text) return true; end;
  1652.  
  1653. -- Called when attempts to use a command.
  1654. function NEXUS:PlayerCanUseCommand(player, commandTable, arguments) return true; end;
  1655.  
  1656. -- Called when a player says something.
  1657. function NEXUS:PlayerSay(player, text, public)
  1658.     text = string.Replace(text, " ' ", "'");
  1659.     text = string.Replace(text, " : ", ":");
  1660.    
  1661.     local prefix = nexus.config.Get("command_prefix"):Get();
  1662.     local curTime = CurTime();
  1663.    
  1664.     if (string.sub(text, 1, 2) == "//") then
  1665.         text = string.Trim( string.sub(text, 3) );
  1666.        
  1667.         if (text != "") then
  1668.             if ( nexus.mount.Call("PlayerCanSayOOC", player, text) ) then
  1669.                 if (!player.nextTalkOOC or curTime > player.nextTalkOOC) then
  1670.                     self:Log("[OOC] "..player:Name()..": "..text);
  1671.                    
  1672.                     nexus.chatBox.Add(nil, player, "ooc", text);
  1673.                    
  1674.                     player.nextTalkOOC = curTime + nexus.config.Get("ooc_interval"):Get();
  1675.                 else
  1676.                     nexus.player.Notify(player, "You cannot cannot talk out-of-character for another "..math.ceil( player.nextTalkOOC - CurTime() ).." second(s)!");
  1677.                    
  1678.                     return "";
  1679.                 end;
  1680.             end;
  1681.         end;
  1682.     elseif (string.sub(text, 1, 3) == ".//" or string.sub(text, 1, 2) == "[[") then
  1683.         if (string.sub(text, 1, 3) == ".//") then
  1684.             text = string.Trim( string.sub(text, 4) );
  1685.         else
  1686.             text = string.Trim( string.sub(text, 3) );
  1687.         end;
  1688.        
  1689.         if (text != "") then
  1690.             if ( nexus.mount.Call("PlayerCanSayLOOC", player, text) ) then
  1691.                 nexus.chatBox.AddInRadius( player, "looc", text, player:GetPos(), nexus.config.Get("talk_radius"):Get() );
  1692.             end;
  1693.         end;
  1694.     elseif (string.sub(text, 1, 1) == prefix) then
  1695.         local prefixLength = string.len(prefix);
  1696.         local arguments = self:ExplodeByTags(text, " ", "\"", "\"", true);
  1697.         local command = string.sub(arguments[1], prefixLength + 1);
  1698.        
  1699.         if (nexus.command.stored[command] and nexus.command.stored[command].arguments < 2
  1700.         and !nexus.command.stored[command].optionalArguments) then
  1701.             text = string.sub(text, string.len(command) + prefixLength + 2);
  1702.            
  1703.             if (text != "") then
  1704.                 arguments = {command, text};
  1705.             else
  1706.                 arguments = {command};
  1707.             end;
  1708.         else
  1709.             arguments[1] = command;
  1710.         end;
  1711.        
  1712.         nexus.command.ConsoleCommand(player, "nx", arguments);
  1713.     elseif ( nexus.mount.Call("PlayerCanSayIC", player, text) ) then
  1714.         nexus.chatBox.AddInRadius( player, "ic", text, player:GetPos(), nexus.config.Get("talk_radius"):Get() );
  1715.        
  1716.         if ( nexus.player.GetDeathCode(player, true) ) then
  1717.             nexus.player.UseDeathCode( player, nil, {text} );
  1718.         end;
  1719.     end;
  1720.    
  1721.     if ( nexus.player.GetDeathCode(player) ) then
  1722.         nexus.player.TakeDeathCode(player);
  1723.     end;
  1724.    
  1725.     return "";
  1726. end;
  1727.  
  1728. -- Called when a player attempts to suicide.
  1729. function NEXUS:CanPlayerSuicide(player) return false; end;
  1730.  
  1731. -- Called when a player attempts to punt an entity with the gravity gun.
  1732. function NEXUS:GravGunPunt(player, entity)
  1733.     return nexus.config.Get("enable_gravgun_punt"):Get();
  1734. end;
  1735.  
  1736. -- Called when a player attempts to pickup an entity with the gravity gun.
  1737. function NEXUS:GravGunPickupAllowed(player, entity)
  1738.     if ( IsValid(entity) ) then
  1739.         if ( !nexus.player.IsAdmin(player) and !nexus.entity.IsInteractable(entity) ) then
  1740.             return false;
  1741.         else
  1742.             return self.BaseClass:GravGunPickupAllowed(player, entity);
  1743.         end;
  1744.     end;
  1745.    
  1746.     return false;
  1747. end;
  1748.  
  1749. -- Called when a player picks up an entity with the gravity gun.
  1750. function NEXUS:GravGunOnPickedUp(player, entity)
  1751.     player.isHoldingEntity = entity;
  1752.     entity.isBeingHeld = player;
  1753. end;
  1754.  
  1755. -- Called when a player drops an entity with the gravity gun.
  1756. function NEXUS:GravGunOnDropped(player, entity)
  1757.     player.isHoldingEntity = nil;
  1758.     entity.isBeingHeld = nil;
  1759. end;
  1760.  
  1761. -- Called when a player attempts to unfreeze an entity.
  1762. function NEXUS:CanPlayerUnfreeze(player, entity, physicsObject)
  1763.     local isAdmin = nexus.player.IsAdmin(player);
  1764.    
  1765.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  1766.         local ownerKey = entity:GetOwnerKey();
  1767.        
  1768.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  1769.             return false;
  1770.         end;
  1771.     end;
  1772.    
  1773.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  1774.         return false;
  1775.     end;
  1776.    
  1777.     if ( entity:IsVehicle() ) then
  1778.         if ( IsValid( entity:GetDriver() ) ) then
  1779.             return false;
  1780.         end;
  1781.     end;
  1782.    
  1783.     return true;
  1784. end;
  1785.  
  1786. -- Called when a player attempts to freeze an entity with the physics gun.
  1787. function NEXUS:OnPhysgunFreeze(weapon, physicsObject, entity, player)
  1788.     local isAdmin = nexus.player.IsAdmin(player);
  1789.    
  1790.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  1791.         local ownerKey = entity:GetOwnerKey();
  1792.        
  1793.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  1794.             return false;
  1795.         end;
  1796.     end;
  1797.    
  1798.     if ( !isAdmin and nexus.entity.IsChairEntity(entity) ) then
  1799.         local entities = ents.FindInSphere(entity:GetPos(), 64);
  1800.        
  1801.         for k, v in ipairs(entities) do
  1802.             if ( nexus.entity.IsDoor(v) ) then
  1803.                 return false;
  1804.             end;
  1805.         end;
  1806.     end;
  1807.    
  1808.     if ( entity:GetPhysicsObject():IsPenetrating() ) then
  1809.         return false;
  1810.     end;
  1811.    
  1812.     if (!isAdmin and entity.PhysgunDisabled) then
  1813.         return false;
  1814.     end;
  1815.    
  1816.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  1817.         return false;
  1818.     else
  1819.         return self.BaseClass:OnPhysgunFreeze(weapon, physicsObject, entity, player);
  1820.     end;
  1821. end;
  1822.  
  1823. -- Called when a player attempts to pickup an entity with the physics gun.
  1824. function NEXUS:PhysgunPickup(player, entity)
  1825.     local canPickup = nil;
  1826.     local isAdmin = nexus.player.IsAdmin(player);
  1827.    
  1828.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  1829.         return false;
  1830.     end;
  1831.    
  1832.     if ( !isAdmin and nexus.entity.IsPlayerRagdoll(entity) ) then
  1833.         return false;
  1834.     end;
  1835.    
  1836.     if (!isAdmin and entity:GetClass() == "prop_ragdoll") then
  1837.         local ownerKey = entity:GetOwnerKey();
  1838.        
  1839.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  1840.             return false;
  1841.         end;
  1842.     end;
  1843.    
  1844.     if (!isAdmin) then
  1845.         canPickup = self.BaseClass:PhysgunPickup(player, entity);
  1846.     else
  1847.         canPickup = true;
  1848.     end;
  1849.    
  1850.     if (nexus.entity.IsChairEntity(entity) and !isAdmin) then
  1851.         local entities = ents.FindInSphere(entity:GetPos(), 256);
  1852.        
  1853.         for k, v in ipairs(entities) do
  1854.             if ( nexus.entity.IsDoor(v) ) then
  1855.                 return false;
  1856.             end;
  1857.         end;
  1858.     end;
  1859.    
  1860.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  1861.         local ownerKey = entity:GetOwnerKey();
  1862.        
  1863.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  1864.             canPickup = false;
  1865.         end;
  1866.     end;
  1867.    
  1868.     if ( entity:IsPlayer() and entity:InVehicle() ) then
  1869.         canPickup = false;
  1870.     end;
  1871.    
  1872.     if (canPickup) then
  1873.         player.isHoldingEntity = entity;
  1874.         entity.isBeingHeld = player;
  1875.        
  1876.         if ( !entity:IsPlayer() ) then
  1877.             if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  1878.                 entity.lastCollisionGroup = entity:GetCollisionGroup();
  1879.                 entity:SetCollisionGroup(COLLISION_GROUP_WEAPON);
  1880.                 entity.damageImmunity = CurTime() + 60;
  1881.             end;
  1882.         else
  1883.             entity.moveType = entity:GetMoveType();
  1884.             entity:SetMoveType(MOVETYPE_NOCLIP);
  1885.         end;
  1886.        
  1887.         return true;
  1888.     else
  1889.         return false;
  1890.     end;
  1891. end;
  1892.  
  1893. -- Called when a player attempts to drop an entity with the physics gun.
  1894. function NEXUS:PhysgunDrop(player, entity)
  1895.     if ( !entity:IsPlayer() ) then
  1896.         if (entity.lastCollisionGroup) then
  1897.             nexus.entity.ReturnCollisionGroup(entity, entity.lastCollisionGroup);
  1898.         end;
  1899.     else
  1900.         entity:SetMoveType(entity.moveType or MOVETYPE_WALK);
  1901.         entity.moveType = nil;
  1902.     end;
  1903.    
  1904.     player.isHoldingEntity = nil;
  1905.     entity.isBeingHeld = nil;
  1906. end;
  1907.  
  1908. -- Called when a player attempts to spawn an NPC.
  1909. function NEXUS:PlayerSpawnNPC(player, model)
  1910.     if ( !nexus.player.HasFlags(player, "n") ) then
  1911.         return false;
  1912.     end;
  1913.    
  1914.     if ( !player:Alive() or player:IsRagdolled() ) then
  1915.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  1916.        
  1917.         return false;
  1918.     end;
  1919.    
  1920.     if ( !nexus.player.IsAdmin(player) ) then
  1921.         return false;
  1922.     else
  1923.         return true;
  1924.     end;
  1925. end;
  1926.  
  1927. -- Called when an NPC has been killed.
  1928. function NEXUS:OnNPCKilled(entity, attacker, inflictor) end;
  1929.  
  1930. -- Called to get whether an entity is being held.
  1931. function NEXUS:GetEntityBeingHeld(entity)
  1932.     return entity.isBeingHeld or entity:IsPlayerHolding();
  1933. end;
  1934.  
  1935. -- Called when an entity is removed.
  1936. function NEXUS:EntityRemoved(entity)
  1937.     if ( !self:IsShuttingDown() ) then
  1938.         if ( IsValid(entity) ) then
  1939.             if (entity.giveRefund) then
  1940.                 if ( CurTime() <= entity.giveRefund[1] ) then
  1941.                     if ( IsValid( entity.giveRefund[2] ) ) then
  1942.                         nexus.player.GiveCash(entity.giveRefund[2], entity.giveRefund[3], "Prop Refund");
  1943.                     end;
  1944.                 end;
  1945.             end;
  1946.            
  1947.             nexus.player.GetAllProperty()[ entity:EntIndex() ] = nil;
  1948.         end;
  1949.        
  1950.         nexus.entity.ClearProperty(entity);
  1951.     end;
  1952. end;
  1953.  
  1954. -- Called when an entity's menu option should be handled.
  1955. function NEXUS:EntityHandleMenuOption(player, entity, option, arguments)
  1956.     local class = entity:GetClass();
  1957.     local generator = nexus.generator.Get(class);
  1958.    
  1959.     if ( class == "nx_item" and (arguments == "nx_itemTake" or arguments == "nx_itemUse") ) then
  1960.         if ( nexus.entity.BelongsToAnotherCharacter(player, entity) ) then
  1961.             nexus.player.Notify(player, "You cannot pick up items you dropped on another character!");
  1962.            
  1963.             return;
  1964.         end;
  1965.        
  1966.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  1967.        
  1968.         local itemTable = entity.item;
  1969.         local quickUse = (arguments == "nx_itemUse");
  1970.        
  1971.         if (itemTable) then
  1972.             local didPickupItem = true;
  1973.             local canPickup = ( !itemTable.CanPickup or itemTable:CanPickup(player, quickUse, entity) );
  1974.            
  1975.             if (canPickup != false) then
  1976.                 if (canPickup and type(canPickup) == "string") then
  1977.                     local newItemTable = nexus.item.Get(canPickup);
  1978.                    
  1979.                     if (newItemTable) then
  1980.                         itemTable = newItemTable;
  1981.                     end;
  1982.                 end;
  1983.                
  1984.                 player:SetItemEntity(entity);
  1985.                
  1986.                 if (quickUse) then
  1987.                     player:UpdateInventory(itemTable.uniqueID, 1, true, true);
  1988.                    
  1989.                     if ( !nexus.player.RunNexusCommand(player, "InvAction", itemTable.uniqueID, "use") ) then
  1990.                         player:UpdateInventory(itemTable.uniqueID, -1, true, true);
  1991.                         didPickupItem = false;
  1992.                     else
  1993.                         player:FakePickup(entity);
  1994.                     end;
  1995.                 else
  1996.                     local success, fault = player:UpdateInventory(itemTable.uniqueID, 1);
  1997.                    
  1998.                     if (!success) then
  1999.                         nexus.player.Notify(player, fault);
  2000.                         didPickupItem = false;
  2001.                     else
  2002.                         player:FakePickup(entity);
  2003.                     end;
  2004.                 end;
  2005.                
  2006.                 if (didPickupItem) then
  2007.                     if (!itemTable.OnPickup or itemTable:OnPickup(player, quickUse, entity) != false) then
  2008.                         entity:Remove();
  2009.                     end;
  2010.                 end;
  2011.                
  2012.                 player:SetItemEntity(nil);
  2013.             end;
  2014.         end;
  2015.     elseif (class == "nx_item" and arguments == "nx_itemAmmo") then
  2016.         local itemTable = entity.item;
  2017.        
  2018.         if ( itemTable and nexus.item.IsWeapon(itemTable) ) then
  2019.             if ( itemTable:HasSecondaryClip() or itemTable:HasPrimaryClip() ) then
  2020.                 if (entity.data.sClip) then
  2021.                     player:GiveAmmo(entity.data.sClip, itemTable.secondaryAmmoClass);
  2022.                 end;
  2023.                
  2024.                 if (entity.data.pClip) then
  2025.                     player:GiveAmmo(entity.data.pClip, itemTable.primaryAmmoClass);
  2026.                 end;
  2027.                
  2028.                 entity.data.sClip = nil;
  2029.                 entity.data.pClip = nil;
  2030.                
  2031.                 player:FakePickup(entity);
  2032.             end;
  2033.         end;
  2034.     elseif (class == "nx_shipment" and arguments == "nx_shipmentOpen") then
  2035.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  2036.         player:FakePickup(entity);
  2037.        
  2038.         nexus.player.OpenStorage( player, {
  2039.             name = "Shipment",
  2040.             weight = entity.weight,
  2041.             entity = entity,
  2042.             distance = 192,
  2043.             inventory = entity.inventory,
  2044.             OnClose = function(player, storageTable, entity)
  2045.                 if ( IsValid(entity) ) then
  2046.                     if (!entity.inventory or table.Count(entity.inventory) == 0) then
  2047.                         entity:Explode(entity:BoundingRadius() * 2);
  2048.                         entity:Remove();
  2049.                     end;
  2050.                 end;
  2051.             end,
  2052.             CanGive = function(player, storageTable, itemTable)
  2053.                 return false;
  2054.             end
  2055.         } );
  2056.     elseif (class == "nx_cash" and arguments == "nx_cashTake") then
  2057.         if ( nexus.entity.BelongsToAnotherCharacter(player, entity) ) then
  2058.             nexus.player.Notify(player, "You cannot pick up cash you dropped on another character!");
  2059.            
  2060.             return;
  2061.         end;
  2062.        
  2063.         nexus.player.GiveCash( player, entity:GetSharedVar("sh_Amount"), nexus.schema.GetOption("name_cash") );
  2064.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  2065.         player:FakePickup(entity);
  2066.        
  2067.         entity:Remove();
  2068.     elseif (generator and arguments == "nx_generatorSupply") then
  2069.         if (entity:GetPower() < generator.power) then
  2070.             if ( !entity.CanSupply or entity:CanSupply(player) ) then
  2071.                 nexus.mount.Call("PlayerChargeGenerator", player, entity, generator);
  2072.                 entity:SetSharedVar("sh_Power", generator.power);
  2073.                 player:FakePickup(entity);
  2074.                
  2075.                 if (entity.OnSupplied) then
  2076.                     entity:OnSupplied(player);
  2077.                 end;
  2078.                
  2079.                 entity:Explode();
  2080.             end;
  2081.         end;
  2082.     end;
  2083. end;
  2084.  
  2085. -- Called when a player has spawned a prop.
  2086. function NEXUS:PlayerSpawnedProp(player, model, entity)
  2087.     if ( IsValid(entity) ) then
  2088.         local scalePropCost = nexus.config.Get("scale_prop_cost"):Get();
  2089.        
  2090.         if (scalePropCost > 0) then
  2091.             local cost = math.ceil( math.max( (entity:BoundingRadius() / 2) * scalePropCost, 1 ) );
  2092.             local info = {cost = cost, name = "Prop"};
  2093.            
  2094.             nexus.mount.Call("PlayerAdjustPropCostInfo", player, entity, info);
  2095.            
  2096.             if ( nexus.player.CanAfford(player, info.cost) ) then
  2097.                 nexus.player.GiveCash(player, -info.cost, info.name);
  2098.                
  2099.                 entity.giveRefund = {CurTime() + 10, player, info.cost};
  2100.             else
  2101.                 nexus.player.Notify(player, "You need another "..FORMAT_CASH(info.cost - nexus.player.GetCash(player), nil, true).."!");
  2102.                
  2103.                 entity:Remove();
  2104.             end;
  2105.         end;
  2106.        
  2107.         if ( IsValid(entity) ) then
  2108.             entity:SetOwnerKey( player:QueryCharacter("key") );
  2109.            
  2110.             self.BaseClass:PlayerSpawnedProp(player, model, entity);
  2111.            
  2112.             if ( IsValid(entity) ) then
  2113.                 self:PrintDebug(player:Name().." spawned "..tostring(model).." ("..tostring(entity)..").");
  2114.                
  2115.                 if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  2116.                     entity.damageImmunity = CurTime() + 60;
  2117.                 end;
  2118.             end;
  2119.         end;
  2120.     end;
  2121. end;
  2122.  
  2123. -- Called when a player attempts to spawn a prop.
  2124. function NEXUS:PlayerSpawnProp(player, model)
  2125.     if ( !nexus.player.HasFlags(player, "e") ) then
  2126.         return false;
  2127.     end;
  2128.    
  2129.     if ( !player:Alive() or player:IsRagdolled() ) then
  2130.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  2131.        
  2132.         return false;
  2133.     end;
  2134.    
  2135.     if ( nexus.player.IsAdmin(player) ) then
  2136.         return true;
  2137.     end;
  2138.    
  2139.     return self.BaseClass:PlayerSpawnProp(player, model);
  2140. end;
  2141.  
  2142. -- Called when a player attempts to spawn a ragdoll.
  2143. function NEXUS:PlayerSpawnRagdoll(player, model)
  2144.     if ( !nexus.player.HasFlags(player, "r") ) then return false; end;
  2145.    
  2146.     if ( !player:Alive() or player:IsRagdolled() ) then
  2147.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  2148.        
  2149.         return false;
  2150.     end;
  2151.    
  2152.     if ( !nexus.player.IsAdmin(player) ) then
  2153.         return false;
  2154.     else
  2155.         return true;
  2156.     end;
  2157. end;
  2158.  
  2159. -- Called when a player attempts to spawn an effect.
  2160. function NEXUS:PlayerSpawnEffect(player, model)
  2161.     if ( !player:Alive() or player:IsRagdolled() ) then
  2162.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  2163.        
  2164.         return false;
  2165.     end;
  2166.    
  2167.     if ( !nexus.player.IsAdmin(player) ) then
  2168.         return false;
  2169.     else
  2170.         return true;
  2171.     end;
  2172. end;
  2173.  
  2174. -- Called when a player attempts to spawn a vehicle.
  2175. function NEXUS:PlayerSpawnVehicle(player, model)
  2176.     if ( !string.find(model, "chair") and !string.find(model, "seat") ) then
  2177.         if ( !nexus.player.HasFlags(player, "C") ) then
  2178.             return false;
  2179.         end;
  2180.     elseif ( !nexus.player.HasFlags(player, "c") ) then
  2181.         return false;
  2182.     end;
  2183.    
  2184.     if ( !player:Alive() or player:IsRagdolled() ) then
  2185.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  2186.        
  2187.         return false;
  2188.     end;
  2189.    
  2190.     if ( nexus.player.IsAdmin(player) ) then
  2191.         return true;
  2192.     end;
  2193.    
  2194.     return self.BaseClass:PlayerSpawnVehicle(player, model);
  2195. end;
  2196.  
  2197. -- Called when a player attempts to use a tool.
  2198. function NEXUS:CanTool(player, trace, tool)
  2199.     local isAdmin = nexus.player.IsAdmin(player);
  2200.    
  2201.     if ( IsValid(trace.Entity) ) then
  2202.         local isPropProtectionEnabled = nexus.config.Get("enable_prop_protection"):Get();
  2203.         local characterKey = player:QueryCharacter("key");
  2204.        
  2205.         if ( !isAdmin and !nexus.entity.IsInteractable(trace.Entity) ) then
  2206.             return false;
  2207.         end;
  2208.        
  2209.         if ( !isAdmin and nexus.entity.IsPlayerRagdoll(trace.Entity) ) then
  2210.             return false;
  2211.         end;
  2212.        
  2213.         if (isPropProtectionEnabled and !isAdmin) then
  2214.             local ownerKey = trace.Entity:GetOwnerKey();
  2215.            
  2216.             if (ownerKey and characterKey != ownerKey) then
  2217.                 return false;
  2218.             end;
  2219.         end;
  2220.        
  2221.         if (!isAdmin) then
  2222.             if (tool == "nail") then
  2223.                 local newTrace = {};
  2224.                
  2225.                 newTrace.start = trace.HitPos;
  2226.                 newTrace.endpos = trace.HitPos + player:GetAimVector() * 16;
  2227.                 newTrace.filter = {player, trace.Entity};
  2228.                
  2229.                 newTrace = util.TraceLine(newTrace);
  2230.                
  2231.                 if ( IsValid(newTrace.Entity) ) then
  2232.                     if ( !nexus.entity.IsInteractable(newTrace.Entity) or nexus.entity.IsPlayerRagdoll(newTrace.Entity) ) then
  2233.                         return false;
  2234.                     end;
  2235.                    
  2236.                     if (isPropProtectionEnabled) then
  2237.                         local ownerKey = newTrace.Entity:GetOwnerKey();
  2238.                        
  2239.                         if (ownerKey and characterKey != ownerKey) then
  2240.                             return false;
  2241.                         end;
  2242.                     end;
  2243.                 end;
  2244.             elseif ( tool == "remover" and player:KeyDown(IN_ATTACK2) and !player:KeyDownLast(IN_ATTACK2) ) then
  2245.                 if ( !trace.Entity:IsMapEntity() ) then
  2246.                     local entities = constraint.GetAllConstrainedEntities(trace.Entity);
  2247.                    
  2248.                     for k, v in pairs(entities) do
  2249.                         if ( v:IsMapEntity() or nexus.entity.IsPlayerRagdoll(v) ) then
  2250.                             return false;
  2251.                         end;
  2252.                        
  2253.                         if (isPropProtectionEnabled) then
  2254.                             local ownerKey = v:GetOwnerKey();
  2255.                            
  2256.                             if (ownerKey and characterKey != ownerKey) then
  2257.                                 return false;
  2258.                             end;
  2259.                         end;
  2260.                     end
  2261.                 else
  2262.                     return false;
  2263.                 end;
  2264.             end
  2265.         end;
  2266.     end;
  2267.    
  2268.     self:PrintDebug(player:Name().." used the "..tostring(tool).." tool.");
  2269.    
  2270.     if (!isAdmin) then
  2271.         return self.BaseClass:CanTool(player, trace, tool);
  2272.     else
  2273.         return true;
  2274.     end;
  2275. end;
  2276.  
  2277. -- Called when a player attempts to NoClip.
  2278. function NEXUS:PlayerNoClip(player)
  2279.     if ( player:IsRagdolled() ) then
  2280.         return false;
  2281.     elseif ( player:IsSuperAdmin() ) then
  2282.         return true;
  2283.     else
  2284.         return false;
  2285.     end;
  2286. end;
  2287.  
  2288. -- Called when a player's character has initialized.
  2289. function NEXUS:PlayerCharacterInitialized(player)
  2290.     umsg.Start("nx_InventoryClear", player);
  2291.     umsg.End();
  2292.    
  2293.     umsg.Start("nx_AttributesClear", player);
  2294.     umsg.End();
  2295.    
  2296.     if ( !nexus.class.Get( player:Team() ) ) then
  2297.         nexus.class.AssignToDefault(player);
  2298.     end;
  2299.    
  2300.     for k, v in pairs( nexus.player.GetInventory(player) ) do
  2301.         local itemTable = nexus.item.Get(k);
  2302.        
  2303.         if (itemTable) then
  2304.             player:UpdateInventory(itemTable.uniqueID, 0, true);
  2305.         end;
  2306.     end;
  2307.        
  2308.     player.attributeProgress = {};
  2309.     player.attributeProgressTime = 0;
  2310.    
  2311.     for k, v in pairs( nexus.attribute.GetAll() ) do
  2312.         player:UpdateAttribute(k);
  2313.     end;
  2314.    
  2315.     for k, v in pairs( player:QueryCharacter("attributes") ) do
  2316.         player.attributeProgress[k] = math.floor(v.progress);
  2317.     end;
  2318.    
  2319.     local startHintsDelay = 4;
  2320.     local starterHintsTable = {
  2321.         "Directory",
  2322.         "Give Name",
  2323.         "Target Recognises",
  2324.         "Raise Weapon"
  2325.     };
  2326.    
  2327.     for k, v in ipairs(starterHintsTable) do
  2328.         local hintTable = nexus.hint.Find(v);
  2329.        
  2330.         if ( hintTable and !player:GetData("hint"..k) ) then
  2331.             if (!hintTable.Callback or hintTable.Callback(player) != false) then
  2332.                 timer.Simple(startHintsDelay, function()
  2333.                     if ( IsValid(player) ) then
  2334.                         nexus.hint.Send(player, hintTable.text, 30);
  2335.                         player:SetData("hint"..k, true);
  2336.                     end;
  2337.                 end);
  2338.                
  2339.                 startHintsDelay = startHintsDelay + 30;
  2340.             end;
  2341.         end;
  2342.     end;
  2343.    
  2344.     if (startHintsDelay > 4) then
  2345.         player.isViewingStarterHints = true;
  2346.        
  2347.         timer.Simple(startHintsDelay, function()
  2348.             if ( IsValid(player) ) then
  2349.                 player.isViewingStarterHints = false;
  2350.             end;
  2351.         end);
  2352.     end;
  2353. end;
  2354.  
  2355. -- Called when a player has used their death code.
  2356. function NEXUS:PlayerDeathCodeUsed(player, commandTable, arguments) end;
  2357.  
  2358. -- Called when a player has created a character.
  2359. function NEXUS:PlayerCharacterCreated(player, character) end;
  2360.  
  2361. -- Called when a player's character has unloaded.
  2362. function NEXUS:PlayerCharacterUnloaded(player)
  2363.     nexus.player.SetupRemovePropertyDelays(player);
  2364.     nexus.player.DisableProperty(player);
  2365.     nexus.player.SetRagdollState(player, RAGDOLL_RESET);
  2366.     nexus.player.CloseStorage(player, true)
  2367.    
  2368.     player:SetTeam(TEAM_UNASSIGNED);
  2369. end;
  2370.  
  2371. -- Called when a player's character has loaded.
  2372. function NEXUS:PlayerCharacterLoaded(player)
  2373.     player:SetSharedVar( "sh_InventoryWeight", nexus.config.Get("default_inv_weight"):Get() );
  2374.    
  2375.     player.characterLoadedTime = CurTime();
  2376.     player.attributeBoosts = {};
  2377.     player.crouchedSpeed = nexus.config.Get("crouched_speed"):Get();
  2378.     player.ragdollTable = {};
  2379.     player.spawnWeapons = {};
  2380.     player.initialized = true;
  2381.     player.firstSpawn = true;
  2382.     player.lightSpawn = false;
  2383.     player.changeClass = false;
  2384.     player.spawnAmmo = {};
  2385.     player.jumpPower = nexus.config.Get("jump_power"):Get();
  2386.     player.walkSpeed = nexus.config.Get("walk_speed"):Get();
  2387.     player.runSpeed = nexus.config.Get("run_speed"):Get();
  2388.    
  2389.     hook.Call( "PlayerRestoreCharacterData", NEXUS, player, player:QueryCharacter("data") );
  2390.     hook.Call( "PlayerRestoreTempData", NEXUS, player, player:CreateTempData() );
  2391.    
  2392.     nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_CLOSE);
  2393.    
  2394.     nexus.mount.Call("PlayerCharacterInitialized", player);
  2395.    
  2396.     nexus.player.RestoreRecognisedNames(player);
  2397.     nexus.player.ReturnProperty(player);
  2398.     nexus.player.SetInitialized(player, true);
  2399.    
  2400.     player.firstSpawn = false;
  2401.    
  2402.     local charactersTable = nexus.config.Get("mysql_characters_table"):Get();
  2403.     local schemaFolder = self:GetSchemaFolder();
  2404.     local characterID = player:QueryCharacter("characterID");
  2405.     local onNextLoad = player:QueryCharacter("onNextLoad");
  2406.     local steamID = player:SteamID();
  2407.     local query = "UPDATE "..charactersTable.." SET _OnNextLoad = \"\" WHERE";
  2408.    
  2409.     if (onNextLoad != "") then
  2410.         tmysql.query(query.." _Schema = \""..schemaFolder.."\" AND _SteamID = \""..steamID.."\" AND _CharacterID = "..characterID);
  2411.        
  2412.         player:SetCharacterData("onNextLoad", "", true);
  2413.        
  2414.         CHARACTER = player:GetCharacter();
  2415.             PLAYER = player;
  2416.                 RunString(onNextLoad);
  2417.             PLAYER = nil;
  2418.         CHARACTER = nil;
  2419.     end;
  2420. end;
  2421.  
  2422. -- Called when a player's property should be restored.
  2423. function NEXUS:PlayerReturnProperty(player) end;
  2424.  
  2425. -- Called when config has initialized for a player.
  2426. function NEXUS:PlayerConfigInitialized(player)
  2427.     nexus.mount.Call("PlayerSendDataStreamInfo", player);
  2428.    
  2429.     if ( player:IsBot() ) then
  2430.         nexus.mount.Call("PlayerDataStreamInfoSent", player);
  2431.     else
  2432.         timer.Simple(FrameTime() * 32, function()
  2433.             if ( IsValid(player) ) then
  2434.                 umsg.Start("nx_DataStreaming", player);
  2435.                 umsg.End();
  2436.             end;
  2437.         end);
  2438.     end;
  2439. end;
  2440.  
  2441. -- Called when a player initially spawns.
  2442. function NEXUS:PlayerInitialSpawn(player)
  2443.     player.hasSpawned = true;
  2444.     player.characters = {};
  2445.     player.sharedVars = {};
  2446.    
  2447.     if ( IsValid(player) ) then
  2448.         player:KillSilent();
  2449.     end;
  2450.    
  2451.     if ( player:IsBot() ) then
  2452.         nexus.config.Send(player);
  2453.     end;
  2454.    
  2455.     if ( !player:IsKicked() ) then
  2456.         nexus.chatBox.Add(nil, nil, "connect", player:SteamName().." has connected to the server.");
  2457.        
  2458.         self:PrintDebug(player:SteamName().." ("..player:SteamID().."|"..player:IPAddress()..") has connected to the server.");
  2459.     end;
  2460. end;
  2461.  
  2462. -- Called each frame that a player is dead.
  2463. function NEXUS:PlayerDeathThink(player)
  2464.     local action = nexus.player.GetAction(player);
  2465.    
  2466.     if ( !player:HasInitialized() or player:GetCharacterData("banned") ) then
  2467.         return true;
  2468.     end;
  2469.    
  2470.     if (action == "spawn") then
  2471.         return true;
  2472.     else
  2473.         player:Spawn();
  2474.     end;
  2475. end;
  2476.  
  2477. -- Called when a player has used their radio.
  2478. function NEXUS:PlayerRadioUsed(player, text, listeners, eavesdroppers) end;
  2479.  
  2480. -- Called when a player's drop weapon info should be adjusted.
  2481. function NEXUS:PlayerAdjustDropWeaponInfo(player, info)
  2482.     return true;
  2483. end;
  2484.  
  2485. -- Called when a player's character creation info should be adjusted.
  2486. function NEXUS:PlayerAdjustCharacterCreationInfo(player, info, data) end;
  2487.  
  2488. -- Called when a player's earn generator info should be adjusted.
  2489. function NEXUS:PlayerAdjustEarnGeneratorInfo(player, info) end;
  2490.  
  2491. -- Called when a player's order item should be adjusted.
  2492. function NEXUS:PlayerAdjustOrderItemTable(player, itemTable) end;
  2493.  
  2494. -- Called when a player's next punch info should be adjusted.
  2495. function NEXUS:PlayerAdjustNextPunchInfo(player, info) end;
  2496.  
  2497. -- Called when a player has an unknown inventory item.
  2498. function NEXUS:PlayerHasUnknownInventoryItem(player, inventory, item, amount) end;
  2499.  
  2500. -- Called when a player uses an unknown item function.
  2501. function NEXUS:PlayerUseUnknownItemFunction(player, itemTable, itemFunction) end;
  2502.  
  2503. -- Called when a player has an unknown attribute.
  2504. function NEXUS:PlayerHasUnknownAttribute(player, attributes, attribute, amount, progress) end;
  2505.  
  2506. -- Called when a player's character table should be adjusted.
  2507. function NEXUS:PlayerAdjustCharacterTable(player, character)
  2508.     if ( nexus.faction.stored[character.faction] ) then
  2509.         if ( nexus.faction.stored[character.faction].whitelist
  2510.         and !nexus.player.IsWhitelisted(player, character.faction) ) then
  2511.             character.data["banned"] = true;
  2512.         end;
  2513.     else
  2514.         return true;
  2515.     end;
  2516. end;
  2517.  
  2518. -- Called when a player's character screen info should be adjusted.
  2519. function NEXUS:PlayerAdjustCharacterScreenInfo(player, character, info) end;
  2520.  
  2521. -- Called when a player's prop cost info should be adjusted.
  2522. function NEXUS:PlayerAdjustPropCostInfo(player, entity, info) end;
  2523.  
  2524. -- Called when a player's death info should be adjusted.
  2525. function NEXUS:PlayerAdjustDeathInfo(player, info) end;
  2526.  
  2527. -- Called when debug info should be adjusted.
  2528. function NEXUS:DebugAdjustInfo(info) end;
  2529.  
  2530. -- Called when chat box info should be adjusted.
  2531. function NEXUS:ChatBoxAdjustInfo(info) end;
  2532.  
  2533. -- Called when a chat box message has been added.
  2534. function NEXUS:ChatBoxMessageAdded(info) end;
  2535.  
  2536. -- Called when a player's radio text should be adjusted.
  2537. function NEXUS:PlayerAdjustRadioInfo(player, info) end;
  2538.  
  2539. -- Called when a player should gain a frag.
  2540. function NEXUS:PlayerCanGainFrag(player, victim) return true; end;
  2541.  
  2542. -- Called when a player's model should be set.
  2543. function NEXUS:PlayerSetModel(player)
  2544.     nexus.player.SetDefaultModel(player);
  2545.     nexus.player.SetDefaultSkin(player);
  2546. end;
  2547.  
  2548. -- Called just after a player spawns.
  2549. function NEXUS:PostPlayerSpawn(player, lightSpawn, changeClass, firstSpawn)
  2550.     if (firstSpawn) then
  2551.         local attributeBoosts = player:GetCharacterData("attributeboosts");
  2552.         local health = player:GetCharacterData("health");
  2553.         local armor = player:GetCharacterData("armor");
  2554.        
  2555.         if (health and health > 1) then
  2556.             player:SetHealth(health);
  2557.         end;
  2558.        
  2559.         if (armor and armor > 1) then
  2560.             player:SetArmor(armor);
  2561.         end;
  2562.        
  2563.         if (attributeBoosts) then
  2564.             for k, v in pairs(attributeBoosts) do
  2565.                 for k2, v2 in pairs(v) do
  2566.                     nexus.attributes.Boost(player, k2, k, v2.amount, v2.duration);
  2567.                 end;
  2568.             end;
  2569.         end;
  2570.     else
  2571.         player:SetCharacterData("attributeboosts", nil);
  2572.         player:SetCharacterData("health", nil);
  2573.         player:SetCharacterData("armor", nil);
  2574.     end;
  2575. end;
  2576.  
  2577. -- Called when a player spawns.
  2578. function NEXUS:PlayerSpawn(player)
  2579.     if ( player:HasInitialized() ) then
  2580.         player:ShouldDropWeapon(false);
  2581.        
  2582.         if (!player.lightSpawn) then
  2583.             nexus.player.SetWeaponRaised(player, false);
  2584.             nexus.player.SetRagdollState(player, RAGDOLL_RESET);
  2585.             nexus.player.SetAction(player, false);
  2586.             nexus.player.SetDrunk(player, false);
  2587.            
  2588.             nexus.attributes.ClearBoosts(player);
  2589.            
  2590.             self:PlayerSetModel(player);
  2591.             self:PlayerLoadout(player);
  2592.            
  2593.             if ( player:FlashlightIsOn() ) then
  2594.                 player:Flashlight(false);
  2595.             end;
  2596.            
  2597.             player:SetForcedAnimation(false);
  2598.             player:SetCollisionGroup(COLLISION_GROUP_PLAYER);
  2599.             player:SetMaxHealth(100);
  2600.             player:SetMaxArmor(100);
  2601.             player:SetMaterial("");
  2602.             player:SetMoveType(MOVETYPE_WALK);
  2603.             player:Extinguish();
  2604.             player:UnSpectate();
  2605.             player:GodDisable();
  2606.             player:RunCommand("-duck");
  2607.             player:SetColor(255, 255, 255, 255);
  2608.            
  2609.             player:SetCrouchedWalkSpeed( nexus.config.Get("crouched_speed"):Get() );
  2610.             player:SetWalkSpeed( nexus.config.Get("walk_speed"):Get() );
  2611.             player:SetJumpPower( nexus.config.Get("jump_power"):Get() );
  2612.             player:SetRunSpeed( nexus.config.Get("run_speed"):Get() );
  2613.            
  2614.             if (player.firstSpawn) then
  2615.                 local ammo = player:QueryCharacter("ammo");
  2616.                
  2617.                 for k, v in pairs(ammo) do
  2618.                     if ( !string.find(k, "p_") and !string.find(k, "s_") ) then
  2619.                         player:GiveAmmo(v, k); ammo[k] = nil;
  2620.                     end;
  2621.                 end;
  2622.             else
  2623.                 player:UnLock();
  2624.             end;
  2625.         end;
  2626.        
  2627.         if (player.lightSpawn and player.lightSpawnCallback) then
  2628.             player.lightSpawnCallback(player, true);
  2629.             player.lightSpawnCallback = nil;
  2630.         end;
  2631.        
  2632.         nexus.mount.Call("PostPlayerSpawn", player, player.lightSpawn, player.changeClass, player.firstSpawn);
  2633.        
  2634.         nexus.player.SetRecognises(player, player, RECOGNISE_TOTAL);
  2635.        
  2636.         player.changeClass = false;
  2637.         player.lightSpawn = false;
  2638.     else
  2639.         player:KillSilent();
  2640.     end;
  2641. end;
  2642.  
  2643. -- Called when a player should take damage.
  2644. function NEXUS:PlayerShouldTakeDamage(player, attacker, inflictor, damageInfo)
  2645.     if ( nexus.player.IsNoClipping(player) ) then
  2646.         return false;
  2647.     end;
  2648.    
  2649.     return true;
  2650. end;
  2651.  
  2652. -- Called when a player is attacked by a trace.
  2653. function NEXUS:PlayerTraceAttack(player, damageInfo, direction, trace)
  2654.     player.lastHitGroup = trace.HitGroup;
  2655.    
  2656.     return false;
  2657. end;
  2658.  
  2659. -- Called just before a player dies.
  2660. function NEXUS:DoPlayerDeath(player, attacker, damageInfo)
  2661.     nexus.player.DropWeapons(player, attacker);
  2662.     nexus.player.SetAction(player, false);
  2663.     nexus.player.SetDrunk(player, false);
  2664.    
  2665.     local deathSound = nexus.mount.Call( "PlayerPlayDeathSound", player, nexus.player.GetGender(player) );
  2666.     local decayTime = nexus.config.Get("body_decay_time"):Get();
  2667.  
  2668.     if (decayTime > 0) then
  2669.         nexus.player.SetRagdollState( player, RAGDOLL_KNOCKEDOUT, nil, decayTime, self:ConvertForce(damageInfo:GetDamageForce() * 32) );
  2670.     else
  2671.         nexus.player.SetRagdollState( player, RAGDOLL_KNOCKEDOUT, nil, 600, self:ConvertForce(damageInfo:GetDamageForce() * 32) );
  2672.     end;
  2673.    
  2674.     if ( nexus.mount.Call("PlayerCanDeathClearRecognisedNames", player, attacker, damageInfo) ) then
  2675.         nexus.player.ClearRecognisedNames(player);
  2676.     end;
  2677.    
  2678.     if ( nexus.mount.Call("PlayerCanDeathClearName", player, attacker, damageInfo) ) then
  2679.         nexus.player.ClearName(player);
  2680.     end;
  2681.    
  2682.     if (deathSound) then
  2683.         player:EmitSound("physics/flesh/flesh_impact_hard"..math.random(1, 5)..".wav", 150);
  2684.        
  2685.         timer.Simple(FrameTime() * 25, function()
  2686.             if ( IsValid(player) ) then
  2687.                 player:EmitSound(deathSound);
  2688.             end;
  2689.         end);
  2690.     end;
  2691.    
  2692.     player:SetForcedAnimation(false);
  2693.     player:SetCharacterData("ammo", {}, true);
  2694.     player:StripWeapons();
  2695.     player:Extinguish();
  2696.     player:StripAmmo();
  2697.     player.spawnAmmo = {};
  2698.     player:AddDeaths(1);
  2699.     player:UnLock();
  2700.    
  2701.     if ( IsValid(attacker) and attacker:IsPlayer() ) then
  2702.         if (player != attacker) then
  2703.             if ( nexus.mount.Call("PlayerCanGainFrag", attacker, player) ) then
  2704.                 attacker:AddFrags(1);
  2705.             end;
  2706.         end;
  2707.     end;
  2708. end;
  2709.  
  2710. -- Called when a player dies.
  2711. function NEXUS:PlayerDeath(player, inflictor, attacker, damageInfo)
  2712.     self:CalculateSpawnTime(player, inflictor, attacker, damageInfo);
  2713.    
  2714.     if ( player:GetRagdollEntity() ) then
  2715.         local ragdoll = player:GetRagdollEntity();
  2716.        
  2717.         if (inflictor:GetClass() == "prop_combine_ball") then
  2718.             if (damageInfo) then
  2719.                 nexus.entity.Disintegrate(player:GetRagdollEntity(), 3, damageInfo:GetDamageForce() * 32);
  2720.             else
  2721.                 nexus.entity.Disintegrate(player:GetRagdollEntity(), 3);
  2722.             end;
  2723.         end;
  2724.     end;
  2725.    
  2726.     if ( attacker:IsPlayer() ) then
  2727.         if ( IsValid( attacker:GetActiveWeapon() ) ) then
  2728.             self:PrintDebug(attacker:Name().." killed "..player:Name().." with "..nexus.player.GetWeaponClass(attacker)..".");
  2729.         else
  2730.             self:PrintDebug(attacker:Name().." killed "..player:Name()..".");
  2731.         end;
  2732.     else
  2733.         self:PrintDebug(attacker:GetClass().." killed "..player:Name()..".");
  2734.     end;
  2735. end;
  2736.  
  2737. -- Called when a player's weapons should be given.
  2738. function NEXUS:PlayerLoadout(player)
  2739.     local weapons = nexus.class.Query(player:Team(), "weapons");
  2740.     local ammo = nexus.class.Query(player:Team(), "ammo");
  2741.    
  2742.     player.spawnWeapons = {};
  2743.     player.spawnAmmo = {};
  2744.    
  2745.     if ( nexus.player.HasFlags(player, "t") ) then
  2746.         nexus.player.GiveSpawnWeapon(player, "gmod_tool");
  2747.     end
  2748.    
  2749.     if ( nexus.player.HasFlags(player, "p") ) then
  2750.         nexus.player.GiveSpawnWeapon(player, "weapon_physgun");
  2751.     end
  2752.    
  2753.     nexus.player.GiveSpawnWeapon(player, "weapon_physcannon");
  2754.     nexus.player.GiveSpawnWeapon(player, "nx_hands");
  2755.     nexus.player.GiveSpawnWeapon(player, "nx_keys");
  2756.    
  2757.     if (weapons) then
  2758.         for k, v in ipairs(weapons) do
  2759.             if ( !nexus.player.GiveSpawnItemWeapon(player, v) ) then
  2760.                 player:Give(v);
  2761.             end;
  2762.         end;
  2763.     end;
  2764.    
  2765.     if (ammo) then
  2766.         for k, v in pairs(ammo) do
  2767.             nexus.player.GiveSpawnAmmo(player, k, v);
  2768.         end;
  2769.     end;
  2770.    
  2771.     nexus.mount.Call("PlayerGiveWeapons", player);
  2772.    
  2773.     player:SelectWeapon("nx_hands");
  2774. end
  2775.  
  2776. -- Called when the server shuts down.
  2777. function NEXUS:ShutDown()
  2778.     self.ShuttingDown = true;
  2779. end;
  2780.  
  2781. -- Called when a player presses F1.
  2782. function NEXUS:ShowHelp(player)
  2783.     umsg.Start("nx_MenuToggle", player);
  2784.     umsg.End();
  2785. end;
  2786.  
  2787. -- Called when a player presses F2.
  2788. function NEXUS:ShowTeam(player)
  2789.     if ( !nexus.player.IsNoClipping(player) ) then
  2790.         local doRecogniseMenu = true;
  2791.         local entity = player:GetEyeTraceNoCursor().Entity;
  2792.        
  2793.         if ( IsValid(entity) and nexus.entity.IsDoor(entity) ) then
  2794.             if (entity:GetPos():Distance( player:GetShootPos() ) <= 192) then
  2795.                 if ( nexus.mount.Call("PlayerCanViewDoor", player, entity) ) then
  2796.                     if ( nexus.mount.Call("PlayerUse", player, entity) ) then
  2797.                         local owner = nexus.entity.GetOwner(entity);
  2798.                        
  2799.                         if (owner) then
  2800.                             if ( nexus.player.HasDoorAccess(player, entity, DOOR_ACCESS_COMPLETE) ) then
  2801.                                 local data = {
  2802.                                     sharedAccess = nexus.entity.DoorHasSharedAccess(entity),
  2803.                                     sharedText = nexus.entity.DoorHasSharedText(entity),
  2804.                                     unsellable = nexus.entity.IsDoorUnsellable(entity),
  2805.                                     accessList = {},
  2806.                                     isParent = nexus.entity.IsDoorParent(entity),
  2807.                                     entity = entity,
  2808.                                     owner = owner
  2809.                                 };
  2810.                                
  2811.                                 for k, v in ipairs( g_Player.GetAll() ) do
  2812.                                     if (v != player and v != owner) then
  2813.                                         if ( nexus.player.HasDoorAccess(v, entity, DOOR_ACCESS_COMPLETE) ) then
  2814.                                             data.accessList[v] = DOOR_ACCESS_COMPLETE;
  2815.                                         elseif ( nexus.player.HasDoorAccess(v, entity, DOOR_ACCESS_BASIC) ) then
  2816.                                             data.accessList[v] = DOOR_ACCESS_BASIC;
  2817.                                         end;
  2818.                                     end;
  2819.                                 end;
  2820.                                
  2821.                                 self:StartDataStream(player, "Door", data);
  2822.                             end;
  2823.                         else
  2824.                             self:StartDataStream(player, "PurchaseDoor", entity);
  2825.                         end;
  2826.                     end;
  2827.                 end;
  2828.                
  2829.                 doRecogniseMenu = false;
  2830.             end;
  2831.         end;
  2832.        
  2833.         if ( nexus.config.Get("recognise_system"):Get() ) then
  2834.             if (doRecogniseMenu) then
  2835.                 umsg.Start("nx_RecogniseMenu", player);
  2836.                 umsg.End();
  2837.             end;
  2838.         end;
  2839.     end;
  2840. end;
  2841.  
  2842. NEXUS:HookDataStream("RecogniseOption", function(player, data)
  2843.     if ( nexus.config.Get("recognise_system"):Get() ) then
  2844.         if (type(data) == "string") then
  2845.             local talkRadius = nexus.config.Get("talk_radius"):Get();
  2846.             local playSound = false;
  2847.             local position = player:GetPos();
  2848.            
  2849.             for k, v in ipairs( g_Player.GetAll() ) do
  2850.                 if (v:HasInitialized() and player != v) then
  2851.                     if ( !nexus.player.IsNoClipping(v) ) then
  2852.                         local distance = v:GetPos():Distance(position);
  2853.                         local recognise = false;
  2854.                        
  2855.                         if (data == "whisper") then
  2856.                             if ( distance <= math.min(talkRadius / 3, 80) ) then
  2857.                                 recognise = true;
  2858.                             end;
  2859.                         elseif (data == "yell") then
  2860.                             if (distance <= talkRadius * 2) then
  2861.                                 recognise = true;
  2862.                             end;
  2863.                         elseif (data == "talk") then
  2864.                             if (distance <= talkRadius) then
  2865.                                 recognise = true;
  2866.                             end;
  2867.                         end;
  2868.                        
  2869.                         if (recognise) then
  2870.                             nexus.player.SetRecognises(v, player, RECOGNISE_SAVE);
  2871.                            
  2872.                             if (!playSound) then
  2873.                                 playSound = true;
  2874.                             end;
  2875.                         end;
  2876.                     end;
  2877.                 end;
  2878.             end;
  2879.            
  2880.             if (playSound) then
  2881.                 nexus.player.PlaySound(player, "buttons/button17.wav");
  2882.             end;
  2883.         end;
  2884.     end;
  2885. end);
  2886.  
  2887. -- Called when a player selects a custom character option.
  2888. function NEXUS:PlayerSelectCustomCharacterOption(player, action, character) end;
  2889.  
  2890. -- Called when a player takes damage.
  2891. function NEXUS:PlayerTakeDamage(player, inflictor, attacker, hitGroup, damageInfo) end;
  2892.  
  2893. -- Called when an entity takes damage.
  2894. function NEXUS:EntityTakeDamage(entity, inflictor, attacker, amount, damageInfo)
  2895.     if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  2896.         local curTime = CurTime();
  2897.        
  2898.         if ( (IsValid(inflictor) and inflictor.damageImmunity and inflictor.damageImmunity > curTime)
  2899.         or (attacker.damageImmunity and attacker.damageImmunity > curTime) ) then
  2900.             damageInfo:SetDamage(0);
  2901.         end;
  2902.        
  2903.         if ( ( IsValid(inflictor) and inflictor:IsBeingHeld() )
  2904.         or attacker:IsBeingHeld() ) then
  2905.             damageInfo:SetDamage(0);
  2906.         end;
  2907.     end;
  2908.    
  2909.     if ( entity:IsPlayer() and entity:InVehicle() and !IsValid( entity:GetVehicle():GetParent() ) ) then
  2910.         entity.lastHitGroup = self:GetRagdollHitBone(entity, damageInfo:GetDamagePosition(), HITGROUP_GEAR);
  2911.        
  2912.         if ( damageInfo:IsBulletDamage() ) then
  2913.             if ( ( attacker:IsPlayer() or attacker:IsNPC() ) and attacker != player ) then
  2914.                 damageInfo:ScaleDamage(10000);
  2915.             end;
  2916.         end;
  2917.     end;
  2918.    
  2919.     if (damageInfo:GetDamage() > 0) then
  2920.         local isPlayerRagdoll = nexus.entity.IsPlayerRagdoll(entity);
  2921.         local player = nexus.entity.GetPlayer(entity);
  2922.        
  2923.         if ( player and (entity:IsPlayer() or isPlayerRagdoll) ) then
  2924.             if ( damageInfo:IsFallDamage() or nexus.config.Get("damage_view_punch"):Get() ) then
  2925.                 player:ViewPunch( Angle( math.random(amount, amount), math.random(amount, amount), math.random(amount, amount) ) );
  2926.             end;
  2927.            
  2928.             if (!isPlayerRagdoll) then
  2929.                 if (damageInfo:IsDamageType(DMG_CRUSH) and damageInfo:GetDamage() < 10) then
  2930.                     damageInfo:SetDamage(0);
  2931.                 else
  2932.                     local lastHitGroup = player:LastHitGroup();
  2933.                     local killed = nil;
  2934.                    
  2935.                     if ( player:InVehicle() and damageInfo:IsExplosionDamage() ) then
  2936.                         if (!damageInfo:GetDamage() or damageInfo:GetDamage() == 0) then
  2937.                             damageInfo:SetDamage( player:GetMaxHealth() );
  2938.                         end;
  2939.                     end;
  2940.                    
  2941.                     self:ScaleDamageByHitGroup(player, attacker, lastHitGroup, damageInfo, amount);
  2942.                    
  2943.                     if (damageInfo:GetDamage() > 0) then
  2944.                         self:CalculatePlayerDamage(player, lastHitGroup, damageInfo);
  2945.                        
  2946.                         player:SetVelocity( self:ConvertForce(damageInfo:GetDamageForce() * 32, 200) );
  2947.                        
  2948.                         if (player:Alive() and player:Health() == 1) then
  2949.                             player:SetFakingDeath(true);
  2950.                                 hook.Call("DoPlayerDeath", self, player, attacker, damageInfo);
  2951.                                 hook.Call("PlayerDeath", self, player, inflictor, attacker, damageInfo);
  2952.                                
  2953.                                 self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, player, damageInfo:GetDamageForce() );
  2954.                             player:SetFakingDeath(false, true);
  2955.                         else
  2956.                             local noMessage = nexus.mount.Call("PlayerTakeDamage", player, inflictor, attacker, lastHitGroup, damageInfo);
  2957.                             local sound = nexus.mount.Call("PlayerPlayPainSound", player, nexus.player.GetGender(player), damageInfo, lastHitGroup);
  2958.                            
  2959.                             self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, player, damageInfo:GetDamageForce() );
  2960.                            
  2961.                             if (sound and !noMessage) then
  2962.                                 player:EmitSound("physics/flesh/flesh_impact_bullet"..math.random(1, 5)..".wav", 150);
  2963.                                
  2964.                                 timer.Simple(FrameTime() * 25, function()
  2965.                                     if ( IsValid(player) ) then
  2966.                                         player:EmitSound(sound);
  2967.                                     end;
  2968.                                 end);
  2969.                             end;
  2970.                            
  2971.                             if ( attacker:IsPlayer() ) then
  2972.                                 self:PrintDebug(player:Name().." took damage from "..attacker:Name().." with "..nexus.player.GetWeaponClass(attacker, "an unknown weapon")..".");
  2973.                             else
  2974.                                 self:PrintDebug(player:Name().." took damage from "..attacker:GetClass()..".");
  2975.                             end;
  2976.                         end;
  2977.                     end;
  2978.                    
  2979.                     damageInfo:SetDamage(0);
  2980.                    
  2981.                     player.lastHitGroup = nil;
  2982.                 end;
  2983.             else
  2984.                 local hitGroup = self:GetRagdollHitGroup( entity, damageInfo:GetDamagePosition() );
  2985.                 local curTime = CurTime();
  2986.                 local killed = nil;
  2987.                
  2988.                 self:ScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, amount);
  2989.                
  2990.                 if (nexus.mount.Call("PlayerRagdollCanTakeDamage", player, entity, inflictor, attacker, hitGroup, damageInfo)
  2991.                 and damageInfo:GetDamage() > 0) then
  2992.                     if ( !attacker:IsPlayer() ) then
  2993.                         if (attacker:GetClass() == "prop_ragdoll" or nexus.entity.IsDoor(attacker)
  2994.                         or damageInfo:GetDamage() < 5) then
  2995.                             return;
  2996.                         end;
  2997.                     end;
  2998.                    
  2999.                     if ( damageInfo:GetDamage() >= 10 or damageInfo:IsBulletDamage() ) then
  3000.                         self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, entity, damageInfo:GetDamageForce() );
  3001.                     end;
  3002.                    
  3003.                     self:CalculatePlayerDamage(player, hitGroup, damageInfo);
  3004.                    
  3005.                     if (player:Alive() and player:Health() == 1) then
  3006.                         player:SetFakingDeath(true);
  3007.                             player:GetRagdollTable().health = 0;
  3008.                             player:GetRagdollTable().armor = 0;
  3009.                            
  3010.                             hook.Call("DoPlayerDeath", self, player, attacker, damageInfo);
  3011.                             hook.Call("PlayerDeath", self, player, inflictor, attacker, damageInfo);
  3012.                         player:SetFakingDeath(false, true);
  3013.                     elseif ( player:Alive() ) then
  3014.                         local noMessage = nexus.mount.Call("PlayerTakeDamage", player, inflictor, attacker, hitGroup, damageInfo);
  3015.                         local sound = nexus.mount.Call("PlayerPlayPainSound", player, nexus.player.GetGender(player), damageInfo, hitGroup);
  3016.                        
  3017.                         if (sound and !noMessage) then
  3018.                             entity:EmitSound("physics/flesh/flesh_impact_bullet"..math.random(1, 5)..".wav", 320, 150);
  3019.                            
  3020.                             timer.Simple(FrameTime() * 25, function()
  3021.                                 if ( IsValid(entity) ) then
  3022.                                     entity:EmitSound(sound);
  3023.                                 end;
  3024.                             end);
  3025.                         end;
  3026.                        
  3027.                         if ( attacker:IsPlayer() ) then
  3028.                             self:PrintDebug(player:Name().." took damage from "..attacker:Name().." with "..nexus.player.GetWeaponClass(attacker, "an unknown weapon")..".");
  3029.                         else
  3030.                             self:PrintDebug(player:Name().." took damage from "..attacker:GetClass()..".");
  3031.                         end;
  3032.                     end;
  3033.                 end;
  3034.                
  3035.                 damageInfo:SetDamage(0);
  3036.             end;
  3037.         elseif (entity:GetClass() == "prop_ragdoll") then
  3038.             if ( damageInfo:GetDamage() >= 20 or damageInfo:IsBulletDamage() ) then
  3039.                 if ( !string.find(entity:GetModel(), "matt") and !string.find(entity:GetModel(), "gib") ) then
  3040.                     local matType = util.QuickTrace( entity:GetPos(), entity:GetPos() ).MatType;
  3041.                    
  3042.                     if (matType == MAT_FLESH or matType == MAT_BLOODYFLESH) then
  3043.                         self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, entity, damageInfo:GetDamageForce() );
  3044.                     end;
  3045.                 end;
  3046.             end;
  3047.            
  3048.             if (inflictor:GetClass() == "prop_combine_ball") then
  3049.                 if (!entity.disintegrating) then
  3050.                     nexus.entity.Disintegrate( entity, 3, damageInfo:GetDamageForce() );
  3051.                    
  3052.                     entity.disintegrating = true;
  3053.                 end;
  3054.             end;
  3055.         elseif ( entity:IsNPC() ) then
  3056.             if (attacker:IsPlayer() and IsValid( attacker:GetActiveWeapon() )
  3057.             and nexus.player.GetWeaponClass(attacker) == "weapon_crowbar") then
  3058.                 damageInfo:ScaleDamage(0.25);
  3059.             end;
  3060.         end;
  3061.     end;
  3062. end;
  3063.  
  3064. -- Called when the death sound for a player should be played.
  3065. function NEXUS:PlayerDeathSound(player) return true; end;
  3066.  
  3067. -- Called when a player attempts to spawn a SWEP.
  3068. function NEXUS:PlayerSpawnSWEP(player, class, weapon)
  3069.     if ( !player:IsSuperAdmin() ) then
  3070.         return false;
  3071.     else
  3072.         return true;
  3073.     end;
  3074. end;
  3075.  
  3076. -- Called when a player is given a SWEP.
  3077. function NEXUS:PlayerGiveSWEP(player, class, weapon)
  3078.     if ( !player:IsSuperAdmin() ) then
  3079.         return false;
  3080.     else
  3081.         return true;
  3082.     end;
  3083. end;
  3084.  
  3085. -- Called when attempts to spawn a SENT.
  3086. function NEXUS:PlayerSpawnSENT(player, class)
  3087.     if ( !player:IsSuperAdmin() ) then
  3088.         return false;
  3089.     else
  3090.         return true;
  3091.     end;
  3092. end;
  3093.  
  3094. -- Called when a player presses a key.
  3095. function NEXUS:KeyPress(player, key)
  3096.     if (key == IN_USE) then
  3097.         local trace = player:GetEyeTraceNoCursor();
  3098.        
  3099.         if ( IsValid(trace.Entity) ) then
  3100.             if (trace.HitPos:Distance( player:GetShootPos() ) <= 192) then
  3101.                 if ( nexus.mount.Call("PlayerUse", player, trace.Entity) ) then
  3102.                     if ( nexus.entity.IsDoor(trace.Entity) and !trace.Entity:HasSpawnFlags(256)
  3103.                     and !trace.Entity:HasSpawnFlags(8192) and !trace.Entity:HasSpawnFlags(32768) ) then
  3104.                         if ( nexus.mount.Call("PlayerCanUseDoor", player, trace.Entity) ) then
  3105.                             nexus.mount.Call("PlayerUseDoor", player, trace.Entity);
  3106.                            
  3107.                             nexus.entity.OpenDoor( trace.Entity, 0, nil, nil, player:GetPos() );
  3108.                         end;
  3109.                     elseif (trace.Entity.UsableInVehicle) then
  3110.                         if ( player:InVehicle() ) then
  3111.                             if (trace.Entity.Use) then
  3112.                                 trace.Entity:Use(player, player);
  3113.                                
  3114.                                 player.nextExitVehicle = CurTime() + 1;
  3115.                             end;
  3116.                         end;
  3117.                     end;
  3118.                 end;
  3119.             end;
  3120.         end;
  3121.     elseif (key == IN_WALK) then
  3122.         local velocity = player:GetVelocity():Length();
  3123.        
  3124.         if ( velocity > 0 and !player:KeyDown(IN_SPEED) ) then
  3125.             if ( player:GetSharedVar("sh_Jogging") ) then
  3126.                 player:SetSharedVar("sh_Jogging", false);
  3127.             else
  3128.                 player:SetSharedVar("sh_Jogging", true);
  3129.             end;
  3130.         elseif ( velocity == 0 and player:KeyDown(IN_SPEED) ) then
  3131.             if ( player:Crouching() ) then
  3132.                 player:RunCommand("-duck");
  3133.             else
  3134.                 player:RunCommand("+duck");
  3135.             end;
  3136.         end;
  3137.     elseif (key == IN_RELOAD) then
  3138.         player.reloadHoldTime = CurTime() + 1;
  3139.     end;
  3140. end;
  3141.  
  3142. -- Called when a player releases a key.
  3143. function NEXUS:KeyRelease(player, key)
  3144.     if (key == IN_RELOAD and player.reloadHoldTime) then
  3145.         player.reloadHoldTime = nil;
  3146.     end;
  3147. end;
  3148.  
  3149. NEXUS:HookDataStream("Door", function(player, data)
  3150.     if ( IsValid( data[1] ) and player:GetEyeTraceNoCursor().Entity == data[1] ) then
  3151.         if (data[1]:GetPos():Distance( player:GetPos() ) <= 192) then
  3152.             if (data[2] == "Purchase") then
  3153.                 if ( !nexus.entity.GetOwner( data[1] ) ) then
  3154.                     if ( hook.Call( "PlayerCanOwnDoor", NEXUS, player, data[1] ) ) then
  3155.                         local doors = nexus.player.GetDoorCount(player);
  3156.                        
  3157.                         if ( doors == nexus.config.Get("max_doors"):Get() ) then
  3158.                             nexus.player.Notify(player, "You cannot purchase another door!");
  3159.                         else
  3160.                             local doorCost = nexus.config.Get("door_cost"):Get();
  3161.                            
  3162.                             if ( doorCost == 0 or nexus.player.CanAfford(player, doorCost) ) then
  3163.                                 local doorName = nexus.entity.GetDoorName( data[1] );
  3164.                                
  3165.                                 if (doorName == "false" or doorName == "hidden" or doorName == "") then
  3166.                                     doorName = "Door";
  3167.                                 end;
  3168.                                
  3169.                                 if (doorCost > 0) then
  3170.                                     nexus.player.GiveCash(player, -doorCost, doorName);
  3171.                                 end;
  3172.                                
  3173.                                 nexus.player.GiveDoor( player, data[1] );
  3174.                             else
  3175.                                 local amount = doorCost - nexus.player.GetCash(player);
  3176.                                
  3177.                                 nexus.player.Notify(player, "You need another "..FORMAT_CASH(amount, nil, true).."!");
  3178.                             end;
  3179.                         end;
  3180.                     end;
  3181.                 end;
  3182.             elseif (data[2] == "Access") then
  3183.                 if ( nexus.player.HasDoorAccess(player, data[1], DOOR_ACCESS_COMPLETE) ) then
  3184.                     if ( IsValid( data[3] ) and data[3] != player and data[3] != nexus.entity.GetOwner( data[1] ) ) then
  3185.                         if (data[4] == DOOR_ACCESS_COMPLETE) then
  3186.                             if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE) ) then
  3187.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC);
  3188.                             else
  3189.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE);
  3190.                             end;
  3191.                         elseif (data[4] == DOOR_ACCESS_BASIC) then
  3192.                             if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC) ) then
  3193.                                 nexus.player.TakeDoorAccess( data[3], data[1] );
  3194.                             else
  3195.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC);
  3196.                             end;
  3197.                         end;
  3198.                        
  3199.                         if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE) ) then
  3200.                             NEXUS:StartDataStream( player, "DoorAccess", {data[3], DOOR_ACCESS_COMPLETE} );
  3201.                         elseif ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC) ) then
  3202.                             NEXUS:StartDataStream( player, "DoorAccess", {data[3], DOOR_ACCESS_BASIC} );
  3203.                         else
  3204.                             NEXUS:StartDataStream( player, "DoorAccess", { data[3] } );
  3205.                         end;
  3206.                     end;
  3207.                 end;
  3208.             elseif (data[2] == "Unshare") then
  3209.                 if ( nexus.entity.IsDoorParent( data[1] ) ) then
  3210.                     if (data[3] == "Text") then
  3211.                         NEXUS:StartDataStream(player, "SetSharedText", false);
  3212.                        
  3213.                         data[1].sharedText = nil;
  3214.                     else
  3215.                         NEXUS:StartDataStream(player, "SetSharedAccess", false);
  3216.                        
  3217.                         data[1].sharedAccess = nil;
  3218.                     end;
  3219.                 end;
  3220.             elseif (data[2] == "Share") then
  3221.                 if ( nexus.entity.IsDoorParent( data[1] ) ) then
  3222.                     if (data[3] == "Text") then
  3223.                         NEXUS:StartDataStream(player, "SetSharedText", true);
  3224.                        
  3225.                         data[1].sharedText = true;
  3226.                     else
  3227.                         NEXUS:StartDataStream(player, "SetSharedAccess", true);
  3228.                        
  3229.                         data[1].sharedAccess = true;
  3230.                     end;
  3231.                 end;
  3232.             elseif (data[2] == "Text" and data[3] != "") then
  3233.                 if ( nexus.player.HasDoorAccess(player, data[1], DOOR_ACCESS_COMPLETE) ) then
  3234.                     if ( !string.find(string.gsub(string.lower( data[3] ), "%s", ""), "thisdoorcanbepurchased")
  3235.                     and string.find(data[3], "%w") ) then
  3236.                         nexus.entity.SetDoorText( data[1], string.sub(data[3], 1, 32) );
  3237.                     end;
  3238.                 end;
  3239.             elseif (data[2] == "Sell") then
  3240.                 if (nexus.entity.GetOwner( data[1] ) == player) then
  3241.                     if ( !nexus.entity.IsDoorUnsellable( data[1] ) ) then
  3242.                         nexus.player.TakeDoor( player, data[1] );
  3243.                     end;
  3244.                 end;
  3245.             end;
  3246.         end;
  3247.     end;
  3248. end);
  3249.  
  3250. NEXUS:HookDataStream("DataStreamInfoSent", function(player, data)
  3251.     if (!player.dataStreamInfoSent) then
  3252.         nexus.mount.Call("PlayerDataStreamInfoSent", player);
  3253.        
  3254.         timer.Simple(FrameTime() * 32, function()
  3255.             if ( IsValid(player) ) then
  3256.                 umsg.Start("nx_DataStreamed", player);
  3257.                 umsg.End();
  3258.             end;
  3259.         end);
  3260.        
  3261.         player.dataStreamInfoSent = true;
  3262.     end;
  3263. end);
  3264.  
  3265. NEXUS:HookDataStream("LocalPlayerCreated", function(player, data)
  3266.     if ( IsValid(player) and !player:HasConfigInitialized() ) then
  3267.         NEXUS:CreateTimer("Send Config: "..player:UniqueID(), FrameTime() * 64, 1, function()
  3268.             if ( IsValid(player) ) then
  3269.                 nexus.config.Send(player);
  3270.             end;
  3271.         end);
  3272.     end;
  3273. end);
  3274.  
  3275. NEXUS:HookDataStream("UnequipItem", function(player, data)
  3276.     local arguments = nil;
  3277.     local uniqueID = data;
  3278.    
  3279.     if (type(data) == "table") then
  3280.         arguments = data[2];
  3281.         uniqueID = data[1];
  3282.     end;
  3283.    
  3284.     if (type(uniqueID) == "string") then
  3285.         if ( player:Alive() and !player:IsRagdolled() ) then
  3286.             local itemTable = nexus.item.Get(uniqueID);
  3287.            
  3288.             if (itemTable and itemTable.OnPlayerUnequipped and itemTable.HasPlayerEquipped) then
  3289.                 if ( itemTable:HasPlayerEquipped(player, arguments) ) then
  3290.                     itemTable:OnPlayerUnequipped(player, arguments);
  3291.                    
  3292.                     player:RebuildInventory();
  3293.                 end;
  3294.             end;
  3295.         end;
  3296.     end;
  3297. end);
  3298.  
  3299. NEXUS:HookDataStream("GetTargetRecognises", function(player, data)
  3300.     if ( ValidEntity(data) and data:IsPlayer() ) then
  3301.         player:SetSharedVar( "sh_TargetRecognises", nexus.player.DoesRecognise(data, player) );
  3302.     end;
  3303. end);
  3304.  
  3305. NEXUS:HookDataStream("EntityMenuOption", function(player, data)
  3306.     local entity = data[1];
  3307.     local option = data[2];
  3308.     local shootPos = player:GetShootPos();
  3309.     local arguments = data[3];
  3310.    
  3311.     if (IsValid(entity) and type(option) == "string") then
  3312.         if (entity:NearestPoint(shootPos):Distance(shootPos) <= 80) then
  3313.             if ( nexus.mount.Call("PlayerUse", player, entity) ) then
  3314.                 nexus.mount.Call("EntityHandleMenuOption", player, entity, option, arguments);
  3315.             end;
  3316.         end;
  3317.     end;
  3318. end);
  3319.  
  3320. NEXUS:HookDataStream("CreateCharacter", function(player, data)
  3321.     if (!player.creatingCharacter) then
  3322.         local minimumPhysDesc = nexus.config.Get("minimum_physdesc"):Get();
  3323.         local attributesTable = nexus.attribute.GetAll();
  3324.         local factionTable = nexus.faction.Get(data.faction);
  3325.         local attributes;
  3326.         local info = {};
  3327.        
  3328.         if (table.Count(attributesTable) > 0) then
  3329.             for k, v in pairs(attributesTable) do
  3330.                 if (v.characterScreen) then
  3331.                     attributes = true;
  3332.                    
  3333.                     break;
  3334.                 end;
  3335.             end;
  3336.         end;
  3337.        
  3338.         if (factionTable) then
  3339.             info.attributes = {};
  3340.             info.faction = factionTable.name;
  3341.             info.gender = data.gender;
  3342.             info.model = data.model;
  3343.             info.data = {};
  3344.            
  3345.             if (attributes and type(data.attributes) == "table") then
  3346.                 local maximumPoints = nexus.config.Get("default_attribute_points"):Get();
  3347.                 local pointsSpent = 0;
  3348.                
  3349.                 if (factionTable.attributePointsScale) then
  3350.                     maximumPoints = math.Round(maximumPoints * factionTable.attributePointsScale);
  3351.                 end;
  3352.                
  3353.                 if (factionTable.maximumAttributePoints) then
  3354.                     maximumPoints = factionTable.maximumAttributePoints;
  3355.                 end;
  3356.                
  3357.                 for k, v in pairs(data.attributes) do
  3358.                     local attributeTable = nexus.attribute.Get(k);
  3359.                    
  3360.                     if (attributeTable and attributeTable.characterScreen) then
  3361.                         local uniqueID = attributeTable.uniqueID;
  3362.                         local amount = math.Clamp(v, 0, attributeTable.maximum);
  3363.                        
  3364.                         info.attributes[uniqueID] = {
  3365.                             amount = amount,
  3366.                             progress = 0
  3367.                         };
  3368.                        
  3369.                         pointsSpent = pointsSpent + amount;
  3370.                     end;
  3371.                 end;
  3372.                
  3373.                 if (pointsSpent > maximumPoints) then
  3374.                     return nexus.player.CreationError(player, "You have chosen more "..nexus.schema.GetOption("name_attribute", true).." points than you can afford to spend!");
  3375.                 end;
  3376.             elseif (attributes) then
  3377.                 return nexus.player.CreationError(player, "You did not choose any "..nexus.schema.GetOption("name_attributes", true).." or the ones that you did are not valid!");
  3378.             end;
  3379.            
  3380.             if (!factionTable.GetName) then
  3381.                 if (!factionTable.useFullName) then
  3382.                     if (data.forename and data.surname) then
  3383.                         data.forename = string.gsub(data.forename, "^.", string.upper);
  3384.                         data.surname = string.gsub(data.surname, "^.", string.upper);
  3385.                        
  3386.                         if ( string.find(data.forename, "[%p%s%d]") or string.find(data.surname, "[%p%s%d]") ) then
  3387.                             return nexus.player.CreationError(player, "Your forename and surname must not contain punctuation, spaces or digits!");
  3388.                         end;
  3389.                        
  3390.                         if ( !string.find(data.forename, "[aeiou]") or !string.find(data.surname, "[aeiou]") ) then
  3391.                             return nexus.player.CreationError(player, "Your forename and surname must both contain at least one vowel!");
  3392.                         end;
  3393.                        
  3394.                         if ( string.len(data.forename) < 2 or string.len(data.surname) < 2) then
  3395.                             return nexus.player.CreationError(player, "Your forename and surname must both be at least 2 characters long!");
  3396.                         end;
  3397.                        
  3398.                         if ( string.len(data.forename) > 16 or string.len(data.surname) > 16) then
  3399.                             return nexus.player.CreationError(player, "Your forename and surname must not be greater than 16 characters long!");
  3400.                         end;
  3401.                     else
  3402.                         return nexus.player.CreationError(player, "You did not choose a name, or the name that you chose is not valid!");
  3403.                     end;
  3404.                 elseif (!data.fullName or data.fullName == "") then
  3405.                     return nexus.player.CreationError(player, "You did not choose a name, or the name that you chose is not valid!");
  3406.                 end;
  3407.             end;
  3408.            
  3409.             if (nexus.command.Get("CharPhysDesc") != nil) then
  3410.                 if (type(data.physDesc) != "string") then
  3411.                     return nexus.player.CreationError(player, "You did not enter a physical description!");
  3412.                 elseif (string.len(data.physDesc) < minimumPhysDesc) then
  3413.                     return nexus.player.CreationError(player, "The physical description must be at least "..minimumPhysDesc.." characters long!");
  3414.                 end;
  3415.                
  3416.                 info.data["physdesc"] = NEXUS:ModifyPhysDesc(data.physDesc);
  3417.             end;
  3418.            
  3419.             if (!factionTable.GetModel and !info.model) then
  3420.                 return nexus.player.CreationError(player, "You did not choose a model, or the model that you chose is not valid!");
  3421.             end;
  3422.            
  3423.             if ( !nexus.faction.IsGenderValid(info.faction, info.gender) ) then
  3424.                 return nexus.player.CreationError(player, "You did not choose a gender, or the gender that you chose is not valid!");
  3425.             end;
  3426.            
  3427.             if ( factionTable.whitelist and !nexus.player.IsWhitelisted(player, info.faction) ) then
  3428.                 return nexus.player.CreationError(player, "You are not on the "..info.faction.." whitelist!");
  3429.             elseif ( nexus.faction.IsModelValid(factionTable.name, info.gender, info.model) or (factionTable.GetModel and !info.model) ) then
  3430.                 local charactersTable = nexus.config.Get("mysql_characters_table"):Get();
  3431.                 local schemaFolder = NEXUS:GetSchemaFolder();
  3432.                 local characterID = nil;
  3433.                 local characters = player:GetCharacters();
  3434.                
  3435.                 if ( nexus.faction.HasReachedMaximum(player, factionTable.name) ) then
  3436.                     return nexus.player.CreationError(player, "You cannot create any more characters in this faction.");
  3437.                 end;
  3438.                
  3439.                 for i = 1, nexus.player.GetMaximumCharacters(player) do
  3440.                     if ( !characters[i] ) then
  3441.                         characterID = i; break;
  3442.                     end;
  3443.                 end;
  3444.                
  3445.                 if (characterID) then
  3446.                     if (factionTable.GetName) then
  3447.                         info.name = factionTable:GetName(player, info, data);
  3448.                     elseif (!factionTable.useFullName) then
  3449.                         info.name = data.forename.." "..data.surname;
  3450.                     else
  3451.                         info.name = data.fullName;
  3452.                     end;
  3453.                    
  3454.                     if (factionTable.GetModel) then
  3455.                         info.model = factionTable:GetModel(player, info, data);
  3456.                     else
  3457.                         info.model = data.model;
  3458.                     end;
  3459.                    
  3460.                     if (factionTable.OnCreation) then
  3461.                         local fault = factionTable:OnCreation(player, info);
  3462.                        
  3463.                         if (fault == false or type(fault) == "string") then
  3464.                             return nexus.player.CreationError(player, fault or "There was an error creating this character!");
  3465.                         end;
  3466.                     end;
  3467.                    
  3468.                     for k, v in pairs(characters) do
  3469.                         if (v.name == info.name) then
  3470.                             return nexus.player.CreationError(player, "You already have a character with the name '"..info.name.."'!");
  3471.                         end;
  3472.                     end;
  3473.                    
  3474.                     local fault = nexus.mount.Call("PlayerAdjustCharacterCreationInfo", player, info, data);
  3475.                    
  3476.                     if (fault == false or type(fault) == "string") then
  3477.                         return nexus.player.CreationError(player, fault or "There was an error creating this character!");
  3478.                     end;
  3479.                    
  3480.                     tmysql.query("SELECT * FROM "..charactersTable.." WHERE _Schema = \""..schemaFolder.."\" AND _Name = \""..tmysql.escape(info.name).."\"", function(result)
  3481.                         if ( IsValid(player) ) then
  3482.                             if (result and type(result) == "table" and #result > 0) then
  3483.                                 nexus.player.CreationError(player, "A character with the name '"..info.name.."' already exists!");
  3484.                                
  3485.                                 player.creatingCharacter = nil;
  3486.                             else
  3487.                                 nexus.player.LoadCharacter( player, characterID, {
  3488.                                     attributes = info.attributes,
  3489.                                     faction = info.faction,
  3490.                                     gender = info.gender,
  3491.                                     model = info.model,
  3492.                                     name = info.name,
  3493.                                     data = info.data
  3494.                                 }, function()
  3495.                                     NEXUS:PrintDebug(player:SteamName().." created a "..info.faction.." character with the name '"..info.name.."'.");
  3496.                                    
  3497.                                     umsg.Start("nx_CharacterFinish", player)
  3498.                                         umsg.Bool(true);
  3499.                                     umsg.End();
  3500.                                    
  3501.                                     player.creatingCharacter = nil;
  3502.                                 end);
  3503.                             end;
  3504.                         end;
  3505.                     end, 1);
  3506.                    
  3507.                     player.creatingCharacter = true;
  3508.                 else
  3509.                     return nexus.player.CreationError(player, "You cannot create any more characters!");
  3510.                 end;
  3511.             else
  3512.                 return nexus.player.CreationError(player, "You did not choose a model, or the model that you chose is not valid!");
  3513.             end;
  3514.         else
  3515.             return nexus.player.CreationError(player, "You did not choose a faction, or the faction that you chose is not valid!");
  3516.         end;
  3517.     end;
  3518. end);
  3519.  
  3520. NEXUS:HookDataStream("InteractCharacter", function(player, data)
  3521.     local characterID = data.characterID;
  3522.     local action = data.action;
  3523.    
  3524.     if (characterID and action) then
  3525.         local character = player:GetCharacters()[characterID];
  3526.        
  3527.         if (character) then
  3528.             local fault = nexus.mount.Call("PlayerCanInteractCharacter", player, action, character);
  3529.            
  3530.             if (fault == false or type(fault) == "string") then
  3531.                 return nexus.player.CreationError(fault or "You cannot interact with this character!");
  3532.             elseif (action == "delete") then
  3533.                 local success, fault = nexus.player.DeleteCharacter(player, characterID);
  3534.                
  3535.                 if (!success) then
  3536.                     nexus.player.CreationError(player, fault);
  3537.                 end;
  3538.             elseif (action == "use") then
  3539.                 local success, fault = nexus.player.UseCharacter(player, characterID);
  3540.                
  3541.                 if (!success) then
  3542.                     nexus.player.CreationError(player, fault);
  3543.                 end;
  3544.             else
  3545.                 nexus.mount.Call("PlayerSelectCustomCharacterOption", player, action, character);
  3546.             end;
  3547.         end;
  3548.     end;
  3549. end);
  3550.  
  3551. NEXUS:HookDataStream("QuizAnswer", function(player, data)
  3552.     if (!player.quizAnswers) then
  3553.         player.quizAnswers = {};
  3554.     end;
  3555.    
  3556.     local question = data[1];
  3557.     local answer = data[2];
  3558.    
  3559.     if ( nexus.quiz.GetQuestion(question) ) then
  3560.         player.quizAnswers[question] = answer;
  3561.     end;
  3562. end);
  3563.  
  3564. NEXUS:HookDataStream("QuizCompleted", function(player, data)
  3565.     if ( player.quizAnswers and !nexus.quiz.GetCompleted(player) ) then
  3566.         local questionsAmount = nexus.quiz.GetQuestionsAmount();
  3567.         local correctAnswers = 0;
  3568.         local quizQuestions = nexus.quiz.GetQuestions();
  3569.        
  3570.         for k, v in pairs(quizQuestions) do
  3571.             if ( player.quizAnswers[k] ) then
  3572.                 if ( nexus.quiz.IsAnswerCorrect( k, player.quizAnswers[k] ) ) then
  3573.                     correctAnswers = correctAnswers + 1;
  3574.                 end;
  3575.             end;
  3576.         end;
  3577.        
  3578.         if ( correctAnswers < math.Round( questionsAmount * (nexus.quiz.GetPercentage() / 100) ) ) then
  3579.             nexus.quiz.CallKickCallback(player, correctAnswers);
  3580.         else
  3581.             nexus.quiz.SetCompleted(player, true);
  3582.         end;
  3583.     end;
  3584. end);
  3585.  
  3586. NEXUS:HookDataStream("GetQuizStatus", function(player, data)
  3587.     if ( !nexus.quiz.GetEnabled() or nexus.quiz.GetCompleted(player) ) then
  3588.         umsg.Start("nx_QuizCompleted", player);
  3589.             umsg.Bool(true);
  3590.         umsg.End();
  3591.     else
  3592.         umsg.Start("nx_QuizCompleted", player);
  3593.             umsg.Bool(false);
  3594.         umsg.End();
  3595.     end;
  3596. end);
  3597.  
  3598. local playerMeta = FindMetaTable("Player");
  3599. local entityMeta = FindMetaTable("Entity");
  3600.  
  3601. playerMeta.NexusSetCrouchedWalkSpeed = playerMeta.SetCrouchedWalkSpeed;
  3602. playerMeta.NexusLastHitGroup = playerMeta.LastHitGroup;
  3603. playerMeta.NexusSetJumpPower = playerMeta.SetJumpPower;
  3604. playerMeta.NexusSetWalkSpeed = playerMeta.SetWalkSpeed;
  3605. playerMeta.NexusStripWeapons = playerMeta.StripWeapons;
  3606. playerMeta.NexusSetRunSpeed = playerMeta.SetRunSpeed;
  3607. entityMeta.NexusSetMaterial = entityMeta.SetMaterial;
  3608. playerMeta.NexusStripWeapon = playerMeta.StripWeapon;
  3609. playerMeta.NexusGodDisable = playerMeta.GodDisable;
  3610. entityMeta.NexusExtinguish = entityMeta.Extinguish;
  3611. entityMeta.NexusWaterLevel = entityMeta.WaterLevel;
  3612. playerMeta.NexusGodEnable = playerMeta.GodEnable;
  3613. entityMeta.NexusSetHealth = entityMeta.SetHealth;
  3614. entityMeta.NexusSetColor = entityMeta.SetColor;
  3615. entityMeta.NexusIsOnFire = entityMeta.IsOnFire;
  3616. entityMeta.NexusSetModel = entityMeta.SetModel;
  3617. playerMeta.NexusSetArmor = playerMeta.SetArmor;
  3618. entityMeta.NexusSetSkin = entityMeta.SetSkin;
  3619. entityMeta.NexusAlive = playerMeta.Alive;
  3620. playerMeta.NexusGive = playerMeta.Give;
  3621. playerMeta.SteamName = playerMeta.Name;
  3622.  
  3623. -- A function to get a player's name.
  3624. function playerMeta:Name()
  3625.     return self:QueryCharacter( "name", self:SteamName() );
  3626. end;
  3627.  
  3628. -- A function to get whether a player is alive.
  3629. function playerMeta:Alive()
  3630.     if (!self.fakingDeath) then
  3631.         return self:NexusAlive();
  3632.     else
  3633.         return false;
  3634.     end;
  3635. end;
  3636.  
  3637. -- A function to set whether a player is faking death.
  3638. function playerMeta:SetFakingDeath(fakingDeath, killSilent)
  3639.     self.fakingDeath = fakingDeath;
  3640.    
  3641.     if (!fakingDeath and killSilent) then
  3642.         self:KillSilent();
  3643.     end;
  3644. end;
  3645.  
  3646. -- A function to save a player's character.
  3647. function playerMeta:SaveCharacter()
  3648.     nexus.player.SaveCharacter(self);
  3649. end;
  3650.  
  3651. -- A function to give a player an item weapon.
  3652. function playerMeta:GiveItemWeapon(item)
  3653.     nexus.player.GiveItemWeapon(self, item);
  3654. end;
  3655.  
  3656. -- A function to give a weapon to a player.
  3657. function playerMeta:Give(class, uniqueID, forceReturn)
  3658.     if ( !nexus.mount.Call("PlayerCanBeGivenWeapon", self, class, uniqueID, forceReturn) ) then
  3659.         return;
  3660.     end;
  3661.    
  3662.     local itemTable = nexus.item.GetWeapon(class, uniqueID);
  3663.     local teamIndex = self:Team();
  3664.    
  3665.     if (self:IsRagdolled() and !forceReturn) then
  3666.         local ragdollWeapons = self:GetRagdollWeapons();
  3667.         local spawnWeapon = nexus.player.GetSpawnWeapon(self, class);
  3668.         local canHolster;
  3669.        
  3670.         if ( itemTable and nexus.mount.Call("PlayerCanHolsterWeapon", self, itemTable, true, true) ) then
  3671.             canHolster = true;
  3672.         end;
  3673.        
  3674.         if (!spawnWeapon) then
  3675.             teamIndex = nil;
  3676.         end;
  3677.        
  3678.         for k, v in pairs(ragdollWeapons) do
  3679.             if (v.weaponData["class"] == class
  3680.             and v.weaponData["uniqueID"] == uniqueID) then
  3681.                 v.canHolster = canHolster;
  3682.                 v.teamIndex = teamIndex;
  3683.                
  3684.                 return;
  3685.             end;
  3686.         end;
  3687.        
  3688.         ragdollWeapons[#ragdollWeapons + 1] = {
  3689.             weaponData = {class = class, uniqueID = uniqueID},
  3690.             canHolster = canHolster,
  3691.             teamIndex = teamIndex,
  3692.         };
  3693.     elseif ( !self:HasWeapon(class) ) then
  3694.         self.forceGive = true;
  3695.             self:NexusGive(class);
  3696.         self.forceGive = nil;
  3697.        
  3698.         local weapon = self:GetWeapon(class);
  3699.        
  3700.         if ( IsValid(weapon) ) then
  3701.             if (itemTable) then
  3702.                 nexus.player.StripDefaultAmmo(self, weapon, itemTable);
  3703.                 nexus.player.RestorePrimaryAmmo(self, weapon);
  3704.                 nexus.player.RestoreSecondaryAmmo(self, weapon);
  3705.             end;
  3706.            
  3707.             if (uniqueID and uniqueID != "") then
  3708.                 weapon:SetNetworkedString("sh_UniqueID", uniqueID);
  3709.             end;
  3710.         else
  3711.             return true;
  3712.         end;
  3713.     end;
  3714.    
  3715.     nexus.mount.Call("PlayerGivenWeapon", self, class, uniqueID, forceReturn);
  3716. end;
  3717.  
  3718. -- A function to get a player's data.
  3719. function playerMeta:GetData(key, default)
  3720.     if (self.data) then
  3721.         if (self.data[key] != nil) then
  3722.             return self.data[key];
  3723.         else
  3724.             return default;
  3725.         end;
  3726.     else
  3727.         return default;
  3728.     end;
  3729. end;
  3730.  
  3731. -- A function to set a player's data.
  3732. function playerMeta:SetData(key, value)
  3733.     if (self.data) then
  3734.         self.data[key] = value;
  3735.     end;
  3736. end;
  3737.  
  3738. -- A function to get a player's playback rate.
  3739. function playerMeta:GetPlaybackRate()
  3740.     return self.playbackRate or 1;
  3741. end;
  3742.  
  3743. -- A function to set an entity's skin.
  3744. function entityMeta:SetSkin(skin)
  3745.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  3746.         self:GetRagdollEntity():SetSkin(skin);
  3747.     end;
  3748.    
  3749.     self:NexusSetSkin(skin);
  3750. end;
  3751.  
  3752. -- A function to set an entity's model.
  3753. function entityMeta:SetModel(model)
  3754.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  3755.         self:GetRagdollEntity():SetModel(model);
  3756.     end;
  3757.    
  3758.     self:NexusSetModel(model);
  3759.     nexus.mount.Call("PlayerModelChanged", self, model);
  3760. end;
  3761.  
  3762. -- A function to get an entity's owner key.
  3763. function entityMeta:GetOwnerKey()
  3764.     return self.ownerKey;
  3765. end;
  3766.  
  3767. -- A function to set an entity's owner key.
  3768. function entityMeta:SetOwnerKey(key)
  3769.     self.ownerKey = key;
  3770. end;
  3771.  
  3772. -- A function to get whether an entity is a map entity.
  3773. function entityMeta:IsMapEntity()
  3774.     return nexus.entity.IsMapEntity(self);
  3775. end;
  3776.  
  3777. -- A function to get an entity's start position.
  3778. function entityMeta:GetStartPosition()
  3779.     return nexus.entity.GetStartPosition(self);
  3780. end;
  3781.  
  3782. -- A function to set an entity's material.
  3783. function entityMeta:SetMaterial(material)
  3784.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  3785.         self:GetRagdollEntity():SetMaterial(material);
  3786.     end;
  3787.    
  3788.     self:NexusSetMaterial(material);
  3789. end;
  3790.  
  3791. -- A function to set an entity's color.
  3792. function entityMeta:SetColor(r, g, b, a)
  3793.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  3794.         self:GetRagdollEntity():SetColor(r, g, b, a);
  3795.     end;
  3796.    
  3797.     self:NexusSetColor(r, g, b, a);
  3798. end;
  3799.  
  3800. -- A function to set a player's armor.
  3801. function playerMeta:SetArmor(armor)
  3802.     nexus.mount.Call("PlayerArmorSet", self, armor);
  3803.    
  3804.     self:NexusSetArmor(armor);
  3805. end;
  3806.  
  3807. -- A function to set a player's health.
  3808. function playerMeta:SetHealth(health)
  3809.     nexus.mount.Call("PlayerHealthSet", self, health);
  3810.    
  3811.     self:NexusSetHealth(health);
  3812. end;
  3813.  
  3814. -- A function to get whether a player is running.
  3815. function playerMeta:IsRunning()
  3816.     if ( self:Alive() and !self:IsRagdolled() and !self:InVehicle() and !self:Crouching() ) then
  3817.         local sprintSpeed = self:GetNetworkedFloat("SprintSpeed");
  3818.         local walkSpeed = self:GetNetworkedFloat("WalkSpeed");
  3819.         local velocity = self:GetVelocity():Length();
  3820.        
  3821.         if (velocity >= math.max(sprintSpeed - 25, 25)
  3822.         and sprintSpeed > walkSpeed) then
  3823.             return true;
  3824.         end;
  3825.     end;
  3826. end;
  3827.  
  3828. -- A function to get whether a player is jogging.
  3829. function playerMeta:IsJogging(testSpeed)
  3830.     if ( !self:IsRunning() and (self:GetSharedVar("sh_Jogging") or testSpeed) ) then
  3831.         if ( self:Alive() and !self:IsRagdolled() and !self:InVehicle() and !self:Crouching() ) then
  3832.             local walkSpeed = self:GetNetworkedFloat("WalkSpeed");
  3833.             local velocity = self:GetVelocity():Length();
  3834.            
  3835.             if ( velocity >= math.max(walkSpeed - 25, 25) ) then
  3836.                 return true;
  3837.             end;
  3838.         end;
  3839.     end;
  3840. end;
  3841.  
  3842. -- A function to strip a weapon from a player.
  3843. function playerMeta:StripWeapon(weaponClass)
  3844.     if ( self:IsRagdolled() ) then
  3845.         local ragdollWeapons = self:GetRagdollWeapons();
  3846.        
  3847.         for k, v in pairs(ragdollWeapons) do
  3848.             if (v.weaponData["class"] == weaponClass) then
  3849.                 weapons[k] = nil;
  3850.             end;
  3851.         end;
  3852.     else
  3853.         self:NexusStripWeapon(weaponClass);
  3854.     end;
  3855. end;
  3856.  
  3857. -- A function to handle a player's attribute progress.
  3858. function playerMeta:HandleAttributeProgress(curTime)
  3859.     if (self.attributeProgressTime and curTime >= self.attributeProgressTime) then
  3860.         self.attributeProgressTime = curTime + 30;
  3861.        
  3862.         for k, v in pairs(self.attributeProgress) do
  3863.             local attributeTable = nexus.attribute.Get(k);
  3864.            
  3865.             if (attributeTable) then
  3866.                 umsg.Start("nx_AttributeProgress", self);
  3867.                     umsg.Long(attributeTable.index);
  3868.                     umsg.Short(v);
  3869.                 umsg.End();
  3870.             end;
  3871.         end;
  3872.        
  3873.         if (self.attributeProgress) then
  3874.             self.attributeProgress = {};
  3875.         end;
  3876.     end;
  3877. end;
  3878.  
  3879. -- A function to handle a player's attribute boosts.
  3880. function playerMeta:HandleAttributeBoosts(curTime)
  3881.     for k, v in pairs(self.attributeBoosts) do
  3882.         for k2, v2 in pairs(v) do
  3883.             if (v2.duration and v2.endTime) then
  3884.                 if (curTime > v2.endTime) then
  3885.                     self:BoostAttribute(k2, k, false);
  3886.                 else
  3887.                     local timeLeft = v2.endTime - curTime;
  3888.                    
  3889.                     if (timeLeft >= 0) then
  3890.                         if (v2.default < 0) then
  3891.                             v2.amount = math.min( (v2.default / v2.duration) * timeLeft, 0 );
  3892.                         else
  3893.                             v2.amount = math.max( (v2.default / v2.duration) * timeLeft, 0 );
  3894.                         end;
  3895.                     end;
  3896.                 end;
  3897.             end;
  3898.         end;
  3899.     end;
  3900. end;
  3901.  
  3902. -- A function to strip a player's weapons.
  3903. function playerMeta:StripWeapons(ragdollForce)
  3904.     if (self:IsRagdolled() and !ragdollForce) then
  3905.         self:GetRagdollTable().weapons = {};
  3906.     else
  3907.         self:NexusStripWeapons();
  3908.     end;
  3909. end;
  3910.  
  3911. -- A function to enable God for a player.
  3912. function playerMeta:GodEnable()
  3913.     self.godMode = true; self:NexusGodEnable();
  3914. end;
  3915.  
  3916. -- A function to disable God for a player.
  3917. function playerMeta:GodDisable()
  3918.     self.godMode = nil; self:NexusGodDisable();
  3919. end;
  3920.  
  3921. -- A function to get whether a player has God mode enabled.
  3922. function playerMeta:IsInGodMode()
  3923.     return self.godMode;
  3924. end;
  3925.  
  3926. -- A function to update whether a player's weapon is raised.
  3927. function playerMeta:UpdateWeaponRaised()
  3928.     nexus.player.UpdateWeaponRaised(self);
  3929. end;
  3930.  
  3931. -- A function to get a player's water level.
  3932. function playerMeta:WaterLevel()
  3933.     if ( self:IsRagdolled() ) then
  3934.         return self:GetRagdollEntity():WaterLevel();
  3935.     else
  3936.         return self:NexusWaterLevel();
  3937.     end;
  3938. end;
  3939.  
  3940. -- A function to get whether a player is on fire.
  3941. function playerMeta:IsOnFire()
  3942.     if ( self:IsRagdolled() ) then
  3943.         return self:GetRagdollEntity():IsOnFire();
  3944.     else
  3945.         return self:NexusIsOnFire();
  3946.     end;
  3947. end;
  3948.  
  3949. -- A function to extinguish a player.
  3950. function playerMeta:Extinguish()
  3951.     if ( self:IsRagdolled() ) then
  3952.         return self:GetRagdollEntity():Extinguish();
  3953.     else
  3954.         return self:NexusExtinguish();
  3955.     end;
  3956. end;
  3957.  
  3958. -- A function to get whether a player is using their hands.
  3959. function playerMeta:IsUsingHands()
  3960.     return nexus.player.GetWeaponClass(self) == "nx_hands";
  3961. end;
  3962.  
  3963. -- A function to get whether a player is using their hands.
  3964. function playerMeta:IsUsingKeys()
  3965.     return nexus.player.GetWeaponClass(self) == "nx_keys";
  3966. end;
  3967.  
  3968. -- A function to get a player's wages.
  3969. function playerMeta:GetWages()
  3970.     return nexus.player.GetWages(self);
  3971. end;
  3972.  
  3973. -- A function to get a player's community ID.
  3974. function playerMeta:CommunityID()
  3975.     local x, y, z = string.match(self:SteamID(), "STEAM_(%d+):(%d+):(%d+)");
  3976.    
  3977.     if (x and y and z) then
  3978.         return (z * 2) + STEAM_COMMUNITY_ID + y;
  3979.     else
  3980.         return self:SteamID();
  3981.     end;
  3982. end;
  3983.  
  3984. -- A function to get whether a player is ragdolled.
  3985. function playerMeta:IsRagdolled(exception, entityless)
  3986.     return nexus.player.IsRagdolled(self, exception, entityless);
  3987. end;
  3988.  
  3989. -- A function to get whether a player is kicked.
  3990. function playerMeta:IsKicked()
  3991.     return self.isKicked;
  3992. end;
  3993.  
  3994. -- A function to get whether a player has spawned.
  3995. function playerMeta:HasSpawned()
  3996.     return self.hasSpawned;
  3997. end;
  3998.  
  3999. -- A function to kick a player.
  4000. function playerMeta:Kick(reason)
  4001.     if ( !self:IsKicked() ) then
  4002.         timer.Simple(FrameTime() * 0.5, function()
  4003.             local isKicked = self:IsKicked();
  4004.            
  4005.             if (IsValid(self) and isKicked) then
  4006.                 if ( self:HasSpawned() ) then
  4007.                     GetNetChannel(self):Shutdown(isKicked);
  4008.                 else
  4009.                     self.isKicked = nil;
  4010.                     self:Kick(isKicked);
  4011.                 end;
  4012.             end;
  4013.         end);
  4014.     end;
  4015.    
  4016.     if (!reason) then
  4017.         self.isKicked = "You have been kicked.";
  4018.     else
  4019.         self.isKicked = reason;
  4020.     end;
  4021. end;
  4022.  
  4023. -- A function to ban a player.
  4024. function playerMeta:Ban(duration, reason)
  4025.     NEXUS:AddBan(self:SteamID(), duration * 60, reason);
  4026. end;
  4027.  
  4028. -- A function to get a player's character table.
  4029. function playerMeta:GetCharacter() return nexus.player.GetCharacter(self); end;
  4030.  
  4031. -- A function to get a player's storage table.
  4032. function playerMeta:GetStorageTable() return nexus.player.GetStorageTable(self); end;
  4033.  
  4034. -- A function to get a player's ragdoll table.
  4035. function playerMeta:GetRagdollTable() return nexus.player.GetRagdollTable(self); end;
  4036.  
  4037. -- A function to get a player's ragdoll state.
  4038. function playerMeta:GetRagdollState() return nexus.player.GetRagdollState(self); end;
  4039.  
  4040. -- A function to get a player's storage entity.
  4041. function playerMeta:GetStorageEntity() return nexus.player.GetStorageEntity(self); end;
  4042.  
  4043. -- A function to get a player's ragdoll entity.
  4044. function playerMeta:GetRagdollEntity() return nexus.player.GetRagdollEntity(self); end;
  4045.  
  4046. -- A function to get a player's ragdoll weapons.
  4047. function playerMeta:GetRagdollWeapons()
  4048.     return self:GetRagdollTable().weapons or {};
  4049. end;
  4050.  
  4051. -- A function to get whether a player's ragdoll has a weapon.
  4052. function playerMeta:RagdollHasWeapon(weaponClass)
  4053.     local ragdollWeapons = self:GetRagdollWeapons();
  4054.    
  4055.     if (ragdollWeapons) then
  4056.         for k, v in pairs(ragdollWeapons) do
  4057.             if (v.weaponData["class"] == weaponClass) then
  4058.                 return true;
  4059.             end;
  4060.         end;
  4061.     end;
  4062. end;
  4063.  
  4064. -- A function to set a player's maximum armor.
  4065. function playerMeta:SetMaxArmor(armor)
  4066.     self:SetSharedVar("sh_MaxArmor", armor);
  4067. end;
  4068.  
  4069. -- A function to get a player's maximum armor.
  4070. function playerMeta:GetMaxArmor(armor)
  4071.     local maxArmor = self:GetSharedVar("sh_MaxArmor");
  4072.    
  4073.     if (maxArmor > 0) then
  4074.         return maxArmor;
  4075.     else
  4076.         return 100;
  4077.     end;
  4078. end;
  4079.  
  4080. -- A function to set a player's maximum health.
  4081. function playerMeta:SetMaxHealth(health)
  4082.     self:SetSharedVar("sh_MaxHealth", health);
  4083. end;
  4084.  
  4085. -- A function to get a player's maximum health.
  4086. function playerMeta:GetMaxHealth(health)
  4087.     local maxHealth = self:GetSharedVar("sh_MaxHealth");
  4088.    
  4089.     if (maxHealth > 0) then
  4090.         return maxHealth;
  4091.     else
  4092.         return 100;
  4093.     end;
  4094. end;
  4095.  
  4096. -- A function to get whether a player is viewing the starter hints.
  4097. function playerMeta:IsViewingStarterHints()
  4098.     return self.isViewingStarterHints;
  4099. end;
  4100.  
  4101. -- A function to get a player's last hit group.
  4102. function playerMeta:LastHitGroup()
  4103.     return self.lastHitGroup or self:NexusLastHitGroup();
  4104. end;
  4105.  
  4106. -- A function to get whether an entity is being held.
  4107. function entityMeta:IsBeingHeld()
  4108.     if ( IsValid(self) ) then
  4109.         return nexus.mount.Call("GetEntityBeingHeld", self);
  4110.     end;
  4111. end;
  4112.  
  4113. -- A function to run a command on a player.
  4114. function playerMeta:RunCommand(...)
  4115.     NEXUS:StartDataStream( self, "RunCommand", {...} );
  4116. end;
  4117.  
  4118. -- A function to get a player's wages name.
  4119. function playerMeta:GetWagesName()
  4120.     return nexus.player.GetWagesName(self);
  4121. end;
  4122.  
  4123. -- A function to set a player's forced animation.
  4124. function playerMeta:SetForcedAnimation(animation, delay, onAnimate, onFinish)
  4125.     local forcedAnimation = self:GetForcedAnimation();
  4126.     local callFinish = false;
  4127.     local sequence = nil;
  4128.    
  4129.     if (animation) then
  4130.         if (!forcedAnimation or forcedAnimation.delay != 0) then
  4131.             if (type(animation) == "string") then
  4132.                 sequence = self:LookupSequence(animation);
  4133.             else
  4134.                 sequence = self:SelectWeightedSequence(animation);
  4135.             end;
  4136.            
  4137.             self.forcedAnimation = {
  4138.                 animation = animation,
  4139.                 onAnimate = onAnimate,
  4140.                 onFinish = onFinish,
  4141.                 delay = delay
  4142.             };
  4143.            
  4144.             if (delay and delay != 0) then
  4145.                 NEXUS:CreateTimer("Forced Animation: "..self:UniqueID(), delay, 1, function()
  4146.                     if ( IsValid(self) ) then
  4147.                         local forcedAnimation = self:GetForcedAnimation();
  4148.                        
  4149.                         if (forcedAnimation) then
  4150.                             self:SetForcedAnimation(false);
  4151.                         end;
  4152.                     end;
  4153.                 end);
  4154.             else
  4155.                 NEXUS:DestroyTimer( "Forced Animation: "..self:UniqueID() );
  4156.             end;
  4157.            
  4158.             self:SetSharedVar("sh_ForcedAnim", sequence);
  4159.             callFinish = true;
  4160.         end;
  4161.     else
  4162.         callFinish = true;
  4163.         self:SetSharedVar("sh_ForcedAnim", 0);
  4164.         self.forcedAnimation = nil;
  4165.     end;
  4166.    
  4167.     if (callFinish) then
  4168.         if (forcedAnimation and forcedAnimation.onFinish) then
  4169.             forcedAnimation.onFinish(self);
  4170.         end;
  4171.     end;
  4172. end;
  4173.  
  4174. -- A function to set whether a player's config has initialized.
  4175. function playerMeta:SetConfigInitialized(initialized)
  4176.     self.configInitialized = initialized;
  4177. end;
  4178.  
  4179. -- A function to get whether a player's config has initialized.
  4180. function playerMeta:HasConfigInitialized()
  4181.     return self.configInitialized;
  4182. end;
  4183.  
  4184. -- A function to get a player's forced animation.
  4185. function playerMeta:GetForcedAnimation()
  4186.     return self.forcedAnimation;
  4187. end;
  4188.  
  4189. -- A function to get a player's item entity.
  4190. function playerMeta:GetItemEntity()
  4191.     if ( IsValid(self.itemEntity) ) then
  4192.         return self.itemEntity;
  4193.     end;
  4194. end;
  4195.  
  4196. -- A function to set a player's item entity.
  4197. function playerMeta:SetItemEntity(entity)
  4198.     self.itemEntity = entity;
  4199. end;
  4200.  
  4201. -- A function to create a player's temporary data.
  4202. function playerMeta:CreateTempData()
  4203.     local uniqueID = self:UniqueID();
  4204.    
  4205.     if ( !NEXUS.TempPlayerData[uniqueID] ) then
  4206.         NEXUS.TempPlayerData[uniqueID] = {};
  4207.     end;
  4208.    
  4209.     return NEXUS.TempPlayerData[uniqueID];
  4210. end;
  4211.  
  4212. -- A function to make a player fake pickup an entity.
  4213. function playerMeta:FakePickup(entity)
  4214.     local entityPosition = entity:GetPos();
  4215.    
  4216.     if ( entity:IsPlayer() ) then
  4217.         entityPosition = entity:GetShootPos();
  4218.     end;
  4219.    
  4220.     local shootPosition = self:GetShootPos();
  4221.     local feetDistance = self:GetPos():Distance(entityPosition);
  4222.     local armsDistance = shootPosition:Distance(entityPosition);
  4223.    
  4224.     if (feetDistance < armsDistance) then
  4225.         self:SetForcedAnimation("pickup", 1.2);
  4226.     else
  4227.         self:SetForcedAnimation("gunrack", 1.2);
  4228.     end;
  4229. end;
  4230.  
  4231. -- A function to set a player's temporary data.
  4232. function playerMeta:SetTempData(key, value)
  4233.     local tempData = self:CreateTempData();
  4234.    
  4235.     if (tempData) then
  4236.         tempData[key] = value;
  4237.     end;
  4238. end;
  4239.  
  4240. -- A function to get a player's temporary data.
  4241. function playerMeta:GetTempData(key, default)
  4242.     local tempData = self:CreateTempData();
  4243.    
  4244.     if (tempData and tempData[key] != nil) then
  4245.         return tempData[key];
  4246.     else
  4247.         return default;
  4248.     end;
  4249. end;
  4250.  
  4251. -- A function to get whether a player has an item.
  4252. function playerMeta:HasItem(item, anywhere)
  4253.     return nexus.inventory.HasItem(self, item, anywhere);
  4254. end;
  4255.  
  4256. -- A function to get a player's attribute boosts.
  4257. function playerMeta:GetAttributeBoosts()
  4258.     return self.attributeBoosts;
  4259. end;
  4260.  
  4261. -- A function to rebuild a player's inventory.
  4262. function playerMeta:RebuildInventory()
  4263.     nexus.inventory.Rebuild(self);
  4264. end;
  4265.  
  4266. -- A function to update a player's inventory.
  4267. function playerMeta:UpdateInventory(item, amount, force, noMessage)
  4268.     return nexus.inventory.Update(self, item, amount, force, noMessage);
  4269. end;
  4270.  
  4271. -- A function to update a player's attribute.
  4272. function playerMeta:UpdateAttribute(attribute, amount)
  4273.     return nexus.attributes.Update(self, attribute, amount);
  4274. end;
  4275.  
  4276. -- A function to progress a player's attribute.
  4277. function playerMeta:ProgressAttribute(attribute, amount, gradual)
  4278.     return nexus.attributes.Progress(self, attribute, amount, gradual);
  4279. end;
  4280.  
  4281. -- A function to boost a player's attribute.
  4282. function playerMeta:BoostAttribute(identifier, attribute, amount, duration)
  4283.     return nexus.attributes.Boost(self, identifier, attribute, amount, duration);
  4284. end;
  4285.  
  4286. -- A function to get whether a boost is active for a player.
  4287. function playerMeta:IsBoostActive(identifier, attribute, amount, duration)
  4288.     return nexus.attributes.IsBoostActive(self, identifier, attribute, amount, duration);
  4289. end;
  4290.  
  4291. -- A function to get a player's characters.
  4292. function playerMeta:GetCharacters()
  4293.     return self.characters;
  4294. end;
  4295.  
  4296. -- A function to set a player's run speed.
  4297. function playerMeta:SetRunSpeed(speed, nexus)
  4298.     if (!nexus) then self.runSpeed = speed; end;
  4299.    
  4300.     self:NexusSetRunSpeed(speed);
  4301. end;
  4302.  
  4303. -- A function to set a player's walk speed.
  4304. function playerMeta:SetWalkSpeed(speed, nexus)
  4305.     if (!nexus) then self.walkSpeed = speed; end;
  4306.    
  4307.     self:NexusSetWalkSpeed(speed);
  4308. end;
  4309.  
  4310. -- A function to set a player's jump power.
  4311. function playerMeta:SetJumpPower(power, nexus)
  4312.     if (!nexus) then self.jumpPower = power; end;
  4313.    
  4314.     self:NexusSetJumpPower(power);
  4315. end;
  4316.  
  4317. -- A function to set a player's crouched walk speed.
  4318. function playerMeta:SetCrouchedWalkSpeed(speed, nexus)
  4319.     if (!nexus) then self.crouchedSpeed = speed; end;
  4320.    
  4321.     self:NexusSetCrouchedWalkSpeed(speed);
  4322. end;
  4323.  
  4324. -- A function to get whether a player has initialized.
  4325. function playerMeta:HasInitialized()
  4326.     return self.initialized;
  4327. end;
  4328.  
  4329. -- A function to query a player's character table.
  4330. function playerMeta:QueryCharacter(key, default)
  4331.     if ( self:GetCharacter() ) then
  4332.         return nexus.player.Query(self, key, default);
  4333.     else
  4334.         return default;
  4335.     end;
  4336. end;
  4337.  
  4338. -- A function to get a player's shared variable.
  4339. function entityMeta:GetSharedVar(key)
  4340.     if ( self:IsPlayer() ) then
  4341.         return nexus.player.GetSharedVar(self, key);
  4342.     else
  4343.         return nexus.entity.GetSharedVar(self, key);
  4344.     end;
  4345. end;
  4346.  
  4347. -- A function to set a shared variable for a player.
  4348. function entityMeta:SetSharedVar(key, value)
  4349.     if ( self:IsPlayer() ) then
  4350.         nexus.player.SetSharedVar(self, key, value);
  4351.     else
  4352.         nexus.entity.SetSharedVar(self, key, value);
  4353.     end;
  4354. end;
  4355.  
  4356. -- A function to get a player's character data.
  4357. function playerMeta:GetCharacterData(key, default)
  4358.     if ( self:GetCharacter() ) then
  4359.         local data = self:QueryCharacter("data");
  4360.        
  4361.         if (data[key] != nil) then
  4362.             return data[key];
  4363.         else
  4364.             return default;
  4365.         end;
  4366.     else
  4367.         return default;
  4368.     end;
  4369. end;
  4370.  
  4371. -- A function to get a player's time joined.
  4372. function playerMeta:TimeJoined()
  4373.     return self.timeJoined or os.time();
  4374. end;
  4375.  
  4376. -- A function to get when a player last played.
  4377. function playerMeta:LastPlayed()
  4378.     return self.lastPlayed or os.time();
  4379. end;
  4380.  
  4381. -- A function to set a player's character data.
  4382. function playerMeta:SetCharacterData(key, value, base)
  4383.     local character = self:GetCharacter();
  4384.    
  4385.     if (character) then
  4386.         if (base) then
  4387.             if (character[key] != nil) then
  4388.                 character[key] = value;
  4389.             end;
  4390.         else
  4391.             character.data[key] = value;
  4392.         end;
  4393.     end;
  4394. end;
  4395.  
  4396. -- A function to get the entity a player is holding.
  4397. function playerMeta:GetHoldingEntity()
  4398.     return self.isHoldingEntity;
  4399. end;
  4400.  
  4401. playerMeta.GetName = playerMeta.Name;
  4402. playerMeta.Nick = playerMeta.Name;
  4403. --[[
  4404. Name: "sv_auto.lua".
  4405. Product: "Nexus".
  4406. --]]
  4407.  
  4408. for k, v in pairs( file.Find("../materials/decals/flesh/blood*") ) do
  4409.     resource.AddFile("materials/decals/flesh/"..v);
  4410. end;
  4411.  
  4412. for k, v in pairs( file.Find("../materials/decals/blood*") ) do
  4413.     resource.AddFile("materials/decals/"..v);
  4414. end;
  4415.  
  4416. for k, v in pairs( file.Find("../materials/effects/blood*") ) do
  4417.     resource.AddFile("materials/effects/"..v);
  4418. end;
  4419.  
  4420. for k, v in pairs( file.Find("../materials/sprites/blood*") ) do
  4421.     resource.AddFile("materials/sprites/"..v);
  4422. end;
  4423.  
  4424. resource.AddFile("materials/gui/silkicons/information.vtf");
  4425. resource.AddFile("materials/gui/silkicons/information.vmt");
  4426. resource.AddFile("materials/gui/silkicons/user_delete.vtf");
  4427. resource.AddFile("materials/gui/silkicons/user_delete.vmt");
  4428. resource.AddFile("materials/gui/silkicons/newspaper.vtf");
  4429. resource.AddFile("materials/gui/silkicons/newspaper.vmt");
  4430. resource.AddFile("materials/gui/silkicons/user_add.vtf");
  4431. resource.AddFile("materials/gui/silkicons/user_add.vmt");
  4432. resource.AddFile("materials/gui/silkicons/comment.vtf");
  4433. resource.AddFile("materials/gui/silkicons/comment.vmt");
  4434. resource.AddFile("materials/gui/silkicons/error.vtf");
  4435. resource.AddFile("materials/gui/silkicons/error.vmt");
  4436. resource.AddFile("materials/gui/silkicons/help.vtf");
  4437. resource.AddFile("materials/gui/silkicons/help.vmt");
  4438. resource.AddFile("models/humans/female_gestures.ani");
  4439. resource.AddFile("models/humans/female_gestures.mdl");
  4440. resource.AddFile("models/humans/female_postures.ani");
  4441. resource.AddFile("models/humans/female_postures.mdl");
  4442. resource.AddFile("models/combine_soldier_anims.ani");
  4443. resource.AddFile("models/combine_soldier_anims.mdl");
  4444. resource.AddFile("models/humans/female_shared.ani");
  4445. resource.AddFile("models/humans/female_shared.mdl");
  4446. resource.AddFile("models/humans/male_gestures.ani");
  4447. resource.AddFile("models/humans/male_gestures.mdl");
  4448. resource.AddFile("models/humans/male_postures.ani");
  4449. resource.AddFile("models/humans/male_postures.mdl");
  4450. resource.AddFile("models/humans/male_shared.ani");
  4451. resource.AddFile("models/humans/male_shared.mdl");
  4452. resource.AddFile("materials/nexus/xhlogo.vtf");
  4453. resource.AddFile("materials/nexus/xhlogo.vmt");
  4454. resource.AddFile("models/police_animations.ani");
  4455. resource.AddFile("models/police_animations.mdl");
  4456. resource.AddFile("models/humans/female_ss.ani");
  4457. resource.AddFile("models/humans/female_ss.mdl");
  4458. resource.AddFile("materials/nexus/unknown.vtf");
  4459. resource.AddFile("materials/nexus/unknown.vmt");
  4460. resource.AddFile("models/humans/male_ss.ani");
  4461. resource.AddFile("models/humans/male_ss.mdl");
  4462. resource.AddFile("models/police_ss.ani");
  4463. resource.AddFile("models/police_ss.mdl");
  4464.  
  4465. CreateConVar("npc_thinknow", 1);
  4466.  
  4467. AddCSLuaFile("sh_enums.lua");
  4468. AddCSLuaFile("sh_core.lua");
  4469. AddCSLuaFile("sh_auto.lua");
  4470. AddCSLuaFile("cl_auto.lua");
  4471.  
  4472. include("sh_auto.lua");
  4473.  
  4474. local gradientTexture = nexus.schema.GetOption("gradient");
  4475. local introImage = nexus.schema.GetOption("intro_image");
  4476. local CurTime = CurTime;
  4477. local hook = hook;
  4478.  
  4479. if (gradientTexture != "gui/gradient_up") then
  4480.     resource.AddFile("materials/"..gradientTexture..".vtf");
  4481.     resource.AddFile("materials/"..gradientTexture..".vmt");
  4482. end;
  4483.  
  4484. if (introImage != "") then
  4485.     resource.AddFile("materials/"..introImage..".vtf");
  4486.     resource.AddFile("materials/"..introImage..".vmt");
  4487. end;
  4488.  
  4489. _R["CRecipientFilter"].IsValid = function()
  4490.     return true;
  4491. end;
  4492.  
  4493. hook.NexusCall = hook.Call;
  4494.  
  4495. -- A function to call a hook.
  4496. function hook.Call(name, gamemode, ...)
  4497.     local callCachedHook = nexus.mount.CallCachedHook;
  4498.     local arguments = {...};
  4499.     local hookCall = hook.NexusCall;
  4500.    
  4501.     if (!gamemode) then
  4502.         gamemode = NEXUS;
  4503.     end;
  4504.    
  4505.     if (name == "EntityTakeDamage") then
  4506.         if ( NEXUS:DoEntityTakeDamageHook(gamemode, arguments) ) then
  4507.             return;
  4508.         end;
  4509.     end;
  4510.    
  4511.     if (name == "PlayerDisconnected") then
  4512.         if ( !IsValid( arguments[1] ) ) then
  4513.             return;
  4514.         end;
  4515.     end;
  4516.    
  4517.     if (name == "PlayerSay") then
  4518.         arguments[2] = string.Replace(arguments[2], "~", "\"");
  4519.     end;
  4520.    
  4521.     local value = callCachedHook(name, arguments);
  4522.    
  4523.     if (value == nil) then
  4524.         return hookCall( name, gamemode, unpack(arguments) );
  4525.     else
  4526.         return value;
  4527.     end;
  4528. end;
  4529.  
  4530. -- Called when the server initializes.
  4531. function NEXUS:Initialize()
  4532.     local useLocalMachineDate = nexus.config.Get("use_local_machine_date"):Get();
  4533.     local useLocalMachineTime = nexus.config.Get("use_local_machine_time"):Get();
  4534.     local defaultDate = nexus.schema.GetOption("default_date");
  4535.     local defaultTime = nexus.schema.GetOption("default_time");
  4536.     local defaultDays = nexus.schema.GetOption("default_days");
  4537.     local username = nexus.config.Get("mysql_username"):Get();
  4538.     local password = nexus.config.Get("mysql_password"):Get();
  4539.     local database = nexus.config.Get("mysql_database"):Get();
  4540.     local dateInfo = os.date("*t");
  4541.     local host = nexus.config.Get("mysql_host"):Get();
  4542.    
  4543.     local success, value = pcall(tmysql.initialize, host, username, password, database, 3306, 6, 6);
  4544.         NEXUS.NoMySQL = !success;
  4545.        
  4546.     if (useLocalMachineTime) then
  4547.         nexus.config.Get("minute_time"):Set(60);
  4548.     end;
  4549.    
  4550.     nexus.config.SetInitialized(true);
  4551.    
  4552.     table.Merge(nexus.time, defaultTime);
  4553.     table.Merge(nexus.date, defaultDate);
  4554.    
  4555.     math.randomseed( os.time() );
  4556.    
  4557.     if (useLocalMachineTime) then
  4558.         local realDay = dateInfo.wday - 1;
  4559.        
  4560.         if (realDay == 0) then
  4561.             realDay = #defaultDays;
  4562.         end;
  4563.        
  4564.         table.Merge( nexus.time, {
  4565.             minute = dateInfo.min,
  4566.             hour = dateInfo.hour,
  4567.             day = realDay
  4568.         } );
  4569.        
  4570.         self.NextDateTimeThink = SysTime() + (60 - dateInfo.sec);
  4571.     else
  4572.         table.Merge( nexus.time, self:RestoreSchemaData("time") );
  4573.     end;
  4574.    
  4575.     if (useLocalMachineDate) then
  4576.         dateInfo.year = dateInfo.year + (defaultDate.year - dateInfo.year);
  4577.        
  4578.         table.Merge( nexus.time, {
  4579.             month = dateInfo.month,
  4580.             year = dateInfo.year,
  4581.             day = dateInfo.yday
  4582.         } );
  4583.     else
  4584.         table.Merge( nexus.date, self:RestoreSchemaData("date") );
  4585.     end;
  4586.    
  4587.     NX_CONVAR_DEBUG = self:CreateConVar("nx_debug", 1);
  4588.     NX_CONVAR_LOG = self:CreateConVar("nx_log", 1)
  4589.    
  4590.     for k, v in pairs(nexus.config.stored) do
  4591.         nexus.mount.Call("NexusConfigInitialized", k, v.value);
  4592.     end;
  4593.    
  4594.     RunConsoleCommand("sv_usermessage_maxsize", "1024");
  4595.         nexus.mount.Call("NexusInitialized");
  4596.     self:LoadBans();
  4597. end;
  4598.  
  4599. -- Called when a player has disconnected.
  4600. function NEXUS:PlayerDisconnected(player)
  4601.     local tempData = player:CreateTempData();
  4602.    
  4603.     if ( player:HasInitialized() ) then
  4604.         if (nexus.mount.Call("PlayerCharacterUnloaded", player) != true) then
  4605.             player:SaveCharacter();
  4606.         end;
  4607.        
  4608.         if (tempData) then
  4609.             nexus.mount.Call("PlayerSaveTempData", player, tempData);
  4610.         end;
  4611.        
  4612.         nexus.chatBox.Add(nil, nil, "disconnect", player:SteamName().." has disconnected from the server.");
  4613.        
  4614.         self:PrintDebug(player:SteamName().." ("..player:SteamID().."|"..player:IPAddress()..") has disconnected from the server.");
  4615.     end;
  4616. end;
  4617.  
  4618. -- Called when the Nexus core has loaded.
  4619. function NEXUS:NexusCoreLoaded()
  4620.     nexus.config.Import("nexus/mysql.cfg");
  4621. end;
  4622.  
  4623. -- Called when Nexus has initialized.
  4624. function NEXUS:NexusInitialized()
  4625.     local cashName = nexus.schema.GetOption("name_cash");
  4626.    
  4627.     if ( !nexus.config.Get("cash_enabled"):Get() ) then
  4628.         nexus.command.SetHidden(string.gsub(cashName, "%s", "").."Give", true);
  4629.         nexus.command.SetHidden(string.gsub(cashName, "%s", "").."Drop", true);
  4630.         nexus.command.SetHidden("StorageTakeCash", true);
  4631.         nexus.command.SetHidden("StorageGiveCash", true);
  4632.        
  4633.         nexus.config.Get("scale_prop_cost"):Set(0, nil, true, true);
  4634.         nexus.config.Get("door_cost"):Set(0, nil, true, true);
  4635.     end;
  4636. end;
  4637.  
  4638. -- Called when a player is banned.
  4639. function NEXUS:PlayerBanned(player, duration, reason) end;
  4640.  
  4641. -- Called when a player's model has changed.
  4642. function NEXUS:PlayerModelChanged(player, model) end;
  4643.  
  4644. -- Called when a player's inventory string is needed.
  4645. function NEXUS:PlayerGetInventoryString(player, character, inventory)
  4646.     if ( player:IsRagdolled() ) then
  4647.         for k, v in pairs( player:GetRagdollWeapons() ) do
  4648.             if (v.canHolster) then
  4649.                 local class = v.weaponData["class"];
  4650.                 local uniqueID = v.weaponData["uniqueID"];
  4651.                 local itemTable = nexus.item.GetWeapon(class, uniqueID);
  4652.                
  4653.                 if (itemTable) then
  4654.                     if ( !nexus.player.GetSpawnWeapon(player, class) ) then
  4655.                         if ( inventory[itemTable.uniqueID] ) then
  4656.                             inventory[itemTable.uniqueID] = inventory[itemTable.uniqueID] + 1;
  4657.                         else
  4658.                             inventory[itemTable.uniqueID] = 1;
  4659.                         end;
  4660.                     end;
  4661.                 end;
  4662.             end;
  4663.         end;
  4664.     end;
  4665.    
  4666.     for k, v in pairs( player:GetWeapons() ) do
  4667.         local class = v:GetClass();
  4668.         local itemTable = nexus.item.GetWeapon(v);
  4669.        
  4670.         if (itemTable) then
  4671.             if ( !nexus.player.GetSpawnWeapon(player, class) ) then
  4672.                 if ( inventory[itemTable.uniqueID] ) then
  4673.                     inventory[itemTable.uniqueID] = inventory[itemTable.uniqueID] + 1;
  4674.                 else
  4675.                     inventory[itemTable.uniqueID] = 1;
  4676.                 end;
  4677.             end;
  4678.         end;
  4679.     end;
  4680. end;
  4681.  
  4682. -- Called when a player's unlock info is needed.
  4683. function NEXUS:PlayerGetUnlockInfo(player, entity)
  4684.     if ( nexus.entity.IsDoor(entity) ) then
  4685.         return {
  4686.             duration = nexus.config.Get("unlock_time"):Get(),
  4687.             Callback = function(player, entity)
  4688.                 entity:Fire("unlock", "", 0);
  4689.             end
  4690.         };
  4691.     end;
  4692. end;
  4693.  
  4694. -- Called when a player's lock info is needed.
  4695. function NEXUS:PlayerGetLockInfo(player, entity)
  4696.     if ( nexus.entity.IsDoor(entity) ) then
  4697.         return {
  4698.             duration = nexus.config.Get("lock_time"):Get(),
  4699.             Callback = function(player, entity)
  4700.                 entity:Fire("lock", "", 0);
  4701.             end
  4702.         };
  4703.     end;
  4704. end;
  4705.  
  4706. -- Called when data should be saved.
  4707. function NEXUS:SaveData()
  4708.     for k, v in ipairs( g_Player.GetAll() ) do
  4709.         if ( v:HasInitialized() ) then
  4710.             v:SaveCharacter();
  4711.         end;
  4712.     end;
  4713.    
  4714.     if ( !nexus.config.Get("use_local_machine_time"):Get() ) then
  4715.         self:SaveSchemaData( "time", nexus.time.GetSaveData() );
  4716.     end;
  4717.    
  4718.     if ( !nexus.config.Get("use_local_machine_date"):Get() ) then
  4719.         self:SaveSchemaData( "date", nexus.date.GetSaveData() );
  4720.     end;
  4721. end;
  4722.  
  4723. -- Called when a player attempts to fire a weapon.
  4724. function NEXUS:PlayerCanFireWeapon(player, raised, weapon, secondary)
  4725.     local canShootTime = player.canShootTime;
  4726.     local curTime = CurTime();
  4727.    
  4728.     if (nexus.config.Get("raised_weapon_system"):Get() and !raised) then
  4729.         if ( !nexus.mount.Call("PlayerCanUseLoweredWeapon", player, weapon, secondary) ) then
  4730.             return false;
  4731.         end;
  4732.     end;
  4733.    
  4734.     if (canShootTime and canShootTime > curTime) then
  4735.         return false;
  4736.     end;
  4737.    
  4738.     return true;
  4739. end;
  4740.  
  4741. -- Called when a player attempts to use a lowered weapon.
  4742. function NEXUS:PlayerCanUseLoweredWeapon(player, weapon, secondary)
  4743.     if (secondary) then
  4744.         return weapon.NeverRaised or (weapon.Secondary and weapon.Secondary.NeverRaised);
  4745.     else
  4746.         return weapon.NeverRaised or (weapon.Primary and weapon.Primary.NeverRaised);
  4747.     end;
  4748. end;
  4749.  
  4750. -- Called when a player's recognised names have been cleared.
  4751. function NEXUS:PlayerRecognisedNamesCleared(player, status, simple) end;
  4752.  
  4753. -- Called when a player's name has been cleared.
  4754. function NEXUS:PlayerNameCleared(player, status, simple) end;
  4755.  
  4756. -- Called when an offline player has been given property.
  4757. function NEXUS:PlayerPropertyGivenOffline(key, uniqueID, entity, networked, removeDelay) end;
  4758.  
  4759. -- Called when an offline player has had property taken.
  4760. function NEXUS:PlayerPropertyTakenOffline(key, uniqueID, entity) end;
  4761.  
  4762. -- Called when a player has been given property.
  4763. function NEXUS:PlayerPropertyGiven(player, entity, networked, removeDelay) end;
  4764.  
  4765. -- Called when a player has had property taken.
  4766. function NEXUS:PlayerPropertyTaken(player, entity) end;
  4767.  
  4768. -- Called when a player's visibility should be set up.
  4769. function NEXUS:SetupPlayerVisibility(player)
  4770.     local ragdollEntity = player:GetRagdollEntity();
  4771.     local curTime = CurTime();
  4772.    
  4773.     if (ragdollEntity) then
  4774.         AddOriginToPVS( ragdollEntity:GetPos() );
  4775.     end;
  4776.    
  4777.     if ( player:HasInitialized() ) then
  4778.         if (!player.nextThink) then
  4779.             player.nextThink = curTime + 0.5;
  4780.         end;
  4781.        
  4782.         if (!player.nextSetSharedVars) then
  4783.             player.nextSetSharedVars = curTime + 3;
  4784.         end;
  4785.        
  4786.         if (curTime >= player.nextThink) then
  4787.             nexus.player.CallThinkHook(player, (curTime >= player.nextSetSharedVars), {}, curTime);
  4788.         end;
  4789.     end;
  4790. end;
  4791.  
  4792. -- Called when a player has been given flags.
  4793. function NEXUS:PlayerFlagsGiven(player, flags)
  4794.     if ( string.find(flags, "p") and player:Alive() ) then
  4795.         nexus.player.GiveSpawnWeapon(player, "weapon_physgun");
  4796.     end;
  4797.    
  4798.     if ( string.find(flags, "t") and player:Alive() ) then
  4799.         nexus.player.GiveSpawnWeapon(player, "gmod_tool");
  4800.     end;
  4801.    
  4802.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  4803. end;
  4804.  
  4805. -- Called when a player has had flags taken.
  4806. function NEXUS:PlayerFlagsTaken(player, flags)
  4807.     if ( string.find(flags, "p") and player:Alive() ) then
  4808.         if ( !nexus.player.HasFlags(player, "p") ) then
  4809.             nexus.player.TakeSpawnWeapon(player, "weapon_physgun");
  4810.         end;
  4811.     end;
  4812.    
  4813.     if ( string.find(flags, "t") and player:Alive() ) then
  4814.         if ( !nexus.player.HasFlags(player, "t") ) then
  4815.             nexus.player.TakeSpawnWeapon(player, "gmod_tool");
  4816.         end;
  4817.     end;
  4818.    
  4819.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  4820. end;
  4821.  
  4822. -- Called when the game description is needed.
  4823. function NEXUS:GetGameDescription()
  4824.     if (SCHEMA and SCHEMA.name != "Base") then
  4825.         return SCHEMA.name;
  4826.     else
  4827.         return self.Name;
  4828.     end;
  4829. end;
  4830.  
  4831. -- Called when a player's phys desc override is needed.
  4832. function NEXUS:GetPlayerPhysDescOverride(player, physDesc) end;
  4833.  
  4834. -- Called when a player's default skin is needed.
  4835. function NEXUS:GetPlayerDefaultSkin(player)
  4836.     local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
  4837.    
  4838.     return skin;
  4839. end;
  4840.  
  4841. -- Called when a player's default model is needed.
  4842. function NEXUS:GetPlayerDefaultModel(player)
  4843.     local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
  4844.    
  4845.     return model;
  4846. end;
  4847.  
  4848. -- Called when a player's default inventory is needed.
  4849. function NEXUS:GetPlayerDefaultInventory(player, character, inventory) end;
  4850.  
  4851. -- Called to get whether a player's weapon is raised.
  4852. function NEXUS:GetPlayerWeaponRaised(player, class, weapon)
  4853.     if (class == "weapon_physgun" or class == "weapon_physcannon" or class == "gmod_tool") then
  4854.         return true;
  4855.     end;
  4856.    
  4857.     if ( weapon:GetNetworkedBool("Ironsights") ) then
  4858.         return true;
  4859.     end;
  4860.    
  4861.     if (weapon:GetNetworkedInt("Zoom") != 0) then
  4862.         return true;
  4863.     end;
  4864.    
  4865.     if ( weapon:GetNetworkedBool("Scope") ) then
  4866.         return true;
  4867.     end;
  4868.    
  4869.     if (player.toggleWeaponRaised == class) then
  4870.         return true;
  4871.     else
  4872.         player.toggleWeaponRaised = nil;
  4873.     end;
  4874.    
  4875.     if (player.autoWeaponRaised == class) then
  4876.         return true;
  4877.     else
  4878.         player.autoWeaponRaised = nil;
  4879.     end;
  4880. end;
  4881.  
  4882. -- Called when a player's attribute has been updated.
  4883. function NEXUS:PlayerAttributeUpdated(player, attributeTable, amount) end;
  4884.  
  4885. -- Called when a player's inventory item has been updated.
  4886. function NEXUS:PlayerInventoryItemUpdated(player, itemTable, amount, force)
  4887.     nexus.player.UpdateStorageForPlayer(player, itemTable.uniqueID);
  4888. end;
  4889.  
  4890. -- Called when a player's cash has been updated.
  4891. function NEXUS:PlayerCashUpdated(player, amount, reason, noMessage)
  4892.     nexus.player.UpdateStorageForPlayer(player);
  4893. end;
  4894.  
  4895. -- A function to scale damage by hit group.
  4896. function NEXUS:PlayerScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, baseDamage)
  4897.     if ( attacker:IsVehicle() or ( attacker:IsPlayer() and attacker:InVehicle() ) ) then
  4898.         damageInfo:ScaleDamage(0.25);
  4899.     end;
  4900. end;
  4901.  
  4902. -- Called when a player switches their flashlight on or off.
  4903. function NEXUS:PlayerSwitchFlashlight(player, on)
  4904.     if (player:HasInitialized() and on) then
  4905.         if ( player:IsRagdolled() ) then
  4906.             return false;
  4907.         else
  4908.             return true;
  4909.         end;
  4910.     else
  4911.         return true;
  4912.     end;
  4913. end;
  4914.  
  4915. -- Called when time has passed.
  4916. function NEXUS:TimePassed(quantity) end;
  4917.  
  4918. -- Called when Nexus config has initialized.
  4919. function NEXUS:NexusConfigInitialized(key, value)
  4920.     if (key == "cash_enabled" and !value) then
  4921.         for k, v in pairs( nexus.item.GetAll() ) do
  4922.             v.cost = 0;
  4923.         end;
  4924.     elseif (key == "local_voice") then
  4925.         if (value) then
  4926.             RunConsoleCommand("sv_alltalk", "0");
  4927.         end;
  4928.     elseif (key == "use_optimised_rates") then
  4929.         if (value) then
  4930.             RunConsoleCommand("sv_maxupdaterate", "66");
  4931.             RunConsoleCommand("sv_minupdaterate", "0");
  4932.             RunConsoleCommand("sv_maxcmdrate", "66");
  4933.             RunConsoleCommand("sv_mincmdrate", "0");
  4934.             RunConsoleCommand("sv_maxrate", "25000");
  4935.             RunConsoleCommand("sv_minrate", "0");
  4936.         end;
  4937.     end;
  4938. end;
  4939.  
  4940. -- Called when a Nexus ConVar has changed.
  4941. function NEXUS:NexusConVarChanged(name, previousValue, newValue)
  4942.     if (name == "local_voice" and newValue) then
  4943.         RunConsoleCommand("sv_alltalk", "1");
  4944.     end;
  4945. end;
  4946.  
  4947. -- Called when Nexus config has changed.
  4948. function NEXUS:NexusConfigChanged(key, data, previousValue, newValue)
  4949.     if (key == "default_flags") then
  4950.         for k, v in ipairs( g_Player.GetAll() ) do
  4951.             if ( v:HasInitialized() and v:Alive() ) then
  4952.                 if ( string.find(previousValue, "p") ) then
  4953.                     if ( !string.find(newValue, "p") ) then
  4954.                         if ( !nexus.player.HasFlags(v, "p") ) then
  4955.                             nexus.player.TakeSpawnWeapon(v, "weapon_physgun");
  4956.                         end;
  4957.                     end;
  4958.                 elseif ( !string.find(previousValue, "p") ) then
  4959.                     if ( string.find(newValue, "p") ) then
  4960.                         nexus.player.GiveSpawnWeapon(v, "weapon_physgun");
  4961.                     end;
  4962.                 end;
  4963.                
  4964.                 if ( string.find(previousValue, "t") ) then
  4965.                     if ( !string.find(newValue, "t") ) then
  4966.                         if ( !nexus.player.HasFlags(v, "t") ) then
  4967.                             nexus.player.TakeSpawnWeapon(v, "gmod_tool");
  4968.                         end;
  4969.                     end;
  4970.                 elseif ( !string.find(previousValue, "t") ) then
  4971.                     if ( string.find(newValue, "t") ) then
  4972.                         nexus.player.GiveSpawnWeapon(v, "gmod_tool");
  4973.                     end;
  4974.                 end;
  4975.             end;
  4976.         end;
  4977.     elseif (key == "crouched_speed") then
  4978.         for k, v in ipairs( g_Player.GetAll() ) do
  4979.             v:SetCrouchedWalkSpeed(newValue);
  4980.         end;
  4981.     elseif (key == "ooc_interval") then
  4982.         for k, v in ipairs( g_Player.GetAll() ) do
  4983.             v.nextTalkOOC = nil;
  4984.         end;
  4985.     elseif (key == "jump_power") then
  4986.         for k, v in ipairs( g_Player.GetAll() ) do
  4987.             v:SetJumpPower(newValue);
  4988.         end;
  4989.     elseif (key == "walk_speed") then
  4990.         for k, v in ipairs( g_Player.GetAll() ) do
  4991.             v:SetWalkSpeed(newValue);
  4992.         end;
  4993.     elseif (key == "run_speed") then
  4994.         for k, v in ipairs( g_Player.GetAll() ) do
  4995.             v:SetRunSpeed(newValue);
  4996.         end;
  4997.     end;
  4998. end;
  4999.  
  5000. -- Called when a player's name has changed.
  5001. function NEXUS:PlayerNameChanged(player, previousName, newName) end;
  5002.  
  5003. -- Called when a player attempts to sprays their tag.
  5004. function NEXUS:PlayerSpray(player)
  5005.     if ( !player:Alive() or player:IsRagdolled() ) then
  5006.         return true;
  5007.     else
  5008.         return nexus.config.Get("disable_sprays"):Get();
  5009.     end;
  5010. end;
  5011.  
  5012. -- Called when a player attempts to use an entity.
  5013. function NEXUS:PlayerUse(player, entity)
  5014.     if ( player:IsRagdolled(RAGDOLL_FALLENOVER) ) then
  5015.         return false;
  5016.     else
  5017.         return true;
  5018.     end;
  5019. end;
  5020.  
  5021. -- Called when a player's move data is set up.
  5022. function NEXUS:SetupMove(player, moveData)
  5023.     if ( player:Alive() and !player:IsRagdolled() ) then
  5024.         local frameTime = FrameTime();
  5025.         local curTime = CurTime();
  5026.         local drunk = nexus.player.GetDrunk(player);
  5027.        
  5028.         if (drunk and player.drunkSwerve) then
  5029.             player.drunkSwerve = math.Clamp( player.drunkSwerve + frameTime, 0, math.min(drunk * 2, 16) );
  5030.            
  5031.             moveData:SetMoveAngles( moveData:GetMoveAngles() + Angle(0, math.cos(curTime) * player.drunkSwerve, 0) );
  5032.         elseif (player.drunkSwerve and player.drunkSwerve > 1) then
  5033.             player.drunkSwerve = math.max(player.drunkSwerve - frameTime, 0);
  5034.            
  5035.             moveData:SetMoveAngles( moveData:GetMoveAngles() + Angle(0, math.cos(curTime) * player.drunkSwerve, 0) );
  5036.         elseif (player.drunkSwerve != 1) then
  5037.             player.drunkSwerve = 1;
  5038.         end;
  5039.     end;
  5040. end;
  5041.  
  5042. -- Called when a player throws a punch.
  5043. function NEXUS:PlayerPunchThrown(player) end;
  5044.  
  5045. -- Called when a player knocks on a door.
  5046. function NEXUS:PlayerKnockOnDoor(player, door) end;
  5047.  
  5048. -- Called when a player attempts to knock on a door.
  5049. function NEXUS:PlayerCanKnockOnDoor(player, door) return true; end;
  5050.  
  5051. -- Called when a player punches an entity.
  5052. function NEXUS:PlayerPunchEntity(player, entity) end;
  5053.  
  5054. -- Called when a player orders an item shipment.
  5055. function NEXUS:PlayerOrderShipment(player, itemTable, entity) end;
  5056.  
  5057. -- Called when a player holsters a weapon.
  5058. function NEXUS:PlayerHolsterWeapon(player, itemTable, forced)
  5059.     if (itemTable.OnHolster) then
  5060.         itemTable:OnHolster(player, forced);
  5061.     end;
  5062. end;
  5063.  
  5064. -- Called when a player attempts to save a recognised name.
  5065. function NEXUS:PlayerCanSaveRecognisedName(player, target)
  5066.     if (player != target) then return true; end;
  5067. end;
  5068.  
  5069. -- Called when a player attempts to restore a recognised name.
  5070. function NEXUS:PlayerCanRestoreRecognisedName(player, target)
  5071.     if (player != target) then return true; end;
  5072. end;
  5073.  
  5074. -- Called when a player attempts to order an item shipment.
  5075. function NEXUS:PlayerCanOrderShipment(player, itemTable)
  5076.     return true;
  5077. end;
  5078.  
  5079. -- Called when a player attempts to get up.
  5080. function NEXUS:PlayerCanGetUp(player) return true; end;
  5081.  
  5082. -- Called when a player knocks out a player with a punch.
  5083. function NEXUS:PlayerPunchKnockout(player, target) end;
  5084.  
  5085. -- Called when a player attempts to throw a punch.
  5086. function NEXUS:PlayerCanThrowPunch(player) return true; end;
  5087.  
  5088. -- Called when a player attempts to punch an entity.
  5089. function NEXUS:PlayerCanPunchEntity(player, entity) return true; end;
  5090.  
  5091. -- Called when a player attempts to knock a player out with a punch.
  5092. function NEXUS:PlayerCanPunchKnockout(player, target) return true; end;
  5093.  
  5094. -- Called when a player attempts to bypass the faction limit.
  5095. function NEXUS:PlayerCanBypassFactionLimit(player, character) return false; end;
  5096.  
  5097. -- Called when a player attempts to bypass the class limit.
  5098. function NEXUS:PlayerCanBypassClassLimit(player, class) return false; end;
  5099.  
  5100. -- Called when a player's pain sound should be played.
  5101. function NEXUS:PlayerPlayPainSound(player, gender, damageInfo, hitGroup)
  5102.     if (damageInfo:IsBulletDamage() and math.random() <= 0.5) then
  5103.         if (hitGroup == HITGROUP_HEAD) then
  5104.             return "vo/npc/"..gender.."01/ow0"..math.random(1, 2)..".wav";
  5105.         elseif (hitGroup == HITGROUP_CHEST or hitGroup == HITGROUP_GENERIC) then
  5106.             return "vo/npc/"..gender.."01/hitingut0"..math.random(1, 2)..".wav";
  5107.         elseif (hitGroup == HITGROUP_LEFTLEG or hitGroup == HITGROUP_RIGHTLEG) then
  5108.             return "vo/npc/"..gender.."01/myleg0"..math.random(1, 2)..".wav";
  5109.         elseif (hitGroup == HITGROUP_LEFTARM or hitGroup == HITGROUP_RIGHTARM) then
  5110.             return "vo/npc/"..gender.."01/myarm0"..math.random(1, 2)..".wav";
  5111.         elseif (hitGroup == HITGROUP_GEAR) then
  5112.             return "vo/npc/"..gender.."01/startle0"..math.random(1, 2)..".wav";
  5113.         end;
  5114.     end;
  5115.    
  5116.     return "vo/npc/"..gender.."01/pain0"..math.random(1, 9)..".wav";
  5117. end;
  5118.  
  5119. -- Called when a player's data has loaded.
  5120. function NEXUS:PlayerDataLoaded(player)
  5121.     if ( nexus.config.Get("nexus_intro_enabled"):Get() ) then
  5122.         if ( !player:GetData("nexus_intro") ) then
  5123.             umsg.Start("nx_NexusIntro", player);
  5124.             umsg.End();
  5125.            
  5126.             player:SetData("nexus_intro", true);
  5127.         end;
  5128.     end;
  5129. end;
  5130.  
  5131. -- Called when a player attempts to be given a weapon.
  5132. function NEXUS:PlayerCanBeGivenWeapon(player, class, uniqueID, forceReturn)
  5133.     return true;
  5134. end;
  5135.  
  5136. -- Called when a player has been given a weapon.
  5137. function NEXUS:PlayerGivenWeapon(player, class, uniqueID, forceReturn)
  5138.     nexus.inventory.Rebuild(player);
  5139. end;
  5140.  
  5141. -- Called when a player attempts to create a character.
  5142. function NEXUS:PlayerCanCreateCharacter(player, character, characterID)
  5143.     if ( nexus.quiz.GetEnabled() and !nexus.quiz.GetCompleted(player) ) then
  5144.         return false, "You have not completed the quiz!";
  5145.     else
  5146.         return true;
  5147.     end;
  5148. end;
  5149.  
  5150. -- Called when a player attempts to interact with a character.
  5151. function NEXUS:PlayerCanInteractCharacter(player, action, character)
  5152.     if ( nexus.quiz.GetEnabled() and !nexus.quiz.GetCompleted(player) ) then
  5153.         return false, "You have not completed the quiz!";
  5154.     else
  5155.         return true;
  5156.     end;
  5157. end;
  5158.  
  5159. -- Called when a player's fall damage is needed.
  5160. function NEXUS:GetFallDamage(player, velocity)
  5161.     local ragdollEntity = nil;
  5162.     local position = player:GetPos();
  5163.     local damage = math.max( (velocity - 464) * 0.225225225, 0 ) * nexus.config.Get("scale_fall_damage"):Get();
  5164.     local filter = {player};
  5165.    
  5166.     if ( nexus.config.Get("wood_breaks_fall"):Get() ) then
  5167.         if ( player:IsRagdolled() ) then
  5168.             ragdollEntity = player:GetRagdollEntity();
  5169.             position = ragdollEntity:GetPos();
  5170.             filter = {player, ragdollEntity};
  5171.         end;
  5172.        
  5173.         local trace = util.TraceLine( {
  5174.             endpos = position - Vector(0, 0, 64),
  5175.             start = position,
  5176.             filter = filter
  5177.         } );
  5178.  
  5179.         if (IsValid(trace.Entity) and trace.MatType == MAT_WOOD) then
  5180.             if ( string.find(trace.Entity:GetClass(), "prop_physics") ) then
  5181.                 trace.Entity:Fire("Break", "", 0);
  5182.                
  5183.                 damage = damage * 0.25;
  5184.             end;
  5185.         end;
  5186.     end;
  5187.    
  5188.     return damage;
  5189. end;
  5190.  
  5191. -- Called when a player's data stream info has been sent.
  5192. function NEXUS:PlayerDataStreamInfoSent(player)
  5193.     if ( player:IsBot() ) then
  5194.         nexus.player.LoadData(player, function(player)
  5195.             nexus.mount.Call("PlayerDataLoaded", player);
  5196.            
  5197.             local factions = table.ClearKeys(nexus.faction.stored, true);
  5198.             local faction = factions[ math.random(1, #factions) ];
  5199.            
  5200.             if (faction) then
  5201.                 local genders = {GENDER_MALE, GENDER_FEMALE};
  5202.                 local gender = faction.singleGender or genders[ math.random(1, #genders) ];
  5203.                 local models = faction.models[ string.lower(gender) ];
  5204.                 local model = models[ math.random(1, #models) ];
  5205.                
  5206.                 nexus.player.LoadCharacter( player, 1, {
  5207.                     faction = faction.name,
  5208.                     gender = gender,
  5209.                     model = model,
  5210.                     name = player:Name(),
  5211.                     data = {}
  5212.                 }, function()
  5213.                     nexus.player.LoadCharacter(player, 1);
  5214.                 end);
  5215.             end;
  5216.         end);
  5217.     elseif (table.Count(nexus.faction.stored) > 0) then
  5218.         nexus.player.LoadData(player, function()
  5219.             nexus.mount.Call("PlayerDataLoaded", player);
  5220.            
  5221.             local whitelisted = player:GetData("whitelisted");
  5222.             local steamName = player:SteamName();
  5223.             local unixTime = os.time();
  5224.            
  5225.             nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_OPEN);
  5226.            
  5227.             for k, v in pairs(whitelisted) do
  5228.                 if ( nexus.faction.stored[v] ) then
  5229.                     self:StartDataStream( player, "SetWhitelisted", {v, true} );
  5230.                 else
  5231.                     whitelisted[k] = nil;
  5232.                 end;
  5233.             end;
  5234.            
  5235.             nexus.player.GetCharacters(player, function(characters)
  5236.                 if (characters) then
  5237.                     for k, v in pairs(characters) do
  5238.                         nexus.player.ConvertCharacterMySQL(v);
  5239.                        
  5240.                         player.characters[v.characterID] = {};
  5241.                        
  5242.                         for k2, v2 in pairs(v.inventory) do
  5243.                             if ( !nexus.item.GetAll()[k2] ) then
  5244.                                 if ( !nexus.mount.Call("PlayerHasUnknownInventoryItem", player, v.inventory, k2, v2) ) then
  5245.                                     v.inventory[k2] = nil;
  5246.                                 end;
  5247.                             end;
  5248.                         end;
  5249.                        
  5250.                         for k2, v2 in pairs(v.attributes) do
  5251.                             if ( !nexus.attribute.GetAll()[k2] ) then
  5252.                                 if ( !nexus.mount.Call("PlayerHasUnknownAttribute", player, v.attributes, k2, v2.amount, v2.progress) ) then
  5253.                                     v.attributes[k2] = nil;
  5254.                                 end;
  5255.                             end;
  5256.                         end;
  5257.                        
  5258.                         for k2, v2 in pairs(v) do
  5259.                             if (k2 == "timeCreated") then
  5260.                                 if (v2 == "") then
  5261.                                     player.characters[v.characterID][k2] = unixTime;
  5262.                                 else
  5263.                                     player.characters[v.characterID][k2] = v2;
  5264.                                 end;
  5265.                             elseif (k2 == "lastPlayed") then
  5266.                                 player.characters[v.characterID][k2] = unixTime;
  5267.                             elseif (k2 == "steamName") then
  5268.                                 player.characters[v.characterID][k2] = steamName;
  5269.                             else
  5270.                                 player.characters[v.characterID][k2] = v2;
  5271.                             end;
  5272.                         end;
  5273.                     end;
  5274.                    
  5275.                     for k, v in pairs(player.characters) do
  5276.                         local delete = nexus.mount.Call("PlayerAdjustCharacterTable", player, v);
  5277.                        
  5278.                         if (!delete) then
  5279.                             nexus.player.CharacterScreenAdd(player, v);
  5280.                         else
  5281.                             nexus.player.ForceDeleteCharacter(player, k);
  5282.                         end;
  5283.                     end;
  5284.                 end;
  5285.                
  5286.                 nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_LOADED);
  5287.             end);
  5288.         end);
  5289.     end;
  5290. end;
  5291.  
  5292. -- Called when a player's data stream info should be sent.
  5293. function NEXUS:PlayerSendDataStreamInfo(player) end;
  5294.  
  5295. -- Called when a player's death sound should be played.
  5296. function NEXUS:PlayerPlayDeathSound(player, gender)
  5297.     return "vo/npc/"..string.lower(gender).."01/pain0"..math.random(1, 9)..".wav";
  5298. end;
  5299.  
  5300. -- Called when a player's character data should be restored.
  5301. function NEXUS:PlayerRestoreCharacterData(player, data)
  5302.     if ( data["physdesc"] ) then
  5303.         data["physdesc"] = self:ModifyPhysDesc( data["physdesc"] );
  5304.     end;
  5305. end;
  5306.  
  5307. -- Called when a player's character data should be saved.
  5308. function NEXUS:PlayerSaveCharacterData(player, data)
  5309.     if ( nexus.config.Get("save_attribute_boosts"):Get() ) then
  5310.         self:SavePlayerAttributeBoosts(player, data);
  5311.     end;
  5312.    
  5313.     data["health"] = player:Health();
  5314.     data["armor"] = player:Armor();
  5315.    
  5316.     if (data["health"] <= 1) then
  5317.         data["health"] = nil;
  5318.     end;
  5319.    
  5320.     if (data["armor"] <= 1) then
  5321.         data["armor"] = nil;
  5322.     end;
  5323. end;
  5324.  
  5325. -- Called when a player's data should be saved.
  5326. function NEXUS:PlayerSaveData(player, data)
  5327.     if (data["whitelisted"] and #data["whitelisted"] == 0) then
  5328.         data["whitelisted"] = nil;
  5329.     end;
  5330. end;
  5331.  
  5332. -- Called when a player's storage should close.
  5333. function NEXUS:PlayerStorageShouldClose(player, storageTable)
  5334.     local entity = player:GetStorageEntity();
  5335.    
  5336.     if ( player:IsRagdolled() or !player:Alive() or !entity or (storageTable.distance and player:GetShootPos():Distance( entity:GetPos() ) > storageTable.distance) ) then
  5337.         return true;
  5338.     elseif ( storageTable.ShouldClose and storageTable.ShouldClose(player, storageTable) ) then
  5339.         return true;
  5340.     end;
  5341. end;
  5342.  
  5343. -- Called when a player attempts to pickup a weapon.
  5344. function NEXUS:PlayerCanPickupWeapon(player, weapon)
  5345.     if ( player.forceGive or ( player:GetEyeTraceNoCursor().Entity == weapon and player:KeyDown(IN_USE) ) ) then
  5346.         return true;
  5347.     else
  5348.         return false;
  5349.     end;
  5350. end;
  5351.  
  5352. -- Called each tick.
  5353. function NEXUS:Tick()
  5354.     if (NEXUS_TICK) then
  5355.         local sysTime = SysTime();
  5356.         local curTime = CurTime();
  5357.        
  5358.         if (!self.NextHint or curTime >= self.NextHint) then
  5359.             nexus.hint.Distribute();
  5360.            
  5361.             self.NextHint = curTime + nexus.config.Get("hint_interval"):Get();
  5362.         end;
  5363.        
  5364.         if (!self.NextWagesTime or curTime >= self.NextWagesTime) then
  5365.             self:DistributeWagesCash();
  5366.             self.NextWagesTime = curTime + nexus.config.Get("wages_interval"):Get();
  5367.         end;
  5368.        
  5369.         if (!self.NextGeneratorTime or curTime >= self.NextGeneratorTime) then
  5370.             self:DistributeGeneratorCash();
  5371.             self.NextGeneratorTime = curTime + nexus.config.Get("generator_interval"):Get();
  5372.         end;
  5373.        
  5374.         if (!self.NextDateTimeThink or sysTime >= self.NextDateTimeThink) then
  5375.             self:PerformDateTimeThink();
  5376.             self.NextDateTimeThink = sysTime + nexus.config.Get("minute_time"):Get();
  5377.         end;
  5378.        
  5379.         if (!self.NextSaveData or sysTime >= self.NextSaveData) then
  5380.             nexus.mount.Call("PreSaveData");
  5381.                 nexus.mount.Call("SaveData");
  5382.             nexus.mount.Call("PostSaveData");
  5383.            
  5384.             self.NextSaveData = sysTime + nexus.config.Get("save_data_interval"):Get();
  5385.         end;
  5386.        
  5387.         if (!self.NextCheckEmpty) then
  5388.             self.NextCheckEmpty = sysTime + 1200;
  5389.         end;
  5390.        
  5391.         if (sysTime >= self.NextCheckEmpty) then
  5392.             self.NextCheckEmpty = nil;
  5393.            
  5394.             if (#g_Player.GetAll() == 0) then
  5395.                 RunConsoleCommand( "changelevel", game.GetMap() );
  5396.             end;
  5397.         end;
  5398.     end;
  5399. end;
  5400.  
  5401. -- Called each frame.
  5402. function NEXUS:Think()
  5403.     self:CallTimerThink( CurTime() );
  5404. end;
  5405.  
  5406. -- Called when a player's shared variables should be set.
  5407. function NEXUS:PlayerSetSharedVars(player, curTime)
  5408.     local weaponClass = nexus.player.GetWeaponClass(player);
  5409.     local r, g, b, a = player:GetColor();
  5410.     local drunk = nexus.player.GetDrunk(player);
  5411.    
  5412.     player:HandleAttributeProgress(curTime);
  5413.     player:HandleAttributeBoosts(curTime);
  5414.    
  5415.     player:SetSharedVar( "sh_PhysDesc", player:GetCharacterData("physdesc") );
  5416.     player:SetSharedVar( "sh_Flags", player:QueryCharacter("flags") );
  5417.     player:SetSharedVar( "sh_Model", player:QueryCharacter("model") );
  5418.     player:SetSharedVar( "sh_Name", player:QueryCharacter("name") );
  5419.     player:SetSharedVar( "sh_Cash", nexus.player.GetCash(player) );
  5420.    
  5421.     if ( nexus.config.Get("enable_temporary_damage"):Get() ) then
  5422.         local maxHealth = player:GetMaxHealth();
  5423.         local health = player:Health();
  5424.        
  5425.         if ( player:Alive() ) then
  5426.             if ( health >= (maxHealth / 2) ) then
  5427.                 if (health < maxHealth) then
  5428.                     player:SetHealth( math.Clamp(health + 1, 0, maxHealth) );
  5429.                 end;
  5430.             elseif (health > 0) then
  5431.                 if (!player.nextSlowRegeneration) then
  5432.                     player.nextSlowRegeneration = curTime + 6;
  5433.                 end;
  5434.                
  5435.                 if (curTime >= player.nextSlowRegeneration) then
  5436.                     player.nextSlowRegeneration = nil;
  5437.                     player:SetHealth( math.Clamp(health + 1, 0, maxHealth) );
  5438.                 end;
  5439.             end;
  5440.         end;
  5441.     end;
  5442.    
  5443.     if (r == 255 and g == 0 and b == 0 and a == 0) then
  5444.         player:SetColor(255, 255, 255, 255);
  5445.     end;
  5446.    
  5447.     if (player.drunk) then
  5448.         for k, v in pairs(player.drunk) do
  5449.             if (curTime >= v) then
  5450.                 table.remove(player.drunk, k);
  5451.             end;
  5452.         end;
  5453.     end;
  5454.    
  5455.     if (drunk) then
  5456.         player:SetSharedVar("sh_Drunk", drunk);
  5457.     else
  5458.         player:SetSharedVar("sh_Drunk", 0);
  5459.     end;
  5460. end;
  5461.  
  5462. -- Called at an interval while a player is connected.
  5463. function NEXUS:PlayerThink(player, curTime, infoTable)
  5464.     local storageTable = player:GetStorageTable();
  5465.    
  5466.     if ( !nexus.config.Get("cash_enabled"):Get() ) then
  5467.         player:SetCharacterData("cash", 0, true);
  5468.        
  5469.         infoTable.wages = 0;
  5470.     end;
  5471.    
  5472.     if (player.reloadHoldTime and curTime >= player.reloadHoldTime) then
  5473.         nexus.player.ToggleWeaponRaised(player);
  5474.        
  5475.         player.reloadHoldTime = nil;
  5476.         player.canShootTime = curTime + nexus.config.Get("shoot_after_raise_time"):Get();
  5477.     end;
  5478.    
  5479.     if ( player:IsRagdolled() ) then
  5480.         player:SetMoveType(MOVETYPE_OBSERVER);
  5481.     end;
  5482.    
  5483.     if (storageTable) then
  5484.         if (hook.Call( "PlayerStorageShouldClose", self, player, storageTable) ) then
  5485.             nexus.player.CloseStorage(player);
  5486.         end;
  5487.     end;
  5488.    
  5489.     player:SetSharedVar( "sh_InventoryWeight", math.ceil(infoTable.inventoryWeight) );
  5490.     player:SetSharedVar( "sh_Wages", math.ceil(infoTable.wages) );
  5491.    
  5492.     if (infoTable.running == false or infoTable.runSpeed < infoTable.walkSpeed) then
  5493.         infoTable.runSpeed = infoTable.walkSpeed;
  5494.     end;
  5495.    
  5496.     if (infoTable.jogging) then
  5497.         infoTable.walkSpeed = infoTable.walkSpeed * 1.75;
  5498.     end;
  5499.    
  5500.     player:UpdateWeaponRaised();
  5501.     player:SetCrouchedWalkSpeed(math.max(infoTable.crouchedSpeed, 0), true);
  5502.     player:SetWalkSpeed(math.max(infoTable.walkSpeed, 0), true);
  5503.     player:SetJumpPower(math.max(infoTable.jumpPower, 0), true);
  5504.     player:SetRunSpeed(math.max(infoTable.runSpeed, 0), true);
  5505. end;
  5506.  
  5507. -- Called when a player uses an item.
  5508. function NEXUS:PlayerUseItem(player, itemTable, itemEntity) end;
  5509.  
  5510. -- Called when a player drops an item.
  5511. function NEXUS:PlayerDropItem(player, itemTable, position, entity)
  5512.     if ( IsValid(entity) and nexus.item.IsWeapon(itemTable) ) then
  5513.         local secondaryAmmo = nexus.player.TakeSecondaryAmmo(player, itemTable.weaponClass);
  5514.         local primaryAmmo = nexus.player.TakePrimaryAmmo(player, itemTable.weaponClass);
  5515.        
  5516.         if (secondaryAmmo > 0) then
  5517.             entity.data.sClip = secondaryAmmo;
  5518.         end;
  5519.        
  5520.         if (primaryAmmo > 0) then
  5521.             entity.data.pClip = primaryAmmo;
  5522.         end;
  5523.     end;
  5524. end;
  5525.  
  5526. -- Called when a player destroys an item.
  5527. function NEXUS:PlayerDestroyItem(player, itemTable) end;
  5528.  
  5529. -- Called when a player drops a weapon.
  5530. function NEXUS:PlayerDropWeapon(player, itemTable, entity)
  5531.     if ( IsValid(entity) ) then
  5532.         local secondaryAmmo = nexus.player.TakeSecondaryAmmo(player, itemTable.weaponClass);
  5533.         local primaryAmmo = nexus.player.TakePrimaryAmmo(player, itemTable.weaponClass);
  5534.        
  5535.         if (secondaryAmmo > 0) then
  5536.             entity.data.sClip = secondaryAmmo;
  5537.         end;
  5538.        
  5539.         if (primaryAmmo > 0) then
  5540.             entity.data.pClip = primaryAmmo;
  5541.         end;
  5542.     end;
  5543. end;
  5544.  
  5545. -- Called when a player charges generator.
  5546. function NEXUS:PlayerChargeGenerator(player, entity, generator) end;
  5547.  
  5548. -- Called when a player destroys generator.
  5549. function NEXUS:PlayerDestroyGenerator(player, entity, generator) end;
  5550.  
  5551. -- Called when a player's data should be restored.
  5552. function NEXUS:PlayerRestoreData(player, data)
  5553.     if ( !data["whitelisted"] ) then
  5554.         data["whitelisted"] = {};
  5555.     end;
  5556. end;
  5557.  
  5558. -- Called when a player's temporary info should be saved.
  5559. function NEXUS:PlayerSaveTempData(player, tempData) end;
  5560.  
  5561. -- Called when a player's temporary info should be restored.
  5562. function NEXUS:PlayerRestoreTempData(player, tempData) end;
  5563.  
  5564. -- Called when a player selects a custom character option.
  5565. function NEXUS:PlayerSelectCharacterOption(player, character, option) end;
  5566.  
  5567. -- Called when a player attempts to see another player's status.
  5568. function NEXUS:PlayerCanSeeStatus(player, target)
  5569.     return "# "..target:UserID().." | "..target:Name().." | "..target:SteamName().." | "..target:SteamID().." | "..target:IPAddress();
  5570. end;
  5571.  
  5572. -- Called when a player attempts to see a player's chat.
  5573. function NEXUS:PlayerCanSeePlayersChat(text, teamOnly, listener, speaker)
  5574.     return true;
  5575. end;
  5576.  
  5577. -- Called when a player attempts to hear another player's voice.
  5578. function NEXUS:PlayerCanHearPlayersVoice(listener, speaker)
  5579.     if ( nexus.config.Get("local_voice"):Get() ) then
  5580.         if ( listener:IsRagdolled(RAGDOLL_FALLENOVER) or !listener:Alive() ) then
  5581.             return false;
  5582.         elseif ( speaker:IsRagdolled(RAGDOLL_FALLENOVER) or !speaker:Alive() ) then
  5583.             return false;
  5584.         elseif ( listener:GetPos():Distance( speaker:GetPos() ) > nexus.config.Get("talk_radius"):Get() ) then
  5585.             return false;
  5586.         end;
  5587.     end;
  5588.    
  5589.     return true;
  5590. end;
  5591.  
  5592. -- Called when a player attempts to delete a character.
  5593. function NEXUS:PlayerCanDeleteCharacter(player, character)
  5594.     if ( nexus.config.Get("cash_enabled"):Get() ) then
  5595.         if ( character.cash < nexus.config.Get("default_cash"):Get() ) then
  5596.             if ( !character.data["banned"] ) then
  5597.                 return "You cannot delete characters with less than "..FORMAT_CASH(nexus.config.Get("default_cash"):Get(), nil, true)..".";
  5598.             end;
  5599.         end;
  5600.     end;
  5601. end;
  5602.  
  5603. -- Called when a player attempts to switch to a character.
  5604. function NEXUS:PlayerCanSwitchCharacter(player, character)
  5605.     local fault = nexus.mount.Call("PlayerCanUseCharacter", player, character);
  5606.     local canUse = false;
  5607.    
  5608.     if (fault == nil or fault == true) then
  5609.         canUse = true;
  5610.     end;
  5611.    
  5612.     if (!player:Alive() and canUse) then
  5613.         return "You cannot switch characters when you are dead!";
  5614.     else
  5615.         return true;
  5616.     end;
  5617. end;
  5618.  
  5619. -- Called when a player attempts to use a character.
  5620. function NEXUS:PlayerCanUseCharacter(player, character)
  5621.     if ( character.data["banned"] ) then
  5622.         return character.name.." is banned and cannot be used!";
  5623.     end;
  5624. end;
  5625.  
  5626. -- Called when a player's weapons should be given.
  5627. function NEXUS:PlayerGiveWeapons(player) end;
  5628.  
  5629. -- Called when a player deletes a character.
  5630. function NEXUS:PlayerDeleteCharacter(player, character) end;
  5631.  
  5632. -- Called when a player's armor is set.
  5633. function NEXUS:PlayerArmorSet(player, armor)
  5634.     if ( player:IsRagdolled() ) then
  5635.         player:GetRagdollTable().armor = armor;
  5636.     end;
  5637. end;
  5638.  
  5639. -- Called when a player's health is set.
  5640. function NEXUS:PlayerHealthSet(player, health)
  5641.     if ( player:IsRagdolled() ) then
  5642.         player:GetRagdollTable().health = health;
  5643.     end;
  5644. end;
  5645.  
  5646. -- Called when a player attempts to own a door.
  5647. function NEXUS:PlayerCanOwnDoor(player, door)
  5648.     if ( nexus.entity.IsDoorUnownable(door) ) then
  5649.         return false;
  5650.     else
  5651.         return true;
  5652.     end;
  5653. end;
  5654.  
  5655. -- Called when a player attempts to view a door.
  5656. function NEXUS:PlayerCanViewDoor(player, door)
  5657.     if ( nexus.entity.IsDoorUnownable(door) ) then
  5658.         return false;
  5659.     end;
  5660.    
  5661.     return true;
  5662. end;
  5663.  
  5664. -- Called when a player attempts to holster a weapon.
  5665. function NEXUS:PlayerCanHolsterWeapon(player, itemTable, forceHolster, noMessage)
  5666.     if ( nexus.player.GetSpawnWeapon(player, itemTable.weaponClass) ) then
  5667.         if (!noMessage) then
  5668.             nexus.player.Notify(player, "You cannot holster this weapon!");
  5669.         end;
  5670.        
  5671.         return false;
  5672.     elseif (itemTable.CanHolsterWeapon) then
  5673.         return itemTable:CanHolsterWeapon(player, forceHolster, noMessage);
  5674.     else
  5675.         return true;
  5676.     end;
  5677. end;
  5678.  
  5679. -- Called when a player attempts to drop a weapon.
  5680. function NEXUS:PlayerCanDropWeapon(player, itemTable, noMessage)
  5681.     if ( nexus.player.GetSpawnWeapon(player, itemTable.weaponClass) ) then
  5682.         if (!noMessage) then
  5683.             nexus.player.Notify(player, "You cannot drop this weapon!");
  5684.         end;
  5685.        
  5686.         return false;
  5687.     elseif (itemTable.CanDropWeapon) then
  5688.         return itemTable:CanDropWeapon(player, noMessage);
  5689.     else
  5690.         return true;
  5691.     end;
  5692. end;
  5693.  
  5694. -- Called when a player attempts to use an item.
  5695. function NEXUS:PlayerCanUseItem(player, itemTable, noMessage)
  5696.     if ( nexus.item.IsWeapon(itemTable) and nexus.player.GetSpawnWeapon( player, itemTable.weaponClass ) ) then
  5697.         if (!noMessage) then
  5698.             nexus.player.Notify(player, "You cannot use this weapon!");
  5699.         end;
  5700.        
  5701.         return false;
  5702.     else
  5703.         return true;
  5704.     end;
  5705. end;
  5706.  
  5707. -- Called when a player attempts to drop an item.
  5708. function NEXUS:PlayerCanDropItem(player, itemTable, noMessage) return true; end;
  5709.  
  5710. -- Called when a player attempts to destroy an item.
  5711. function NEXUS:PlayerCanDestroyItem(player, itemTable, noMessage) return true; end;
  5712.  
  5713. -- Called when a player attempts to destroy generator.
  5714. function NEXUS:PlayerCanDestroyGenerator(player, entity, generator) return true; end;
  5715.  
  5716. -- Called when a player attempts to knockout a player.
  5717. function NEXUS:PlayerCanKnockout(player, target) return true; end;
  5718.  
  5719. -- Called when a player attempts to use the radio.
  5720. function NEXUS:PlayerCanRadio(player, text, listeners, eavesdroppers) return true; end;
  5721.  
  5722. -- Called when death attempts to clear a player's name.
  5723. function NEXUS:PlayerCanDeathClearName(player, attacker, damageInfo) return false; end;
  5724.  
  5725. -- Called when death attempts to clear a player's recognised names.
  5726. function NEXUS:PlayerCanDeathClearRecognisedNames(player, attacker, damageInfo) return false; end;
  5727.  
  5728. -- Called when a player's ragdoll attempts to take damage.
  5729. function NEXUS:PlayerRagdollCanTakeDamage(player, ragdoll, inflictor, attacker, hitGroup, damageInfo)
  5730.     if (!attacker:IsPlayer() and player:GetRagdollTable().immunity) then
  5731.         if (CurTime() <= player:GetRagdollTable().immunity) then
  5732.             return false;
  5733.         end;
  5734.     end;
  5735.    
  5736.     return true;
  5737. end;
  5738.  
  5739. -- Called when a player has been authenticated.
  5740. function NEXUS:PlayerAuthed(player, steamID)
  5741.     local banTable = self.BanList[ player:IPAddress() ] or self.BanList[steamID];
  5742.    
  5743.     if (banTable) then
  5744.         local unixTime = os.time();
  5745.         local timeLeft = banTable.unbanTime - unixTime;
  5746.         local hoursLeft = math.Round( math.max(timeLeft / 3600, 0) );
  5747.         local minutesLeft = math.Round( math.max(timeLeft / 60, 0) );
  5748.        
  5749.         if (banTable.unbanTime > 0 and unixTime < banTable.unbanTime) then
  5750.             local bannedMessage = nexus.config.Get("banned_message"):Get();
  5751.            
  5752.             if (hoursLeft >= 1) then
  5753.                 hoursLeft = tostring(hoursLeft);
  5754.                
  5755.                 bannedMessage = string.gsub(bannedMessage, "!t", hoursLeft);
  5756.                 bannedMessage = string.gsub(bannedMessage, "!f", "hour(s)");
  5757.             elseif (minutesLeft >= 1) then
  5758.                 minutesLeft = tostring(minutesLeft);
  5759.                
  5760.                 bannedMessage = string.gsub(bannedMessage, "!t", minutesLeft);
  5761.                 bannedMessage = string.gsub(bannedMessage, "!f", "minutes(s)");
  5762.             else
  5763.                 timeLeft = tostring(timeLeft);
  5764.                
  5765.                 bannedMessage = string.gsub(bannedMessage, "!t", timeLeft);
  5766.                 bannedMessage = string.gsub(bannedMessage, "!f", "second(s)");
  5767.             end;
  5768.            
  5769.             player:Kick(bannedMessage);
  5770.         elseif (banTable.unbanTime == 0) then
  5771.             player:Kick(banTable.reason);
  5772.         else
  5773.             self:RemoveBan(ipAddress);
  5774.             self:RemoveBan(steamID);
  5775.         end;
  5776.     end;
  5777. end;
  5778.  
  5779. -- Called when the player attempts to be ragdolled.
  5780. function NEXUS:PlayerCanRagdoll(player, state, delay, decay, ragdoll)
  5781.     return true;
  5782. end;
  5783.  
  5784. -- Called when the player attempts to be unragdolled.
  5785. function NEXUS:PlayerCanUnragdoll(player, state, ragdoll)
  5786.     return true;
  5787. end;
  5788.  
  5789. -- Called when a player has been ragdolled.
  5790. function NEXUS:PlayerRagdolled(player, state, ragdoll)
  5791.     player:SetSharedVar("sh_FallenOver", false);
  5792. end;
  5793.  
  5794. -- Called when a player has been unragdolled.
  5795. function NEXUS:PlayerUnragdolled(player, state, ragdoll)
  5796.     player:SetSharedVar("sh_FallenOver", false);
  5797. end;
  5798.  
  5799. -- Called to check if a player does have an flag.
  5800. function NEXUS:PlayerDoesHaveFlag(player, flag)
  5801.     if ( string.find(nexus.config.Get("default_flags"):Get(), flag) ) then
  5802.         return true;
  5803.     end;
  5804. end;
  5805.  
  5806. -- Called to check if a player does have door access.
  5807. function NEXUS:PlayerDoesHaveDoorAccess(player, door, access, simple)
  5808.     if (nexus.entity.GetOwner(door) == player) then
  5809.         return true;
  5810.     else
  5811.         local key = player:QueryCharacter("key");
  5812.        
  5813.         if ( door.accessList and door.accessList[key] ) then
  5814.             if (simple) then
  5815.                 return door.accessList[key] == access;
  5816.             else
  5817.                 return door.accessList[key] >= access;
  5818.             end;
  5819.         end;
  5820.     end;
  5821.    
  5822.     return false;
  5823. end;
  5824.  
  5825. -- Called to check if a player does know another player.
  5826. function NEXUS:PlayerDoesRecognisePlayer(player, target, status, simple, default)
  5827.     return default;
  5828. end;
  5829.  
  5830. -- Called to check if a player does have an item.
  5831. function NEXUS:PlayerDoesHaveItem(player, itemTable) return false; end;
  5832.  
  5833. -- Called when a player attempts to lock an entity.
  5834. function NEXUS:PlayerCanLockEntity(player, entity)
  5835.     if ( nexus.entity.IsDoor(entity) ) then
  5836.         return nexus.player.HasDoorAccess(player, entity);
  5837.     else
  5838.         return true;
  5839.     end;
  5840. end;
  5841.  
  5842. -- Called when a player's class has been set.
  5843. function NEXUS:PlayerClassSet(player, newClass, oldClass, noRespawn, addDelay, noModelChange) end;
  5844.  
  5845. -- Called when a player attempts to unlock an entity.
  5846. function NEXUS:PlayerCanUnlockEntity(player, entity)
  5847.     if ( nexus.entity.IsDoor(entity) ) then
  5848.         return nexus.player.HasDoorAccess(player, entity);
  5849.     else
  5850.         return true;
  5851.     end;
  5852. end;
  5853.  
  5854. -- Called when a player attempts to use a door.
  5855. function NEXUS:PlayerCanUseDoor(player, door)
  5856.     if ( nexus.entity.GetOwner(door) and !nexus.player.HasDoorAccess(player, door) ) then
  5857.         return false;
  5858.     end;
  5859.    
  5860.     if ( nexus.entity.IsDoorFalse(door) ) then
  5861.         return false;
  5862.     end;
  5863.    
  5864.     return true;
  5865. end;
  5866.  
  5867. -- Called when a player uses a door.
  5868. function NEXUS:PlayerUseDoor(player, door) end;
  5869.  
  5870. -- Called when a player attempts to use an entity in a vehicle.
  5871. function NEXUS:PlayerCanUseEntityInVehicle(player, entity, vehicle)
  5872.     if ( entity.UsableInVehicle or nexus.entity.IsDoor(entity) ) then
  5873.         return true;
  5874.     end;
  5875. end;
  5876.  
  5877. -- Called when a player's ragdoll attempts to decay.
  5878. function NEXUS:PlayerCanRagdollDecay(player, ragdoll, seconds)
  5879.     return true;
  5880. end;
  5881.  
  5882. -- Called when a player attempts to exit a vehicle.
  5883. function NEXUS:CanExitVehicle(vehicle, player)
  5884.     if ( player.nextExitVehicle and player.nextExitVehicle > CurTime() ) then
  5885.         return false;
  5886.     end;
  5887.    
  5888.     if ( IsValid(player) and player:IsPlayer() ) then
  5889.         local trace = player:GetEyeTraceNoCursor();
  5890.        
  5891.         if ( IsValid(trace.Entity) and !trace.Entity:IsVehicle() ) then
  5892.             if ( nexus.mount.Call("PlayerCanUseEntityInVehicle", player, trace.Entity, vehicle) ) then
  5893.                 return false;
  5894.             end;
  5895.         end;
  5896.     end;
  5897.    
  5898.     if ( nexus.entity.IsChairEntity(vehicle) and !IsValid( vehicle:GetParent() ) ) then
  5899.         local trace = player:GetEyeTraceNoCursor();
  5900.        
  5901.         if (trace.HitPos:Distance( player:GetShootPos() ) <= 192) then
  5902.             trace = {
  5903.                 start = trace.HitPos,
  5904.                 endpos = trace.HitPos - Vector(0, 0, 1024),
  5905.                 filter = {player, vehicle}
  5906.             };
  5907.            
  5908.             player.exitVehicle = util.TraceLine(trace).HitPos;
  5909.            
  5910.             player:SetMoveType(MOVETYPE_NOCLIP);
  5911.         else
  5912.             return false;
  5913.         end;
  5914.     end;
  5915.    
  5916.     return true;
  5917. end;
  5918.  
  5919. -- Called when a player leaves a vehicle.
  5920. function NEXUS:PlayerLeaveVehicle(player, vehicle)
  5921.     timer.Simple(FrameTime() * 0.5, function()
  5922.         if ( IsValid(player) and !player:InVehicle() ) then
  5923.             if ( IsValid(vehicle) ) then
  5924.                 if ( nexus.entity.IsChairEntity(vehicle) ) then
  5925.                     local position = player.exitVehicle or vehicle:GetPos();
  5926.                     local targetPosition = nexus.player.GetSafePosition(player, position, vehicle);
  5927.                    
  5928.                     if (targetPosition) then
  5929.                         player:SetMoveType(MOVETYPE_NOCLIP);
  5930.                         player:SetPos(targetPosition);
  5931.                     end;
  5932.                    
  5933.                     player:SetMoveType(MOVETYPE_WALK);
  5934.                    
  5935.                     player.exitVehicle = nil;
  5936.                 end;
  5937.             end;
  5938.         end;
  5939.     end);
  5940. end;
  5941.  
  5942. -- Called when a player enters a vehicle.
  5943. function NEXUS:PlayerEnteredVehicle(player, vehicle, class)
  5944.     timer.Simple(FrameTime() * 0.5, function()
  5945.         if ( IsValid(player) ) then
  5946.             local model = player:GetModel();
  5947.             local class = nexus.animation.GetModelClass(model);
  5948.            
  5949.             if ( IsValid(vehicle) and !string.find(model, "/player/") ) then
  5950.                 if (class == "maleHuman" or class == "femaleHuman") then
  5951.                     if ( nexus.entity.IsChairEntity(vehicle) ) then
  5952.                         player:SetLocalPos( Vector(16.5438, -0.1642, -20.5493) );
  5953.                     else
  5954.                         player:SetLocalPos( Vector(30.1880, 4.2020, -6.6476) );
  5955.                     end;
  5956.                 end;
  5957.             end;
  5958.            
  5959.             player:SetCollisionGroup(COLLISION_GROUP_PLAYER);
  5960.         end;
  5961.     end);
  5962. end;
  5963.  
  5964. -- Called when a player attempts to change class.
  5965. function NEXUS:PlayerCanChangeClass(player, class)
  5966.     local curTime = CurTime();
  5967.    
  5968.     if (player.nextChangeClass and curTime < player.nextChangeClass) then
  5969.         nexus.player.Notify(player, "You cannot change class for another "..math.ceil(player.nextChangeClass - curTime).." second(s)!");
  5970.        
  5971.         return false;
  5972.     else
  5973.         return true;
  5974.     end;
  5975. end;
  5976.  
  5977. -- Called when a player attempts to earn generator cash.
  5978. function NEXUS:PlayerCanEarnGeneratorCash(player, info, cash)
  5979.     return true;
  5980. end;
  5981.  
  5982. -- Called when a player earns generator cash.
  5983. function NEXUS:PlayerEarnGeneratorCash(player, info, cash) end;
  5984.  
  5985. -- Called when a player attempts to earn wages cash.
  5986. function NEXUS:PlayerCanEarnWagesCash(player, cash)
  5987.     return true;
  5988. end;
  5989.  
  5990. -- Called when a player is given wages cash.
  5991. function NEXUS:PlayerGiveWagesCash(player, cash, wagesName)
  5992.     return true;
  5993. end;
  5994.  
  5995. -- Called when a player earns wages cash.
  5996. function NEXUS:PlayerEarnWagesCash(player, cash) end;
  5997.  
  5998. -- Called when Nexus has loaded all of the entities.
  5999. function NEXUS:NexusInitPostEntity() end;
  6000.  
  6001. -- Called when the map has loaded all the entities.
  6002. function NEXUS:InitPostEntity()
  6003.     for k, v in ipairs( ents.GetAll() ) do
  6004.         if ( IsValid(v) and v:GetModel() ) then
  6005.             nexus.entity.SetMapEntity(v, true);
  6006.             nexus.entity.SetStartAngles( v, v:GetAngles() );
  6007.             nexus.entity.SetStartPosition( v, v:GetPos() );
  6008.            
  6009.             if ( nexus.entity.SetChairAnimations(v) ) then
  6010.                 v:SetCollisionGroup(COLLISION_GROUP_WEAPON);
  6011.                
  6012.                 local physicsObject = v:GetPhysicsObject();
  6013.                
  6014.                 if ( IsValid(physicsObject) ) then
  6015.                     physicsObject:EnableMotion(false);
  6016.                 end;
  6017.             end;
  6018.         end;
  6019.     end;
  6020.    
  6021.     nexus.entity.RegisterSharedVars(GetWorldEntity(), self.GlobalSharedVars);
  6022.         NEXUS:SetSharedVar("sh_NoMySQL", self.NoMySQL);
  6023.     nexus.mount.Call("NexusInitPostEntity");
  6024.    
  6025.     NEXUS_TICK = true;
  6026. end;
  6027.  
  6028. -- Called when a player attempts to say something in-character.
  6029. function NEXUS:PlayerCanSayIC(player, text)
  6030.     if ( ( !player:Alive() or player:IsRagdolled(RAGDOLL_FALLENOVER) ) and !nexus.player.GetDeathCode(player, true) ) then
  6031.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6032.        
  6033.         return false;
  6034.     else
  6035.         return true;
  6036.     end;
  6037. end;
  6038.  
  6039. -- Called when a player attempts to say something out-of-character.
  6040. function NEXUS:PlayerCanSayOOC(player, text) return true; end;
  6041.  
  6042. -- Called when a player attempts to say something locally out-of-character.
  6043. function NEXUS:PlayerCanSayLOOC(player, text) return true; end;
  6044.  
  6045. -- Called when attempts to use a command.
  6046. function NEXUS:PlayerCanUseCommand(player, commandTable, arguments) return true; end;
  6047.  
  6048. -- Called when a player says something.
  6049. function NEXUS:PlayerSay(player, text, public)
  6050.     text = string.Replace(text, " ' ", "'");
  6051.     text = string.Replace(text, " : ", ":");
  6052.    
  6053.     local prefix = nexus.config.Get("command_prefix"):Get();
  6054.     local curTime = CurTime();
  6055.    
  6056.     if (string.sub(text, 1, 2) == "//") then
  6057.         text = string.Trim( string.sub(text, 3) );
  6058.        
  6059.         if (text != "") then
  6060.             if ( nexus.mount.Call("PlayerCanSayOOC", player, text) ) then
  6061.                 if (!player.nextTalkOOC or curTime > player.nextTalkOOC) then
  6062.                     self:Log("[OOC] "..player:Name()..": "..text);
  6063.                    
  6064.                     nexus.chatBox.Add(nil, player, "ooc", text);
  6065.                    
  6066.                     player.nextTalkOOC = curTime + nexus.config.Get("ooc_interval"):Get();
  6067.                 else
  6068.                     nexus.player.Notify(player, "You cannot cannot talk out-of-character for another "..math.ceil( player.nextTalkOOC - CurTime() ).." second(s)!");
  6069.                    
  6070.                     return "";
  6071.                 end;
  6072.             end;
  6073.         end;
  6074.     elseif (string.sub(text, 1, 3) == ".//" or string.sub(text, 1, 2) == "[[") then
  6075.         if (string.sub(text, 1, 3) == ".//") then
  6076.             text = string.Trim( string.sub(text, 4) );
  6077.         else
  6078.             text = string.Trim( string.sub(text, 3) );
  6079.         end;
  6080.        
  6081.         if (text != "") then
  6082.             if ( nexus.mount.Call("PlayerCanSayLOOC", player, text) ) then
  6083.                 nexus.chatBox.AddInRadius( player, "looc", text, player:GetPos(), nexus.config.Get("talk_radius"):Get() );
  6084.             end;
  6085.         end;
  6086.     elseif (string.sub(text, 1, 1) == prefix) then
  6087.         local prefixLength = string.len(prefix);
  6088.         local arguments = self:ExplodeByTags(text, " ", "\"", "\"", true);
  6089.         local command = string.sub(arguments[1], prefixLength + 1);
  6090.        
  6091.         if (nexus.command.stored[command] and nexus.command.stored[command].arguments < 2
  6092.         and !nexus.command.stored[command].optionalArguments) then
  6093.             text = string.sub(text, string.len(command) + prefixLength + 2);
  6094.            
  6095.             if (text != "") then
  6096.                 arguments = {command, text};
  6097.             else
  6098.                 arguments = {command};
  6099.             end;
  6100.         else
  6101.             arguments[1] = command;
  6102.         end;
  6103.        
  6104.         nexus.command.ConsoleCommand(player, "nx", arguments);
  6105.     elseif ( nexus.mount.Call("PlayerCanSayIC", player, text) ) then
  6106.         nexus.chatBox.AddInRadius( player, "ic", text, player:GetPos(), nexus.config.Get("talk_radius"):Get() );
  6107.        
  6108.         if ( nexus.player.GetDeathCode(player, true) ) then
  6109.             nexus.player.UseDeathCode( player, nil, {text} );
  6110.         end;
  6111.     end;
  6112.    
  6113.     if ( nexus.player.GetDeathCode(player) ) then
  6114.         nexus.player.TakeDeathCode(player);
  6115.     end;
  6116.    
  6117.     return "";
  6118. end;
  6119.  
  6120. -- Called when a player attempts to suicide.
  6121. function NEXUS:CanPlayerSuicide(player) return false; end;
  6122.  
  6123. -- Called when a player attempts to punt an entity with the gravity gun.
  6124. function NEXUS:GravGunPunt(player, entity)
  6125.     return nexus.config.Get("enable_gravgun_punt"):Get();
  6126. end;
  6127.  
  6128. -- Called when a player attempts to pickup an entity with the gravity gun.
  6129. function NEXUS:GravGunPickupAllowed(player, entity)
  6130.     if ( IsValid(entity) ) then
  6131.         if ( !nexus.player.IsAdmin(player) and !nexus.entity.IsInteractable(entity) ) then
  6132.             return false;
  6133.         else
  6134.             return self.BaseClass:GravGunPickupAllowed(player, entity);
  6135.         end;
  6136.     end;
  6137.    
  6138.     return false;
  6139. end;
  6140.  
  6141. -- Called when a player picks up an entity with the gravity gun.
  6142. function NEXUS:GravGunOnPickedUp(player, entity)
  6143.     player.isHoldingEntity = entity;
  6144.     entity.isBeingHeld = player;
  6145. end;
  6146.  
  6147. -- Called when a player drops an entity with the gravity gun.
  6148. function NEXUS:GravGunOnDropped(player, entity)
  6149.     player.isHoldingEntity = nil;
  6150.     entity.isBeingHeld = nil;
  6151. end;
  6152.  
  6153. -- Called when a player attempts to unfreeze an entity.
  6154. function NEXUS:CanPlayerUnfreeze(player, entity, physicsObject)
  6155.     local isAdmin = nexus.player.IsAdmin(player);
  6156.    
  6157.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  6158.         local ownerKey = entity:GetOwnerKey();
  6159.        
  6160.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  6161.             return false;
  6162.         end;
  6163.     end;
  6164.    
  6165.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  6166.         return false;
  6167.     end;
  6168.    
  6169.     if ( entity:IsVehicle() ) then
  6170.         if ( IsValid( entity:GetDriver() ) ) then
  6171.             return false;
  6172.         end;
  6173.     end;
  6174.    
  6175.     return true;
  6176. end;
  6177.  
  6178. -- Called when a player attempts to freeze an entity with the physics gun.
  6179. function NEXUS:OnPhysgunFreeze(weapon, physicsObject, entity, player)
  6180.     local isAdmin = nexus.player.IsAdmin(player);
  6181.    
  6182.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  6183.         local ownerKey = entity:GetOwnerKey();
  6184.        
  6185.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  6186.             return false;
  6187.         end;
  6188.     end;
  6189.    
  6190.     if ( !isAdmin and nexus.entity.IsChairEntity(entity) ) then
  6191.         local entities = ents.FindInSphere(entity:GetPos(), 64);
  6192.        
  6193.         for k, v in ipairs(entities) do
  6194.             if ( nexus.entity.IsDoor(v) ) then
  6195.                 return false;
  6196.             end;
  6197.         end;
  6198.     end;
  6199.    
  6200.     if ( entity:GetPhysicsObject():IsPenetrating() ) then
  6201.         return false;
  6202.     end;
  6203.    
  6204.     if (!isAdmin and entity.PhysgunDisabled) then
  6205.         return false;
  6206.     end;
  6207.    
  6208.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  6209.         return false;
  6210.     else
  6211.         return self.BaseClass:OnPhysgunFreeze(weapon, physicsObject, entity, player);
  6212.     end;
  6213. end;
  6214.  
  6215. -- Called when a player attempts to pickup an entity with the physics gun.
  6216. function NEXUS:PhysgunPickup(player, entity)
  6217.     local canPickup = nil;
  6218.     local isAdmin = nexus.player.IsAdmin(player);
  6219.    
  6220.     if ( !isAdmin and !nexus.entity.IsInteractable(entity) ) then
  6221.         return false;
  6222.     end;
  6223.    
  6224.     if ( !isAdmin and nexus.entity.IsPlayerRagdoll(entity) ) then
  6225.         return false;
  6226.     end;
  6227.    
  6228.     if (!isAdmin and entity:GetClass() == "prop_ragdoll") then
  6229.         local ownerKey = entity:GetOwnerKey();
  6230.        
  6231.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  6232.             return false;
  6233.         end;
  6234.     end;
  6235.    
  6236.     if (!isAdmin) then
  6237.         canPickup = self.BaseClass:PhysgunPickup(player, entity);
  6238.     else
  6239.         canPickup = true;
  6240.     end;
  6241.    
  6242.     if (nexus.entity.IsChairEntity(entity) and !isAdmin) then
  6243.         local entities = ents.FindInSphere(entity:GetPos(), 256);
  6244.        
  6245.         for k, v in ipairs(entities) do
  6246.             if ( nexus.entity.IsDoor(v) ) then
  6247.                 return false;
  6248.             end;
  6249.         end;
  6250.     end;
  6251.    
  6252.     if (nexus.config.Get("enable_prop_protection"):Get() and !isAdmin) then
  6253.         local ownerKey = entity:GetOwnerKey();
  6254.        
  6255.         if (ownerKey and player:QueryCharacter("key") != ownerKey) then
  6256.             canPickup = false;
  6257.         end;
  6258.     end;
  6259.    
  6260.     if ( entity:IsPlayer() and entity:InVehicle() ) then
  6261.         canPickup = false;
  6262.     end;
  6263.    
  6264.     if (canPickup) then
  6265.         player.isHoldingEntity = entity;
  6266.         entity.isBeingHeld = player;
  6267.        
  6268.         if ( !entity:IsPlayer() ) then
  6269.             if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  6270.                 entity.lastCollisionGroup = entity:GetCollisionGroup();
  6271.                 entity:SetCollisionGroup(COLLISION_GROUP_WEAPON);
  6272.                 entity.damageImmunity = CurTime() + 60;
  6273.             end;
  6274.         else
  6275.             entity.moveType = entity:GetMoveType();
  6276.             entity:SetMoveType(MOVETYPE_NOCLIP);
  6277.         end;
  6278.        
  6279.         return true;
  6280.     else
  6281.         return false;
  6282.     end;
  6283. end;
  6284.  
  6285. -- Called when a player attempts to drop an entity with the physics gun.
  6286. function NEXUS:PhysgunDrop(player, entity)
  6287.     if ( !entity:IsPlayer() ) then
  6288.         if (entity.lastCollisionGroup) then
  6289.             nexus.entity.ReturnCollisionGroup(entity, entity.lastCollisionGroup);
  6290.         end;
  6291.     else
  6292.         entity:SetMoveType(entity.moveType or MOVETYPE_WALK);
  6293.         entity.moveType = nil;
  6294.     end;
  6295.    
  6296.     player.isHoldingEntity = nil;
  6297.     entity.isBeingHeld = nil;
  6298. end;
  6299.  
  6300. -- Called when a player attempts to spawn an NPC.
  6301. function NEXUS:PlayerSpawnNPC(player, model)
  6302.     if ( !nexus.player.HasFlags(player, "n") ) then
  6303.         return false;
  6304.     end;
  6305.    
  6306.     if ( !player:Alive() or player:IsRagdolled() ) then
  6307.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6308.        
  6309.         return false;
  6310.     end;
  6311.    
  6312.     if ( !nexus.player.IsAdmin(player) ) then
  6313.         return false;
  6314.     else
  6315.         return true;
  6316.     end;
  6317. end;
  6318.  
  6319. -- Called when an NPC has been killed.
  6320. function NEXUS:OnNPCKilled(entity, attacker, inflictor) end;
  6321.  
  6322. -- Called to get whether an entity is being held.
  6323. function NEXUS:GetEntityBeingHeld(entity)
  6324.     return entity.isBeingHeld or entity:IsPlayerHolding();
  6325. end;
  6326.  
  6327. -- Called when an entity is removed.
  6328. function NEXUS:EntityRemoved(entity)
  6329.     if ( !self:IsShuttingDown() ) then
  6330.         if ( IsValid(entity) ) then
  6331.             if (entity.giveRefund) then
  6332.                 if ( CurTime() <= entity.giveRefund[1] ) then
  6333.                     if ( IsValid( entity.giveRefund[2] ) ) then
  6334.                         nexus.player.GiveCash(entity.giveRefund[2], entity.giveRefund[3], "Prop Refund");
  6335.                     end;
  6336.                 end;
  6337.             end;
  6338.            
  6339.             nexus.player.GetAllProperty()[ entity:EntIndex() ] = nil;
  6340.         end;
  6341.        
  6342.         nexus.entity.ClearProperty(entity);
  6343.     end;
  6344. end;
  6345.  
  6346. -- Called when an entity's menu option should be handled.
  6347. function NEXUS:EntityHandleMenuOption(player, entity, option, arguments)
  6348.     local class = entity:GetClass();
  6349.     local generator = nexus.generator.Get(class);
  6350.    
  6351.     if ( class == "nx_item" and (arguments == "nx_itemTake" or arguments == "nx_itemUse") ) then
  6352.         if ( nexus.entity.BelongsToAnotherCharacter(player, entity) ) then
  6353.             nexus.player.Notify(player, "You cannot pick up items you dropped on another character!");
  6354.            
  6355.             return;
  6356.         end;
  6357.        
  6358.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  6359.        
  6360.         local itemTable = entity.item;
  6361.         local quickUse = (arguments == "nx_itemUse");
  6362.        
  6363.         if (itemTable) then
  6364.             local didPickupItem = true;
  6365.             local canPickup = ( !itemTable.CanPickup or itemTable:CanPickup(player, quickUse, entity) );
  6366.            
  6367.             if (canPickup != false) then
  6368.                 if (canPickup and type(canPickup) == "string") then
  6369.                     local newItemTable = nexus.item.Get(canPickup);
  6370.                    
  6371.                     if (newItemTable) then
  6372.                         itemTable = newItemTable;
  6373.                     end;
  6374.                 end;
  6375.                
  6376.                 player:SetItemEntity(entity);
  6377.                
  6378.                 if (quickUse) then
  6379.                     player:UpdateInventory(itemTable.uniqueID, 1, true, true);
  6380.                    
  6381.                     if ( !nexus.player.RunNexusCommand(player, "InvAction", itemTable.uniqueID, "use") ) then
  6382.                         player:UpdateInventory(itemTable.uniqueID, -1, true, true);
  6383.                         didPickupItem = false;
  6384.                     else
  6385.                         player:FakePickup(entity);
  6386.                     end;
  6387.                 else
  6388.                     local success, fault = player:UpdateInventory(itemTable.uniqueID, 1);
  6389.                    
  6390.                     if (!success) then
  6391.                         nexus.player.Notify(player, fault);
  6392.                         didPickupItem = false;
  6393.                     else
  6394.                         player:FakePickup(entity);
  6395.                     end;
  6396.                 end;
  6397.                
  6398.                 if (didPickupItem) then
  6399.                     if (!itemTable.OnPickup or itemTable:OnPickup(player, quickUse, entity) != false) then
  6400.                         entity:Remove();
  6401.                     end;
  6402.                 end;
  6403.                
  6404.                 player:SetItemEntity(nil);
  6405.             end;
  6406.         end;
  6407.     elseif (class == "nx_item" and arguments == "nx_itemAmmo") then
  6408.         local itemTable = entity.item;
  6409.        
  6410.         if ( itemTable and nexus.item.IsWeapon(itemTable) ) then
  6411.             if ( itemTable:HasSecondaryClip() or itemTable:HasPrimaryClip() ) then
  6412.                 if (entity.data.sClip) then
  6413.                     player:GiveAmmo(entity.data.sClip, itemTable.secondaryAmmoClass);
  6414.                 end;
  6415.                
  6416.                 if (entity.data.pClip) then
  6417.                     player:GiveAmmo(entity.data.pClip, itemTable.primaryAmmoClass);
  6418.                 end;
  6419.                
  6420.                 entity.data.sClip = nil;
  6421.                 entity.data.pClip = nil;
  6422.                
  6423.                 player:FakePickup(entity);
  6424.             end;
  6425.         end;
  6426.     elseif (class == "nx_shipment" and arguments == "nx_shipmentOpen") then
  6427.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  6428.         player:FakePickup(entity);
  6429.        
  6430.         nexus.player.OpenStorage( player, {
  6431.             name = "Shipment",
  6432.             weight = entity.weight,
  6433.             entity = entity,
  6434.             distance = 192,
  6435.             inventory = entity.inventory,
  6436.             OnClose = function(player, storageTable, entity)
  6437.                 if ( IsValid(entity) ) then
  6438.                     if (!entity.inventory or table.Count(entity.inventory) == 0) then
  6439.                         entity:Explode(entity:BoundingRadius() * 2);
  6440.                         entity:Remove();
  6441.                     end;
  6442.                 end;
  6443.             end,
  6444.             CanGive = function(player, storageTable, itemTable)
  6445.                 return false;
  6446.             end
  6447.         } );
  6448.     elseif (class == "nx_cash" and arguments == "nx_cashTake") then
  6449.         if ( nexus.entity.BelongsToAnotherCharacter(player, entity) ) then
  6450.             nexus.player.Notify(player, "You cannot pick up cash you dropped on another character!");
  6451.            
  6452.             return;
  6453.         end;
  6454.        
  6455.         nexus.player.GiveCash( player, entity:GetSharedVar("sh_Amount"), nexus.schema.GetOption("name_cash") );
  6456.         player:EmitSound("physics/body/body_medium_impact_soft"..math.random(1, 7)..".wav");
  6457.         player:FakePickup(entity);
  6458.        
  6459.         entity:Remove();
  6460.     elseif (generator and arguments == "nx_generatorSupply") then
  6461.         if (entity:GetPower() < generator.power) then
  6462.             if ( !entity.CanSupply or entity:CanSupply(player) ) then
  6463.                 nexus.mount.Call("PlayerChargeGenerator", player, entity, generator);
  6464.                 entity:SetSharedVar("sh_Power", generator.power);
  6465.                 player:FakePickup(entity);
  6466.                
  6467.                 if (entity.OnSupplied) then
  6468.                     entity:OnSupplied(player);
  6469.                 end;
  6470.                
  6471.                 entity:Explode();
  6472.             end;
  6473.         end;
  6474.     end;
  6475. end;
  6476.  
  6477. -- Called when a player has spawned a prop.
  6478. function NEXUS:PlayerSpawnedProp(player, model, entity)
  6479.     if ( IsValid(entity) ) then
  6480.         local scalePropCost = nexus.config.Get("scale_prop_cost"):Get();
  6481.        
  6482.         if (scalePropCost > 0) then
  6483.             local cost = math.ceil( math.max( (entity:BoundingRadius() / 2) * scalePropCost, 1 ) );
  6484.             local info = {cost = cost, name = "Prop"};
  6485.            
  6486.             nexus.mount.Call("PlayerAdjustPropCostInfo", player, entity, info);
  6487.            
  6488.             if ( nexus.player.CanAfford(player, info.cost) ) then
  6489.                 nexus.player.GiveCash(player, -info.cost, info.name);
  6490.                
  6491.                 entity.giveRefund = {CurTime() + 10, player, info.cost};
  6492.             else
  6493.                 nexus.player.Notify(player, "You need another "..FORMAT_CASH(info.cost - nexus.player.GetCash(player), nil, true).."!");
  6494.                
  6495.                 entity:Remove();
  6496.             end;
  6497.         end;
  6498.        
  6499.         if ( IsValid(entity) ) then
  6500.             entity:SetOwnerKey( player:QueryCharacter("key") );
  6501.            
  6502.             self.BaseClass:PlayerSpawnedProp(player, model, entity);
  6503.            
  6504.             if ( IsValid(entity) ) then
  6505.                 self:PrintDebug(player:Name().." spawned "..tostring(model).." ("..tostring(entity)..").");
  6506.                
  6507.                 if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  6508.                     entity.damageImmunity = CurTime() + 60;
  6509.                 end;
  6510.             end;
  6511.         end;
  6512.     end;
  6513. end;
  6514.  
  6515. -- Called when a player attempts to spawn a prop.
  6516. function NEXUS:PlayerSpawnProp(player, model)
  6517.     if ( !nexus.player.HasFlags(player, "e") ) then
  6518.         return false;
  6519.     end;
  6520.    
  6521.     if ( !player:Alive() or player:IsRagdolled() ) then
  6522.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6523.        
  6524.         return false;
  6525.     end;
  6526.    
  6527.     if ( nexus.player.IsAdmin(player) ) then
  6528.         return true;
  6529.     end;
  6530.    
  6531.     return self.BaseClass:PlayerSpawnProp(player, model);
  6532. end;
  6533.  
  6534. -- Called when a player attempts to spawn a ragdoll.
  6535. function NEXUS:PlayerSpawnRagdoll(player, model)
  6536.     if ( !nexus.player.HasFlags(player, "r") ) then return false; end;
  6537.    
  6538.     if ( !player:Alive() or player:IsRagdolled() ) then
  6539.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6540.        
  6541.         return false;
  6542.     end;
  6543.    
  6544.     if ( !nexus.player.IsAdmin(player) ) then
  6545.         return false;
  6546.     else
  6547.         return true;
  6548.     end;
  6549. end;
  6550.  
  6551. -- Called when a player attempts to spawn an effect.
  6552. function NEXUS:PlayerSpawnEffect(player, model)
  6553.     if ( !player:Alive() or player:IsRagdolled() ) then
  6554.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6555.        
  6556.         return false;
  6557.     end;
  6558.    
  6559.     if ( !nexus.player.IsAdmin(player) ) then
  6560.         return false;
  6561.     else
  6562.         return true;
  6563.     end;
  6564. end;
  6565.  
  6566. -- Called when a player attempts to spawn a vehicle.
  6567. function NEXUS:PlayerSpawnVehicle(player, model)
  6568.     if ( !string.find(model, "chair") and !string.find(model, "seat") ) then
  6569.         if ( !nexus.player.HasFlags(player, "C") ) then
  6570.             return false;
  6571.         end;
  6572.     elseif ( !nexus.player.HasFlags(player, "c") ) then
  6573.         return false;
  6574.     end;
  6575.    
  6576.     if ( !player:Alive() or player:IsRagdolled() ) then
  6577.         nexus.player.Notify(player, "You don't have permission to do this right now!");
  6578.        
  6579.         return false;
  6580.     end;
  6581.    
  6582.     if ( nexus.player.IsAdmin(player) ) then
  6583.         return true;
  6584.     end;
  6585.    
  6586.     return self.BaseClass:PlayerSpawnVehicle(player, model);
  6587. end;
  6588.  
  6589. -- Called when a player attempts to use a tool.
  6590. function NEXUS:CanTool(player, trace, tool)
  6591.     local isAdmin = nexus.player.IsAdmin(player);
  6592.    
  6593.     if ( IsValid(trace.Entity) ) then
  6594.         local isPropProtectionEnabled = nexus.config.Get("enable_prop_protection"):Get();
  6595.         local characterKey = player:QueryCharacter("key");
  6596.        
  6597.         if ( !isAdmin and !nexus.entity.IsInteractable(trace.Entity) ) then
  6598.             return false;
  6599.         end;
  6600.        
  6601.         if ( !isAdmin and nexus.entity.IsPlayerRagdoll(trace.Entity) ) then
  6602.             return false;
  6603.         end;
  6604.        
  6605.         if (isPropProtectionEnabled and !isAdmin) then
  6606.             local ownerKey = trace.Entity:GetOwnerKey();
  6607.            
  6608.             if (ownerKey and characterKey != ownerKey) then
  6609.                 return false;
  6610.             end;
  6611.         end;
  6612.        
  6613.         if (!isAdmin) then
  6614.             if (tool == "nail") then
  6615.                 local newTrace = {};
  6616.                
  6617.                 newTrace.start = trace.HitPos;
  6618.                 newTrace.endpos = trace.HitPos + player:GetAimVector() * 16;
  6619.                 newTrace.filter = {player, trace.Entity};
  6620.                
  6621.                 newTrace = util.TraceLine(newTrace);
  6622.                
  6623.                 if ( IsValid(newTrace.Entity) ) then
  6624.                     if ( !nexus.entity.IsInteractable(newTrace.Entity) or nexus.entity.IsPlayerRagdoll(newTrace.Entity) ) then
  6625.                         return false;
  6626.                     end;
  6627.                    
  6628.                     if (isPropProtectionEnabled) then
  6629.                         local ownerKey = newTrace.Entity:GetOwnerKey();
  6630.                        
  6631.                         if (ownerKey and characterKey != ownerKey) then
  6632.                             return false;
  6633.                         end;
  6634.                     end;
  6635.                 end;
  6636.             elseif ( tool == "remover" and player:KeyDown(IN_ATTACK2) and !player:KeyDownLast(IN_ATTACK2) ) then
  6637.                 if ( !trace.Entity:IsMapEntity() ) then
  6638.                     local entities = constraint.GetAllConstrainedEntities(trace.Entity);
  6639.                    
  6640.                     for k, v in pairs(entities) do
  6641.                         if ( v:IsMapEntity() or nexus.entity.IsPlayerRagdoll(v) ) then
  6642.                             return false;
  6643.                         end;
  6644.                        
  6645.                         if (isPropProtectionEnabled) then
  6646.                             local ownerKey = v:GetOwnerKey();
  6647.                            
  6648.                             if (ownerKey and characterKey != ownerKey) then
  6649.                                 return false;
  6650.                             end;
  6651.                         end;
  6652.                     end
  6653.                 else
  6654.                     return false;
  6655.                 end;
  6656.             end
  6657.         end;
  6658.     end;
  6659.    
  6660.     self:PrintDebug(player:Name().." used the "..tostring(tool).." tool.");
  6661.    
  6662.     if (!isAdmin) then
  6663.         return self.BaseClass:CanTool(player, trace, tool);
  6664.     else
  6665.         return true;
  6666.     end;
  6667. end;
  6668.  
  6669. -- Called when a player attempts to NoClip.
  6670. function NEXUS:PlayerNoClip(player)
  6671.     if ( player:IsRagdolled() ) then
  6672.         return false;
  6673.     elseif ( player:IsSuperAdmin() ) then
  6674.         return true;
  6675.     else
  6676.         return false;
  6677.     end;
  6678. end;
  6679.  
  6680. -- Called when a player's character has initialized.
  6681. function NEXUS:PlayerCharacterInitialized(player)
  6682.     umsg.Start("nx_InventoryClear", player);
  6683.     umsg.End();
  6684.    
  6685.     umsg.Start("nx_AttributesClear", player);
  6686.     umsg.End();
  6687.    
  6688.     if ( !nexus.class.Get( player:Team() ) ) then
  6689.         nexus.class.AssignToDefault(player);
  6690.     end;
  6691.    
  6692.     for k, v in pairs( nexus.player.GetInventory(player) ) do
  6693.         local itemTable = nexus.item.Get(k);
  6694.        
  6695.         if (itemTable) then
  6696.             player:UpdateInventory(itemTable.uniqueID, 0, true);
  6697.         end;
  6698.     end;
  6699.        
  6700.     player.attributeProgress = {};
  6701.     player.attributeProgressTime = 0;
  6702.    
  6703.     for k, v in pairs( nexus.attribute.GetAll() ) do
  6704.         player:UpdateAttribute(k);
  6705.     end;
  6706.    
  6707.     for k, v in pairs( player:QueryCharacter("attributes") ) do
  6708.         player.attributeProgress[k] = math.floor(v.progress);
  6709.     end;
  6710.    
  6711.     local startHintsDelay = 4;
  6712.     local starterHintsTable = {
  6713.         "Directory",
  6714.         "Give Name",
  6715.         "Target Recognises",
  6716.         "Raise Weapon"
  6717.     };
  6718.    
  6719.     for k, v in ipairs(starterHintsTable) do
  6720.         local hintTable = nexus.hint.Find(v);
  6721.        
  6722.         if ( hintTable and !player:GetData("hint"..k) ) then
  6723.             if (!hintTable.Callback or hintTable.Callback(player) != false) then
  6724.                 timer.Simple(startHintsDelay, function()
  6725.                     if ( IsValid(player) ) then
  6726.                         nexus.hint.Send(player, hintTable.text, 30);
  6727.                         player:SetData("hint"..k, true);
  6728.                     end;
  6729.                 end);
  6730.                
  6731.                 startHintsDelay = startHintsDelay + 30;
  6732.             end;
  6733.         end;
  6734.     end;
  6735.    
  6736.     if (startHintsDelay > 4) then
  6737.         player.isViewingStarterHints = true;
  6738.        
  6739.         timer.Simple(startHintsDelay, function()
  6740.             if ( IsValid(player) ) then
  6741.                 player.isViewingStarterHints = false;
  6742.             end;
  6743.         end);
  6744.     end;
  6745. end;
  6746.  
  6747. -- Called when a player has used their death code.
  6748. function NEXUS:PlayerDeathCodeUsed(player, commandTable, arguments) end;
  6749.  
  6750. -- Called when a player has created a character.
  6751. function NEXUS:PlayerCharacterCreated(player, character) end;
  6752.  
  6753. -- Called when a player's character has unloaded.
  6754. function NEXUS:PlayerCharacterUnloaded(player)
  6755.     nexus.player.SetupRemovePropertyDelays(player);
  6756.     nexus.player.DisableProperty(player);
  6757.     nexus.player.SetRagdollState(player, RAGDOLL_RESET);
  6758.     nexus.player.CloseStorage(player, true)
  6759.    
  6760.     player:SetTeam(TEAM_UNASSIGNED);
  6761. end;
  6762.  
  6763. -- Called when a player's character has loaded.
  6764. function NEXUS:PlayerCharacterLoaded(player)
  6765.     player:SetSharedVar( "sh_InventoryWeight", nexus.config.Get("default_inv_weight"):Get() );
  6766.    
  6767.     player.characterLoadedTime = CurTime();
  6768.     player.attributeBoosts = {};
  6769.     player.crouchedSpeed = nexus.config.Get("crouched_speed"):Get();
  6770.     player.ragdollTable = {};
  6771.     player.spawnWeapons = {};
  6772.     player.initialized = true;
  6773.     player.firstSpawn = true;
  6774.     player.lightSpawn = false;
  6775.     player.changeClass = false;
  6776.     player.spawnAmmo = {};
  6777.     player.jumpPower = nexus.config.Get("jump_power"):Get();
  6778.     player.walkSpeed = nexus.config.Get("walk_speed"):Get();
  6779.     player.runSpeed = nexus.config.Get("run_speed"):Get();
  6780.    
  6781.     hook.Call( "PlayerRestoreCharacterData", NEXUS, player, player:QueryCharacter("data") );
  6782.     hook.Call( "PlayerRestoreTempData", NEXUS, player, player:CreateTempData() );
  6783.    
  6784.     nexus.player.SetCharacterMenuState(player, CHARACTER_MENU_CLOSE);
  6785.    
  6786.     nexus.mount.Call("PlayerCharacterInitialized", player);
  6787.    
  6788.     nexus.player.RestoreRecognisedNames(player);
  6789.     nexus.player.ReturnProperty(player);
  6790.     nexus.player.SetInitialized(player, true);
  6791.    
  6792.     player.firstSpawn = false;
  6793.    
  6794.     local charactersTable = nexus.config.Get("mysql_characters_table"):Get();
  6795.     local schemaFolder = self:GetSchemaFolder();
  6796.     local characterID = player:QueryCharacter("characterID");
  6797.     local onNextLoad = player:QueryCharacter("onNextLoad");
  6798.     local steamID = player:SteamID();
  6799.     local query = "UPDATE "..charactersTable.." SET _OnNextLoad = \"\" WHERE";
  6800.    
  6801.     if (onNextLoad != "") then
  6802.         tmysql.query(query.." _Schema = \""..schemaFolder.."\" AND _SteamID = \""..steamID.."\" AND _CharacterID = "..characterID);
  6803.        
  6804.         player:SetCharacterData("onNextLoad", "", true);
  6805.        
  6806.         CHARACTER = player:GetCharacter();
  6807.             PLAYER = player;
  6808.                 RunString(onNextLoad);
  6809.             PLAYER = nil;
  6810.         CHARACTER = nil;
  6811.     end;
  6812. end;
  6813.  
  6814. -- Called when a player's property should be restored.
  6815. function NEXUS:PlayerReturnProperty(player) end;
  6816.  
  6817. -- Called when config has initialized for a player.
  6818. function NEXUS:PlayerConfigInitialized(player)
  6819.     nexus.mount.Call("PlayerSendDataStreamInfo", player);
  6820.    
  6821.     if ( player:IsBot() ) then
  6822.         nexus.mount.Call("PlayerDataStreamInfoSent", player);
  6823.     else
  6824.         timer.Simple(FrameTime() * 32, function()
  6825.             if ( IsValid(player) ) then
  6826.                 umsg.Start("nx_DataStreaming", player);
  6827.                 umsg.End();
  6828.             end;
  6829.         end);
  6830.     end;
  6831. end;
  6832.  
  6833. -- Called when a player initially spawns.
  6834. function NEXUS:PlayerInitialSpawn(player)
  6835.     player.hasSpawned = true;
  6836.     player.characters = {};
  6837.     player.sharedVars = {};
  6838.    
  6839.     if ( IsValid(player) ) then
  6840.         player:KillSilent();
  6841.     end;
  6842.    
  6843.     if ( player:IsBot() ) then
  6844.         nexus.config.Send(player);
  6845.     end;
  6846.    
  6847.     if ( !player:IsKicked() ) then
  6848.         nexus.chatBox.Add(nil, nil, "connect", player:SteamName().." has connected to the server.");
  6849.        
  6850.         self:PrintDebug(player:SteamName().." ("..player:SteamID().."|"..player:IPAddress()..") has connected to the server.");
  6851.     end;
  6852. end;
  6853.  
  6854. -- Called each frame that a player is dead.
  6855. function NEXUS:PlayerDeathThink(player)
  6856.     local action = nexus.player.GetAction(player);
  6857.    
  6858.     if ( !player:HasInitialized() or player:GetCharacterData("banned") ) then
  6859.         return true;
  6860.     end;
  6861.    
  6862.     if (action == "spawn") then
  6863.         return true;
  6864.     else
  6865.         player:Spawn();
  6866.     end;
  6867. end;
  6868.  
  6869. -- Called when a player has used their radio.
  6870. function NEXUS:PlayerRadioUsed(player, text, listeners, eavesdroppers) end;
  6871.  
  6872. -- Called when a player's drop weapon info should be adjusted.
  6873. function NEXUS:PlayerAdjustDropWeaponInfo(player, info)
  6874.     return true;
  6875. end;
  6876.  
  6877. -- Called when a player's character creation info should be adjusted.
  6878. function NEXUS:PlayerAdjustCharacterCreationInfo(player, info, data) end;
  6879.  
  6880. -- Called when a player's earn generator info should be adjusted.
  6881. function NEXUS:PlayerAdjustEarnGeneratorInfo(player, info) end;
  6882.  
  6883. -- Called when a player's order item should be adjusted.
  6884. function NEXUS:PlayerAdjustOrderItemTable(player, itemTable) end;
  6885.  
  6886. -- Called when a player's next punch info should be adjusted.
  6887. function NEXUS:PlayerAdjustNextPunchInfo(player, info) end;
  6888.  
  6889. -- Called when a player has an unknown inventory item.
  6890. function NEXUS:PlayerHasUnknownInventoryItem(player, inventory, item, amount) end;
  6891.  
  6892. -- Called when a player uses an unknown item function.
  6893. function NEXUS:PlayerUseUnknownItemFunction(player, itemTable, itemFunction) end;
  6894.  
  6895. -- Called when a player has an unknown attribute.
  6896. function NEXUS:PlayerHasUnknownAttribute(player, attributes, attribute, amount, progress) end;
  6897.  
  6898. -- Called when a player's character table should be adjusted.
  6899. function NEXUS:PlayerAdjustCharacterTable(player, character)
  6900.     if ( nexus.faction.stored[character.faction] ) then
  6901.         if ( nexus.faction.stored[character.faction].whitelist
  6902.         and !nexus.player.IsWhitelisted(player, character.faction) ) then
  6903.             character.data["banned"] = true;
  6904.         end;
  6905.     else
  6906.         return true;
  6907.     end;
  6908. end;
  6909.  
  6910. -- Called when a player's character screen info should be adjusted.
  6911. function NEXUS:PlayerAdjustCharacterScreenInfo(player, character, info) end;
  6912.  
  6913. -- Called when a player's prop cost info should be adjusted.
  6914. function NEXUS:PlayerAdjustPropCostInfo(player, entity, info) end;
  6915.  
  6916. -- Called when a player's death info should be adjusted.
  6917. function NEXUS:PlayerAdjustDeathInfo(player, info) end;
  6918.  
  6919. -- Called when debug info should be adjusted.
  6920. function NEXUS:DebugAdjustInfo(info) end;
  6921.  
  6922. -- Called when chat box info should be adjusted.
  6923. function NEXUS:ChatBoxAdjustInfo(info) end;
  6924.  
  6925. -- Called when a chat box message has been added.
  6926. function NEXUS:ChatBoxMessageAdded(info) end;
  6927.  
  6928. -- Called when a player's radio text should be adjusted.
  6929. function NEXUS:PlayerAdjustRadioInfo(player, info) end;
  6930.  
  6931. -- Called when a player should gain a frag.
  6932. function NEXUS:PlayerCanGainFrag(player, victim) return true; end;
  6933.  
  6934. -- Called when a player's model should be set.
  6935. function NEXUS:PlayerSetModel(player)
  6936.     nexus.player.SetDefaultModel(player);
  6937.     nexus.player.SetDefaultSkin(player);
  6938. end;
  6939.  
  6940. -- Called just after a player spawns.
  6941. function NEXUS:PostPlayerSpawn(player, lightSpawn, changeClass, firstSpawn)
  6942.     if (firstSpawn) then
  6943.         local attributeBoosts = player:GetCharacterData("attributeboosts");
  6944.         local health = player:GetCharacterData("health");
  6945.         local armor = player:GetCharacterData("armor");
  6946.        
  6947.         if (health and health > 1) then
  6948.             player:SetHealth(health);
  6949.         end;
  6950.        
  6951.         if (armor and armor > 1) then
  6952.             player:SetArmor(armor);
  6953.         end;
  6954.        
  6955.         if (attributeBoosts) then
  6956.             for k, v in pairs(attributeBoosts) do
  6957.                 for k2, v2 in pairs(v) do
  6958.                     nexus.attributes.Boost(player, k2, k, v2.amount, v2.duration);
  6959.                 end;
  6960.             end;
  6961.         end;
  6962.     else
  6963.         player:SetCharacterData("attributeboosts", nil);
  6964.         player:SetCharacterData("health", nil);
  6965.         player:SetCharacterData("armor", nil);
  6966.     end;
  6967. end;
  6968.  
  6969. -- Called when a player spawns.
  6970. function NEXUS:PlayerSpawn(player)
  6971.     if ( player:HasInitialized() ) then
  6972.         player:ShouldDropWeapon(false);
  6973.        
  6974.         if (!player.lightSpawn) then
  6975.             nexus.player.SetWeaponRaised(player, false);
  6976.             nexus.player.SetRagdollState(player, RAGDOLL_RESET);
  6977.             nexus.player.SetAction(player, false);
  6978.             nexus.player.SetDrunk(player, false);
  6979.            
  6980.             nexus.attributes.ClearBoosts(player);
  6981.            
  6982.             self:PlayerSetModel(player);
  6983.             self:PlayerLoadout(player);
  6984.            
  6985.             if ( player:FlashlightIsOn() ) then
  6986.                 player:Flashlight(false);
  6987.             end;
  6988.            
  6989.             player:SetForcedAnimation(false);
  6990.             player:SetCollisionGroup(COLLISION_GROUP_PLAYER);
  6991.             player:SetMaxHealth(100);
  6992.             player:SetMaxArmor(100);
  6993.             player:SetMaterial("");
  6994.             player:SetMoveType(MOVETYPE_WALK);
  6995.             player:Extinguish();
  6996.             player:UnSpectate();
  6997.             player:GodDisable();
  6998.             player:RunCommand("-duck");
  6999.             player:SetColor(255, 255, 255, 255);
  7000.            
  7001.             player:SetCrouchedWalkSpeed( nexus.config.Get("crouched_speed"):Get() );
  7002.             player:SetWalkSpeed( nexus.config.Get("walk_speed"):Get() );
  7003.             player:SetJumpPower( nexus.config.Get("jump_power"):Get() );
  7004.             player:SetRunSpeed( nexus.config.Get("run_speed"):Get() );
  7005.            
  7006.             if (player.firstSpawn) then
  7007.                 local ammo = player:QueryCharacter("ammo");
  7008.                
  7009.                 for k, v in pairs(ammo) do
  7010.                     if ( !string.find(k, "p_") and !string.find(k, "s_") ) then
  7011.                         player:GiveAmmo(v, k); ammo[k] = nil;
  7012.                     end;
  7013.                 end;
  7014.             else
  7015.                 player:UnLock();
  7016.             end;
  7017.         end;
  7018.        
  7019.         if (player.lightSpawn and player.lightSpawnCallback) then
  7020.             player.lightSpawnCallback(player, true);
  7021.             player.lightSpawnCallback = nil;
  7022.         end;
  7023.        
  7024.         nexus.mount.Call("PostPlayerSpawn", player, player.lightSpawn, player.changeClass, player.firstSpawn);
  7025.        
  7026.         nexus.player.SetRecognises(player, player, RECOGNISE_TOTAL);
  7027.        
  7028.         player.changeClass = false;
  7029.         player.lightSpawn = false;
  7030.     else
  7031.         player:KillSilent();
  7032.     end;
  7033. end;
  7034.  
  7035. -- Called when a player should take damage.
  7036. function NEXUS:PlayerShouldTakeDamage(player, attacker, inflictor, damageInfo)
  7037.     if ( nexus.player.IsNoClipping(player) ) then
  7038.         return false;
  7039.     end;
  7040.    
  7041.     return true;
  7042. end;
  7043.  
  7044. -- Called when a player is attacked by a trace.
  7045. function NEXUS:PlayerTraceAttack(player, damageInfo, direction, trace)
  7046.     player.lastHitGroup = trace.HitGroup;
  7047.    
  7048.     return false;
  7049. end;
  7050.  
  7051. -- Called just before a player dies.
  7052. function NEXUS:DoPlayerDeath(player, attacker, damageInfo)
  7053.     nexus.player.DropWeapons(player, attacker);
  7054.     nexus.player.SetAction(player, false);
  7055.     nexus.player.SetDrunk(player, false);
  7056.    
  7057.     local deathSound = nexus.mount.Call( "PlayerPlayDeathSound", player, nexus.player.GetGender(player) );
  7058.     local decayTime = nexus.config.Get("body_decay_time"):Get();
  7059.  
  7060.     if (decayTime > 0) then
  7061.         nexus.player.SetRagdollState( player, RAGDOLL_KNOCKEDOUT, nil, decayTime, self:ConvertForce(damageInfo:GetDamageForce() * 32) );
  7062.     else
  7063.         nexus.player.SetRagdollState( player, RAGDOLL_KNOCKEDOUT, nil, 600, self:ConvertForce(damageInfo:GetDamageForce() * 32) );
  7064.     end;
  7065.    
  7066.     if ( nexus.mount.Call("PlayerCanDeathClearRecognisedNames", player, attacker, damageInfo) ) then
  7067.         nexus.player.ClearRecognisedNames(player);
  7068.     end;
  7069.    
  7070.     if ( nexus.mount.Call("PlayerCanDeathClearName", player, attacker, damageInfo) ) then
  7071.         nexus.player.ClearName(player);
  7072.     end;
  7073.    
  7074.     if (deathSound) then
  7075.         player:EmitSound("physics/flesh/flesh_impact_hard"..math.random(1, 5)..".wav", 150);
  7076.        
  7077.         timer.Simple(FrameTime() * 25, function()
  7078.             if ( IsValid(player) ) then
  7079.                 player:EmitSound(deathSound);
  7080.             end;
  7081.         end);
  7082.     end;
  7083.    
  7084.     player:SetForcedAnimation(false);
  7085.     player:SetCharacterData("ammo", {}, true);
  7086.     player:StripWeapons();
  7087.     player:Extinguish();
  7088.     player:StripAmmo();
  7089.     player.spawnAmmo = {};
  7090.     player:AddDeaths(1);
  7091.     player:UnLock();
  7092.    
  7093.     if ( IsValid(attacker) and attacker:IsPlayer() ) then
  7094.         if (player != attacker) then
  7095.             if ( nexus.mount.Call("PlayerCanGainFrag", attacker, player) ) then
  7096.                 attacker:AddFrags(1);
  7097.             end;
  7098.         end;
  7099.     end;
  7100. end;
  7101.  
  7102. -- Called when a player dies.
  7103. function NEXUS:PlayerDeath(player, inflictor, attacker, damageInfo)
  7104.     self:CalculateSpawnTime(player, inflictor, attacker, damageInfo);
  7105.    
  7106.     if ( player:GetRagdollEntity() ) then
  7107.         local ragdoll = player:GetRagdollEntity();
  7108.        
  7109.         if (inflictor:GetClass() == "prop_combine_ball") then
  7110.             if (damageInfo) then
  7111.                 nexus.entity.Disintegrate(player:GetRagdollEntity(), 3, damageInfo:GetDamageForce() * 32);
  7112.             else
  7113.                 nexus.entity.Disintegrate(player:GetRagdollEntity(), 3);
  7114.             end;
  7115.         end;
  7116.     end;
  7117.    
  7118.     if ( attacker:IsPlayer() ) then
  7119.         if ( IsValid( attacker:GetActiveWeapon() ) ) then
  7120.             self:PrintDebug(attacker:Name().." killed "..player:Name().." with "..nexus.player.GetWeaponClass(attacker)..".");
  7121.         else
  7122.             self:PrintDebug(attacker:Name().." killed "..player:Name()..".");
  7123.         end;
  7124.     else
  7125.         self:PrintDebug(attacker:GetClass().." killed "..player:Name()..".");
  7126.     end;
  7127. end;
  7128.  
  7129. -- Called when a player's weapons should be given.
  7130. function NEXUS:PlayerLoadout(player)
  7131.     local weapons = nexus.class.Query(player:Team(), "weapons");
  7132.     local ammo = nexus.class.Query(player:Team(), "ammo");
  7133.    
  7134.     player.spawnWeapons = {};
  7135.     player.spawnAmmo = {};
  7136.    
  7137.     if ( nexus.player.HasFlags(player, "t") ) then
  7138.         nexus.player.GiveSpawnWeapon(player, "gmod_tool");
  7139.     end
  7140.    
  7141.     if ( nexus.player.HasFlags(player, "p") ) then
  7142.         nexus.player.GiveSpawnWeapon(player, "weapon_physgun");
  7143.     end
  7144.    
  7145.     nexus.player.GiveSpawnWeapon(player, "weapon_physcannon");
  7146.     nexus.player.GiveSpawnWeapon(player, "nx_hands");
  7147.     nexus.player.GiveSpawnWeapon(player, "nx_keys");
  7148.    
  7149.     if (weapons) then
  7150.         for k, v in ipairs(weapons) do
  7151.             if ( !nexus.player.GiveSpawnItemWeapon(player, v) ) then
  7152.                 player:Give(v);
  7153.             end;
  7154.         end;
  7155.     end;
  7156.    
  7157.     if (ammo) then
  7158.         for k, v in pairs(ammo) do
  7159.             nexus.player.GiveSpawnAmmo(player, k, v);
  7160.         end;
  7161.     end;
  7162.    
  7163.     nexus.mount.Call("PlayerGiveWeapons", player);
  7164.    
  7165.     player:SelectWeapon("nx_hands");
  7166. end
  7167.  
  7168. -- Called when the server shuts down.
  7169. function NEXUS:ShutDown()
  7170.     self.ShuttingDown = true;
  7171. end;
  7172.  
  7173. -- Called when a player presses F1.
  7174. function NEXUS:ShowHelp(player)
  7175.     umsg.Start("nx_MenuToggle", player);
  7176.     umsg.End();
  7177. end;
  7178.  
  7179. -- Called when a player presses F2.
  7180. function NEXUS:ShowTeam(player)
  7181.     if ( !nexus.player.IsNoClipping(player) ) then
  7182.         local doRecogniseMenu = true;
  7183.         local entity = player:GetEyeTraceNoCursor().Entity;
  7184.        
  7185.         if ( IsValid(entity) and nexus.entity.IsDoor(entity) ) then
  7186.             if (entity:GetPos():Distance( player:GetShootPos() ) <= 192) then
  7187.                 if ( nexus.mount.Call("PlayerCanViewDoor", player, entity) ) then
  7188.                     if ( nexus.mount.Call("PlayerUse", player, entity) ) then
  7189.                         local owner = nexus.entity.GetOwner(entity);
  7190.                        
  7191.                         if (owner) then
  7192.                             if ( nexus.player.HasDoorAccess(player, entity, DOOR_ACCESS_COMPLETE) ) then
  7193.                                 local data = {
  7194.                                     sharedAccess = nexus.entity.DoorHasSharedAccess(entity),
  7195.                                     sharedText = nexus.entity.DoorHasSharedText(entity),
  7196.                                     unsellable = nexus.entity.IsDoorUnsellable(entity),
  7197.                                     accessList = {},
  7198.                                     isParent = nexus.entity.IsDoorParent(entity),
  7199.                                     entity = entity,
  7200.                                     owner = owner
  7201.                                 };
  7202.                                
  7203.                                 for k, v in ipairs( g_Player.GetAll() ) do
  7204.                                     if (v != player and v != owner) then
  7205.                                         if ( nexus.player.HasDoorAccess(v, entity, DOOR_ACCESS_COMPLETE) ) then
  7206.                                             data.accessList[v] = DOOR_ACCESS_COMPLETE;
  7207.                                         elseif ( nexus.player.HasDoorAccess(v, entity, DOOR_ACCESS_BASIC) ) then
  7208.                                             data.accessList[v] = DOOR_ACCESS_BASIC;
  7209.                                         end;
  7210.                                     end;
  7211.                                 end;
  7212.                                
  7213.                                 self:StartDataStream(player, "Door", data);
  7214.                             end;
  7215.                         else
  7216.                             self:StartDataStream(player, "PurchaseDoor", entity);
  7217.                         end;
  7218.                     end;
  7219.                 end;
  7220.                
  7221.                 doRecogniseMenu = false;
  7222.             end;
  7223.         end;
  7224.        
  7225.         if ( nexus.config.Get("recognise_system"):Get() ) then
  7226.             if (doRecogniseMenu) then
  7227.                 umsg.Start("nx_RecogniseMenu", player);
  7228.                 umsg.End();
  7229.             end;
  7230.         end;
  7231.     end;
  7232. end;
  7233.  
  7234. NEXUS:HookDataStream("RecogniseOption", function(player, data)
  7235.     if ( nexus.config.Get("recognise_system"):Get() ) then
  7236.         if (type(data) == "string") then
  7237.             local talkRadius = nexus.config.Get("talk_radius"):Get();
  7238.             local playSound = false;
  7239.             local position = player:GetPos();
  7240.            
  7241.             for k, v in ipairs( g_Player.GetAll() ) do
  7242.                 if (v:HasInitialized() and player != v) then
  7243.                     if ( !nexus.player.IsNoClipping(v) ) then
  7244.                         local distance = v:GetPos():Distance(position);
  7245.                         local recognise = false;
  7246.                        
  7247.                         if (data == "whisper") then
  7248.                             if ( distance <= math.min(talkRadius / 3, 80) ) then
  7249.                                 recognise = true;
  7250.                             end;
  7251.                         elseif (data == "yell") then
  7252.                             if (distance <= talkRadius * 2) then
  7253.                                 recognise = true;
  7254.                             end;
  7255.                         elseif (data == "talk") then
  7256.                             if (distance <= talkRadius) then
  7257.                                 recognise = true;
  7258.                             end;
  7259.                         end;
  7260.                        
  7261.                         if (recognise) then
  7262.                             nexus.player.SetRecognises(v, player, RECOGNISE_SAVE);
  7263.                            
  7264.                             if (!playSound) then
  7265.                                 playSound = true;
  7266.                             end;
  7267.                         end;
  7268.                     end;
  7269.                 end;
  7270.             end;
  7271.            
  7272.             if (playSound) then
  7273.                 nexus.player.PlaySound(player, "buttons/button17.wav");
  7274.             end;
  7275.         end;
  7276.     end;
  7277. end);
  7278.  
  7279. -- Called when a player selects a custom character option.
  7280. function NEXUS:PlayerSelectCustomCharacterOption(player, action, character) end;
  7281.  
  7282. -- Called when a player takes damage.
  7283. function NEXUS:PlayerTakeDamage(player, inflictor, attacker, hitGroup, damageInfo) end;
  7284.  
  7285. -- Called when an entity takes damage.
  7286. function NEXUS:EntityTakeDamage(entity, inflictor, attacker, amount, damageInfo)
  7287.     if ( nexus.config.Get("prop_kill_protection"):Get() ) then
  7288.         local curTime = CurTime();
  7289.        
  7290.         if ( (IsValid(inflictor) and inflictor.damageImmunity and inflictor.damageImmunity > curTime)
  7291.         or (attacker.damageImmunity and attacker.damageImmunity > curTime) ) then
  7292.             damageInfo:SetDamage(0);
  7293.         end;
  7294.        
  7295.         if ( ( IsValid(inflictor) and inflictor:IsBeingHeld() )
  7296.         or attacker:IsBeingHeld() ) then
  7297.             damageInfo:SetDamage(0);
  7298.         end;
  7299.     end;
  7300.    
  7301.     if ( entity:IsPlayer() and entity:InVehicle() and !IsValid( entity:GetVehicle():GetParent() ) ) then
  7302.         entity.lastHitGroup = self:GetRagdollHitBone(entity, damageInfo:GetDamagePosition(), HITGROUP_GEAR);
  7303.        
  7304.         if ( damageInfo:IsBulletDamage() ) then
  7305.             if ( ( attacker:IsPlayer() or attacker:IsNPC() ) and attacker != player ) then
  7306.                 damageInfo:ScaleDamage(10000);
  7307.             end;
  7308.         end;
  7309.     end;
  7310.    
  7311.     if (damageInfo:GetDamage() > 0) then
  7312.         local isPlayerRagdoll = nexus.entity.IsPlayerRagdoll(entity);
  7313.         local player = nexus.entity.GetPlayer(entity);
  7314.        
  7315.         if ( player and (entity:IsPlayer() or isPlayerRagdoll) ) then
  7316.             if ( damageInfo:IsFallDamage() or nexus.config.Get("damage_view_punch"):Get() ) then
  7317.                 player:ViewPunch( Angle( math.random(amount, amount), math.random(amount, amount), math.random(amount, amount) ) );
  7318.             end;
  7319.            
  7320.             if (!isPlayerRagdoll) then
  7321.                 if (damageInfo:IsDamageType(DMG_CRUSH) and damageInfo:GetDamage() < 10) then
  7322.                     damageInfo:SetDamage(0);
  7323.                 else
  7324.                     local lastHitGroup = player:LastHitGroup();
  7325.                     local killed = nil;
  7326.                    
  7327.                     if ( player:InVehicle() and damageInfo:IsExplosionDamage() ) then
  7328.                         if (!damageInfo:GetDamage() or damageInfo:GetDamage() == 0) then
  7329.                             damageInfo:SetDamage( player:GetMaxHealth() );
  7330.                         end;
  7331.                     end;
  7332.                    
  7333.                     self:ScaleDamageByHitGroup(player, attacker, lastHitGroup, damageInfo, amount);
  7334.                    
  7335.                     if (damageInfo:GetDamage() > 0) then
  7336.                         self:CalculatePlayerDamage(player, lastHitGroup, damageInfo);
  7337.                        
  7338.                         player:SetVelocity( self:ConvertForce(damageInfo:GetDamageForce() * 32, 200) );
  7339.                        
  7340.                         if (player:Alive() and player:Health() == 1) then
  7341.                             player:SetFakingDeath(true);
  7342.                                 hook.Call("DoPlayerDeath", self, player, attacker, damageInfo);
  7343.                                 hook.Call("PlayerDeath", self, player, inflictor, attacker, damageInfo);
  7344.                                
  7345.                                 self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, player, damageInfo:GetDamageForce() );
  7346.                             player:SetFakingDeath(false, true);
  7347.                         else
  7348.                             local noMessage = nexus.mount.Call("PlayerTakeDamage", player, inflictor, attacker, lastHitGroup, damageInfo);
  7349.                             local sound = nexus.mount.Call("PlayerPlayPainSound", player, nexus.player.GetGender(player), damageInfo, lastHitGroup);
  7350.                            
  7351.                             self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, player, damageInfo:GetDamageForce() );
  7352.                            
  7353.                             if (sound and !noMessage) then
  7354.                                 player:EmitSound("physics/flesh/flesh_impact_bullet"..math.random(1, 5)..".wav", 150);
  7355.                                
  7356.                                 timer.Simple(FrameTime() * 25, function()
  7357.                                     if ( IsValid(player) ) then
  7358.                                         player:EmitSound(sound);
  7359.                                     end;
  7360.                                 end);
  7361.                             end;
  7362.                            
  7363.                             if ( attacker:IsPlayer() ) then
  7364.                                 self:PrintDebug(player:Name().." took damage from "..attacker:Name().." with "..nexus.player.GetWeaponClass(attacker, "an unknown weapon")..".");
  7365.                             else
  7366.                                 self:PrintDebug(player:Name().." took damage from "..attacker:GetClass()..".");
  7367.                             end;
  7368.                         end;
  7369.                     end;
  7370.                    
  7371.                     damageInfo:SetDamage(0);
  7372.                    
  7373.                     player.lastHitGroup = nil;
  7374.                 end;
  7375.             else
  7376.                 local hitGroup = self:GetRagdollHitGroup( entity, damageInfo:GetDamagePosition() );
  7377.                 local curTime = CurTime();
  7378.                 local killed = nil;
  7379.                
  7380.                 self:ScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, amount);
  7381.                
  7382.                 if (nexus.mount.Call("PlayerRagdollCanTakeDamage", player, entity, inflictor, attacker, hitGroup, damageInfo)
  7383.                 and damageInfo:GetDamage() > 0) then
  7384.                     if ( !attacker:IsPlayer() ) then
  7385.                         if (attacker:GetClass() == "prop_ragdoll" or nexus.entity.IsDoor(attacker)
  7386.                         or damageInfo:GetDamage() < 5) then
  7387.                             return;
  7388.                         end;
  7389.                     end;
  7390.                    
  7391.                     if ( damageInfo:GetDamage() >= 10 or damageInfo:IsBulletDamage() ) then
  7392.                         self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, entity, damageInfo:GetDamageForce() );
  7393.                     end;
  7394.                    
  7395.                     self:CalculatePlayerDamage(player, hitGroup, damageInfo);
  7396.                    
  7397.                     if (player:Alive() and player:Health() == 1) then
  7398.                         player:SetFakingDeath(true);
  7399.                             player:GetRagdollTable().health = 0;
  7400.                             player:GetRagdollTable().armor = 0;
  7401.                            
  7402.                             hook.Call("DoPlayerDeath", self, player, attacker, damageInfo);
  7403.                             hook.Call("PlayerDeath", self, player, inflictor, attacker, damageInfo);
  7404.                         player:SetFakingDeath(false, true);
  7405.                     elseif ( player:Alive() ) then
  7406.                         local noMessage = nexus.mount.Call("PlayerTakeDamage", player, inflictor, attacker, hitGroup, damageInfo);
  7407.                         local sound = nexus.mount.Call("PlayerPlayPainSound", player, nexus.player.GetGender(player), damageInfo, hitGroup);
  7408.                        
  7409.                         if (sound and !noMessage) then
  7410.                             entity:EmitSound("physics/flesh/flesh_impact_bullet"..math.random(1, 5)..".wav", 320, 150);
  7411.                            
  7412.                             timer.Simple(FrameTime() * 25, function()
  7413.                                 if ( IsValid(entity) ) then
  7414.                                     entity:EmitSound(sound);
  7415.                                 end;
  7416.                             end);
  7417.                         end;
  7418.                        
  7419.                         if ( attacker:IsPlayer() ) then
  7420.                             self:PrintDebug(player:Name().." took damage from "..attacker:Name().." with "..nexus.player.GetWeaponClass(attacker, "an unknown weapon")..".");
  7421.                         else
  7422.                             self:PrintDebug(player:Name().." took damage from "..attacker:GetClass()..".");
  7423.                         end;
  7424.                     end;
  7425.                 end;
  7426.                
  7427.                 damageInfo:SetDamage(0);
  7428.             end;
  7429.         elseif (entity:GetClass() == "prop_ragdoll") then
  7430.             if ( damageInfo:GetDamage() >= 20 or damageInfo:IsBulletDamage() ) then
  7431.                 if ( !string.find(entity:GetModel(), "matt") and !string.find(entity:GetModel(), "gib") ) then
  7432.                     local matType = util.QuickTrace( entity:GetPos(), entity:GetPos() ).MatType;
  7433.                    
  7434.                     if (matType == MAT_FLESH or matType == MAT_BLOODYFLESH) then
  7435.                         self:CreateBloodEffects( damageInfo:GetDamagePosition(), 1, entity, damageInfo:GetDamageForce() );
  7436.                     end;
  7437.                 end;
  7438.             end;
  7439.            
  7440.             if (inflictor:GetClass() == "prop_combine_ball") then
  7441.                 if (!entity.disintegrating) then
  7442.                     nexus.entity.Disintegrate( entity, 3, damageInfo:GetDamageForce() );
  7443.                    
  7444.                     entity.disintegrating = true;
  7445.                 end;
  7446.             end;
  7447.         elseif ( entity:IsNPC() ) then
  7448.             if (attacker:IsPlayer() and IsValid( attacker:GetActiveWeapon() )
  7449.             and nexus.player.GetWeaponClass(attacker) == "weapon_crowbar") then
  7450.                 damageInfo:ScaleDamage(0.25);
  7451.             end;
  7452.         end;
  7453.     end;
  7454. end;
  7455.  
  7456. -- Called when the death sound for a player should be played.
  7457. function NEXUS:PlayerDeathSound(player) return true; end;
  7458.  
  7459. -- Called when a player attempts to spawn a SWEP.
  7460. function NEXUS:PlayerSpawnSWEP(player, class, weapon)
  7461.     if ( !player:IsSuperAdmin() ) then
  7462.         return false;
  7463.     else
  7464.         return true;
  7465.     end;
  7466. end;
  7467.  
  7468. -- Called when a player is given a SWEP.
  7469. function NEXUS:PlayerGiveSWEP(player, class, weapon)
  7470.     if ( !player:IsSuperAdmin() ) then
  7471.         return false;
  7472.     else
  7473.         return true;
  7474.     end;
  7475. end;
  7476.  
  7477. -- Called when attempts to spawn a SENT.
  7478. function NEXUS:PlayerSpawnSENT(player, class)
  7479.     if ( !player:IsSuperAdmin() ) then
  7480.         return false;
  7481.     else
  7482.         return true;
  7483.     end;
  7484. end;
  7485.  
  7486. -- Called when a player presses a key.
  7487. function NEXUS:KeyPress(player, key)
  7488.     if (key == IN_USE) then
  7489.         local trace = player:GetEyeTraceNoCursor();
  7490.        
  7491.         if ( IsValid(trace.Entity) ) then
  7492.             if (trace.HitPos:Distance( player:GetShootPos() ) <= 192) then
  7493.                 if ( nexus.mount.Call("PlayerUse", player, trace.Entity) ) then
  7494.                     if ( nexus.entity.IsDoor(trace.Entity) and !trace.Entity:HasSpawnFlags(256)
  7495.                     and !trace.Entity:HasSpawnFlags(8192) and !trace.Entity:HasSpawnFlags(32768) ) then
  7496.                         if ( nexus.mount.Call("PlayerCanUseDoor", player, trace.Entity) ) then
  7497.                             nexus.mount.Call("PlayerUseDoor", player, trace.Entity);
  7498.                            
  7499.                             nexus.entity.OpenDoor( trace.Entity, 0, nil, nil, player:GetPos() );
  7500.                         end;
  7501.                     elseif (trace.Entity.UsableInVehicle) then
  7502.                         if ( player:InVehicle() ) then
  7503.                             if (trace.Entity.Use) then
  7504.                                 trace.Entity:Use(player, player);
  7505.                                
  7506.                                 player.nextExitVehicle = CurTime() + 1;
  7507.                             end;
  7508.                         end;
  7509.                     end;
  7510.                 end;
  7511.             end;
  7512.         end;
  7513.     elseif (key == IN_WALK) then
  7514.         local velocity = player:GetVelocity():Length();
  7515.        
  7516.         if ( velocity > 0 and !player:KeyDown(IN_SPEED) ) then
  7517.             if ( player:GetSharedVar("sh_Jogging") ) then
  7518.                 player:SetSharedVar("sh_Jogging", false);
  7519.             else
  7520.                 player:SetSharedVar("sh_Jogging", true);
  7521.             end;
  7522.         elseif ( velocity == 0 and player:KeyDown(IN_SPEED) ) then
  7523.             if ( player:Crouching() ) then
  7524.                 player:RunCommand("-duck");
  7525.             else
  7526.                 player:RunCommand("+duck");
  7527.             end;
  7528.         end;
  7529.     elseif (key == IN_RELOAD) then
  7530.         player.reloadHoldTime = CurTime() + 1;
  7531.     end;
  7532. end;
  7533.  
  7534. -- Called when a player releases a key.
  7535. function NEXUS:KeyRelease(player, key)
  7536.     if (key == IN_RELOAD and player.reloadHoldTime) then
  7537.         player.reloadHoldTime = nil;
  7538.     end;
  7539. end;
  7540.  
  7541. NEXUS:HookDataStream("Door", function(player, data)
  7542.     if ( IsValid( data[1] ) and player:GetEyeTraceNoCursor().Entity == data[1] ) then
  7543.         if (data[1]:GetPos():Distance( player:GetPos() ) <= 192) then
  7544.             if (data[2] == "Purchase") then
  7545.                 if ( !nexus.entity.GetOwner( data[1] ) ) then
  7546.                     if ( hook.Call( "PlayerCanOwnDoor", NEXUS, player, data[1] ) ) then
  7547.                         local doors = nexus.player.GetDoorCount(player);
  7548.                        
  7549.                         if ( doors == nexus.config.Get("max_doors"):Get() ) then
  7550.                             nexus.player.Notify(player, "You cannot purchase another door!");
  7551.                         else
  7552.                             local doorCost = nexus.config.Get("door_cost"):Get();
  7553.                            
  7554.                             if ( doorCost == 0 or nexus.player.CanAfford(player, doorCost) ) then
  7555.                                 local doorName = nexus.entity.GetDoorName( data[1] );
  7556.                                
  7557.                                 if (doorName == "false" or doorName == "hidden" or doorName == "") then
  7558.                                     doorName = "Door";
  7559.                                 end;
  7560.                                
  7561.                                 if (doorCost > 0) then
  7562.                                     nexus.player.GiveCash(player, -doorCost, doorName);
  7563.                                 end;
  7564.                                
  7565.                                 nexus.player.GiveDoor( player, data[1] );
  7566.                             else
  7567.                                 local amount = doorCost - nexus.player.GetCash(player);
  7568.                                
  7569.                                 nexus.player.Notify(player, "You need another "..FORMAT_CASH(amount, nil, true).."!");
  7570.                             end;
  7571.                         end;
  7572.                     end;
  7573.                 end;
  7574.             elseif (data[2] == "Access") then
  7575.                 if ( nexus.player.HasDoorAccess(player, data[1], DOOR_ACCESS_COMPLETE) ) then
  7576.                     if ( IsValid( data[3] ) and data[3] != player and data[3] != nexus.entity.GetOwner( data[1] ) ) then
  7577.                         if (data[4] == DOOR_ACCESS_COMPLETE) then
  7578.                             if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE) ) then
  7579.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC);
  7580.                             else
  7581.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE);
  7582.                             end;
  7583.                         elseif (data[4] == DOOR_ACCESS_BASIC) then
  7584.                             if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC) ) then
  7585.                                 nexus.player.TakeDoorAccess( data[3], data[1] );
  7586.                             else
  7587.                                 nexus.player.GiveDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC);
  7588.                             end;
  7589.                         end;
  7590.                        
  7591.                         if ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_COMPLETE) ) then
  7592.                             NEXUS:StartDataStream( player, "DoorAccess", {data[3], DOOR_ACCESS_COMPLETE} );
  7593.                         elseif ( nexus.player.HasDoorAccess(data[3], data[1], DOOR_ACCESS_BASIC) ) then
  7594.                             NEXUS:StartDataStream( player, "DoorAccess", {data[3], DOOR_ACCESS_BASIC} );
  7595.                         else
  7596.                             NEXUS:StartDataStream( player, "DoorAccess", { data[3] } );
  7597.                         end;
  7598.                     end;
  7599.                 end;
  7600.             elseif (data[2] == "Unshare") then
  7601.                 if ( nexus.entity.IsDoorParent( data[1] ) ) then
  7602.                     if (data[3] == "Text") then
  7603.                         NEXUS:StartDataStream(player, "SetSharedText", false);
  7604.                        
  7605.                         data[1].sharedText = nil;
  7606.                     else
  7607.                         NEXUS:StartDataStream(player, "SetSharedAccess", false);
  7608.                        
  7609.                         data[1].sharedAccess = nil;
  7610.                     end;
  7611.                 end;
  7612.             elseif (data[2] == "Share") then
  7613.                 if ( nexus.entity.IsDoorParent( data[1] ) ) then
  7614.                     if (data[3] == "Text") then
  7615.                         NEXUS:StartDataStream(player, "SetSharedText", true);
  7616.                        
  7617.                         data[1].sharedText = true;
  7618.                     else
  7619.                         NEXUS:StartDataStream(player, "SetSharedAccess", true);
  7620.                        
  7621.                         data[1].sharedAccess = true;
  7622.                     end;
  7623.                 end;
  7624.             elseif (data[2] == "Text" and data[3] != "") then
  7625.                 if ( nexus.player.HasDoorAccess(player, data[1], DOOR_ACCESS_COMPLETE) ) then
  7626.                     if ( !string.find(string.gsub(string.lower( data[3] ), "%s", ""), "thisdoorcanbepurchased")
  7627.                     and string.find(data[3], "%w") ) then
  7628.                         nexus.entity.SetDoorText( data[1], string.sub(data[3], 1, 32) );
  7629.                     end;
  7630.                 end;
  7631.             elseif (data[2] == "Sell") then
  7632.                 if (nexus.entity.GetOwner( data[1] ) == player) then
  7633.                     if ( !nexus.entity.IsDoorUnsellable( data[1] ) ) then
  7634.                         nexus.player.TakeDoor( player, data[1] );
  7635.                     end;
  7636.                 end;
  7637.             end;
  7638.         end;
  7639.     end;
  7640. end);
  7641.  
  7642. NEXUS:HookDataStream("DataStreamInfoSent", function(player, data)
  7643.     if (!player.dataStreamInfoSent) then
  7644.         nexus.mount.Call("PlayerDataStreamInfoSent", player);
  7645.        
  7646.         timer.Simple(FrameTime() * 32, function()
  7647.             if ( IsValid(player) ) then
  7648.                 umsg.Start("nx_DataStreamed", player);
  7649.                 umsg.End();
  7650.             end;
  7651.         end);
  7652.        
  7653.         player.dataStreamInfoSent = true;
  7654.     end;
  7655. end);
  7656.  
  7657. NEXUS:HookDataStream("LocalPlayerCreated", function(player, data)
  7658.     if ( IsValid(player) and !player:HasConfigInitialized() ) then
  7659.         NEXUS:CreateTimer("Send Config: "..player:UniqueID(), FrameTime() * 64, 1, function()
  7660.             if ( IsValid(player) ) then
  7661.                 nexus.config.Send(player);
  7662.             end;
  7663.         end);
  7664.     end;
  7665. end);
  7666.  
  7667. NEXUS:HookDataStream("UnequipItem", function(player, data)
  7668.     local arguments = nil;
  7669.     local uniqueID = data;
  7670.    
  7671.     if (type(data) == "table") then
  7672.         arguments = data[2];
  7673.         uniqueID = data[1];
  7674.     end;
  7675.    
  7676.     if (type(uniqueID) == "string") then
  7677.         if ( player:Alive() and !player:IsRagdolled() ) then
  7678.             local itemTable = nexus.item.Get(uniqueID);
  7679.            
  7680.             if (itemTable and itemTable.OnPlayerUnequipped and itemTable.HasPlayerEquipped) then
  7681.                 if ( itemTable:HasPlayerEquipped(player, arguments) ) then
  7682.                     itemTable:OnPlayerUnequipped(player, arguments);
  7683.                    
  7684.                     player:RebuildInventory();
  7685.                 end;
  7686.             end;
  7687.         end;
  7688.     end;
  7689. end);
  7690.  
  7691. NEXUS:HookDataStream("GetTargetRecognises", function(player, data)
  7692.     if ( ValidEntity(data) and data:IsPlayer() ) then
  7693.         player:SetSharedVar( "sh_TargetRecognises", nexus.player.DoesRecognise(data, player) );
  7694.     end;
  7695. end);
  7696.  
  7697. NEXUS:HookDataStream("EntityMenuOption", function(player, data)
  7698.     local entity = data[1];
  7699.     local option = data[2];
  7700.     local shootPos = player:GetShootPos();
  7701.     local arguments = data[3];
  7702.    
  7703.     if (IsValid(entity) and type(option) == "string") then
  7704.         if (entity:NearestPoint(shootPos):Distance(shootPos) <= 80) then
  7705.             if ( nexus.mount.Call("PlayerUse", player, entity) ) then
  7706.                 nexus.mount.Call("EntityHandleMenuOption", player, entity, option, arguments);
  7707.             end;
  7708.         end;
  7709.     end;
  7710. end);
  7711.  
  7712. NEXUS:HookDataStream("CreateCharacter", function(player, data)
  7713.     if (!player.creatingCharacter) then
  7714.         local minimumPhysDesc = nexus.config.Get("minimum_physdesc"):Get();
  7715.         local attributesTable = nexus.attribute.GetAll();
  7716.         local factionTable = nexus.faction.Get(data.faction);
  7717.         local attributes;
  7718.         local info = {};
  7719.        
  7720.         if (table.Count(attributesTable) > 0) then
  7721.             for k, v in pairs(attributesTable) do
  7722.                 if (v.characterScreen) then
  7723.                     attributes = true;
  7724.                    
  7725.                     break;
  7726.                 end;
  7727.             end;
  7728.         end;
  7729.        
  7730.         if (factionTable) then
  7731.             info.attributes = {};
  7732.             info.faction = factionTable.name;
  7733.             info.gender = data.gender;
  7734.             info.model = data.model;
  7735.             info.data = {};
  7736.            
  7737.             if (attributes and type(data.attributes) == "table") then
  7738.                 local maximumPoints = nexus.config.Get("default_attribute_points"):Get();
  7739.                 local pointsSpent = 0;
  7740.                
  7741.                 if (factionTable.attributePointsScale) then
  7742.                     maximumPoints = math.Round(maximumPoints * factionTable.attributePointsScale);
  7743.                 end;
  7744.                
  7745.                 if (factionTable.maximumAttributePoints) then
  7746.                     maximumPoints = factionTable.maximumAttributePoints;
  7747.                 end;
  7748.                
  7749.                 for k, v in pairs(data.attributes) do
  7750.                     local attributeTable = nexus.attribute.Get(k);
  7751.                    
  7752.                     if (attributeTable and attributeTable.characterScreen) then
  7753.                         local uniqueID = attributeTable.uniqueID;
  7754.                         local amount = math.Clamp(v, 0, attributeTable.maximum);
  7755.                        
  7756.                         info.attributes[uniqueID] = {
  7757.                             amount = amount,
  7758.                             progress = 0
  7759.                         };
  7760.                        
  7761.                         pointsSpent = pointsSpent + amount;
  7762.                     end;
  7763.                 end;
  7764.                
  7765.                 if (pointsSpent > maximumPoints) then
  7766.                     return nexus.player.CreationError(player, "You have chosen more "..nexus.schema.GetOption("name_attribute", true).." points than you can afford to spend!");
  7767.                 end;
  7768.             elseif (attributes) then
  7769.                 return nexus.player.CreationError(player, "You did not choose any "..nexus.schema.GetOption("name_attributes", true).." or the ones that you did are not valid!");
  7770.             end;
  7771.            
  7772.             if (!factionTable.GetName) then
  7773.                 if (!factionTable.useFullName) then
  7774.                     if (data.forename and data.surname) then
  7775.                         data.forename = string.gsub(data.forename, "^.", string.upper);
  7776.                         data.surname = string.gsub(data.surname, "^.", string.upper);
  7777.                        
  7778.                         if ( string.find(data.forename, "[%p%s%d]") or string.find(data.surname, "[%p%s%d]") ) then
  7779.                             return nexus.player.CreationError(player, "Your forename and surname must not contain punctuation, spaces or digits!");
  7780.                         end;
  7781.                        
  7782.                         if ( !string.find(data.forename, "[aeiou]") or !string.find(data.surname, "[aeiou]") ) then
  7783.                             return nexus.player.CreationError(player, "Your forename and surname must both contain at least one vowel!");
  7784.                         end;
  7785.                        
  7786.                         if ( string.len(data.forename) < 2 or string.len(data.surname) < 2) then
  7787.                             return nexus.player.CreationError(player, "Your forename and surname must both be at least 2 characters long!");
  7788.                         end;
  7789.                        
  7790.                         if ( string.len(data.forename) > 16 or string.len(data.surname) > 16) then
  7791.                             return nexus.player.CreationError(player, "Your forename and surname must not be greater than 16 characters long!");
  7792.                         end;
  7793.                     else
  7794.                         return nexus.player.CreationError(player, "You did not choose a name, or the name that you chose is not valid!");
  7795.                     end;
  7796.                 elseif (!data.fullName or data.fullName == "") then
  7797.                     return nexus.player.CreationError(player, "You did not choose a name, or the name that you chose is not valid!");
  7798.                 end;
  7799.             end;
  7800.            
  7801.             if (nexus.command.Get("CharPhysDesc") != nil) then
  7802.                 if (type(data.physDesc) != "string") then
  7803.                     return nexus.player.CreationError(player, "You did not enter a physical description!");
  7804.                 elseif (string.len(data.physDesc) < minimumPhysDesc) then
  7805.                     return nexus.player.CreationError(player, "The physical description must be at least "..minimumPhysDesc.." characters long!");
  7806.                 end;
  7807.                
  7808.                 info.data["physdesc"] = NEXUS:ModifyPhysDesc(data.physDesc);
  7809.             end;
  7810.            
  7811.             if (!factionTable.GetModel and !info.model) then
  7812.                 return nexus.player.CreationError(player, "You did not choose a model, or the model that you chose is not valid!");
  7813.             end;
  7814.            
  7815.             if ( !nexus.faction.IsGenderValid(info.faction, info.gender) ) then
  7816.                 return nexus.player.CreationError(player, "You did not choose a gender, or the gender that you chose is not valid!");
  7817.             end;
  7818.            
  7819.             if ( factionTable.whitelist and !nexus.player.IsWhitelisted(player, info.faction) ) then
  7820.                 return nexus.player.CreationError(player, "You are not on the "..info.faction.." whitelist!");
  7821.             elseif ( nexus.faction.IsModelValid(factionTable.name, info.gender, info.model) or (factionTable.GetModel and !info.model) ) then
  7822.                 local charactersTable = nexus.config.Get("mysql_characters_table"):Get();
  7823.                 local schemaFolder = NEXUS:GetSchemaFolder();
  7824.                 local characterID = nil;
  7825.                 local characters = player:GetCharacters();
  7826.                
  7827.                 if ( nexus.faction.HasReachedMaximum(player, factionTable.name) ) then
  7828.                     return nexus.player.CreationError(player, "You cannot create any more characters in this faction.");
  7829.                 end;
  7830.                
  7831.                 for i = 1, nexus.player.GetMaximumCharacters(player) do
  7832.                     if ( !characters[i] ) then
  7833.                         characterID = i; break;
  7834.                     end;
  7835.                 end;
  7836.                
  7837.                 if (characterID) then
  7838.                     if (factionTable.GetName) then
  7839.                         info.name = factionTable:GetName(player, info, data);
  7840.                     elseif (!factionTable.useFullName) then
  7841.                         info.name = data.forename.." "..data.surname;
  7842.                     else
  7843.                         info.name = data.fullName;
  7844.                     end;
  7845.                    
  7846.                     if (factionTable.GetModel) then
  7847.                         info.model = factionTable:GetModel(player, info, data);
  7848.                     else
  7849.                         info.model = data.model;
  7850.                     end;
  7851.                    
  7852.                     if (factionTable.OnCreation) then
  7853.                         local fault = factionTable:OnCreation(player, info);
  7854.                        
  7855.                         if (fault == false or type(fault) == "string") then
  7856.                             return nexus.player.CreationError(player, fault or "There was an error creating this character!");
  7857.                         end;
  7858.                     end;
  7859.                    
  7860.                     for k, v in pairs(characters) do
  7861.                         if (v.name == info.name) then
  7862.                             return nexus.player.CreationError(player, "You already have a character with the name '"..info.name.."'!");
  7863.                         end;
  7864.                     end;
  7865.                    
  7866.                     local fault = nexus.mount.Call("PlayerAdjustCharacterCreationInfo", player, info, data);
  7867.                    
  7868.                     if (fault == false or type(fault) == "string") then
  7869.                         return nexus.player.CreationError(player, fault or "There was an error creating this character!");
  7870.                     end;
  7871.                    
  7872.                     tmysql.query("SELECT * FROM "..charactersTable.." WHERE _Schema = \""..schemaFolder.."\" AND _Name = \""..tmysql.escape(info.name).."\"", function(result)
  7873.                         if ( IsValid(player) ) then
  7874.                             if (result and type(result) == "table" and #result > 0) then
  7875.                                 nexus.player.CreationError(player, "A character with the name '"..info.name.."' already exists!");
  7876.                                
  7877.                                 player.creatingCharacter = nil;
  7878.                             else
  7879.                                 nexus.player.LoadCharacter( player, characterID, {
  7880.                                     attributes = info.attributes,
  7881.                                     faction = info.faction,
  7882.                                     gender = info.gender,
  7883.                                     model = info.model,
  7884.                                     name = info.name,
  7885.                                     data = info.data
  7886.                                 }, function()
  7887.                                     NEXUS:PrintDebug(player:SteamName().." created a "..info.faction.." character with the name '"..info.name.."'.");
  7888.                                    
  7889.                                     umsg.Start("nx_CharacterFinish", player)
  7890.                                         umsg.Bool(true);
  7891.                                     umsg.End();
  7892.                                    
  7893.                                     player.creatingCharacter = nil;
  7894.                                 end);
  7895.                             end;
  7896.                         end;
  7897.                     end, 1);
  7898.                    
  7899.                     player.creatingCharacter = true;
  7900.                 else
  7901.                     return nexus.player.CreationError(player, "You cannot create any more characters!");
  7902.                 end;
  7903.             else
  7904.                 return nexus.player.CreationError(player, "You did not choose a model, or the model that you chose is not valid!");
  7905.             end;
  7906.         else
  7907.             return nexus.player.CreationError(player, "You did not choose a faction, or the faction that you chose is not valid!");
  7908.         end;
  7909.     end;
  7910. end);
  7911.  
  7912. NEXUS:HookDataStream("InteractCharacter", function(player, data)
  7913.     local characterID = data.characterID;
  7914.     local action = data.action;
  7915.    
  7916.     if (characterID and action) then
  7917.         local character = player:GetCharacters()[characterID];
  7918.        
  7919.         if (character) then
  7920.             local fault = nexus.mount.Call("PlayerCanInteractCharacter", player, action, character);
  7921.            
  7922.             if (fault == false or type(fault) == "string") then
  7923.                 return nexus.player.CreationError(fault or "You cannot interact with this character!");
  7924.             elseif (action == "delete") then
  7925.                 local success, fault = nexus.player.DeleteCharacter(player, characterID);
  7926.                
  7927.                 if (!success) then
  7928.                     nexus.player.CreationError(player, fault);
  7929.                 end;
  7930.             elseif (action == "use") then
  7931.                 local success, fault = nexus.player.UseCharacter(player, characterID);
  7932.                
  7933.                 if (!success) then
  7934.                     nexus.player.CreationError(player, fault);
  7935.                 end;
  7936.             else
  7937.                 nexus.mount.Call("PlayerSelectCustomCharacterOption", player, action, character);
  7938.             end;
  7939.         end;
  7940.     end;
  7941. end);
  7942.  
  7943. NEXUS:HookDataStream("QuizAnswer", function(player, data)
  7944.     if (!player.quizAnswers) then
  7945.         player.quizAnswers = {};
  7946.     end;
  7947.    
  7948.     local question = data[1];
  7949.     local answer = data[2];
  7950.    
  7951.     if ( nexus.quiz.GetQuestion(question) ) then
  7952.         player.quizAnswers[question] = answer;
  7953.     end;
  7954. end);
  7955.  
  7956. NEXUS:HookDataStream("QuizCompleted", function(player, data)
  7957.     if ( player.quizAnswers and !nexus.quiz.GetCompleted(player) ) then
  7958.         local questionsAmount = nexus.quiz.GetQuestionsAmount();
  7959.         local correctAnswers = 0;
  7960.         local quizQuestions = nexus.quiz.GetQuestions();
  7961.        
  7962.         for k, v in pairs(quizQuestions) do
  7963.             if ( player.quizAnswers[k] ) then
  7964.                 if ( nexus.quiz.IsAnswerCorrect( k, player.quizAnswers[k] ) ) then
  7965.                     correctAnswers = correctAnswers + 1;
  7966.                 end;
  7967.             end;
  7968.         end;
  7969.        
  7970.         if ( correctAnswers < math.Round( questionsAmount * (nexus.quiz.GetPercentage() / 100) ) ) then
  7971.             nexus.quiz.CallKickCallback(player, correctAnswers);
  7972.         else
  7973.             nexus.quiz.SetCompleted(player, true);
  7974.         end;
  7975.     end;
  7976. end);
  7977.  
  7978. NEXUS:HookDataStream("GetQuizStatus", function(player, data)
  7979.     if ( !nexus.quiz.GetEnabled() or nexus.quiz.GetCompleted(player) ) then
  7980.         umsg.Start("nx_QuizCompleted", player);
  7981.             umsg.Bool(true);
  7982.         umsg.End();
  7983.     else
  7984.         umsg.Start("nx_QuizCompleted", player);
  7985.             umsg.Bool(false);
  7986.         umsg.End();
  7987.     end;
  7988. end);
  7989.  
  7990. local playerMeta = FindMetaTable("Player");
  7991. local entityMeta = FindMetaTable("Entity");
  7992.  
  7993. playerMeta.NexusSetCrouchedWalkSpeed = playerMeta.SetCrouchedWalkSpeed;
  7994. playerMeta.NexusLastHitGroup = playerMeta.LastHitGroup;
  7995. playerMeta.NexusSetJumpPower = playerMeta.SetJumpPower;
  7996. playerMeta.NexusSetWalkSpeed = playerMeta.SetWalkSpeed;
  7997. playerMeta.NexusStripWeapons = playerMeta.StripWeapons;
  7998. playerMeta.NexusSetRunSpeed = playerMeta.SetRunSpeed;
  7999. entityMeta.NexusSetMaterial = entityMeta.SetMaterial;
  8000. playerMeta.NexusStripWeapon = playerMeta.StripWeapon;
  8001. playerMeta.NexusGodDisable = playerMeta.GodDisable;
  8002. entityMeta.NexusExtinguish = entityMeta.Extinguish;
  8003. entityMeta.NexusWaterLevel = entityMeta.WaterLevel;
  8004. playerMeta.NexusGodEnable = playerMeta.GodEnable;
  8005. entityMeta.NexusSetHealth = entityMeta.SetHealth;
  8006. entityMeta.NexusSetColor = entityMeta.SetColor;
  8007. entityMeta.NexusIsOnFire = entityMeta.IsOnFire;
  8008. entityMeta.NexusSetModel = entityMeta.SetModel;
  8009. playerMeta.NexusSetArmor = playerMeta.SetArmor;
  8010. entityMeta.NexusSetSkin = entityMeta.SetSkin;
  8011. entityMeta.NexusAlive = playerMeta.Alive;
  8012. playerMeta.NexusGive = playerMeta.Give;
  8013. playerMeta.SteamName = playerMeta.Name;
  8014.  
  8015. -- A function to get a player's name.
  8016. function playerMeta:Name()
  8017.     return self:QueryCharacter( "name", self:SteamName() );
  8018. end;
  8019.  
  8020. -- A function to get whether a player is alive.
  8021. function playerMeta:Alive()
  8022.     if (!self.fakingDeath) then
  8023.         return self:NexusAlive();
  8024.     else
  8025.         return false;
  8026.     end;
  8027. end;
  8028.  
  8029. -- A function to set whether a player is faking death.
  8030. function playerMeta:SetFakingDeath(fakingDeath, killSilent)
  8031.     self.fakingDeath = fakingDeath;
  8032.    
  8033.     if (!fakingDeath and killSilent) then
  8034.         self:KillSilent();
  8035.     end;
  8036. end;
  8037.  
  8038. -- A function to save a player's character.
  8039. function playerMeta:SaveCharacter()
  8040.     nexus.player.SaveCharacter(self);
  8041. end;
  8042.  
  8043. -- A function to give a player an item weapon.
  8044. function playerMeta:GiveItemWeapon(item)
  8045.     nexus.player.GiveItemWeapon(self, item);
  8046. end;
  8047.  
  8048. -- A function to give a weapon to a player.
  8049. function playerMeta:Give(class, uniqueID, forceReturn)
  8050.     if ( !nexus.mount.Call("PlayerCanBeGivenWeapon", self, class, uniqueID, forceReturn) ) then
  8051.         return;
  8052.     end;
  8053.    
  8054.     local itemTable = nexus.item.GetWeapon(class, uniqueID);
  8055.     local teamIndex = self:Team();
  8056.    
  8057.     if (self:IsRagdolled() and !forceReturn) then
  8058.         local ragdollWeapons = self:GetRagdollWeapons();
  8059.         local spawnWeapon = nexus.player.GetSpawnWeapon(self, class);
  8060.         local canHolster;
  8061.        
  8062.         if ( itemTable and nexus.mount.Call("PlayerCanHolsterWeapon", self, itemTable, true, true) ) then
  8063.             canHolster = true;
  8064.         end;
  8065.        
  8066.         if (!spawnWeapon) then
  8067.             teamIndex = nil;
  8068.         end;
  8069.        
  8070.         for k, v in pairs(ragdollWeapons) do
  8071.             if (v.weaponData["class"] == class
  8072.             and v.weaponData["uniqueID"] == uniqueID) then
  8073.                 v.canHolster = canHolster;
  8074.                 v.teamIndex = teamIndex;
  8075.                
  8076.                 return;
  8077.             end;
  8078.         end;
  8079.        
  8080.         ragdollWeapons[#ragdollWeapons + 1] = {
  8081.             weaponData = {class = class, uniqueID = uniqueID},
  8082.             canHolster = canHolster,
  8083.             teamIndex = teamIndex,
  8084.         };
  8085.     elseif ( !self:HasWeapon(class) ) then
  8086.         self.forceGive = true;
  8087.             self:NexusGive(class);
  8088.         self.forceGive = nil;
  8089.        
  8090.         local weapon = self:GetWeapon(class);
  8091.        
  8092.         if ( IsValid(weapon) ) then
  8093.             if (itemTable) then
  8094.                 nexus.player.StripDefaultAmmo(self, weapon, itemTable);
  8095.                 nexus.player.RestorePrimaryAmmo(self, weapon);
  8096.                 nexus.player.RestoreSecondaryAmmo(self, weapon);
  8097.             end;
  8098.            
  8099.             if (uniqueID and uniqueID != "") then
  8100.                 weapon:SetNetworkedString("sh_UniqueID", uniqueID);
  8101.             end;
  8102.         else
  8103.             return true;
  8104.         end;
  8105.     end;
  8106.    
  8107.     nexus.mount.Call("PlayerGivenWeapon", self, class, uniqueID, forceReturn);
  8108. end;
  8109.  
  8110. -- A function to get a player's data.
  8111. function playerMeta:GetData(key, default)
  8112.     if (self.data) then
  8113.         if (self.data[key] != nil) then
  8114.             return self.data[key];
  8115.         else
  8116.             return default;
  8117.         end;
  8118.     else
  8119.         return default;
  8120.     end;
  8121. end;
  8122.  
  8123. -- A function to set a player's data.
  8124. function playerMeta:SetData(key, value)
  8125.     if (self.data) then
  8126.         self.data[key] = value;
  8127.     end;
  8128. end;
  8129.  
  8130. -- A function to get a player's playback rate.
  8131. function playerMeta:GetPlaybackRate()
  8132.     return self.playbackRate or 1;
  8133. end;
  8134.  
  8135. -- A function to set an entity's skin.
  8136. function entityMeta:SetSkin(skin)
  8137.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  8138.         self:GetRagdollEntity():SetSkin(skin);
  8139.     end;
  8140.    
  8141.     self:NexusSetSkin(skin);
  8142. end;
  8143.  
  8144. -- A function to set an entity's model.
  8145. function entityMeta:SetModel(model)
  8146.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  8147.         self:GetRagdollEntity():SetModel(model);
  8148.     end;
  8149.    
  8150.     self:NexusSetModel(model);
  8151.     nexus.mount.Call("PlayerModelChanged", self, model);
  8152. end;
  8153.  
  8154. -- A function to get an entity's owner key.
  8155. function entityMeta:GetOwnerKey()
  8156.     return self.ownerKey;
  8157. end;
  8158.  
  8159. -- A function to set an entity's owner key.
  8160. function entityMeta:SetOwnerKey(key)
  8161.     self.ownerKey = key;
  8162. end;
  8163.  
  8164. -- A function to get whether an entity is a map entity.
  8165. function entityMeta:IsMapEntity()
  8166.     return nexus.entity.IsMapEntity(self);
  8167. end;
  8168.  
  8169. -- A function to get an entity's start position.
  8170. function entityMeta:GetStartPosition()
  8171.     return nexus.entity.GetStartPosition(self);
  8172. end;
  8173.  
  8174. -- A function to set an entity's material.
  8175. function entityMeta:SetMaterial(material)
  8176.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  8177.         self:GetRagdollEntity():SetMaterial(material);
  8178.     end;
  8179.    
  8180.     self:NexusSetMaterial(material);
  8181. end;
  8182.  
  8183. -- A function to set an entity's color.
  8184. function entityMeta:SetColor(r, g, b, a)
  8185.     if ( self:IsPlayer() and self:IsRagdolled() ) then
  8186.         self:GetRagdollEntity():SetColor(r, g, b, a);
  8187.     end;
  8188.    
  8189.     self:NexusSetColor(r, g, b, a);
  8190. end;
  8191.  
  8192. -- A function to set a player's armor.
  8193. function playerMeta:SetArmor(armor)
  8194.     nexus.mount.Call("PlayerArmorSet", self, armor);
  8195.    
  8196.     self:NexusSetArmor(armor);
  8197. end;
  8198.  
  8199. -- A function to set a player's health.
  8200. function playerMeta:SetHealth(health)
  8201.     nexus.mount.Call("PlayerHealthSet", self, health);
  8202.    
  8203.     self:NexusSetHealth(health);
  8204. end;
  8205.  
  8206. -- A function to get whether a player is running.
  8207. function playerMeta:IsRunning()
  8208.     if ( self:Alive() and !self:IsRagdolled() and !self:InVehicle() and !self:Crouching() ) then
  8209.         local sprintSpeed = self:GetNetworkedFloat("SprintSpeed");
  8210.         local walkSpeed = self:GetNetworkedFloat("WalkSpeed");
  8211.         local velocity = self:GetVelocity():Length();
  8212.        
  8213.         if (velocity >= math.max(sprintSpeed - 25, 25)
  8214.         and sprintSpeed > walkSpeed) then
  8215.             return true;
  8216.         end;
  8217.     end;
  8218. end;
  8219.  
  8220. -- A function to get whether a player is jogging.
  8221. function playerMeta:IsJogging(testSpeed)
  8222.     if ( !self:IsRunning() and (self:GetSharedVar("sh_Jogging") or testSpeed) ) then
  8223.         if ( self:Alive() and !self:IsRagdolled() and !self:InVehicle() and !self:Crouching() ) then
  8224.             local walkSpeed = self:GetNetworkedFloat("WalkSpeed");
  8225.             local velocity = self:GetVelocity():Length();
  8226.            
  8227.             if ( velocity >= math.max(walkSpeed - 25, 25) ) then
  8228.                 return true;
  8229.             end;
  8230.         end;
  8231.     end;
  8232. end;
  8233.  
  8234. -- A function to strip a weapon from a player.
  8235. function playerMeta:StripWeapon(weaponClass)
  8236.     if ( self:IsRagdolled() ) then
  8237.         local ragdollWeapons = self:GetRagdollWeapons();
  8238.        
  8239.         for k, v in pairs(ragdollWeapons) do
  8240.             if (v.weaponData["class"] == weaponClass) then
  8241.                 weapons[k] = nil;
  8242.             end;
  8243.         end;
  8244.     else
  8245.         self:NexusStripWeapon(weaponClass);
  8246.     end;
  8247. end;
  8248.  
  8249. -- A function to handle a player's attribute progress.
  8250. function playerMeta:HandleAttributeProgress(curTime)
  8251.     if (self.attributeProgressTime and curTime >= self.attributeProgressTime) then
  8252.         self.attributeProgressTime = curTime + 30;
  8253.        
  8254.         for k, v in pairs(self.attributeProgress) do
  8255.             local attributeTable = nexus.attribute.Get(k);
  8256.            
  8257.             if (attributeTable) then
  8258.                 umsg.Start("nx_AttributeProgress", self);
  8259.                     umsg.Long(attributeTable.index);
  8260.                     umsg.Short(v);
  8261.                 umsg.End();
  8262.             end;
  8263.         end;
  8264.        
  8265.         if (self.attributeProgress) then
  8266.             self.attributeProgress = {};
  8267.         end;
  8268.     end;
  8269. end;
  8270.  
  8271. -- A function to handle a player's attribute boosts.
  8272. function playerMeta:HandleAttributeBoosts(curTime)
  8273.     for k, v in pairs(self.attributeBoosts) do
  8274.         for k2, v2 in pairs(v) do
  8275.             if (v2.duration and v2.endTime) then
  8276.                 if (curTime > v2.endTime) then
  8277.                     self:BoostAttribute(k2, k, false);
  8278.                 else
  8279.                     local timeLeft = v2.endTime - curTime;
  8280.                    
  8281.                     if (timeLeft >= 0) then
  8282.                         if (v2.default < 0) then
  8283.                             v2.amount = math.min( (v2.default / v2.duration) * timeLeft, 0 );
  8284.                         else
  8285.                             v2.amount = math.max( (v2.default / v2.duration) * timeLeft, 0 );
  8286.                         end;
  8287.                     end;
  8288.                 end;
  8289.             end;
  8290.         end;
  8291.     end;
  8292. end;
  8293.  
  8294. -- A function to strip a player's weapons.
  8295. function playerMeta:StripWeapons(ragdollForce)
  8296.     if (self:IsRagdolled() and !ragdollForce) then
  8297.         self:GetRagdollTable().weapons = {};
  8298.     else
  8299.         self:NexusStripWeapons();
  8300.     end;
  8301. end;
  8302.  
  8303. -- A function to enable God for a player.
  8304. function playerMeta:GodEnable()
  8305.     self.godMode = true; self:NexusGodEnable();
  8306. end;
  8307.  
  8308. -- A function to disable God for a player.
  8309. function playerMeta:GodDisable()
  8310.     self.godMode = nil; self:NexusGodDisable();
  8311. end;
  8312.  
  8313. -- A function to get whether a player has God mode enabled.
  8314. function playerMeta:IsInGodMode()
  8315.     return self.godMode;
  8316. end;
  8317.  
  8318. -- A function to update whether a player's weapon is raised.
  8319. function playerMeta:UpdateWeaponRaised()
  8320.     nexus.player.UpdateWeaponRaised(self);
  8321. end;
  8322.  
  8323. -- A function to get a player's water level.
  8324. function playerMeta:WaterLevel()
  8325.     if ( self:IsRagdolled() ) then
  8326.         return self:GetRagdollEntity():WaterLevel();
  8327.     else
  8328.         return self:NexusWaterLevel();
  8329.     end;
  8330. end;
  8331.  
  8332. -- A function to get whether a player is on fire.
  8333. function playerMeta:IsOnFire()
  8334.     if ( self:IsRagdolled() ) then
  8335.         return self:GetRagdollEntity():IsOnFire();
  8336.     else
  8337.         return self:NexusIsOnFire();
  8338.     end;
  8339. end;
  8340.  
  8341. -- A function to extinguish a player.
  8342. function playerMeta:Extinguish()
  8343.     if ( self:IsRagdolled() ) then
  8344.         return self:GetRagdollEntity():Extinguish();
  8345.     else
  8346.         return self:NexusExtinguish();
  8347.     end;
  8348. end;
  8349.  
  8350. -- A function to get whether a player is using their hands.
  8351. function playerMeta:IsUsingHands()
  8352.     return nexus.player.GetWeaponClass(self) == "nx_hands";
  8353. end;
  8354.  
  8355. -- A function to get whether a player is using their hands.
  8356. function playerMeta:IsUsingKeys()
  8357.     return nexus.player.GetWeaponClass(self) == "nx_keys";
  8358. end;
  8359.  
  8360. -- A function to get a player's wages.
  8361. function playerMeta:GetWages()
  8362.     return nexus.player.GetWages(self);
  8363. end;
  8364.  
  8365. -- A function to get a player's community ID.
  8366. function playerMeta:CommunityID()
  8367.     local x, y, z = string.match(self:SteamID(), "STEAM_(%d+):(%d+):(%d+)");
  8368.    
  8369.     if (x and y and z) then
  8370.         return (z * 2) + STEAM_COMMUNITY_ID + y;
  8371.     else
  8372.         return self:SteamID();
  8373.     end;
  8374. end;
  8375.  
  8376. -- A function to get whether a player is ragdolled.
  8377. function playerMeta:IsRagdolled(exception, entityless)
  8378.     return nexus.player.IsRagdolled(self, exception, entityless);
  8379. end;
  8380.  
  8381. -- A function to get whether a player is kicked.
  8382. function playerMeta:IsKicked()
  8383.     return self.isKicked;
  8384. end;
  8385.  
  8386. -- A function to get whether a player has spawned.
  8387. function playerMeta:HasSpawned()
  8388.     return self.hasSpawned;
  8389. end;
  8390.  
  8391. -- A function to kick a player.
  8392. function playerMeta:Kick(reason)
  8393.     if ( !self:IsKicked() ) then
  8394.         timer.Simple(FrameTime() * 0.5, function()
  8395.             local isKicked = self:IsKicked();
  8396.            
  8397.             if (IsValid(self) and isKicked) then
  8398.                 if ( self:HasSpawned() ) then
  8399.                     GetNetChannel(self):Shutdown(isKicked);
  8400.                 else
  8401.                     self.isKicked = nil;
  8402.                     self:Kick(isKicked);
  8403.                 end;
  8404.             end;
  8405.         end);
  8406.     end;
  8407.    
  8408.     if (!reason) then
  8409.         self.isKicked = "You have been kicked.";
  8410.     else
  8411.         self.isKicked = reason;
  8412.     end;
  8413. end;
  8414.  
  8415. -- A function to ban a player.
  8416. function playerMeta:Ban(duration, reason)
  8417.     NEXUS:AddBan(self:SteamID(), duration * 60, reason);
  8418. end;
  8419.  
  8420. -- A function to get a player's character table.
  8421. function playerMeta:GetCharacter() return nexus.player.GetCharacter(self); end;
  8422.  
  8423. -- A function to get a player's storage table.
  8424. function playerMeta:GetStorageTable() return nexus.player.GetStorageTable(self); end;
  8425.  
  8426. -- A function to get a player's ragdoll table.
  8427. function playerMeta:GetRagdollTable() return nexus.player.GetRagdollTable(self); end;
  8428.  
  8429. -- A function to get a player's ragdoll state.
  8430. function playerMeta:GetRagdollState() return nexus.player.GetRagdollState(self); end;
  8431.  
  8432. -- A function to get a player's storage entity.
  8433. function playerMeta:GetStorageEntity() return nexus.player.GetStorageEntity(self); end;
  8434.  
  8435. -- A function to get a player's ragdoll entity.
  8436. function playerMeta:GetRagdollEntity() return nexus.player.GetRagdollEntity(self); end;
  8437.  
  8438. -- A function to get a player's ragdoll weapons.
  8439. function playerMeta:GetRagdollWeapons()
  8440.     return self:GetRagdollTable().weapons or {};
  8441. end;
  8442.  
  8443. -- A function to get whether a player's ragdoll has a weapon.
  8444. function playerMeta:RagdollHasWeapon(weaponClass)
  8445.     local ragdollWeapons = self:GetRagdollWeapons();
  8446.    
  8447.     if (ragdollWeapons) then
  8448.         for k, v in pairs(ragdollWeapons) do
  8449.             if (v.weaponData["class"] == weaponClass) then
  8450.                 return true;
  8451.             end;
  8452.         end;
  8453.     end;
  8454. end;
  8455.  
  8456. -- A function to set a player's maximum armor.
  8457. function playerMeta:SetMaxArmor(armor)
  8458.     self:SetSharedVar("sh_MaxArmor", armor);
  8459. end;
  8460.  
  8461. -- A function to get a player's maximum armor.
  8462. function playerMeta:GetMaxArmor(armor)
  8463.     local maxArmor = self:GetSharedVar("sh_MaxArmor");
  8464.    
  8465.     if (maxArmor > 0) then
  8466.         return maxArmor;
  8467.     else
  8468.         return 100;
  8469.     end;
  8470. end;
  8471.  
  8472. -- A function to set a player's maximum health.
  8473. function playerMeta:SetMaxHealth(health)
  8474.     self:SetSharedVar("sh_MaxHealth", health);
  8475. end;
  8476.  
  8477. -- A function to get a player's maximum health.
  8478. function playerMeta:GetMaxHealth(health)
  8479.     local maxHealth = self:GetSharedVar("sh_MaxHealth");
  8480.    
  8481.     if (maxHealth > 0) then
  8482.         return maxHealth;
  8483.     else
  8484.         return 100;
  8485.     end;
  8486. end;
  8487.  
  8488. -- A function to get whether a player is viewing the starter hints.
  8489. function playerMeta:IsViewingStarterHints()
  8490.     return self.isViewingStarterHints;
  8491. end;
  8492.  
  8493. -- A function to get a player's last hit group.
  8494. function playerMeta:LastHitGroup()
  8495.     return self.lastHitGroup or self:NexusLastHitGroup();
  8496. end;
  8497.  
  8498. -- A function to get whether an entity is being held.
  8499. function entityMeta:IsBeingHeld()
  8500.     if ( IsValid(self) ) then
  8501.         return nexus.mount.Call("GetEntityBeingHeld", self);
  8502.     end;
  8503. end;
  8504.  
  8505. -- A function to run a command on a player.
  8506. function playerMeta:RunCommand(...)
  8507.     NEXUS:StartDataStream( self, "RunCommand", {...} );
  8508. end;
  8509.  
  8510. -- A function to get a player's wages name.
  8511. function playerMeta:GetWagesName()
  8512.     return nexus.player.GetWagesName(self);
  8513. end;
  8514.  
  8515. -- A function to set a player's forced animation.
  8516. function playerMeta:SetForcedAnimation(animation, delay, onAnimate, onFinish)
  8517.     local forcedAnimation = self:GetForcedAnimation();
  8518.     local callFinish = false;
  8519.     local sequence = nil;
  8520.    
  8521.     if (animation) then
  8522.         if (!forcedAnimation or forcedAnimation.delay != 0) then
  8523.             if (type(animation) == "string") then
  8524.                 sequence = self:LookupSequence(animation);
  8525.             else
  8526.                 sequence = self:SelectWeightedSequence(animation);
  8527.             end;
  8528.            
  8529.             self.forcedAnimation = {
  8530.                 animation = animation,
  8531.                 onAnimate = onAnimate,
  8532.                 onFinish = onFinish,
  8533.                 delay = delay
  8534.             };
  8535.            
  8536.             if (delay and delay != 0) then
  8537.                 NEXUS:CreateTimer("Forced Animation: "..self:UniqueID(), delay, 1, function()
  8538.                     if ( IsValid(self) ) then
  8539.                         local forcedAnimation = self:GetForcedAnimation();
  8540.                        
  8541.                         if (forcedAnimation) then
  8542.                             self:SetForcedAnimation(false);
  8543.                         end;
  8544.                     end;
  8545.                 end);
  8546.             else
  8547.                 NEXUS:DestroyTimer( "Forced Animation: "..self:UniqueID() );
  8548.             end;
  8549.            
  8550.             self:SetSharedVar("sh_ForcedAnim", sequence);
  8551.             callFinish = true;
  8552.         end;
  8553.     else
  8554.         callFinish = true;
  8555.         self:SetSharedVar("sh_ForcedAnim", 0);
  8556.         self.forcedAnimation = nil;
  8557.     end;
  8558.    
  8559.     if (callFinish) then
  8560.         if (forcedAnimation and forcedAnimation.onFinish) then
  8561.             forcedAnimation.onFinish(self);
  8562.         end;
  8563.     end;
  8564. end;
  8565.  
  8566. -- A function to set whether a player's config has initialized.
  8567. function playerMeta:SetConfigInitialized(initialized)
  8568.     self.configInitialized = initialized;
  8569. end;
  8570.  
  8571. -- A function to get whether a player's config has initialized.
  8572. function playerMeta:HasConfigInitialized()
  8573.     return self.configInitialized;
  8574. end;
  8575.  
  8576. -- A function to get a player's forced animation.
  8577. function playerMeta:GetForcedAnimation()
  8578.     return self.forcedAnimation;
  8579. end;
  8580.  
  8581. -- A function to get a player's item entity.
  8582. function playerMeta:GetItemEntity()
  8583.     if ( IsValid(self.itemEntity) ) then
  8584.         return self.itemEntity;
  8585.     end;
  8586. end;
  8587.  
  8588. -- A function to set a player's item entity.
  8589. function playerMeta:SetItemEntity(entity)
  8590.     self.itemEntity = entity;
  8591. end;
  8592.  
  8593. -- A function to create a player's temporary data.
  8594. function playerMeta:CreateTempData()
  8595.     local uniqueID = self:UniqueID();
  8596.    
  8597.     if ( !NEXUS.TempPlayerData[uniqueID] ) then
  8598.         NEXUS.TempPlayerData[uniqueID] = {};
  8599.     end;
  8600.    
  8601.     return NEXUS.TempPlayerData[uniqueID];
  8602. end;
  8603.  
  8604. -- A function to make a player fake pickup an entity.
  8605. function playerMeta:FakePickup(entity)
  8606.     local entityPosition = entity:GetPos();
  8607.    
  8608.     if ( entity:IsPlayer() ) then
  8609.         entityPosition = entity:GetShootPos();
  8610.     end;
  8611.    
  8612.     local shootPosition = self:GetShootPos();
  8613.     local feetDistance = self:GetPos():Distance(entityPosition);
  8614.     local armsDistance = shootPosition:Distance(entityPosition);
  8615.    
  8616.     if (feetDistance < armsDistance) then
  8617.         self:SetForcedAnimation("pickup", 1.2);
  8618.     else
  8619.         self:SetForcedAnimation("gunrack", 1.2);
  8620.     end;
  8621. end;
  8622.  
  8623. -- A function to set a player's temporary data.
  8624. function playerMeta:SetTempData(key, value)
  8625.     local tempData = self:CreateTempData();
  8626.    
  8627.     if (tempData) then
  8628.         tempData[key] = value;
  8629.     end;
  8630. end;
  8631.  
  8632. -- A function to get a player's temporary data.
  8633. function playerMeta:GetTempData(key, default)
  8634.     local tempData = self:CreateTempData();
  8635.    
  8636.     if (tempData and tempData[key] != nil) then
  8637.         return tempData[key];
  8638.     else
  8639.         return default;
  8640.     end;
  8641. end;
  8642.  
  8643. -- A function to get whether a player has an item.
  8644. function playerMeta:HasItem(item, anywhere)
  8645.     return nexus.inventory.HasItem(self, item, anywhere);
  8646. end;
  8647.  
  8648. -- A function to get a player's attribute boosts.
  8649. function playerMeta:GetAttributeBoosts()
  8650.     return self.attributeBoosts;
  8651. end;
  8652.  
  8653. -- A function to rebuild a player's inventory.
  8654. function playerMeta:RebuildInventory()
  8655.     nexus.inventory.Rebuild(self);
  8656. end;
  8657.  
  8658. -- A function to update a player's inventory.
  8659. function playerMeta:UpdateInventory(item, amount, force, noMessage)
  8660.     return nexus.inventory.Update(self, item, amount, force, noMessage);
  8661. end;
  8662.  
  8663. -- A function to update a player's attribute.
  8664. function playerMeta:UpdateAttribute(attribute, amount)
  8665.     return nexus.attributes.Update(self, attribute, amount);
  8666. end;
  8667.  
  8668. -- A function to progress a player's attribute.
  8669. function playerMeta:ProgressAttribute(attribute, amount, gradual)
  8670.     return nexus.attributes.Progress(self, attribute, amount, gradual);
  8671. end;
  8672.  
  8673. -- A function to boost a player's attribute.
  8674. function playerMeta:BoostAttribute(identifier, attribute, amount, duration)
  8675.     return nexus.attributes.Boost(self, identifier, attribute, amount, duration);
  8676. end;
  8677.  
  8678. -- A function to get whether a boost is active for a player.
  8679. function playerMeta:IsBoostActive(identifier, attribute, amount, duration)
  8680.     return nexus.attributes.IsBoostActive(self, identifier, attribute, amount, duration);
  8681. end;
  8682.  
  8683. -- A function to get a player's characters.
  8684. function playerMeta:GetCharacters()
  8685.     return self.characters;
  8686. end;
  8687.  
  8688. -- A function to set a player's run speed.
  8689. function playerMeta:SetRunSpeed(speed, nexus)
  8690.     if (!nexus) then self.runSpeed = speed; end;
  8691.    
  8692.     self:NexusSetRunSpeed(speed);
  8693. end;
  8694.  
  8695. -- A function to set a player's walk speed.
  8696. function playerMeta:SetWalkSpeed(speed, nexus)
  8697.     if (!nexus) then self.walkSpeed = speed; end;
  8698.    
  8699.     self:NexusSetWalkSpeed(speed);
  8700. end;
  8701.  
  8702. -- A function to set a player's jump power.
  8703. function playerMeta:SetJumpPower(power, nexus)
  8704.     if (!nexus) then self.jumpPower = power; end;
  8705.    
  8706.     self:NexusSetJumpPower(power);
  8707. end;
  8708.  
  8709. -- A function to set a player's crouched walk speed.
  8710. function playerMeta:SetCrouchedWalkSpeed(speed, nexus)
  8711.     if (!nexus) then self.crouchedSpeed = speed; end;
  8712.    
  8713.     self:NexusSetCrouchedWalkSpeed(speed);
  8714. end;
  8715.  
  8716. -- A function to get whether a player has initialized.
  8717. function playerMeta:HasInitialized()
  8718.     return self.initialized;
  8719. end;
  8720.  
  8721. -- A function to query a player's character table.
  8722. function playerMeta:QueryCharacter(key, default)
  8723.     if ( self:GetCharacter() ) then
  8724.         return nexus.player.Query(self, key, default);
  8725.     else
  8726.         return default;
  8727.     end;
  8728. end;
  8729.  
  8730. -- A function to get a player's shared variable.
  8731. function entityMeta:GetSharedVar(key)
  8732.     if ( self:IsPlayer() ) then
  8733.         return nexus.player.GetSharedVar(self, key);
  8734.     else
  8735.         return nexus.entity.GetSharedVar(self, key);
  8736.     end;
  8737. end;
  8738.  
  8739. -- A function to set a shared variable for a player.
  8740. function entityMeta:SetSharedVar(key, value)
  8741.     if ( self:IsPlayer() ) then
  8742.         nexus.player.SetSharedVar(self, key, value);
  8743.     else
  8744.         nexus.entity.SetSharedVar(self, key, value);
  8745.     end;
  8746. end;
  8747.  
  8748. -- A function to get a player's character data.
  8749. function playerMeta:GetCharacterData(key, default)
  8750.     if ( self:GetCharacter() ) then
  8751.         local data = self:QueryCharacter("data");
  8752.        
  8753.         if (data[key] != nil) then
  8754.             return data[key];
  8755.         else
  8756.             return default;
  8757.         end;
  8758.     else
  8759.         return default;
  8760.     end;
  8761. end;
  8762.  
  8763. -- A function to get a player's time joined.
  8764. function playerMeta:TimeJoined()
  8765.     return self.timeJoined or os.time();
  8766. end;
  8767.  
  8768. -- A function to get when a player last played.
  8769. function playerMeta:LastPlayed()
  8770.     return self.lastPlayed or os.time();
  8771. end;
  8772.  
  8773. -- A function to set a player's character data.
  8774. function playerMeta:SetCharacterData(key, value, base)
  8775.     local character = self:GetCharacter();
  8776.    
  8777.     if (character) then
  8778.         if (base) then
  8779.             if (character[key] != nil) then
  8780.                 character[key] = value;
  8781.             end;
  8782.         else
  8783.             character.data[key] = value;
  8784.         end;
  8785.     end;
  8786. end;
  8787.  
  8788. -- A function to get the entity a player is holding.
  8789. function playerMeta:GetHoldingEntity()
  8790.     return self.isHoldingEntity;
  8791. end;
  8792.  
  8793. playerMeta.GetName = playerMeta.Name;
  8794. playerMeta.Nick = playerMeta.Name;
  8795.  
  8796. nexus.mount.Call("NexusCoreLoaded");
  8797. nexus.mount.Call("NexusCoreLoaded"); 2.62467192), math.min(size, 14) ), size);
  8798. end;
  8799.  
  8800. -- A function to hook a data stream.
  8801. function NEXUS:HookDataStream(name, Callback)
  8802.     self.DataStreamHooks[name] = Callback;
  8803. end;
  8804.  
  8805. -- A function to get the schema folder.
  8806. function NEXUS:GetSchemaFolder()
  8807.     local folder = string.gsub(self.SchemaFolder, "gamemodes/", "");
  8808.    
  8809.     if (folder) then
  8810.         return folder;
  8811.     end;
  8812. end;
  8813.  
  8814. -- A function to get the mount directory.
  8815. function NEXUS:GetMountDirectory()
  8816.     return MOUNT_DIRECTORY;
  8817. end;
  8818.  
  8819. -- A function to get the Nexus folder.
  8820. function NEXUS:GetNexusFolder()
  8821.     local folder = string.gsub(self.NexusFolder, "gamemodes/", "");
  8822.    
  8823.     if (folder) then
  8824.         return folder;
  8825.     end;
  8826. end;
  8827.  
  8828. -- A function to save schema data.
  8829. function NEXUS:SaveSchemaData(fileName, data)
  8830.     g_File.Write( "nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt", glon.encode(data) );
  8831. end;
  8832.  
  8833. -- A function to delete schema data.
  8834. function NEXUS:DeleteSchemaData(fileName)
  8835.     g_File.Delete("nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
  8836. end;
  8837.  
  8838. -- A function to check if schema data exists.
  8839. function NEXUS:SchemaDataExists(fileName)
  8840.     return g_File.Exists("nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
  8841. end;
  8842.  
  8843. -- A function to restore schema data.
  8844. function NEXUS:RestoreSchemaData(fileName, default)
  8845.     if ( self:SchemaDataExists(fileName) ) then
  8846.         local data = g_File.Read("nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
  8847.        
  8848.         if (data) then
  8849.             local success, value = pcall(glon.decode, data);
  8850.            
  8851.             if (success and value != nil) then
  8852.                 return value;
  8853.             else
  8854.                 local success, value = pcall(Json.Decode, data);
  8855.                
  8856.                 if (success and value != nil) then
  8857.                     return value;
  8858.                 end;
  8859.             end;
  8860.         end;
  8861.     end;
  8862.    
  8863.     if (default != nil) then
  8864.         return default;
  8865.     else
  8866.         return {};
  8867.     end;
  8868. end;
  8869.  
  8870. -- A function to save Nexus data.
  8871. function NEXUS:SaveNexusData(fileName, data)
  8872.     g_File.Write( "nexus/"..fileName..".txt", glon.encode(data) );
  8873. end;
  8874.  
  8875. -- A function to check if Nexus data exists.
  8876. function NEXUS:NexusDataExists(fileName)
  8877.     return g_File.Exists("nexus/"..fileName..".txt");
  8878. end;
  8879.  
  8880. -- A function to delete Nexus data.
  8881. function NEXUS:DeleteNexusData(fileName)
  8882.     g_File.Delete("nexus/"..fileName..".txt");
  8883. end;
  8884.  
  8885. -- A function to convert a string to a boolean.
  8886. function NEXUS:ToBool(text)
  8887.     if (text == "true" or text == "yes" or text == "1") then
  8888.         return true;
  8889.     else
  8890.         return false;
  8891.     end;
  8892. end;
  8893.  
  8894. -- A function to split a string.
  8895. function NEXUS:SplitString(text, interval)
  8896.     local length = string.len(text);
  8897.     local base = {};
  8898.     local i = 0;
  8899.    
  8900.     while (i * interval < length) do
  8901.         base[i + 1] = string.sub(text, i * interval + 1, (i + 1) * interval);
  8902.        
  8903.         i = i + 1;
  8904.     end;
  8905.    
  8906.     return base;
  8907. end;
  8908.  
  8909. -- Called when the player's jumping animation should be handled.
  8910. function NEXUS:HandlePlayerJumping(player)
  8911.     if (!player.m_bJumping and !player:OnGround() and player:WaterLevel() <= 0) then
  8912.         player.m_bJumping = true;
  8913.         player.m_bFirstJumpFrame = false;
  8914.         player.m_flJumpStartTime = 0;
  8915.     end
  8916.    
  8917.     if (player.m_bJumping) then
  8918.         if (player.m_bFirstJumpFrame) then
  8919.             player.m_bFirstJumpFrame = false;
  8920.             player:AnimRestartMainSequence();
  8921.         end;
  8922.        
  8923.         if (player:WaterLevel() >= 2) then
  8924.             player.m_bJumping = false;
  8925.             player:AnimRestartMainSequence();
  8926.         elseif (CurTime() - player.m_flJumpStartTime > 0.2) then
  8927.             if ( player:OnGround() ) then
  8928.                 player.m_bJumping = false;
  8929.                 player:AnimRestartMainSequence();
  8930.             end
  8931.         end
  8932.        
  8933.         if (player.m_bJumping) then
  8934.             player.CalcIdeal = nexus.animation.GetForModel(player:GetModel(), "jump");
  8935.            
  8936.             return true;
  8937.         end;
  8938.     end;
  8939.    
  8940.     return false;
  8941. end;
  8942.  
  8943. -- Called when the player's ducking animation should be handled.
  8944. function NEXUS:HandlePlayerDucking(player, velocity)
  8945.     if ( player:Crouching() ) then
  8946.         local model = player:GetModel();
  8947.         local weapon = player:GetActiveWeapon();
  8948.         local raised = nexus.player.GetWeaponRaised(player, true);
  8949.         local velLength = velocity:Length2D();
  8950.         local animationAct = "crouch";
  8951.         local weaponHoldType = "pistol";
  8952.        
  8953.         if ( IsValid(weapon) ) then
  8954.             weaponHoldType = nexus.animation.GetWeaponHoldType(player, weapon);
  8955.        
  8956.             if (weaponHoldType) then
  8957.                 animationAct = animationAct.."_"..weaponHoldType;
  8958.             end;
  8959.         end;
  8960.        
  8961.         if (raised) then
  8962.             animationAct = animationAct.."_aim";
  8963.         end;
  8964.        
  8965.         if (velLength > 0.5) then
  8966.             animationAct = animationAct.."_walk";
  8967.         else
  8968.             animationAct = animationAct.."_idle";
  8969.         end;
  8970.  
  8971.         player.CalcIdeal = nexus.animation.GetForModel(model, animationAct);
  8972.        
  8973.         return true;
  8974.     end;
  8975.    
  8976.     return false;
  8977. end;
  8978.  
  8979. -- Called when the player's swimming animation should be handled.
  8980. function NEXUS:HandlePlayerSwimming(player)
  8981.     if (player:WaterLevel() >= 2) then
  8982.         if (player.m_bFirstSwimFrame) then
  8983.             player:AnimRestartMainSequence();
  8984.             player.m_bFirstSwimFrame = false;
  8985.         end;
  8986.        
  8987.         player.m_bInSwim = true;
  8988.     else
  8989.         player.m_bInSwim = false;
  8990.        
  8991.         if (!player.m_bFirstSwimFrame) then
  8992.             player.m_bFirstSwimFrame = true;
  8993.         end;
  8994.     end;
  8995.    
  8996.     return false;
  8997. end;
  8998.  
  8999. -- Called when the player's driving animation should be handled.
  9000. function NEXUS:HandlePlayerDriving(player)
  9001.     if ( player:InVehicle() ) then
  9002.         player.CalcIdeal = nexus.animation.GetForModel(player:GetModel(), "sit");
  9003.        
  9004.         return true;
  9005.     end;
  9006.    
  9007.     return false;
  9008. end;
  9009.  
  9010. -- Called when a player's animation is updated.
  9011. function NEXUS:UpdateAnimation(player, velocity, maxSeqGroundSpeed)
  9012.     local velLength = velocity:Length2D();
  9013.     local rate = 1.0;
  9014.    
  9015.     if (velLength > 0.5) then
  9016.         rate = ( ( velLength * 0.8 ) / maxSeqGroundSpeed );
  9017.     end
  9018.    
  9019.     player.playbackRate = math.Clamp(rate, 0, 1.5);
  9020.     player:SetPlaybackRate(player.playbackRate);
  9021. end;
  9022.  
  9023. -- Called when the main activity should be calculated.
  9024. function NEXUS:CalcMainActivity(player, velocity)
  9025.     local model = player:GetModel();
  9026.    
  9027.     if ( string.find(model, "/player/") ) then
  9028.         return self.BaseClass:CalcMainActivity(player, velocity);
  9029.     end;
  9030.    
  9031.     local weapon = player:GetActiveWeapon();
  9032.     local raised = nexus.player.GetWeaponRaised(player, true);
  9033.     local animationAct = "stand";
  9034.     local weaponHoldType = "pistol";
  9035.     local forcedAnimation = player:GetForcedAnimation();
  9036.  
  9037.     if ( IsValid(weapon) ) then
  9038.         weaponHoldType = nexus.animation.GetWeaponHoldType(player, weapon);
  9039.    
  9040.         if (weaponHoldType) then
  9041.             animationAct = animationAct.."_"..weaponHoldType;
  9042.         end;
  9043.     end;
  9044.    
  9045.     if (raised) then
  9046.         animationAct = animationAct.."_aim";
  9047.     end;
  9048.    
  9049.     player.CalcIdeal = nexus.animation.GetForModel(model, animationAct.."_idle");
  9050.     player.CalcSeqOverride = -1;
  9051.    
  9052.     if ( !self:HandlePlayerDriving(player)
  9053.     and !self:HandlePlayerJumping(player)
  9054.     and !self:HandlePlayerDucking(player, velocity)
  9055.     and !self:HandlePlayerSwimming(player) ) then
  9056.         local velLength = velocity:Length2D();
  9057.        
  9058.         if ( player:IsRunning() or player:IsJogging() ) then
  9059.             player.CalcIdeal = nexus.animation.GetForModel(model, animationAct.."_run");
  9060.         elseif (velLength > 0.5) then
  9061.             player.CalcIdeal = nexus.animation.GetForModel(model, animationAct.."_walk");
  9062.         end;
  9063.     end;
  9064.    
  9065.     if (forcedAnimation) then
  9066.         player.CalcSeqOverride = forcedAnimation.animation;
  9067.        
  9068.         if (forcedAnimation.onAnimate) then
  9069.             forcedAnimation.onAnimate(player);
  9070.             forcedAnimation.onAnimate = nil;
  9071.         end;
  9072.     end;
  9073.    
  9074.     if (type(player.CalcSeqOverride) == "string") then
  9075.         player.CalcSeqOverride = player:LookupSequence(player.CalcSeqOverride);
  9076.     end;
  9077.    
  9078.     if (type(player.CalcIdeal) == "string") then
  9079.         player.CalcSeqOverride = player:LookupSequence(player.CalcIdeal);
  9080.     end;
  9081.    
  9082.     return player.CalcIdeal, player.CalcSeqOverride;
  9083. end;
  9084.  
  9085. local IdleActivity = ACT_HL2MP_IDLE;
  9086. local IdleActivityTranslate = {
  9087.     ACT_MP_ATTACK_CROUCH_PRIMARYFIRE = IdleActivity + 5,
  9088.     ACT_MP_ATTACK_STAND_PRIMARYFIRE = IdleActivity + 5,
  9089.     ACT_MP_RELOAD_CROUCH = IdleActivity + 6,
  9090.     ACT_MP_RELOAD_STAND = IdleActivity + 6,
  9091.     ACT_MP_CROUCH_IDLE = IdleActivity + 3,
  9092.     ACT_MP_STAND_IDLE = IdleActivity,
  9093.     ACT_MP_CROUCHWALK = IdleActivity + 4,
  9094.     ACT_MP_JUMP = ACT_HL2MP_JUMP_SLAM,
  9095.     ACT_MP_WALK = IdleActivity + 1,
  9096.     ACT_MP_RUN = IdleActivity + 2,
  9097. };
  9098.    
  9099. -- Called when a player's activity is supposed to be translated.
  9100. function NEXUS:TranslateActivity(player, act)
  9101.     local model = player:GetModel();
  9102.     local raised = nexus.player.GetWeaponRaised(player, true);
  9103.    
  9104.     if ( string.find(model, "/player/") ) then
  9105.         local newAct = player:TranslateWeaponActivity(act);
  9106.        
  9107.         if (!raised or act == newAct) then
  9108.             return IdleActivityTranslate[act];
  9109.         else
  9110.             return newAct;
  9111.         end;
  9112.     end;
  9113.    
  9114.     return act;
  9115. end;
  9116.  
  9117. -- Called when the animation event is supposed to be done.
  9118. function NEXUS:DoAnimationEvent(player, event, data)
  9119.     local model = player:GetModel();
  9120.    
  9121.     if ( string.find(model, "/player/") ) then
  9122.         return self.BaseClass:DoAnimationEvent(player, event, data);
  9123.     end;
  9124.    
  9125.     local weapon = player:GetActiveWeapon();
  9126.     local animationAct = "pistol";
  9127.    
  9128.     if ( IsValid(weapon) ) then
  9129.         weaponHoldType = nexus.animation.GetWeaponHoldType(player, weapon);
  9130.    
  9131.         if (weaponHoldType) then
  9132.             animationAct = weaponHoldType;
  9133.         end;
  9134.     end;
  9135.    
  9136.     if (event == PLAYERANIMEVENT_ATTACK_PRIMARY) then
  9137.         local gestureSequence = nexus.animation.GetForModel(model, animationAct.."_attack");
  9138.  
  9139.         if ( player:Crouching() ) then
  9140.             player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
  9141.         else
  9142.             player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
  9143.         end;
  9144.        
  9145.         return ACT_VM_PRIMARYATTACK;
  9146.     elseif (event == PLAYERANIMEVENT_RELOAD) then
  9147.         local gestureSequence = nexus.animation.GetForModel(model, animationAct.."_reload");
  9148.  
  9149.         if ( player:Crouching() ) then
  9150.             player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
  9151.         else
  9152.             player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
  9153.         end;
  9154.        
  9155.         return ACT_INVALID;
  9156.     elseif event == PLAYERANIMEVENT_JUMP then
  9157.         player.m_bJumping = true;
  9158.         player.m_bFirstJumpFrame = true;
  9159.         player.m_flJumpStartTime = CurTime();
  9160.        
  9161.         player:AnimRestartMainSequence();
  9162.        
  9163.         return ACT_INVALID;
  9164.     elseif (event == PLAYERANIMEVENT_CANCEL_RELOAD) then
  9165.         player:AnimResetGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD);
  9166.        
  9167.         return ACT_INVALID;
  9168.     end;
  9169.  
  9170.     return nil;
  9171. end;
  9172.  
  9173. if (SERVER) then
  9174.     NEXUS.Entities = {};
  9175.     NEXUS.TempPlayerData = {};
  9176.     NEXUS.HitGroupBonesCache = {
  9177.         {"ValveBiped.Bip01_R_UpperArm", HITGROUP_RIGHTARM},
  9178.         {"ValveBiped.Bip01_R_Forearm", HITGROUP_RIGHTARM},
  9179.         {"ValveBiped.Bip01_L_UpperArm", HITGROUP_LEFTARM},
  9180.         {"ValveBiped.Bip01_L_Forearm", HITGROUP_LEFTARM},
  9181.         {"ValveBiped.Bip01_R_Thigh", HITGROUP_RIGHTLEG},
  9182.         {"ValveBiped.Bip01_R_Calf", HITGROUP_RIGHTLEG},
  9183.         {"ValveBiped.Bip01_R_Foot", HITGROUP_RIGHTLEG},
  9184.         {"ValveBiped.Bip01_R_Hand", HITGROUP_RIGHTARM},
  9185.         {"ValveBiped.Bip01_L_Thigh", HITGROUP_LEFTLEG},
  9186.         {"ValveBiped.Bip01_L_Calf", HITGROUP_LEFTLEG},
  9187.         {"ValveBiped.Bip01_L_Foot", HITGROUP_LEFTLEG},
  9188.         {"ValveBiped.Bip01_L_Hand", HITGROUP_LEFTARM},
  9189.         {"ValveBiped.Bip01_Spine2", HITGROUP_CHEST},
  9190.         {"ValveBiped.Bip01_Spine1", HITGROUP_CHEST},
  9191.         {"ValveBiped.Bip01_Pelvis", HITGROUP_GEAR},
  9192.         {"ValveBiped.Bip01_Head1", HITGROUP_HEAD},
  9193.         {"ValveBiped.Bip01_Neck1", HITGROUP_HEAD}
  9194.     };
  9195.     NEXUS.MeleeTranslation = {
  9196.         [ACT_HL2MP_GESTURE_RANGE_ATTACK] = ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE2,
  9197.         [ACT_HL2MP_GESTURE_RELOAD] = ACT_HL2MP_GESTURE_RELOAD_MELEE2,
  9198.         [ACT_HL2MP_WALK_CROUCH] = ACT_HL2MP_WALK_CROUCH_MELEE2,
  9199.         [ACT_HL2MP_IDLE_CROUCH] = ACT_HL2MP_IDLE_CROUCH_MELEE2,
  9200.         [ACT_RANGE_ATTACK1] = ACT_RANGE_ATTACK1_MELEE2,
  9201.         [ACT_HL2MP_IDLE] = ACT_HL2MP_IDLE_MELEE2,
  9202.         [ACT_HL2MP_WALK] = ACT_HL2MP_WALK_MELEE2,
  9203.         [ACT_HL2MP_JUMP] = ACT_HL2MP_JUMP_MELEE2,
  9204.         [ACT_HL2MP_RUN] = ACT_HL2MP_RUN_MELEE2
  9205.     };
  9206.    
  9207.     -- A function to load the bans.
  9208.     function NEXUS:LoadBans()
  9209.         self.BanList = self:RestoreNexusData("bans");
  9210.        
  9211.         local unixTime = os.time();
  9212.        
  9213.         for k, v in pairs(self.BanList) do
  9214.             if (type(v) == "table") then
  9215.                 if (v.unbanTime > 0 and unixTime >= v.unbanTime) then
  9216.                     self:RemoveBan(k, true);
  9217.                 end;
  9218.             else
  9219.                 self.BanList[k] = nil;
  9220.             end;
  9221.         end;
  9222.        
  9223.         self:SaveNexusData("bans", self.BanList);
  9224.     end;
  9225.    
  9226.     -- A function to add a ban.
  9227.     function NEXUS:AddBan(identifier, duration, reason, Callback, saveless)
  9228.         local steamName = nil;
  9229.         local playerGet = nexus.player.Get(identifier);
  9230.        
  9231.         if (identifier) then
  9232.             identifier = string.upper(identifier);
  9233.         end;
  9234.        
  9235.         for k, v in ipairs( g_Player.GetAll() ) do
  9236.             local playerIP = v:IPAddress();
  9237.             local playerSteam = v:SteamID();
  9238.            
  9239.             if (playerSteam == identifier or playerIP == identifier or playerGet == v) then
  9240.                 nexus.mount.Call("PlayerBanned", v, duration, reason);
  9241.                
  9242.                 if (playerIP == identifier) then
  9243.                     identifier = playerIP;
  9244.                 else
  9245.                     identifier = playerSteam;
  9246.                 end;
  9247.                
  9248.                 steamName = v:SteamName();
  9249.                 v:Kick(reason);
  9250.             end;
  9251.         end;
  9252.        
  9253.         if (!reason) then
  9254.             reason = "Banned for an unspecified reason.";
  9255.         end;
  9256.        
  9257.         if (!steamName) then
  9258.             local playersTable = nexus.config.Get("mysql_players_table"):Get();
  9259.             local newIdentifier = tmysql.escape(identifier);
  9260.            
  9261.             if ( string.find(identifier, "STEAM") ) then
  9262.                 tmysql.query("SELECT * FROM "..playersTable.." WHERE _SteamID = \""..newIdentifier.."\"", function(result)
  9263.                     local steamName = identifier;
  9264.                    
  9265.                     if (result and type(result) == "table" and #result > 0) then
  9266.                         steamName = result[1]._SteamName;
  9267.                     end;
  9268.                    
  9269.                     if (duration == 0) then
  9270.                         self.BanList[identifier] = {
  9271.                             unbanTime = 0,
  9272.                             steamName = steamName,
  9273.                             duration = duration,
  9274.                             reason = reason
  9275.                         };
  9276.                     else
  9277.                         self.BanList[identifier] = {
  9278.                             unbanTime = os.time() + duration,
  9279.                             steamName = steamName,
  9280.                             duration = duration,
  9281.                             reason = reason
  9282.                         };
  9283.                     end;
  9284.                    
  9285.                     if (!saveless) then
  9286.                         self:SaveNexusData("bans", self.BanList);
  9287.                     end;
  9288.                    
  9289.                     if (Callback) then
  9290.                         Callback(steamName, duration, reason);
  9291.                     end;
  9292.                 end, 1);
  9293.             elseif ( string.find(identifier, "%d+%.%d+%.%d+%.%d+") ) then
  9294.                 tmysql.query("SELECT * FROM "..playersTable.." WHERE _IPAddress = \""..newIdentifier.."\"", function(result)
  9295.                     local steamName = identifier;
  9296.                    
  9297.                     if (result and type(result) == "table" and #result > 0) then
  9298.                         steamName = result[1]._SteamName;
  9299.                     end;
  9300.                    
  9301.                     if (duration == 0) then
  9302.                         self.BanList[identifier] = {
  9303.                             unbanTime = 0,
  9304.                             steamName = steamName,
  9305.                             duration = duration,
  9306.                             reason = reason
  9307.                         };
  9308.                     else
  9309.                         self.BanList[identifier] = {
  9310.                             unbanTime = os.time() + duration,
  9311.                             steamName = steamName,
  9312.                             duration = duration,
  9313.                             reason = reason
  9314.                         };
  9315.                     end;
  9316.                    
  9317.                     if (!saveless) then
  9318.                         self:SaveNexusData("bans", self.BanList);
  9319.                     end;
  9320.                    
  9321.                     if (Callback) then
  9322.                         Callback(steamName, duration, reason);
  9323.                     end;
  9324.                 end, 1);
  9325.             elseif (Callback) then
  9326.                 Callback();
  9327.             end;
  9328.         else
  9329.             if (duration == 0) then
  9330.                 self.BanList[identifier] = {
  9331.                     unbanTime = 0,
  9332.                     steamName = steamName,
  9333.                     duration = duration,
  9334.                     reason = reason
  9335.                 };
  9336.             else
  9337.                 self.BanList[identifier] = {
  9338.                     unbanTime = os.time() + duration,
  9339.                     steamName = steamName,
  9340.                     duration = duration,
  9341.                     reason = reason
  9342.                 };
  9343.             end;
  9344.            
  9345.             if (!saveless) then
  9346.                 self:SaveNexusData("bans", self.BanList);
  9347.             end;
  9348.            
  9349.             if (Callback) then
  9350.                 Callback(steamName, duration, reason);
  9351.             end;
  9352.         end;
  9353.     end;
  9354.    
  9355.     -- A function to remove a ban.
  9356.     function NEXUS:RemoveBan(identifier, saveless)
  9357.         if ( self.BanList[identifier] ) then
  9358.             self.BanList[identifier] = nil;
  9359.            
  9360.             if (!saveless) then
  9361.                 self:SaveNexusData("bans", self.BanList);
  9362.             end;
  9363.         end;
  9364.     end;
  9365.    
  9366.     -- A function to start a data stream.
  9367.     function NEXUS:StartDataStream(player, name, data)
  9368.         if (type(player) != "table") then
  9369.             if (!player) then
  9370.                 player = g_Player.GetAll();
  9371.             else
  9372.                 player = {player};
  9373.             end;
  9374.         end;
  9375.        
  9376.         local encodedData = glon.encode(data);
  9377.         local splitTable = self:SplitString(encodedData, 128);
  9378.         local players = RecipientFilter();
  9379.        
  9380.         for k, v in pairs(player) do
  9381.             if (type(v) == "Player") then
  9382.                 players:AddPlayer(v);
  9383.             elseif (type(k) == "Player") then
  9384.                 players:AddPlayer(k);
  9385.             end;
  9386.         end;
  9387.        
  9388.         if (#splitTable > 0) then
  9389.             umsg.Start("nx_dsStart", players);
  9390.                 umsg.String(name);
  9391.                 umsg.String( splitTable[1] );
  9392.                 umsg.Short(#splitTable);
  9393.             umsg.End();
  9394.            
  9395.             if (#splitTable > 1) then
  9396.                 for k, v in ipairs(splitTable) do
  9397.                     if (k > 1) then
  9398.                         umsg.Start("nx_dsData", players);
  9399.                             umsg.String(v);
  9400.                             umsg.Short(k);
  9401.                         umsg.End();
  9402.                     end;
  9403.                 end;
  9404.             end;
  9405.         end;
  9406.     end;
  9407.  
  9408.     -- A function to convert a force.
  9409.     function NEXUS:ConvertForce(force, limit)
  9410.         local forceLength = force:Length();
  9411.        
  9412.         if (forceLength == 0) then
  9413.             return Vector(0, 0, 0);
  9414.         end;
  9415.        
  9416.         if (!limit) then
  9417.             limit = 800;
  9418.         end;
  9419.        
  9420.         if (forceLength > limit) then
  9421.             return force / (forceLength / limit);
  9422.         else
  9423.             return force;
  9424.         end;
  9425.     end;
  9426.    
  9427.     -- A function to restore Nexus data.
  9428.     function NEXUS:RestoreNexusData(fileName, default)
  9429.         if ( self:NexusDataExists(fileName) ) then
  9430.             local data = g_File.Read("nexus/"..fileName..".txt");
  9431.            
  9432.             if (data) then
  9433.                 local success, value = pcall(glon.decode, data);
  9434.                
  9435.                 if (success and value != nil) then
  9436.                     return value;
  9437.                 else
  9438.                     local success, value = pcall(Json.Decode, data);
  9439.                    
  9440.                     if (success and value != nil) then
  9441.                         return value;
  9442.                     end;
  9443.                 end;
  9444.             end;
  9445.         end;
  9446.        
  9447.         if (default != nil) then
  9448.             return default;
  9449.         else
  9450.             return {};
  9451.         end;
  9452.     end;
  9453.    
  9454.     -- A function to save a player's attribute boosts.
  9455.     function NEXUS:SavePlayerAttributeBoosts(player, data)
  9456.         local attributeBoosts = player:GetAttributeBoosts();
  9457.         local curTime = CurTime();
  9458.        
  9459.         if ( data["attributeboosts"] ) then
  9460.             data["attributeboosts"] = nil;
  9461.         end;
  9462.        
  9463.         if (table.Count(attributeBoosts) > 0) then
  9464.             data["attributeboosts"] = {};
  9465.            
  9466.             for k, v in pairs(attributeBoosts) do
  9467.                 data["attributeboosts"][k] = {};
  9468.                
  9469.                 for k2, v2 in pairs(v) do
  9470.                     if (v2.duration) then
  9471.                         if (curTime < v2.endTime) then
  9472.                             data["attributeboosts"][k][k2] = {
  9473.                                 duration = math.ceil(v2.endTime - curTime),
  9474.                                 amount = v2.amount
  9475.                             };
  9476.                         end;
  9477.                     else
  9478.                         data["attributeboosts"][k][k2] = {
  9479.                             amount = v2.amount
  9480.                         };
  9481.                     end;
  9482.                 end;
  9483.             end;
  9484.         end;
  9485.     end;
  9486.    
  9487.     -- A function to calculate a player's spawn time.
  9488.     function NEXUS:CalculateSpawnTime(player, inflictor, attacker, damageInfo)
  9489.         local info = {
  9490.             attacker = attacker,
  9491.             inflictor = inflictor,
  9492.             spawnTime = nexus.config.Get("spawn_time"):Get(),
  9493.             damageInfo = damageInfo
  9494.         };
  9495.  
  9496.         nexus.mount.Call("PlayerAdjustDeathInfo", player, info);
  9497.  
  9498.         if (info.spawnTime and info.spawnTime > 0) then
  9499.             nexus.player.SetAction(player, "spawn", info.spawnTime, 3);
  9500.         end;
  9501.     end;
  9502.    
  9503.     -- A function to create a decal.
  9504.     function NEXUS:CreateDecal(texture, position, temporary)
  9505.         local decal = ents.Create("infodecal");
  9506.        
  9507.         if (temporary) then
  9508.             decal:SetKeyValue("LowPriority", "true");
  9509.         end;
  9510.        
  9511.         decal:SetKeyValue("Texture", texture);
  9512.         decal:SetPos(position);
  9513.         decal:Spawn();
  9514.         decal:Fire("activate");
  9515.        
  9516.         return decal;
  9517.     end;
  9518.    
  9519.     -- A function to handle a player's weapon fire delay.
  9520.     function NEXUS:HandleWeaponFireDelay(player, raised, weapon, curTime)
  9521.         local delaySecondaryFire = nil;
  9522.         local delayPrimaryFire = nil;
  9523.        
  9524.         if ( !nexus.mount.Call("PlayerCanFireWeapon", player, raised, weapon, true) ) then
  9525.             delaySecondaryFire = curTime + 60;
  9526.         end;
  9527.        
  9528.         if ( !nexus.mount.Call("PlayerCanFireWeapon", player, raised, weapon) ) then
  9529.             delayPrimaryFire = curTime + 60;
  9530.         end;
  9531.        
  9532.         if (delaySecondaryFire == nil and weapon.secondaryFireDelayed) then
  9533.             weapon:SetNextSecondaryFire(weapon.secondaryFireDelayed);
  9534.             weapon.secondaryFireDelayed = nil;
  9535.         end;
  9536.        
  9537.         if (delayPrimaryFire == nil and weapon.primaryFireDelayed) then
  9538.             weapon:SetNextPrimaryFire(weapon.primaryFireDelayed);
  9539.             weapon.primaryFireDelayed = nil;
  9540.         end;
  9541.        
  9542.         if (delaySecondaryFire) then
  9543.             if (!weapon.secondaryFireDelayed) then
  9544.                 weapon.secondaryFireDelayed = weapon:GetNextSecondaryFire();
  9545.             end;
  9546.            
  9547.             weapon:SetNextSecondaryFire(delaySecondaryFire);
  9548.         end;
  9549.        
  9550.         if (delayPrimaryFire) then
  9551.             if (!weapon.primaryFireDelayed) then
  9552.                 weapon.primaryFireDelayed = weapon:GetNextPrimaryFire();
  9553.             end;
  9554.            
  9555.             weapon:SetNextPrimaryFire(delayPrimaryFire);
  9556.         end;
  9557.     end;
  9558.    
  9559.     -- A function to scale damage by hit group.
  9560.     function NEXUS:ScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, baseDamage)
  9561.         if ( !damageInfo:IsFallDamage() and !damageInfo:IsDamageType(DMG_CRUSH) ) then
  9562.             if (hitGroup == HITGROUP_HEAD) then
  9563.                 damageInfo:ScaleDamage( nexus.config.Get("scale_head_dmg"):Get() );
  9564.             elseif (hitGroup == HITGROUP_CHEST or hitGroup == HITGROUP_GENERIC) then
  9565.                 damageInfo:ScaleDamage( nexus.config.Get("scale_chest_dmg"):Get() );
  9566.             elseif (hitGroup == HITGROUP_LEFTARM or hitGroup == HITGROUP_RIGHTARM or hitGroup == HITGROUP_LEFTLEG
  9567.             or hitGroup == HITGROUP_RIGHTLEG or hitGroup == HITGROUP_GEAR) then
  9568.                 damageInfo:ScaleDamage( nexus.config.Get("scale_limb_dmg"):Get() );
  9569.             end;
  9570.         end;
  9571.        
  9572.         nexus.mount.Call("PlayerScaleDamageByHitGroup", player, attacker, hitGroup, damageInfo, baseDamage);
  9573.     end;
  9574.    
  9575.     -- A function to calculate player damage.
  9576.     function NEXUS:CalculatePlayerDamage(player, hitGroup, damageInfo)
  9577.         local damageIsValid = damageInfo:IsBulletDamage() or damageInfo:IsDamageType(DMG_CLUB) or damageInfo:IsDamageType(DMG_SLASH);
  9578.         local hitGroupIsValid = true;
  9579.        
  9580.         if ( nexus.config.Get("armor_chest_only"):Get() ) then
  9581.             if (hitGroup != HITGROUP_CHEST and hitGroup != HITGROUP_GENERIC) then
  9582.                 hitGroupIsValid = nil;
  9583.             end;
  9584.         end;
  9585.        
  9586.         if (player:Armor() > 0 and damageIsValid and hitGroupIsValid) then
  9587.             local armor = player:Armor() - damageInfo:GetDamage();
  9588.            
  9589.             if (armor < 0) then
  9590.                 player:SetHealth( math.max(player:Health() - math.abs(armor), 1) );
  9591.                 player:SetArmor( math.max(armor, 0) );
  9592.             else
  9593.                 player:SetArmor( math.max(armor, 0) );
  9594.             end;
  9595.         else
  9596.             player:SetHealth( math.max(player:Health() - damageInfo:GetDamage(), 1) );
  9597.         end;
  9598.     end;
  9599.    
  9600.     -- A function to get a ragdoll's hit bone.
  9601.     function NEXUS:GetRagdollHitBone(entity, position, default, minimum)
  9602.         local closest = {};
  9603.        
  9604.         for k, v in ipairs(self.HitGroupBonesCache) do
  9605.             local bone = entity:LookupBone( v[1] );
  9606.            
  9607.             if (bone) then
  9608.                 local bonePosition = entity:GetBonePosition(bone);
  9609.                
  9610.                 if (bonePosition) then
  9611.                     local distance = bonePosition:Distance(position);
  9612.                    
  9613.                     if ( !closest[1] or distance < closest[1] ) then
  9614.                         if (!minimum or distance <= minimum) then
  9615.                             closest[1] = distance;
  9616.                             closest[2] = bone;
  9617.                         end;
  9618.                     end;
  9619.                 end;
  9620.             end;
  9621.         end;
  9622.        
  9623.         if ( closest[2] ) then
  9624.             return closest[2];
  9625.         else
  9626.             return default;
  9627.         end;
  9628.     end;
  9629.    
  9630.     -- A function to get a ragdoll's hit group.
  9631.     function NEXUS:GetRagdollHitGroup(entity, position)
  9632.         local closest = {nil, HITGROUP_GENERIC};
  9633.        
  9634.         for k, v in ipairs(self.HitGroupBonesCache) do
  9635.             local bone = entity:LookupBone( v[1] );
  9636.            
  9637.             if (bone) then
  9638.                 local bonePosition = entity:GetBonePosition(bone);
  9639.                
  9640.                 if (position) then
  9641.                     local distance = bonePosition:Distance(position);
  9642.                    
  9643.                     if ( !closest[1] or distance < closest[1] ) then
  9644.                         closest[1] = distance;
  9645.                         closest[2] = v[2];
  9646.                     end;
  9647.                 end;
  9648.             end;
  9649.         end;
  9650.        
  9651.         return closest[2];
  9652.     end;
  9653.  
  9654.     -- A function to create blood effects at a position.
  9655.     function NEXUS:CreateBloodEffects(position, decals, entity, force)
  9656.         if (!force) then
  9657.             force = VectorRand() * 80;
  9658.         end;
  9659.        
  9660.         local effectData = EffectData();
  9661.             effectData:SetOrigin(position);
  9662.             effectData:SetNormal(force);
  9663.             effectData:SetScale(0.5);
  9664.         util.Effect("nx_bloodsmoke", effectData, true, true);
  9665.        
  9666.         local effectData = EffectData();
  9667.             effectData:SetOrigin(position);
  9668.             effectData:SetEntity(entity);
  9669.             effectData:SetStart(position);
  9670.             effectData:SetScale(0.5);
  9671.         util.Effect("BloodImpact", effectData, true, true);
  9672.        
  9673.         for i = 1, decals do
  9674.             local trace = {};
  9675.                 trace.start = position;
  9676.                 trace.endpos = trace.start;
  9677.                 trace.filter = entity;
  9678.             trace = util.TraceLine(trace);
  9679.            
  9680.             util.Decal("Blood", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal);
  9681.         end;
  9682.     end;
  9683.    
  9684.     -- A function to do the entity take damage hook.
  9685.     function NEXUS:DoEntityTakeDamageHook(gamemode, arguments)
  9686.         if ( arguments[4] != arguments[5]:GetDamage() ) then
  9687.             arguments[4] = arguments[5]:GetDamage();
  9688.         end;
  9689.        
  9690.         local player = nexus.entity.GetPlayer( arguments[1] );
  9691.        
  9692.         if (player) then
  9693.             local ragdoll = player:GetRagdollEntity();
  9694.            
  9695.             if ( !hook.Call( "PlayerShouldTakeDamage", gamemode, player, arguments[3], arguments[2], arguments[5] ) or player:IsInGodMode() ) then
  9696.                 arguments[5]:SetDamage(0);
  9697.                
  9698.                 return true;
  9699.             end;
  9700.            
  9701.             if (ragdoll and arguments[1] != ragdoll) then
  9702.                 hook.Call( "EntityTakeDamage", gamemode, ragdoll, arguments[2], arguments[3], arguments[4], arguments[5] );
  9703.                
  9704.                 arguments[5]:SetDamage(0);
  9705.                
  9706.                 return true;
  9707.             elseif (arguments[1] == ragdoll) then
  9708.                 local physicsObject = arguments[1]:GetPhysicsObject();
  9709.                
  9710.                 if ( IsValid(physicsObject) ) then
  9711.                     local velocity = physicsObject:GetVelocity():Length();
  9712.                     local curTime = CurTime();
  9713.                    
  9714.                     if ( arguments[5]:IsDamageType(DMG_CRUSH) ) then
  9715.                         if (arguments[1].nextFallDamage and curTime < arguments[1].nextFallDamage) then
  9716.                             arguments[5]:SetDamage(0);
  9717.                            
  9718.                             return true;
  9719.                         end;
  9720.                        
  9721.                         arguments[4] = hook.Call("GetFallDamage", gamemode, player, velocity);
  9722.                         arguments[1].nextFallDamage = curTime + 1;
  9723.                         arguments[5]:SetDamage( arguments[4] )
  9724.                     end;
  9725.                 end;
  9726.             end;
  9727.         end;
  9728.     end;
  9729.    
  9730.     -- A function to perform the date and time think.
  9731.     function NEXUS:PerformDateTimeThink()
  9732.         local defaultDays = nexus.schema.GetOption("default_days");
  9733.         local minute = nexus.time.GetMinute();
  9734.         local month = nexus.date.GetMonth();
  9735.         local year = nexus.date.GetYear();
  9736.         local hour = nexus.time.GetHour();
  9737.         local day = nexus.time.GetDay();
  9738.        
  9739.         nexus.time.minute = nexus.time.GetMinute() + 1;
  9740.        
  9741.         if (nexus.time.GetMinute() == 60) then
  9742.             nexus.time.minute = 0;
  9743.             nexus.time.hour = nexus.time.GetHour() + 1;
  9744.            
  9745.             if (nexus.time.GetHour() == 24) then
  9746.                 nexus.time.hour = 0;
  9747.                 nexus.time.day = nexus.time.GetDay() + 1;
  9748.                 nexus.date.day = nexus.date.GetDay() + 1;
  9749.                
  9750.                 if (nexus.time.GetDay() == #defaultDays + 1) then
  9751.                     nexus.time.day = 1;
  9752.                 end;
  9753.                
  9754.                 if (nexus.date.GetDay() == 31) then
  9755.                     nexus.date.day = 1;
  9756.                     nexus.date.month = nexus.date.GetMonth() + 1;
  9757.                    
  9758.                     if (nexus.date.GetMonth() == 13) then
  9759.                         nexus.date.month = 1;
  9760.                         nexus.date.year = nexus.date.GetYear() + 1;
  9761.                     end;
  9762.                 end;
  9763.             end;
  9764.         end;
  9765.        
  9766.         if (nexus.time.GetMinute() != minute) then
  9767.             nexus.mount.Call("TimePassed", TIME_MINUTE);
  9768.         end;
  9769.        
  9770.         if (nexus.time.GetHour() != hour) then
  9771.             nexus.mount.Call("TimePassed", TIME_HOUR);
  9772.         end;
  9773.        
  9774.         if (nexus.time.GetDay() != day) then
  9775.             nexus.mount.Call("TimePassed", TIME_DAY);
  9776.         end;
  9777.        
  9778.         if (nexus.date.GetMonth() != month) then
  9779.             nexus.mount.Call("TimePassed", TIME_MONTH);
  9780.         end;
  9781.        
  9782.         if (nexus.date.GetYear() != year) then
  9783.             nexus.mount.Call("TimePassed", TIME_YEAR);
  9784.         end;
  9785.        
  9786.         local month = self:ZeroNumberToDigits(nexus.date.GetMonth(), 2);
  9787.         local day = self:ZeroNumberToDigits(nexus.date.GetDay(), 2);
  9788.        
  9789.         self:SetSharedVar( "sh_Minute", nexus.time.GetMinute() );
  9790.         self:SetSharedVar( "sh_Hour", nexus.time.GetHour() );
  9791.         self:SetSharedVar( "sh_Date", day.."/"..month.."/"..nexus.date.GetYear() );
  9792.         self:SetSharedVar( "sh_Day", nexus.time.GetDay() );
  9793.     end;
  9794.    
  9795.     -- A function to create a ConVar.
  9796.     function NEXUS:CreateConVar(name, value, flags, Callback)
  9797.         local conVar = CreateConVar(name, value, flags or FCVAR_REPLICATED + FCVAR_NOTIFY + FCVAR_ARCHIVE);
  9798.        
  9799.         cvars.AddChangeCallback(name, function(conVar, previousValue, newValue)
  9800.             nexus.mount.Call("NexusConVarChanged", conVar, previousValue, newValue);
  9801.            
  9802.             if (Callback) then
  9803.                 Callback(conVar, previousValue, newValue);
  9804.             end;
  9805.         end);
  9806.        
  9807.         return conVar;
  9808.     end;
  9809.    
  9810.     -- A function to check if the server is shutting down.
  9811.     function NEXUS:IsShuttingDown()
  9812.         return self.ShuttingDown;
  9813.     end;
  9814.    
  9815.     -- A function to distribute wages cash.
  9816.     function NEXUS:DistributeWagesCash()
  9817.         for k, v in ipairs( g_Player.GetAll() ) do
  9818.             if ( v:HasInitialized() and v:Alive() ) then
  9819.                 local wages = v:GetWages();
  9820.                
  9821.                 if ( nexus.mount.Call("PlayerCanEarnWagesCash", v, wages) ) then
  9822.                     if (wages > 0) then
  9823.                         if ( nexus.mount.Call("PlayerGiveWagesCash", v, wages, v:GetWagesName() ) ) then
  9824.                             nexus.player.GiveCash( v, wages, v:GetWagesName() );
  9825.                         end;
  9826.                     end;
  9827.                    
  9828.                     nexus.mount.Call("PlayerEarnWagesCash", v, wages);
  9829.                 end;
  9830.             end;
  9831.         end;
  9832.     end;
  9833.    
  9834.     -- A function to distribute generator cash.
  9835.     function NEXUS:DistributeGeneratorCash()
  9836.         local generatorEntities = {};
  9837.        
  9838.         for k, v in pairs(nexus.generator.stored) do
  9839.             table.Add( generatorEntities, ents.FindByClass(k) );
  9840.         end;
  9841.        
  9842.         for k, v in pairs(generatorEntities) do
  9843.             local generator = nexus.generator.Get( v:GetClass() );
  9844.             local player = v:GetPlayer();
  9845.            
  9846.             if ( IsValid(player) ) then
  9847.                 if (v:GetPower() != 0) then
  9848.                     local info = {
  9849.                         generator = generator,
  9850.                         entity = v,
  9851.                         cash = generator.cash,
  9852.                         name = "Generator"
  9853.                     };
  9854.                    
  9855.                     v:SetSharedVar( "sh_Power", math.max(v:GetPower() - 1, 0) );
  9856.                    
  9857.                     nexus.mount.Call("PlayerAdjustEarnGeneratorInfo", player, info);
  9858.                    
  9859.                     if ( nexus.mount.Call("PlayerCanEarnGeneratorCash", player, info, info.cash) ) then
  9860.                         if (v.OnEarned) then
  9861.                             local result = v:OnEarned(player, info.cash);
  9862.                            
  9863.                             if (type(result) == "number") then
  9864.                                 info.cash = result;
  9865.                             end;
  9866.                            
  9867.                             if (result != false) then
  9868.                                 if (result != true) then
  9869.                                     nexus.player.GiveCash(k, info.cash, info.name);
  9870.                                 end;
  9871.                                
  9872.                                 nexus.mount.Call("PlayerEarnGeneratorCash", player, info, info.cash);
  9873.                             end;
  9874.                         else
  9875.                             nexus.player.GiveCash(k, info.cash, info.name);
  9876.                            
  9877.                             nexus.mount.Call("PlayerEarnGeneratorCash", player, info, info.cash);
  9878.                         end;
  9879.                     end;
  9880.                 end;
  9881.             end;
  9882.         end;
  9883.     end;
  9884.    
  9885.     -- A function to include the schema.
  9886.     function NEXUS:IncludeSchema()
  9887.         local schemaFolder = self:GetSchemaFolder();
  9888.        
  9889.         if (schemaFolder and type(schemaFolder) == "string") then
  9890.             nexus.config.Load(nil, true);
  9891.                 nexus.mount.Include(schemaFolder.."/gamemode/schema", true);
  9892.             nexus.config.Load();
  9893.         end;
  9894.     end;
  9895.    
  9896.     -- A function to print a debug message.
  9897.     function NEXUS:PrintDebug(text, private)
  9898.         if (NX_CONVAR_DEBUG:GetInt() == 1) then
  9899.             local listeners = {};
  9900.            
  9901.             for k, v in ipairs( g_Player.GetAll() ) do
  9902.                 if (v:HasInitialized() and v:GetInfoNum("nx_showlog", 0) == 1) then
  9903.                     if ( nexus.player.IsAdmin(v) ) then
  9904.                         listeners[#listeners + 1] = v;
  9905.                     end;
  9906.                 end;
  9907.             end;
  9908.            
  9909.             local info = {
  9910.                 text = text,
  9911.                 private = private,
  9912.                 listeners = listeners
  9913.             };
  9914.            
  9915.             nexus.mount.Call("DebugAdjustInfo", info);
  9916.            
  9917.             for k, v in pairs(listeners) do
  9918.                 if ( info.private or !v:IsListenServerHost() ) then
  9919.                     v:PrintMessage(2, info.text);
  9920.                 end;
  9921.             end;
  9922.            
  9923.             if (!info.private) then
  9924.                 NEXUS:Log(info.text);
  9925.             end;
  9926.         end;
  9927.     end;
  9928.    
  9929.     -- A function to log an action.
  9930.     function NEXUS:Log(action)
  9931.         if (NX_CONVAR_LOG:GetInt() == 1) then
  9932.             ServerLog(action.."\n");
  9933.            
  9934.             print(action);
  9935.         end;
  9936.     end;
  9937. else
  9938.     NEXUS.ProgressBarColor = Color(50, 100, 150, 200);
  9939.     NEXUS.TargetPlayerText = { text = {} };
  9940.     NEXUS.BackgroundBlurs = {};
  9941.     NEXUS.RecognisedNames = {};
  9942.     NEXUS.PlayerInfoText = { text = {}, width = 0, subText = {} };
  9943.     NEXUS.ColorModify = {};
  9944.     NEXUS.Cinematics = {};
  9945.     NEXUS.MenuItems = { items = {} };
  9946.     NEXUS.ESPInfo = {};
  9947.     NEXUS.Hints = {};
  9948.     NEXUS.Bars = { x = 0, y = 0, width = 0, height = 0, bars = {} };
  9949.  
  9950.     -- A function to get some a menu item.
  9951.     function NEXUS.MenuItems:Get(text)
  9952.         for k, v in pairs(self.items) do
  9953.             if (v.text == text) then
  9954.                 return v;
  9955.             end;
  9956.         end;
  9957.     end;
  9958.    
  9959.     -- A function to add a menu item.
  9960.     function NEXUS.MenuItems:Add(text, panel, tip)
  9961.         self.items[#self.items + 1] = {text = text, panel = panel, tip = tip};
  9962.     end;
  9963.  
  9964.     -- A function to destroy a menu item.
  9965.     function NEXUS.MenuItems:Destroy(text)
  9966.         for k, v in pairs(self.items) do
  9967.             if (v.text == text) then
  9968.                 table.remove(self.items, k);
  9969.             end;
  9970.         end;
  9971.     end;
  9972.    
  9973.     -- A function to add some target player text.
  9974.     function NEXUS.TargetPlayerText:Add(uniqueID, text, color)
  9975.         self.text[#self.text + 1] = {
  9976.             uniqueID = uniqueID,
  9977.             color = color,
  9978.             text = text
  9979.         };
  9980.     end;
  9981.    
  9982.     -- A function to get some target player text.
  9983.     function NEXUS.TargetPlayerText:Get(uniqueID)
  9984.         for k, v in pairs(self.text) do
  9985.             if (v.uniqueID == uniqueID) then
  9986.                 return v;
  9987.             end;
  9988.         end;
  9989.     end;
  9990.  
  9991.     -- A function to destroy some target player text.
  9992.     function NEXUS.TargetPlayerText:Destroy(uniqueID)
  9993.         for k, v in pairs(self.text) do
  9994.             if (v.uniqueID == uniqueID) then
  9995.                 table.remove(self.text, k);
  9996.             end;
  9997.         end;
  9998.     end;
  9999.    
  10000.     -- A function to get whether any player info text exists.
  10001.     function NEXUS.PlayerInfoText:DoesAnyExist()
  10002.         return (#self.text > 0 or #self.subText > 0);
  10003.     end;
  10004.  
  10005.     -- A function to add some player info text.
  10006.     function NEXUS.PlayerInfoText:Add(uniqueID, text)
  10007.         if (text) then
  10008.             self.text[#self.text + 1] = {
  10009.                 uniqueID = uniqueID,
  10010.                 text = text
  10011.             };
  10012.         end;
  10013.     end;
  10014.    
  10015.     -- A function to get some player info text.
  10016.     function NEXUS.PlayerInfoText:Get(uniqueID)
  10017.        
  10018.         for k, v in pairs(self.text) do
  10019.             if (v.uniqueID == uniqueID) then
  10020.                 return v;
  10021.             end;
  10022.         end;
  10023.     end;
  10024.  
  10025.     -- A function to add some sub player info text.
  10026.     function NEXUS.PlayerInfoText:AddSub(uniqueID, text, priority)
  10027.         if (text) then
  10028.             self.subText[#self.subText + 1] = {
  10029.                 priority = priority or 0,
  10030.                 uniqueID = uniqueID,
  10031.                 text = text
  10032.             };
  10033.         end;
  10034.     end;
  10035.    
  10036.     -- A function to get some sub player info text.
  10037.     function NEXUS.PlayerInfoText:GetSub(uniqueID)
  10038.        
  10039.         for k, v in pairs(self.subText) do
  10040.             if (v.uniqueID == uniqueID) then
  10041.                 return v;
  10042.             end;
  10043.         end;
  10044.     end;
  10045.  
  10046.     -- A function to destroy some player info text.
  10047.     function NEXUS.PlayerInfoText:Destroy(uniqueID)
  10048.        
  10049.         for k, v in pairs(self.text) do
  10050.             if (v.uniqueID == uniqueID) then
  10051.                 table.remove(self.text, k);
  10052.             end;
  10053.         end;
  10054.     end;
  10055.  
  10056.     -- A function to destroy some sub player info text.
  10057.     function NEXUS.PlayerInfoText:DestroySub(uniqueID)
  10058.        
  10059.         for k, v in pairs(self.subText) do
  10060.             if (v.uniqueID == uniqueID) then
  10061.                 table.remove(self.subText, k);
  10062.             end;
  10063.         end;
  10064.     end;
  10065.  
  10066.     -- A function to get a top bar.
  10067.     function NEXUS.Bars:Get(uniqueID)
  10068.         for k, v in pairs(self.bars) do
  10069.             if (v.uniqueID == uniqueID) then return v; end;
  10070.         end;
  10071.     end;
  10072.    
  10073.     -- A function to add a top bar.
  10074.     function NEXUS.Bars:Add(uniqueID, color, text, value, maximum, flash, priority)
  10075.         self.bars[#self.bars + 1] = {
  10076.             uniqueID = uniqueID,
  10077.             priority = priority or 0,
  10078.             maximum = maximum,
  10079.             color = color,
  10080.             class = class,
  10081.             value = value,
  10082.             flash = flash,
  10083.             text = text,
  10084.         };
  10085.     end;
  10086.  
  10087.     -- A function to destroy a top bar.
  10088.     function NEXUS.Bars:Destroy(uniqueID)
  10089.         for k, v in pairs(self.bars) do
  10090.             if (v.uniqueID == uniqueID) then
  10091.                 table.remove(self.bars, k);
  10092.             end;
  10093.         end;
  10094.     end;
  10095.    
  10096.     -- A function to create a client ConVar.
  10097.     function NEXUS:CreateClientConVar(name, value, save, userData, Callback)
  10098.         local conVar = CreateClientConVar(name, value, save, userData);
  10099.        
  10100.         cvars.AddChangeCallback(name, function(conVar, previousValue, newValue)
  10101.             nexus.mount.Call("NexusConVarChanged", conVar, previousValue, newValue);
  10102.            
  10103.             if (Callback) then
  10104.                 Callback(conVar, previousValue, newValue);
  10105.             end;
  10106.         end);
  10107.        
  10108.         return conVar;
  10109.     end;
  10110.    
  10111.     -- A function to get the size of text.
  10112.     function NEXUS:GetTextSize(font, text)
  10113.         local defaultWidth, defaultHeight = self:GetCachedTextSize(font, "U");
  10114.         local height = defaultHeight;
  10115.         local width = 0;
  10116.        
  10117.         for i = 1, string.len(text) do
  10118.             local textWidth, textHeight = self:GetCachedTextSize( font, string.sub(text, i, i) );
  10119.            
  10120.             if (textWidth == 0) then
  10121.                 textWidth = defaultWidth;
  10122.             end;
  10123.            
  10124.             if (textHeight > height) then
  10125.                 height = textHeight;
  10126.             end;
  10127.            
  10128.             width = width + textWidth;
  10129.         end;
  10130.        
  10131.         return width, height;
  10132.     end;
  10133.    
  10134.     -- A function to calculate alpha from a distance.
  10135.     function NEXUS:CalculateAlphaFromDistance(maximum, start, finish)
  10136.         if (type(start) == "Player") then
  10137.             start = start:GetShootPos();
  10138.         elseif (type(start) == "Entity") then
  10139.             start = start:GetPos();
  10140.         end;
  10141.        
  10142.         if (type(finish) == "Player") then
  10143.             finish = finish:GetShootPos();
  10144.         elseif (type(finish) == "Entity") then
  10145.             finish = finish:GetPos();
  10146.         end;
  10147.        
  10148.         return math.Clamp(255 - ( (255 / maximum) * ( start:Distance(finish) ) ), 0, 255);
  10149.     end;
  10150.    
  10151.     -- A function to wrap text into a table.
  10152.     function NEXUS:WrapText(text, font, width, baseTable)
  10153.         if (width <= 0 or !text or text == "") then
  10154.             return;
  10155.         end;
  10156.        
  10157.         if (self:GetTextSize(font, text) > width) then
  10158.             local length = 0;
  10159.             local exploded = {};
  10160.             local seperator = "";
  10161.            
  10162.             if ( string.find(text, " ") ) then 
  10163.                 exploded = NEXUS:ExplodeString(" ", text);
  10164.                 seperator = " ";
  10165.             else
  10166.                 exploded = string.ToTable(text);
  10167.                 seperator = "";
  10168.             end;
  10169.            
  10170.             local i = 1;
  10171.            
  10172.             while (length < width) do
  10173.                 if ( !exploded[i] ) then
  10174.                     break;
  10175.                 end;
  10176.                
  10177.                 length = self:GetTextSize( font, table.concat(exploded, seperator, 1, i) );
  10178.                
  10179.                 i = i + 1;
  10180.             end;
  10181.            
  10182.             baseTable[#baseTable + 1] = table.concat(exploded, seperator, 1, i - 2);
  10183.            
  10184.             text = table.concat(exploded, seperator, i - 1);
  10185.            
  10186.             if (self:GetTextSize(font, text) > width) then
  10187.                 self:WrapText(text, font, width, baseTable);
  10188.             else
  10189.                 baseTable[#baseTable + 1] = text;
  10190.             end;
  10191.         else
  10192.             baseTable[#baseTable + 1] = text;
  10193.         end;
  10194.     end;
  10195.    
  10196.     -- A function to handle an entity's menu.
  10197.     function NEXUS:HandleEntityMenu(entity)
  10198.         local options = {};
  10199.         local menu = nil;
  10200.        
  10201.         nexus.mount.Call("GetEntityMenuOptions", entity, options);
  10202.        
  10203.         if (table.Count(options) > 0) then
  10204.             menu = NEXUS:AddMenuFromData(nil, options, function(menu, option, arguments)
  10205.                 menu:AddOption(option, function()
  10206.                     if (type(arguments) == "table" and arguments.arguments) then
  10207.                         if (!arguments.Callback) then
  10208.                             nexus.entity.ForceMenuOption(entity, option, arguments.uniqueID);
  10209.                         else
  10210.                             arguments.Callback(entity);
  10211.                         end;
  10212.                     else
  10213.                         nexus.entity.ForceMenuOption(entity, option, arguments);
  10214.                     end;
  10215.                    
  10216.                     timer.Simple(FrameTime(), function()
  10217.                         self:RemoveActiveToolTip();
  10218.                     end);
  10219.                 end);
  10220.                
  10221.                 local panel = menu.Panels[#menu.Panels];
  10222.                
  10223.                 if ( IsValid(panel) ) then
  10224.                     if (type(arguments) == "table") then
  10225.                         if (arguments.order) then
  10226.                             menu.Panels[#menu.Panels] = nil;
  10227.                            
  10228.                             table.insert(menu.Panels, 1, panel);
  10229.                         end;
  10230.                        
  10231.                         if (arguments.toolTip) then
  10232.                             panel:SetToolTip(arguments.toolTip);
  10233.                         end;
  10234.                     end;
  10235.                 end;
  10236.             end);
  10237.            
  10238.             return menu;
  10239.         end;
  10240.     end;
  10241.    
  10242.     -- A function to get the gradient texture.
  10243.     function NEXUS:GetGradientTexture()
  10244.         return self.GradientTexture;
  10245.     end;
  10246.    
  10247.     -- A function to add a menu from data.
  10248.     function NEXUS:AddMenuFromData(menu, data, Callback)
  10249.         local options = {};
  10250.         local created;
  10251.        
  10252.         if (!menu) then
  10253.             created = true; menu = DermaMenu();
  10254.         end;
  10255.        
  10256.         for k, v in pairs(data) do
  10257.             options[#options + 1] = {k, v};
  10258.         end;
  10259.        
  10260.         table.sort(options, function(a, b)
  10261.             return a[1] < b[1];
  10262.         end);
  10263.        
  10264.         for k, v in pairs(options) do
  10265.             if (type( v[2] ) == "table" and !v[2].arguments) then
  10266.                 if (table.Count( v[2] ) > 0) then
  10267.                     self:AddMenuFromData(menu:AddSubMenu( v[1] ), v[2], Callback);
  10268.                 end;
  10269.             elseif (type( v[2] ) == "function") then
  10270.                 menu:AddOption( v[1], v[2] );
  10271.             elseif (Callback) then
  10272.                 Callback( menu, v[1], v[2] );
  10273.             end;
  10274.         end;
  10275.        
  10276.         if (created) then
  10277.             if (#options > 0) then
  10278.                 menu:Open();
  10279.             else
  10280.                 menu:Remove();
  10281.             end;
  10282.            
  10283.             return menu;
  10284.         end;
  10285.     end;
  10286.    
  10287.     -- A function to adjust the width of text.
  10288.     function NEXUS:AdjustMaximumWidth(font, text, width, addition, extra)
  10289.         local textString = tostring( string.Replace(text, "&", "U") );
  10290.         local textWidth = self:GetCachedTextSize(font, textString) + (extra or 0);
  10291.        
  10292.         if (textWidth > width) then
  10293.             width = textWidth + (addition or 0);
  10294.         end;
  10295.        
  10296.         return width;
  10297.     end;
  10298.    
  10299.     -- A function to add a top hint.
  10300.     function NEXUS:AddTopHint(text, delay, color, noSound)
  10301.         local colorWhite = nexus.schema.GetColor("white");
  10302.        
  10303.         for k, v in ipairs(self.Hints) do
  10304.             if (v.text == text) then
  10305.                 return;
  10306.             end;
  10307.         end;
  10308.        
  10309.         if (table.Count(self.Hints) == 10) then
  10310.             table.remove(self.Hints, 10);
  10311.         end;
  10312.        
  10313.         if (!noSound) then
  10314.             surface.PlaySound("ui/buttonrollover.wav");
  10315.         end;
  10316.        
  10317.         table.insert( self.Hints, 1, {
  10318.             targetAlpha = 255,
  10319.             alphaSpeed = 64,
  10320.             color = color or colorWhite,
  10321.             delay = delay,
  10322.             alpha = 0,
  10323.             text = text
  10324.         } );
  10325.     end;
  10326.    
  10327.     -- A function to calculate the top hints.
  10328.     function NEXUS:CalculateHints()
  10329.         local frameTime = FrameTime();
  10330.         local curTime = UnPredictedCurTime();
  10331.        
  10332.         for k, v in pairs(self.Hints) do
  10333.             if (!v.nextChangeTarget or curTime >= v.nextChangeTarget) then
  10334.                 v.alpha = math.Approach(v.alpha, v.targetAlpha, v.alphaSpeed * frameTime);
  10335.                
  10336.                 if (v.alpha == v.targetAlpha) then
  10337.                     if (v.targetAlpha == 0) then
  10338.                         table.remove(self.Hints, k);
  10339.                     else
  10340.                         v.nextChangeTarget = curTime + v.delay;
  10341.                         v.targetAlpha = 0;
  10342.                         v.alphaSpeed = 16;
  10343.                     end;
  10344.                 end;
  10345.             end;
  10346.         end;
  10347.     end;
  10348.    
  10349.     -- A function to draw the date and time.
  10350.     function NEXUS:DrawDateTime()
  10351.         local colorWhite = nexus.schema.GetColor("white");
  10352.         local info = {
  10353.             width = ScrW() * 0.1,
  10354.             x = 8,
  10355.             y = 8
  10356.         };
  10357.        
  10358.         if ( nexus.mount.Call("PlayerCanSeeDateTime") ) then
  10359.             local dateTimeFont = nexus.schema.GetFont("date_time_text");
  10360.             local dateString = nexus.date.GetString();
  10361.             local timeString = nexus.time.GetString();
  10362.             local dayName = nexus.time.GetDayName();
  10363.             local text = string.upper(dateString..". "..dayName..", "..timeString..".");
  10364.            
  10365.             self:OverrideMainFont(dateTimeFont);
  10366.                 info.y = self:DrawInfo(text, info.x, info.y, colorWhite, 255, true);
  10367.             self:OverrideMainFont(false);
  10368.            
  10369.             local textWidth, textHeight = NEXUS:GetCachedTextSize(dateTimeFont, text);
  10370.            
  10371.             if (textWidth and textHeight) then
  10372.                 info.width = textWidth;
  10373.             end;
  10374.         end;
  10375.        
  10376.         self:DrawBars(info);
  10377.             nexus.mount.Call("NexusDateTimeDrawn", info);
  10378.     end;
  10379.  
  10380.     -- A function to draw the top hints.
  10381.     function NEXUS:DrawHints()
  10382.         local x = ScrW();
  10383.         local y = 8;
  10384.        
  10385.         if ( nexus.mount.Call("PlayerCanSeeHints") ) then
  10386.             for k, v in pairs(self.Hints) do
  10387.                 self:OverrideMainFont( nexus.schema.GetFont("hints_text") );
  10388.                     y = self:DrawInfo(string.upper(v.text), x, y, v.color, v.alpha, true, function(x, y, width, height)
  10389.                         return x - width - 8, y;
  10390.                     end);
  10391.                 self:OverrideMainFont(false);
  10392.             end;
  10393.         end;
  10394.     end;
  10395.  
  10396.     -- A function to draw the top bars.
  10397.     function NEXUS:DrawBars(info)
  10398.         local barTextFont = nexus.schema.GetFont("bar_text");
  10399.        
  10400.         self.Bars.width = info.width;
  10401.         self.Bars.height = 12;
  10402.         self.Bars.x = info.x;
  10403.         self.Bars.y = info.y;
  10404.        
  10405.         nexus.schema.SetFont( "bar_text", nexus.schema.GetFont("auto_bar_text") );
  10406.             if ( nexus.mount.Call("PlayerCanSeeBars") ) then
  10407.                 for k, v in ipairs(self.Bars.bars) do
  10408.                     self.Bars.y = self:DrawBar(self.Bars.x, self.Bars.y, self.Bars.width, self.Bars.height, v.color, v.text, v.value, v.maximum, v.flash) + (self.Bars.height + 2);
  10409.                 end;
  10410.             end;
  10411.         nexus.schema.SetFont("bar_text", barTextFont);
  10412.        
  10413.         info.y = self.Bars.y;
  10414.     end;
  10415.    
  10416.     -- A function to get the ESP info.
  10417.     function NEXUS:GetESPInfo()
  10418.         return self.ESPInfo;
  10419.     end;
  10420.    
  10421.     -- A function to draw the admin ESP.
  10422.     function NEXUS:DrawAdminESP()
  10423.         local colorWhite = nexus.schema.GetColor("white");
  10424.         local curTime = UnPredictedCurTime();
  10425.        
  10426.         if (!self.NextGetESPInfo) then
  10427.             self.NextGetESPInfo = curTime + 1;
  10428.         end;
  10429.        
  10430.         if (curTime >= self.NextGetESPInfo) then
  10431.             self.NextGetESPInfo = curTime + 1;
  10432.             self.ESPInfo = {};
  10433.            
  10434.             nexus.mount.Call("GetAdminESPInfo", self.ESPInfo);
  10435.         end;
  10436.        
  10437.         for k, v in pairs(self.ESPInfo) do
  10438.             local position = v.position:ToScreen();
  10439.            
  10440.             if (position) then
  10441.                 self:DrawSimpleText(v.text, position.x, position.y, v.color or colorWhite, 1, 1);
  10442.             end;
  10443.         end;
  10444.     end;
  10445.  
  10446.     -- A function to draw a bar with a value and a maximum.
  10447.     function NEXUS:DrawBar(x, y, width, height, color, text, value, maximum, flash, barInfo)
  10448.         local backgroundColor = nexus.schema.GetColor("background");
  10449.         local progressWidth = math.Clamp( ( (width - 2) / maximum ) * value, 0, width - 2 );
  10450.         local colorWhite = nexus.schema.GetColor("white");
  10451.         local newBarInfo = {
  10452.             progressWidth = progressWidth,
  10453.             drawBackground = true,
  10454.             drawGradient = true,
  10455.             drawProgress = true,
  10456.             cornerSize = 4,
  10457.             maximum = maximum,
  10458.             height = height,
  10459.             width = width,
  10460.             color = color,
  10461.             value = value,
  10462.             flash = flash,
  10463.             text = text,
  10464.             x = x,
  10465.             y = y
  10466.         };
  10467.        
  10468.         if (barInfo) then
  10469.             for k, v in pairs(newBarInfo) do
  10470.                 if ( !barInfo[k] ) then
  10471.                     barInfo[k] = v;
  10472.                 end;
  10473.             end;
  10474.         else
  10475.             barInfo = newBarInfo;
  10476.         end;
  10477.        
  10478.         if ( !nexus.mount.Call("PreDrawBar", barInfo) ) then
  10479.             if (barInfo.drawBackground) then
  10480.                 draw.RoundedBox(barInfo.cornerSize, barInfo.x, barInfo.y, barInfo.width, barInfo.height, backgroundColor);
  10481.             end;
  10482.            
  10483.             if (barInfo.drawProgress) then
  10484.                 draw.RoundedBox(0, barInfo.x + 1, barInfo.y + 1, barInfo.progressWidth, barInfo.height - 2, barInfo.color);
  10485.             end;
  10486.            
  10487.             if (barInfo.flash) then
  10488.                 local alpha = math.Clamp(math.abs(math.sin( UnPredictedCurTime() ) * 50), 0, 50);
  10489.                
  10490.                 if (alpha > 0) then
  10491.                     draw.RoundedBox( 0, barInfo.x + 2, barInfo.y + 2, barInfo.width - 4, barInfo.height - 4, Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha) );
  10492.                 end;
  10493.             end;
  10494.         end;
  10495.        
  10496.         if ( !nexus.mount.Call("PostDrawBar", barInfo) ) then
  10497.             if (barInfo.text and barInfo.text != "") then
  10498.                 self:OverrideMainFont( nexus.schema.GetFont("bar_text") );
  10499.                     self:DrawSimpleText(barInfo.text, barInfo.x + (barInfo.width / 2), barInfo.y + (barInfo.height / 2), Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha), 1, 1);
  10500.                 self:OverrideMainFont(false);
  10501.             end;
  10502.         end;
  10503.        
  10504.         if (barInfo.drawGradient) then
  10505.             surface.SetDrawColor(100, 100, 100, 100);
  10506.             surface.SetTexture( self:GetGradientTexture() );
  10507.             surface.DrawTexturedRect(barInfo.x + 2, barInfo.y + 2, barInfo.width - 4, barInfo.height - 4);
  10508.         end;
  10509.        
  10510.         return barInfo.y;
  10511.     end;
  10512.    
  10513.     -- A function to set the recognise menu.
  10514.     function NEXUS:SetRecogniseMenu(menu)
  10515.         self.RecogniseMenu = menu;
  10516.     end;
  10517.    
  10518.     -- A function to get the recognise menu.
  10519.     function NEXUS:GetRecogniseMenu(menu)
  10520.         return self.RecogniseMenu;
  10521.     end;
  10522.    
  10523.     -- A function to override the main font.
  10524.     function NEXUS:OverrideMainFont(font)
  10525.         if (font) then
  10526.             if (!self.PreviousMainFont) then
  10527.                 self.PreviousMainFont = nexus.schema.GetFont("main_text");
  10528.             end;
  10529.            
  10530.             nexus.schema.SetFont("main_text", font);
  10531.         elseif (self.PreviousMainFont) then
  10532.             nexus.schema.SetFont("main_text", self.PreviousMainFont)
  10533.         end;
  10534.     end;
  10535.  
  10536.     -- A function to get the screen's center.
  10537.     function NEXUS:GetScreenCenter()
  10538.         return ScrW() / 2, (ScrH() / 2) + 32;
  10539.     end;
  10540.    
  10541.     -- A function to draw some simple text.
  10542.     function NEXUS:DrawSimpleText(text, x, y, color, alignX, alignY, shadowless, shadowDepth)
  10543.         local mainTextFont = nexus.schema.GetFont("main_text");
  10544.         local realX = math.Round(x);
  10545.         local realY = math.Round(y);
  10546.        
  10547.         if (!shadowless) then
  10548.             local outlineColor = Color( 25, 25, 25, math.min(225, color.a) );
  10549.             local depth = shadowDepth or 1;
  10550.            
  10551.             draw.SimpleText(text, mainTextFont, realX + -depth, realY + -depth, outlineColor, alignX, alignY);
  10552.             draw.SimpleText(text, mainTextFont, realX + -depth, realY + depth, outlineColor, alignX, alignY);
  10553.             draw.SimpleText(text, mainTextFont, realX + depth, realY + -depth, outlineColor, alignX, alignY);
  10554.             draw.SimpleText(text, mainTextFont, realX + depth, realY + depth, outlineColor, alignX, alignY);
  10555.         end;
  10556.        
  10557.         local width, height = draw.SimpleText(text, mainTextFont, realX, realY, color, alignX, alignY);
  10558.        
  10559.         if (width and height) then
  10560.             if (height == 0) then
  10561.                 height = draw.GetFontHeight(mainTextFont);
  10562.             end;
  10563.            
  10564.             return realY + height + 2;
  10565.         else
  10566.             return realY;
  10567.         end;
  10568.     end;
  10569.    
  10570.     -- A function to get the black fade alpha.
  10571.     function NEXUS:GetBlackFadeAlpha()
  10572.         return self.BlackFadeIn or self.BlackFadeOut or 0;
  10573.     end;
  10574.    
  10575.     -- A function to get whether the screen is faded black.
  10576.     function NEXUS:IsScreenFadedBlack()
  10577.         return (self.BlackFadeIn == 255);
  10578.     end;
  10579.    
  10580.     -- A function to get a cached text size.
  10581.     function NEXUS:GetCachedTextSize(font, text)
  10582.         if (!self.CachedTextSizes) then
  10583.             self.CachedTextSizes = {};
  10584.         end;
  10585.        
  10586.         if ( !self.CachedTextSizes[font] ) then
  10587.             self.CachedTextSizes[font] = {};
  10588.         end;
  10589.        
  10590.         if ( !self.CachedTextSizes[font][text] ) then
  10591.             surface.SetFont(font);
  10592.            
  10593.             self.CachedTextSizes[font][text] = { surface.GetTextSize(text) };
  10594.         end;
  10595.        
  10596.         return unpack( self.CachedTextSizes[font][text] );
  10597.     end;
  10598.    
  10599.     -- A function to draw information at a position.
  10600.     function NEXUS:DrawInfo(text, x, y, color, alpha, alignLeft, Callback, shadowDepth)
  10601.         local mainTextFont = nexus.schema.GetFont("main_text");
  10602.         local width, height = self:GetCachedTextSize(mainTextFont, text);
  10603.        
  10604.         if (width and height) then
  10605.             if (!alignLeft) then
  10606.                 x = x - (width / 2);
  10607.             end;
  10608.            
  10609.             if (Callback) then
  10610.                 x, y = Callback(x, y, width, height);
  10611.             end;
  10612.        
  10613.             return self:DrawSimpleText(text, x, y, Color(color.r, color.g, color.b, alpha or color.a), nil, nil, nil, shadowDepth);
  10614.         end;
  10615.     end;
  10616.    
  10617.     -- A function to get the player info box.
  10618.     function NEXUS:GetPlayerInfoBox()
  10619.         return self.PlayerInfoBox;
  10620.     end;
  10621.  
  10622.     -- A function to draw the local player's information.
  10623.     function NEXUS:DrawPlayerInfo()
  10624.         if ( nexus.mount.Call("PlayerCanSeePlayerInfo") ) then
  10625.             local backgroundColor = nexus.schema.GetColor("background");
  10626.             local subInformation = self.PlayerInfoText.subText;
  10627.             local information = self.PlayerInfoText.text;
  10628.             local colorWhite = nexus.schema.GetColor("white");
  10629.             local textWidth, textHeight = self:GetCachedTextSize(nexus.schema.GetFont("player_info_text"), "U");
  10630.             local width = self.PlayerInfoText.width;
  10631.            
  10632.             if (#information > 0 or #subInformation > 0) then
  10633.                 local height = (textHeight * #information) + ( (textHeight + 4) * #subInformation );
  10634.                 local scrW = ScrW();
  10635.                 local scrH = ScrH();
  10636.                
  10637.                 if (#information > 0) then
  10638.                     height = height + 8;
  10639.                 end;
  10640.                
  10641.                 local y = scrH - height - (scrH * 0.025);
  10642.                 local x = scrW * 0.025;
  10643.                
  10644.                 local boxInfo = {
  10645.                     subInformation = subInformation,
  10646.                     drawBackground = true,
  10647.                     drawGradient = true,
  10648.                     information = information,
  10649.                     textHeight = textHeight,
  10650.                     cornerSize = 4,
  10651.                     textWidth = textWidth,
  10652.                     height = height,
  10653.                     width = width,
  10654.                     x = x,
  10655.                     y = y
  10656.                 };
  10657.                
  10658.                 if ( !nexus.mount.Call("PreDrawPlayerInfo", boxInfo, information, subInformation) ) then
  10659.                     self:OverrideMainFont( nexus.schema.GetFont("player_info_text") );
  10660.                         for k, v in ipairs(subInformation) do
  10661.                             x, y = self:DrawPlayerInfoSubBox(v.text, x, y, width, boxInfo);
  10662.                         end;
  10663.                        
  10664.                         if (#information > 0) then
  10665.                             if (boxInfo.drawBackground) then
  10666.                                 draw.RoundedBox(boxInfo.cornerSize, x, y, width, height - ( (textHeight + 4) * #subInformation ), backgroundColor);
  10667.                             end;
  10668.                         end;
  10669.                        
  10670.                         if (#information > 0) then
  10671.                             x = x + 8
  10672.                             y = y + 4;
  10673.                         end;
  10674.                            
  10675.                         for k, v in ipairs(information) do
  10676.                             self:DrawInfo(v.text, x, y - 1, colorWhite, 255, true);
  10677.                            
  10678.                             y = y + textHeight;
  10679.                         end;
  10680.                     self:OverrideMainFont(false);
  10681.                 end;
  10682.                
  10683.                 nexus.mount.Call("PostDrawPlayerInfo", boxInfo, information, subInformation);
  10684.                
  10685.                 if (boxInfo.drawGradient) then
  10686.                     surface.SetDrawColor(255, 255, 255, 5);
  10687.                     surface.SetTexture( self:GetGradientTexture() );
  10688.                     surface.DrawTexturedRect(boxInfo.x + 2, boxInfo.y + 2, boxInfo.width - 4, boxInfo.height - 4);
  10689.                 end;
  10690.                
  10691.                 return boxInfo;
  10692.             end;
  10693.         end;
  10694.     end;
  10695.    
  10696.     -- A function to get the ragdoll eye angles.
  10697.     function NEXUS:GetRagdollEyeAngles()
  10698.         if (!self.RagdollEyeAngles) then
  10699.             self.RagdollEyeAngles = Angle(0, 0, 0);
  10700.         end;
  10701.        
  10702.         return self.RagdollEyeAngles;
  10703.     end;
  10704.    
  10705.     -- A function to draw a rounded gradient.
  10706.     function NEXUS:DrawRoundedGradient(cornerSize, x, y, width, height, color)
  10707.         local gradientAlpha = math.min(color.a, 100);
  10708.        
  10709.         draw.RoundedBox(cornerSize, x, y, width, height, color);
  10710.        
  10711.         if (x + 2 < x + width and y + 2 < y + height) then
  10712.             surface.SetDrawColor(gradientAlpha, gradientAlpha, gradientAlpha, gradientAlpha);
  10713.             surface.SetTexture( self:GetGradientTexture() );
  10714.             surface.DrawTexturedRect(x + 2, y + 2, width - 4, height - 4);
  10715.         end;
  10716.     end;
  10717.  
  10718.     -- A function to draw a player information sub box.
  10719.     function NEXUS:DrawPlayerInfoSubBox(text, x, y, width, boxInfo)
  10720.         local backgroundColor = nexus.schema.GetColor("background");
  10721.         local colorWhite = nexus.schema.GetColor("white");
  10722.        
  10723.         if (!boxInfo or boxInfo.drawBackground) then
  10724.             draw.RoundedBox( 4, x, y, width, boxInfo.textHeight + 2, backgroundColor );
  10725.         end;
  10726.        
  10727.         self:DrawInfo(text, x + 8, y + 1, colorWhite, 255, true);
  10728.        
  10729.         if (boxInfo) then
  10730.             return x, y + boxInfo.textHeight + 4;
  10731.         else
  10732.             return x, y + 20;
  10733.         end;
  10734.     end;
  10735.    
  10736.     -- A function to create a colored spawn icon.
  10737.     function NEXUS:CreateColoredSpawnIcon(parent)
  10738.         local spawnIcon = vgui.Create("SpawnIcon", parent);
  10739.        
  10740.         -- A function to set the spawn icon's color.
  10741.         function spawnIcon.SetColor(spawnIcon, color)
  10742.             spawnIcon.Color = color;
  10743.         end;
  10744.        
  10745.         -- Called after the spawn icon has been hovered over.
  10746.         function spawnIcon.PaintOverHovered(spawnIcon)
  10747.             surface.SetDrawColor(255, 255, 255, 255);
  10748.             surface.SetMaterial(self.SpawnIconMaterial);
  10749.            
  10750.             spawnIcon:DrawTexturedRect();
  10751.         end;
  10752.        
  10753.         -- Called after the spawn icon's children are painted.
  10754.         function spawnIcon.PaintOver(spawnIcon)
  10755.             if (spawnIcon.Color) then
  10756.                 self.SpawnIconMaterial:SetMaterialVector( "$color", Vector(spawnIcon.Color.r / 255, spawnIcon.Color.g / 255, spawnIcon.Color.b / 255) );
  10757.                     surface.SetDrawColor(spawnIcon.Color.r, spawnIcon.Color.g, spawnIcon.Color.b, spawnIcon.Color.a);
  10758.                     surface.SetMaterial(self.SpawnIconMaterial);
  10759.                    
  10760.                     spawnIcon:DrawTexturedRect();
  10761.                 self.SpawnIconMaterial:SetMaterialVector( "$color", Vector(1, 1, 1) );
  10762.             end;
  10763.         end;
  10764.        
  10765.         return spawnIcon;
  10766.     end;
  10767.  
  10768.     -- A function to draw the armor bar.
  10769.     function NEXUS:DrawArmorBar()
  10770.         local armor = math.Clamp( g_LocalPlayer:Armor(), 0, g_LocalPlayer:GetMaxArmor() );
  10771.        
  10772.         if (armor > 0) then
  10773.             self.Bars:Add("ARMOR", Color(139, 174, 179, 255), "", armor, g_LocalPlayer:GetMaxArmor(), armor < 10, 1);
  10774.         end;
  10775.     end;
  10776.  
  10777.     -- A function to draw the health bar.
  10778.     function NEXUS:DrawHealthBar()
  10779.         local health = math.Clamp( g_LocalPlayer:Health(), 0, g_LocalPlayer:GetMaxHealth() );
  10780.        
  10781.         if (health > 0) then
  10782.             self.Bars:Add("HEALTH", Color(179, 46, 49, 255), "", health, g_LocalPlayer:GetMaxHealth(), health < 10, 2);
  10783.         end;
  10784.     end;
  10785.    
  10786.     -- A function to remove the active tool tip.
  10787.     function NEXUS:RemoveActiveToolTip()
  10788.         ChangeTooltip();
  10789.     end;
  10790.    
  10791.     -- A function to close active Derma menus.
  10792.     function NEXUS:CloseActiveDermaMenus()
  10793.         CloseDermaMenus();
  10794.     end;
  10795.    
  10796.     -- A function to register a background blur.
  10797.     function NEXUS:RegisterBackgroundBlur(panel, createTime)
  10798.         self.BackgroundBlurs[panel] = createTime;
  10799.     end;
  10800.    
  10801.     -- A function to remove a background blur.
  10802.     function NEXUS:RemoveBackgroundBlur(panel)
  10803.         self.BackgroundBlurs[panel] = nil;
  10804.     end;
  10805.    
  10806.     -- A function to draw the background blurs.
  10807.     function NEXUS:DrawBackgroundBlurs()
  10808.         local sysTime = SysTime();
  10809.         local scrH = ScrH();
  10810.         local scrW = ScrW();
  10811.        
  10812.         for k, v in pairs(self.BackgroundBlurs) do
  10813.             if ( type(k) == "string" or ( IsValid(k) and k:IsVisible() ) ) then
  10814.                 local fraction = math.Clamp( (sysTime - v) / 1, 0, 1 );
  10815.                 local x, y = 0, 0;
  10816.                
  10817.                 surface.SetMaterial(self.ScreenBlur);
  10818.                 surface.SetDrawColor(255, 255, 255, 255);
  10819.                
  10820.                 for i = 0.33, 1, 0.33 do
  10821.                     self.ScreenBlur:SetMaterialFloat("$blur", fraction * 5 * i);
  10822.                    
  10823.                     if (render) then
  10824.                         render.UpdateScreenEffectTexture();
  10825.                     end;
  10826.                    
  10827.                     surface.DrawTexturedRect(x, y, scrW, scrH);
  10828.                 end;
  10829.                
  10830.                 surface.SetDrawColor(10, 10, 10, 200 * fraction);
  10831.                 surface.DrawRect(x, y, scrW, scrH);
  10832.             end;
  10833.         end;
  10834.     end;
  10835.    
  10836.     -- A function to add some cinematic text.
  10837.     function NEXUS:AddCinematicText(text, color, hangTime)
  10838.         local colorWhite = nexus.schema.GetColor("white");
  10839.        
  10840.         self.Cinematics[#self.Cinematics + 1] = {
  10841.             hangTime = hangTime or 3,
  10842.             color = color or colorWhite,
  10843.             text = text,
  10844.             add = 0
  10845.         };
  10846.     end;
  10847.    
  10848.     -- A function to add a notice.
  10849.     function NEXUS:AddNotify(text, class, length)
  10850.         if (class != NOTIFY_HINT or string.sub(text, 1, 6) != "#Hint_") then
  10851.             self.BaseClass:AddNotify(text, class, length);
  10852.         end;
  10853.     end;
  10854.    
  10855.     -- A function to get whether the local player is using the tool gun.
  10856.     function NEXUS:IsUsingTool()
  10857.         if (IsValid( g_LocalPlayer:GetActiveWeapon() )
  10858.         and g_LocalPlayer:GetActiveWeapon():GetClass() == "gmod_tool") then
  10859.             return true;
  10860.         else
  10861.             return false;
  10862.         end;
  10863.     end;
  10864.  
  10865.     -- A function to get whether the local player is using the camera.
  10866.     function NEXUS:IsUsingCamera()
  10867.         if (IsValid( g_LocalPlayer:GetActiveWeapon() )
  10868.         and g_LocalPlayer:GetActiveWeapon():GetClass() == "gmod_camera") then
  10869.             return true;
  10870.         else
  10871.             return false;
  10872.         end;
  10873.     end;
  10874.    
  10875.     -- A function to get the target ID data.
  10876.     function NEXUS:GetTargetIDData()
  10877.         return self.TargetIDData;
  10878.     end;
  10879.    
  10880.     -- A function to calculate the screen fading.
  10881.     function NEXUS:CalculateScreenFading()
  10882.         if ( nexus.mount.Call("ShouldPlayerScreenFadeBlack") ) then
  10883.             if (!self.BlackFadeIn) then
  10884.                 if (self.BlackFadeOut) then
  10885.                     self.BlackFadeIn = self.BlackFadeOut;
  10886.                 else
  10887.                     self.BlackFadeIn = 0;
  10888.                 end;
  10889.             end;
  10890.            
  10891.             self.BlackFadeIn = math.Clamp(self.BlackFadeIn + (FrameTime() * 20), 0, 255);
  10892.             self.BlackFadeOut = nil;
  10893.            
  10894.             self:DrawRoundedGradient( 0, 0, 0, ScrW(), ScrH(), Color(0, 0, 0, self.BlackFadeIn) );
  10895.         else
  10896.             if (self.BlackFadeIn) then
  10897.                 self.BlackFadeOut = self.BlackFadeIn;
  10898.             end;
  10899.            
  10900.             self.BlackFadeIn = nil;
  10901.            
  10902.             if (self.BlackFadeOut) then
  10903.                 self.BlackFadeOut = math.Clamp(self.BlackFadeOut - (FrameTime() * 40), 0, 255);
  10904.                
  10905.                 self:DrawRoundedGradient( 0, 0, 0, ScrW(), ScrH(), Color(0, 0, 0, self.BlackFadeOut) );
  10906.                
  10907.                 if (self.BlackFadeOut == 0) then
  10908.                     self.BlackFadeOut = nil;
  10909.                 end;
  10910.             end;
  10911.         end;
  10912.     end;
  10913.    
  10914.     -- A function to draw a cinematic.
  10915.     function NEXUS:DrawCinematic(cinematic, curTime)
  10916.         local maxBarLength = ScrH() / 13;
  10917.         local font = nexus.schema.GetFont("cinematic_text");
  10918.        
  10919.         if (cinematic.goBack and curTime > cinematic.goBack) then
  10920.             cinematic.add = math.Clamp(cinematic.add - 2, 0, maxBarLength);
  10921.            
  10922.             if (cinematic.add == 0) then
  10923.                 table.remove(self.Cinematics, 1);
  10924.                
  10925.                 cinematic = nil;
  10926.             end;
  10927.         else
  10928.             cinematic.add = math.Clamp(cinematic.add + 1, 0, maxBarLength);
  10929.            
  10930.             if (cinematic.add == maxBarLength and !cinematic.goBack) then
  10931.                 cinematic.goBack = curTime + cinematic.hangTime;
  10932.             end;
  10933.         end;
  10934.        
  10935.         if (cinematic) then
  10936.             draw.RoundedBox( 0, 0, -maxBarLength + cinematic.add, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
  10937.             draw.RoundedBox( 0, 0, ScrH() - cinematic.add, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
  10938.            
  10939.             draw.SimpleText(cinematic.text, font, ScrW() / 2, (ScrH() - cinematic.add) + (maxBarLength / 2), cinematic.color, 1, 1);
  10940.         end
  10941.     end;
  10942.    
  10943.     -- A function to draw the cinematic introduction.
  10944.     function NEXUS:DrawCinematicIntro(curTime)
  10945.         local cinematicInfo = nexus.mount.Call("GetCinematicIntroInfo");
  10946.         local colorWhite = nexus.schema.GetColor("white");
  10947.        
  10948.         if (cinematicInfo) then
  10949.             if (self.CinematicScreenAlpha and self.CinematicScreenTarget) then
  10950.                 self.CinematicScreenAlpha = math.Approach(self.CinematicScreenAlpha, self.CinematicScreenTarget, 2);
  10951.                
  10952.                 if (self.CinematicScreenAlpha == self.CinematicScreenTarget) then
  10953.                     if (self.CinematicScreenTarget == 255) then
  10954.                         if (!self.CinematicScreenGoBack) then
  10955.                             self.CinematicScreenGoBack = curTime + 3;
  10956.                         end;
  10957.                     else
  10958.                         self.CinematicScreenDone = true;
  10959.                     end;
  10960.                 end;
  10961.                
  10962.                 if (self.CinematicScreenGoBack and curTime >= self.CinematicScreenGoBack) then
  10963.                     self.CinematicScreenGoBack = nil;
  10964.                     self.CinematicScreenTarget = 0;
  10965.                 end;
  10966.                
  10967.                 if (!self.CinematicScreenDone and cinematicInfo.credits) then
  10968.                     local alpha = math.Clamp(self.CinematicScreenAlpha, 0, 255);
  10969.                    
  10970.                     self:OverrideMainFont( nexus.schema.GetFont("intro_text_tiny") );
  10971.                         self:DrawSimpleText( cinematicInfo.credits, ScrW() / 8, ScrH() * 0.75, Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha) );
  10972.                     self:OverrideMainFont(false);
  10973.                 end;
  10974.             else
  10975.                 self.CinematicScreenAlpha = 0;
  10976.                 self.CinematicScreenTarget = 255;
  10977.             end;
  10978.            
  10979.             self:DrawCinematicIntroBars();
  10980.         end;
  10981.     end;
  10982.    
  10983.     -- A function to draw the cinematic introduction bars.
  10984.     function NEXUS:DrawCinematicIntroBars()
  10985.         local maxBarLength = ScrH() / 13;
  10986.        
  10987.         if (self.CinematicScreenTarget and self.CinematicScreenTarget == 0) then
  10988.             if (self.CinematicScreenBarLength != 0) then
  10989.                 self.CinematicScreenBarLength = math.Clamp( (maxBarLength / 255) * self.CinematicScreenAlpha, 0, maxBarLength );
  10990.             end;
  10991.         end;
  10992.        
  10993.         if (!self.CinematicScreenBarLength or self.CinematicScreenBarLength > 0) then
  10994.             local cinematicScreenBarLength = self.CinematicScreenBarLength or maxBarLength;
  10995.            
  10996.             draw.RoundedBox( 0, 0, 0, ScrW(), cinematicScreenBarLength, Color(0, 0, 0, 255) );
  10997.             draw.RoundedBox( 0, 0, ScrH() - cinematicScreenBarLength, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
  10998.         end;
  10999.     end;
  11000.    
  11001.     -- A function to draw some door text.
  11002.     function NEXUS:DrawDoorText(entity, eyePos, eyeAngles, font, color)
  11003.         local r, g, b, a = entity:GetColor();
  11004.        
  11005.         if ( a > 0 and !entity:IsEffectActive(EF_NODRAW) ) then
  11006.             local doorData = nexus.entity.CalculateDoorTextPosition(entity);
  11007.            
  11008.             if (!doorData.hitWorld) then
  11009.                 local frontY = -26;
  11010.                 local backY = -26;
  11011.                 local alpha = self:CalculateAlphaFromDistance( 256, eyePos, entity:GetPos() );
  11012.                
  11013.                 if (alpha > 0) then
  11014.                     local owner = nexus.entity.GetOwner(entity);
  11015.                     local name = nexus.mount.Call("GetDoorInfo", entity, DOOR_INFO_NAME);
  11016.                     local text = nexus.mount.Call("GetDoorInfo", entity, DOOR_INFO_TEXT);
  11017.                    
  11018.                     if (name or text) then
  11019.                         local nameWidth = self:GetCachedTextSize(font, name or "");
  11020.                         local textWidth = self:GetCachedTextSize(font, text or "");
  11021.                         local longWidth = nameWidth;
  11022.                        
  11023.                         if (textWidth > longWidth) then
  11024.                             longWidth = textWidth;
  11025.                         end;
  11026.                        
  11027.                         local scale = math.abs( (doorData.width * 0.75) / longWidth );
  11028.                         local nameScale = math.min(scale, 0.05);
  11029.                         local textScale = math.min(scale, 0.03);
  11030.                        
  11031.                         if (name) then
  11032.                             cam.Start3D2D(doorData.position, doorData.angles, nameScale);
  11033.                                 self:OverrideMainFont(font);
  11034.                                     frontY = self:DrawInfo(name, 0, frontY, color, alpha, nil, nil, 3);
  11035.                                 self:OverrideMainFont(false);
  11036.                             cam.End3D2D();
  11037.                            
  11038.                             cam.Start3D2D(doorData.positionBack, doorData.anglesBack, nameScale);
  11039.                                 self:OverrideMainFont(font);
  11040.                                     backY = self:DrawInfo(name, 0, backY, color, alpha, nil, nil, 3);
  11041.                                 self:OverrideMainFont(false);
  11042.                             cam.End3D2D();
  11043.                         end;
  11044.                        
  11045.                         if (text) then
  11046.                             cam.Start3D2D(doorData.position, doorData.angles, textScale);
  11047.                                 self:OverrideMainFont(font);
  11048.                                     frontY = self:DrawInfo(text, 0, frontY, color, alpha, nil, nil, 3);
  11049.                                 self:OverrideMainFont(false);
  11050.                             cam.End3D2D();
  11051.                            
  11052.                             cam.Start3D2D(doorData.positionBack, doorData.anglesBack, textScale);
  11053.                                 self:OverrideMainFont(font);
  11054.                                     backY = self:DrawInfo(text, 0, backY, color, alpha, nil, nil, 3);
  11055.                                 self:OverrideMainFont(false);
  11056.                             cam.End3D2D();
  11057.                         end;
  11058.                     end;
  11059.                 end;
  11060.             end;
  11061.         end;
  11062.     end;
  11063.    
  11064.     -- A function to get whether the local player's character screen is open.
  11065.     function NEXUS:IsCharacterScreenOpen(isVisible)
  11066.         if ( nexus.character.IsPanelOpen() ) then
  11067.             local panel = nexus.character.GetPanel();
  11068.            
  11069.             if (isVisible) then
  11070.                 if (panel) then
  11071.                     return panel:IsVisible();
  11072.                 end;
  11073.             else
  11074.                 return panel != nil;
  11075.             end;
  11076.         end;
  11077.     end;
  11078.    
  11079.     -- A function to run a Nexus command.
  11080.     function NEXUS:RunCommand(command, ...)
  11081.         RunConsoleCommand("nx", command, ...);
  11082.     end;
  11083.    
  11084.     -- A function to get whether the local player is choosing a character.
  11085.     function NEXUS:IsChoosingCharacter()
  11086.         if ( nexus.character.GetPanel() ) then
  11087.             return nexus.character.IsPanelOpen();
  11088.         else
  11089.             return true;
  11090.         end;
  11091.     end;
  11092.    
  11093.     -- A function to include the schema.
  11094.     function NEXUS:IncludeSchema()
  11095.         local schemaFolder = self:GetSchemaFolder();
  11096.        
  11097.         if (schemaFolder and type(schemaFolder) == "string") then
  11098.             nexus.mount.Include(schemaFolder.."/gamemode/schema", true);
  11099.         end;
  11100.     end;
  11101.    
  11102.     -- A function to start a data stream.
  11103.     function NEXUS:StartDataStream(name, data)
  11104.         local encodedData = glon.encode(data);
  11105.         local splitTable = self:SplitString(string.gsub(string.gsub(encodedData, "\\", "\\\\"), "\n", "\\n"), 128);
  11106.        
  11107.         if (#splitTable > 0) then
  11108.             RunConsoleCommand( "nx_dsStart", name, tostring(#splitTable) );
  11109.            
  11110.             for k, v in ipairs(splitTable) do
  11111.                 RunConsoleCommand( "nx_dsData", v, tostring(k) );
  11112.             end;
  11113.         end;
  11114.     end;
  11115. end;
  11116.  
  11117. -- A function to explode a string by tags.
  11118. function NEXUS:ExplodeByTags(text, seperator, open, close, hide)
  11119.     local results = {};
  11120.     local current = "";
  11121.     local tag = nil;
  11122.     -- local i;
  11123.    
  11124.     for i = 1, string.len(text) do
  11125.         local character = string.sub(text, i, i);
  11126.        
  11127.         if (!tag) then
  11128.             if (character == open) then
  11129.                 if (!hide) then
  11130.                     current = current..character;
  11131.                 end;
  11132.                
  11133.                 tag = true;
  11134.             elseif (character == seperator) then
  11135.                 results[#results + 1] = current; current = "";
  11136.             else
  11137.                 current = current..character;
  11138.             end;
  11139.         else
  11140.             if (character == close) then
  11141.                 if (!hide) then
  11142.                     current = current..character;
  11143.                 end;
  11144.                
  11145.                 tag = nil;
  11146.             else
  11147.                 current = current..character;
  11148.             end;
  11149.         end;
  11150.     end;
  11151.    
  11152.     if (current != "") then
  11153.         results[#results + 1] = current;
  11154.     end;
  11155.    
  11156.     return results;
  11157. end;
  11158.  
  11159. -- A function to modify a physical description.
  11160. function NEXUS:ModifyPhysDesc(description)
  11161.     if (string.len(description) <= 128) then
  11162.         if ( !string.find(string.sub(description, -2), "%p") ) then
  11163.             return description..".";
  11164.         else
  11165.             return description;
  11166.         end;
  11167.     else
  11168.         return string.sub(description, 1, 125).."...";
  11169.     end;
  11170. end;
  11171.  
  11172. -- A function to explode a string.
  11173. function NEXUS:ExplodeString(seperator, text)
  11174.     local exploded = {};
  11175.    
  11176.     for value in string.gmatch(text, "([^"..seperator.."]+)") do
  11177.         exploded[#exploded + 1] = value;
  11178.     end;
  11179.    
  11180.     return exploded;
  11181. end;
  11182.  
  11183. -- A function to create a new meta table.
  11184. function NEXUS:NewMetaTable(base)
  11185.     local object = {};
  11186.    
  11187.     setmetatable(object, base);
  11188.    
  11189.     base.__index = base;
  11190.    
  11191.     return object;
  11192. end;
  11193.  
  11194. -- A function to set whether a string should be in camel case.
  11195. function NEXUS:SetCamelCase(text, camelCase)
  11196.     if (camelCase) then
  11197.         return string.gsub(text, "^.", string.lower);
  11198.     else
  11199.         return string.gsub(text, "^.", string.upper);
  11200.     end;
  11201. end;
  11202.  
  11203. -- A function to include files in a directory.
  11204. function NEXUS:IncludeDirectory(directory)
  11205.     if (string.sub(directory, -1) != "/") then
  11206.         directory = directory.."/";
  11207.     end;
  11208.    
  11209.     for k, v in pairs( g_File.FindInLua(directory.."*.lua") ) do
  11210.         NEXUS:IncludePrefixed(directory..v);
  11211.     end;
  11212. end;
  11213.  
  11214. -- A function to include a prefixed g_File.
  11215. function NEXUS:IncludePrefixed(fileName)
  11216.     if (string.find(fileName, "sv_") and !SERVER) then
  11217.         return;
  11218.     end;
  11219.    
  11220.     if (string.find(fileName, "sh_") and SERVER) then
  11221.         AddCSLuaFile(fileName);
  11222.     elseif (string.find(fileName, "cl_") and SERVER) then
  11223.         AddCSLuaFile(fileName);
  11224.        
  11225.         return;
  11226.     end;
  11227.    
  11228.     include(fileName);
  11229. end;
  11230.  
  11231. -- A function to include mounts in a directory.
  11232. function NEXUS:IncludeMounts(directory)
  11233.     if (string.sub(directory, -1) != "/") then
  11234.         directory = directory.."/";
  11235.     end;
  11236.    
  11237.     for k, v in pairs( g_File.FindInLua(directory.."*") ) do
  11238.         if (v != ".." and v != ".") then
  11239.             if (CLIENT) then
  11240.                 if ( g_File.IsDir("../lua_temp/"..directory..v) ) then
  11241.                     nexus.mount.Include(directory..v);
  11242.                 end;
  11243.             elseif ( g_File.IsDir("../gamemodes/"..directory..v) ) then
  11244.                 nexus.mount.Include(directory..v);
  11245.             end;
  11246.         end;
  11247.     end;
  11248.    
  11249.     return true;
  11250. end;
  11251.  
  11252. -- A function to perform the timer think.
  11253. function NEXUS:CallTimerThink(curTime)
  11254.     for k, v in pairs(self.Timers) do
  11255.         if (!v.paused) then
  11256.             if (curTime >= v.nextCall) then
  11257.                 local success, value = pcall( v.Callback, unpack(v.arguments) );
  11258.                
  11259.                 if (!success) then
  11260.                     ErrorNoHalt("Nexus -> the "..tostring(k).." timer has failed to run.");
  11261.                     ErrorNoHalt(value);
  11262.                 end;
  11263.                
  11264.                 v.nextCall = curTime + v.delay;
  11265.                 v.calls = v.calls + 1;
  11266.                
  11267.                 if (v.calls == v.repetitions) then
  11268.                     self.Timers[k] = nil;
  11269.                 end;
  11270.             end;
  11271.         end;
  11272.     end;
  11273. end;
  11274.  
  11275. -- A function to get whether a timer exists.
  11276. function NEXUS:TimerExists(name)
  11277.     return self.Timers[name];
  11278. end;
  11279.  
  11280. -- A function to start a timer.
  11281. function NEXUS:StartTimer(name)
  11282.     if (self.Timers[name] and self.Timers[name].paused) then
  11283.         self.Timers[name].nextCall = CurTime() + self.Timers[name].timeLeft;
  11284.         self.Timers[name].paused = nil;
  11285.     end;
  11286. end;
  11287.  
  11288. -- A function to pause a timer.
  11289. function NEXUS:PauseTimer(name)
  11290.     if (self.Timers[name] and !self.Timers[name].paused) then
  11291.         self.Timers[name].timeLeft = self.Timers[name].nextCall - CurTime();
  11292.         self.Timers[name].paused = true;
  11293.     end;
  11294. end;
  11295.  
  11296.  
  11297. -- A function to destroy a timer.
  11298. function NEXUS:DestroyTimer(name)
  11299.     self.Timers[name] = nil;
  11300. end;
  11301.  
  11302. -- A function to create a timer.
  11303. function NEXUS:CreateTimer(name, delay, repetitions, Callback, ...)
  11304.     self.Timers[name] = {
  11305.         calls = 0,
  11306.         delay = delay,
  11307.         nextCall = CurTime() + delay,
  11308.         Callback = Callback,
  11309.         arguments = {...},
  11310.         repetitions = repetitions
  11311.     };
  11312. end;
  11313.  
  11314. -- A function to get whether a player has access to an object.
  11315. function NEXUS:HasObjectAccess(player, object)
  11316.     local hasAccess = false;
  11317.     local faction = nil;
  11318.    
  11319.     if (SERVER) then
  11320.         faction = player:QueryCharacter("faction");
  11321.     else
  11322.         faction = nexus.player.GetFaction(player);
  11323.     end;
  11324.    
  11325.     if (object.access) then
  11326.         if ( nexus.player.HasAnyFlags(player, object.access) ) then
  11327.             hasAccess = true;
  11328.         end;
  11329.     end;
  11330.    
  11331.     if (object.factions) then
  11332.         if ( table.HasValue(object.factions, faction) ) then
  11333.             hasAccess = true;
  11334.         end;
  11335.     end;
  11336.    
  11337.     if (object.classes) then
  11338.         local team = player:Team();
  11339.         local class = nexus.class.Get(team);
  11340.        
  11341.         if (class) then
  11342.             if ( table.HasValue(object.classes, team) or table.HasValue(object.classes, class.name) ) then
  11343.                 hasAccess = true;
  11344.             end;
  11345.         end;
  11346.     end;
  11347.    
  11348.     if (!object.access and !object.factions and !object.classes) then
  11349.         hasAccess = true;
  11350.     end;
  11351.    
  11352.     if (object.blacklist) then
  11353.         local team = player:Team();
  11354.         local class = nexus.class.Get(team);
  11355.        
  11356.         if ( table.HasValue(object.blacklist, faction) ) then
  11357.             hasAccess = false;
  11358.         elseif (class) then
  11359.             if ( table.HasValue(object.blacklist, team) or table.HasValue(object.blacklist, class.name) ) then
  11360.                 hasAccess = false;
  11361.             end;
  11362.         else
  11363.             for k, v in ipairs(object.blacklist) do
  11364.                 if (type(v) == "string") then
  11365.                     if ( nexus.player.HasAnyFlags(player, v) ) then
  11366.                         hasAccess = false;
  11367.                        
  11368.                         break;
  11369.                     end;
  11370.                 end;
  11371.             end;
  11372.         end;
  11373.     end;
  11374.    
  11375.     if (object.HasObjectAccess) then
  11376.         return object:HasObjectAccess(player, hasAccess);
  11377.     end;
  11378.    
  11379.     return hasAccess;
  11380. end;
  11381.  
  11382. -- A function to derive from Sandbox.
  11383. function NEXUS:DeriveFromSandbox()
  11384.     DeriveGamemode("Sandbox");
  11385.  
  11386.     if (!NEXUS.IsSandboxDerived) then
  11387.         GM = {Folder = "gamemodes/sandbox"};
  11388.        
  11389.         if (CLIENT) then
  11390.             include("sandbox/gamemode/cl_init.lua");
  11391.         else
  11392.             include("sandbox/gamemode/init.lua");
  11393.         end;
  11394.        
  11395.         local sandboxGamemode = GM;
  11396.         local baseGamemode = gamemode.Get("base");
  11397.        
  11398.         if (sandboxGamemode and baseGamemode) then
  11399.             table.Inherit(sandboxGamemode, baseGamemode);
  11400.             table.Inherit(NEXUS, sandboxGamemode);
  11401.            
  11402.             timer.Simple(FrameTime(), function()
  11403.                 NEXUS.BaseClass = sandboxGamemode;
  11404.             end);
  11405.            
  11406.             GM = NEXUS;
  11407.         end;
  11408.     end;
  11409. end;
  11410.  
  11411. -- A function to get the sorted commands.
  11412. function NEXUS:GetSortedCommands()
  11413.     local commands = {};
  11414.     local source = nexus.command.stored;
  11415.    
  11416.     for k, v in pairs(source) do
  11417.         commands[#commands + 1] = k;
  11418.     end;
  11419.    
  11420.     table.sort(commands, function(a, b)
  11421.         return a < b;
  11422.     end);
  11423.    
  11424.     return commands;
  11425. end;
  11426.  
  11427. -- A function to zero a number to an amount of digits.
  11428. function NEXUS:ZeroNumberToDigits(number, digits)
  11429.     return string.rep( "0", math.Clamp(digits - string.len( tostring(number) ), 0, digits) )..number;
  11430. end;
  11431.  
  11432. -- A function to get a short CRC from a value.
  11433. function NEXUS:GetShortCRC(value)
  11434.     return math.ceil(util.CRC(value) / 100000);
  11435. end;
  11436.  
  11437. -- A function to validate a table's keys.
  11438. function NEXUS:ValidateTableKeys(base)
  11439.     for i = 1, #base do
  11440.         if ( !base[i] ) then
  11441.             table.remove(base, i);
  11442.         end;
  11443.     end;
  11444. end;
  11445.  
  11446. -- A function to get the map's physics entities.
  11447. function NEXUS:GetPhysicsEntities()
  11448.     local entities = {};
  11449.    
  11450.     for k, v in ipairs( ents.FindByClass("prop_physics_multiplayer") ) do
  11451.         if ( IsValid(v) ) then
  11452.             entities[#entities + 1] = v;
  11453.         end;
  11454.     end;
  11455.    
  11456.     for k, v in ipairs( ents.FindByClass("prop_physics") ) do
  11457.         if ( IsValid(v) ) then
  11458.             entities[#entities + 1] = v;
  11459.         end;
  11460.     end;
  11461.    
  11462.     return entities;
  11463. end;
  11464.  
  11465. -- A function to create a multicall table (by Deco Da Man).
  11466. function NEXUS:CreateMulticallTable(base, object)
  11467.     local metaTable = getmetatable(base) or {};
  11468.    
  11469.     -- Called when an index is needed.
  11470.     function metaTable.__index(base, key)
  11471.         return function(base, ...)
  11472.             for k, v in pairs(base) do
  11473.                 object[key](v, ...);
  11474.             end;
  11475.         end
  11476.     end
  11477.    
  11478.     setmetatable(base, metaTable);
  11479.    
  11480.     return base;
  11481. end;
  11482.  
  11483. -- A function to check if the shared variables have initialized.
  11484. function NEXUS:SharedVarsHaveInitialized()
  11485.     local worldEntity = GetWorldEntity();
  11486.    
  11487.     if ( worldEntity and worldEntity.IsWorld and worldEntity:IsWorld() ) then
  11488.         return true;
  11489.     end;
  11490. end;
  11491.  
  11492. -- A function to convert a user message class.
  11493. function NEXUS:ConvertUserMessageClass(class)
  11494.     local convertTable = {
  11495.         [NWTYPE_STRING] = "String",
  11496.         [NWTYPE_ENTITY] = "Entity",
  11497.         [NWTYPE_VECTOR] = "Vector",
  11498.         [NWTYPE_NUMBER] = "Long",
  11499.         [NWTYPE_ANGLE] = "Angle",
  11500.         [NWTYPE_FLOAT] = "Float",
  11501.         [NWTYPE_BOOL] = "Bool"
  11502.     };
  11503.    
  11504.     return convertTable[class];
  11505. end;
  11506.  
  11507. -- A function to get a default networked value.
  11508. function NEXUS:GetDefaultNetworkedValue(class)
  11509.     local convertTable = {
  11510.         [NWTYPE_STRING] = "",
  11511.         [NWTYPE_ENTITY] = NULL,
  11512.         [NWTYPE_VECTOR] = Vector(0, 0, 0),
  11513.         [NWTYPE_NUMBER] = 0,
  11514.         [NWTYPE_ANGLE] = Angle(0, 0, 0),
  11515.         [NWTYPE_FLOAT] = 0.0,
  11516.         [NWTYPE_BOOL] = false
  11517.     };
  11518.    
  11519.     return convertTable[class];
  11520. end;
  11521.  
  11522. -- A function to convert a networked class.
  11523. function NEXUS:ConvertNetworkedClass(class)
  11524.     local convertTable = {
  11525.         [NWTYPE_STRING] = "String",
  11526.         [NWTYPE_ENTITY] = "Entity",
  11527.         [NWTYPE_VECTOR] = "Vector",
  11528.         [NWTYPE_NUMBER] = "Int",
  11529.         [NWTYPE_ANGLE] = "Angle",
  11530.         [NWTYPE_FLOAT] = "Float",
  11531.         [NWTYPE_BOOL] = "Bool"
  11532.     };
  11533.    
  11534.     return convertTable[class];
  11535. end;
  11536.  
  11537. -- A function to get the default class value.
  11538. function NEXUS:GetDefaultClassValue(class)
  11539.     local convertTable = {
  11540.         ["String"] = "",
  11541.         ["Entity"] = NULL,
  11542.         ["Vector"] = Vector(0, 0, 0),
  11543.         ["Int"] = 0,
  11544.         ["Angle"] = Angle(0, 0, 0),
  11545.         ["Float"] = 0.0,
  11546.         ["Bool"] = false
  11547.     };
  11548.    
  11549.     return convertTable[class];
  11550. end;
  11551.  
  11552. -- A function to set a shared variable.
  11553. function NEXUS:SetSharedVar(key, value)
  11554.     local entity = GetWorldEntity();
  11555.    
  11556.     if ( entity.sharedVars and entity.sharedVars[key] ) then
  11557.         local class = self:ConvertNetworkedClass( entity.sharedVars[key] );
  11558.        
  11559.         if (class) then
  11560.             if (value == nil) then
  11561.                 value = NEXUS:GetDefaultClassValue(class);
  11562.             end;
  11563.            
  11564.             entity["SetNetworked"..class](entity, key, value);
  11565.         else
  11566.             entity:SetNetworkedVar(key, value);
  11567.         end;
  11568.     else
  11569.         entity:SetNetworkedVar(key, value);
  11570.     end;
  11571. end;
  11572.  
  11573. -- A function to get a shared variable.
  11574. function NEXUS:GetSharedVar(key)
  11575.     local entity = GetWorldEntity();
  11576.    
  11577.     if ( entity.sharedVars and entity.sharedVars[key] ) then
  11578.         local class = self:ConvertNetworkedClass( entity.sharedVars[key] );
  11579.        
  11580.         if (class) then
  11581.             return entity["GetNetworked"..class](entity, key);
  11582.         else
  11583.             return entity:GetNetworkedVar(key);
  11584.         end;
  11585.     else
  11586.         return entity:GetNetworkedVar(key);
  11587.     end;
  11588. end;
  11589.  
  11590. -- A function to register a global shared variable.
  11591. function NEXUS:RegisterGlobalSharedVar(name, class)
  11592.     self.GlobalSharedVars[#self.GlobalSharedVars + 1] = {name, class};
  11593. end;
  11594.  
  11595. -- A function to create fake damage info.
  11596. function NEXUS:FakeDamageInfo(damage, inflictor, attacker, position, damageType, damageForce)
  11597.     local damageInfo = DamageInfo();
  11598.     local realDamage = math.ceil( math.max(damage, 0) );
  11599.    
  11600.     damageInfo:SetDamagePosition(position);
  11601.     damageInfo:SetDamageForce(Vector() * damageForce);
  11602.     damageInfo:SetDamageType(damageType);
  11603.     damageInfo:SetInflictor(inflictor);
  11604.     damageInfo:SetAttacker(attacker);
  11605.     damageInfo:SetDamage(realDamage);
  11606.    
  11607.     return damageInfo;
  11608. end;
  11609.  
  11610. -- A function to unpack a color.
  11611. function NEXUS:UnpackColor(color)
  11612.     return color.r, color.g, color.b, color.a;
  11613. end;
  11614.  
  11615. -- A function to parse data in text.
  11616. function NEXUS:ParseData(text)
  11617.     local classes = {"%^", "%!"};
  11618.    
  11619.     for k, v in ipairs(classes) do
  11620.         for key in string.gmatch(text, v.."(.-)"..v) do
  11621.             local lower = false;
  11622.             local amount;
  11623.            
  11624.             if (string.sub(key, 1, 1) == "(" and string.sub(key, -1) == ")") then
  11625.                 lower = true;
  11626.                 amount = tonumber( string.sub(key, 2, -2) );
  11627.             else
  11628.                 amount = tonumber(key);
  11629.             end;
  11630.            
  11631.             if (amount) then
  11632.                 text = string.gsub( text, v..string.gsub(key, "([%(%)])", "%%%1")..v, tostring( FORMAT_CASH(amount, k == 2, lower) ) );
  11633.             end;
  11634.         end;
  11635.     end;
  11636.    
  11637.     for k in string.gmatch(text, "%*(.-)%*") do
  11638.         k = string.gsub(k, "[%(%)]", "");
  11639.        
  11640.         if (k != "") then
  11641.             text = string.gsub( text, "%*%("..k.."%)%*", tostring( nexus.schema.GetOption(k, true) ) );
  11642.             text = string.gsub( text, "%*"..k.."%*", tostring( nexus.schema.GetOption(k) ) );
  11643.         end;
  11644.     end;
  11645.    
  11646.     return nexus.config.Parse(text);
  11647. end;
Add Comment
Please, Sign In to add comment