· 9 years ago · Jun 30, 2017, 03:20 PM
1--[[
2Name: "sh_core.lua".
3Product: "Nexus".
4--]]
5
6NEXUS.Timers = {};
7NEXUS.DataStreamHooks = {};
8NEXUS.GlobalSharedVars = {};
9
10function ScaleToWideScreen(size)
11 return math.min(math.max( ScreenScale(size /--[[
12Name: "sv_auto.lua".
13Product: "Nexus".
14--]]
15
16for k, v in pairs( file.Find("../materials/decals/flesh/blood*") ) do
17 resource.AddFile("materials/decals/flesh/"..v);
18end;
19
20for k, v in pairs( file.Find("../materials/decals/blood*") ) do
21 resource.AddFile("materials/decals/"..v);
22end;
23
24for k, v in pairs( file.Find("../materials/effects/blood*") ) do
25 resource.AddFile("materials/effects/"..v);
26end;
27
28for k, v in pairs( file.Find("../materials/sprites/blood*") ) do
29 resource.AddFile("materials/sprites/"..v);
30end;
31
32resource.AddFile("materials/gui/silkicons/information.vtf");
33resource.AddFile("materials/gui/silkicons/information.vmt");
34resource.AddFile("materials/gui/silkicons/user_delete.vtf");
35resource.AddFile("materials/gui/silkicons/user_delete.vmt");
36resource.AddFile("materials/gui/silkicons/newspaper.vtf");
37resource.AddFile("materials/gui/silkicons/newspaper.vmt");
38resource.AddFile("materials/gui/silkicons/user_add.vtf");
39resource.AddFile("materials/gui/silkicons/user_add.vmt");
40resource.AddFile("materials/gui/silkicons/comment.vtf");
41resource.AddFile("materials/gui/silkicons/comment.vmt");
42resource.AddFile("materials/gui/silkicons/error.vtf");
43resource.AddFile("materials/gui/silkicons/error.vmt");
44resource.AddFile("materials/gui/silkicons/help.vtf");
45resource.AddFile("materials/gui/silkicons/help.vmt");
46resource.AddFile("models/humans/female_gestures.ani");
47resource.AddFile("models/humans/female_gestures.mdl");
48resource.AddFile("models/humans/female_postures.ani");
49resource.AddFile("models/humans/female_postures.mdl");
50resource.AddFile("models/combine_soldier_anims.ani");
51resource.AddFile("models/combine_soldier_anims.mdl");
52resource.AddFile("models/humans/female_shared.ani");
53resource.AddFile("models/humans/female_shared.mdl");
54resource.AddFile("models/humans/male_gestures.ani");
55resource.AddFile("models/humans/male_gestures.mdl");
56resource.AddFile("models/humans/male_postures.ani");
57resource.AddFile("models/humans/male_postures.mdl");
58resource.AddFile("models/humans/male_shared.ani");
59resource.AddFile("models/humans/male_shared.mdl");
60resource.AddFile("materials/nexus/xhlogo.vtf");
61resource.AddFile("materials/nexus/xhlogo.vmt");
62resource.AddFile("models/police_animations.ani");
63resource.AddFile("models/police_animations.mdl");
64resource.AddFile("models/humans/female_ss.ani");
65resource.AddFile("models/humans/female_ss.mdl");
66resource.AddFile("materials/nexus/unknown.vtf");
67resource.AddFile("materials/nexus/unknown.vmt");
68resource.AddFile("models/humans/male_ss.ani");
69resource.AddFile("models/humans/male_ss.mdl");
70resource.AddFile("models/police_ss.ani");
71resource.AddFile("models/police_ss.mdl");
72
73CreateConVar("npc_thinknow", 1);
74
75AddCSLuaFile("sh_enums.lua");
76AddCSLuaFile("sh_core.lua");
77AddCSLuaFile("sh_auto.lua");
78AddCSLuaFile("cl_auto.lua");
79
80include("sh_auto.lua");
81
82local gradientTexture = nexus.schema.GetOption("gradient");
83local introImage = nexus.schema.GetOption("intro_image");
84local CurTime = CurTime;
85local hook = hook;
86
87if (gradientTexture != "gui/gradient_up") then
88 resource.AddFile("materials/"..gradientTexture..".vtf");
89 resource.AddFile("materials/"..gradientTexture..".vmt");
90end;
91
92if (introImage != "") then
93 resource.AddFile("materials/"..introImage..".vtf");
94 resource.AddFile("materials/"..introImage..".vmt");
95end;
96
97_R["CRecipientFilter"].IsValid = function()
98 return true;
99end;
100
101hook.NexusCall = hook.Call;
102
103-- A function to call a hook.
104function 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;
136end;
137
138-- Called when the server initializes.
139function 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();
205end;
206
207-- Called when a player has disconnected.
208function 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;
224end;
225
226-- Called when the Nexus core has loaded.
227function NEXUS:NexusCoreLoaded()
228 nexus.config.Import("nexus/mysql.cfg");
229end;
230
231-- Called when Nexus has initialized.
232function 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;
244end;
245
246-- Called when a player is banned.
247function NEXUS:PlayerBanned(player, duration, reason) end;
248
249-- Called when a player's model has changed.
250function NEXUS:PlayerModelChanged(player, model) end;
251
252-- Called when a player's inventory string is needed.
253function 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;
288end;
289
290-- Called when a player's unlock info is needed.
291function 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;
300end;
301
302-- Called when a player's lock info is needed.
303function 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;
312end;
313
314-- Called when data should be saved.
315function 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;
329end;
330
331-- Called when a player attempts to fire a weapon.
332function 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;
347end;
348
349-- Called when a player attempts to use a lowered weapon.
350function 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;
356end;
357
358-- Called when a player's recognised names have been cleared.
359function NEXUS:PlayerRecognisedNamesCleared(player, status, simple) end;
360
361-- Called when a player's name has been cleared.
362function NEXUS:PlayerNameCleared(player, status, simple) end;
363
364-- Called when an offline player has been given property.
365function NEXUS:PlayerPropertyGivenOffline(key, uniqueID, entity, networked, removeDelay) end;
366
367-- Called when an offline player has had property taken.
368function NEXUS:PlayerPropertyTakenOffline(key, uniqueID, entity) end;
369
370-- Called when a player has been given property.
371function NEXUS:PlayerPropertyGiven(player, entity, networked, removeDelay) end;
372
373-- Called when a player has had property taken.
374function NEXUS:PlayerPropertyTaken(player, entity) end;
375
376-- Called when a player's visibility should be set up.
377function 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;
398end;
399
400-- Called when a player has been given flags.
401function 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") );
411end;
412
413-- Called when a player has had flags taken.
414function 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") );
428end;
429
430-- Called when the game description is needed.
431function NEXUS:GetGameDescription()
432 if (SCHEMA and SCHEMA.name != "Base") then
433 return SCHEMA.name;
434 else
435 return self.Name;
436 end;
437end;
438
439-- Called when a player's phys desc override is needed.
440function NEXUS:GetPlayerPhysDescOverride(player, physDesc) end;
441
442-- Called when a player's default skin is needed.
443function NEXUS:GetPlayerDefaultSkin(player)
444 local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
445
446 return skin;
447end;
448
449-- Called when a player's default model is needed.
450function NEXUS:GetPlayerDefaultModel(player)
451 local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
452
453 return model;
454end;
455
456-- Called when a player's default inventory is needed.
457function NEXUS:GetPlayerDefaultInventory(player, character, inventory) end;
458
459-- Called to get whether a player's weapon is raised.
460function 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;
488end;
489
490-- Called when a player's attribute has been updated.
491function NEXUS:PlayerAttributeUpdated(player, attributeTable, amount) end;
492
493-- Called when a player's inventory item has been updated.
494function NEXUS:PlayerInventoryItemUpdated(player, itemTable, amount, force)
495 nexus.player.UpdateStorageForPlayer(player, itemTable.uniqueID);
496end;
497
498-- Called when a player's cash has been updated.
499function NEXUS:PlayerCashUpdated(player, amount, reason, noMessage)
500 nexus.player.UpdateStorageForPlayer(player);
501end;
502
503-- A function to scale damage by hit group.
504function 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;
508end;
509
510-- Called when a player switches their flashlight on or off.
511function 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;
521end;
522
523-- Called when time has passed.
524function NEXUS:TimePassed(quantity) end;
525
526-- Called when Nexus config has initialized.
527function 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;
546end;
547
548-- Called when a Nexus ConVar has changed.
549function NEXUS:NexusConVarChanged(name, previousValue, newValue)
550 if (name == "local_voice" and newValue) then
551 RunConsoleCommand("sv_alltalk", "1");
552 end;
553end;
554
555-- Called when Nexus config has changed.
556function 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;
606end;
607
608-- Called when a player's name has changed.
609function NEXUS:PlayerNameChanged(player, previousName, newName) end;
610
611-- Called when a player attempts to sprays their tag.
612function 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;
618end;
619
620-- Called when a player attempts to use an entity.
621function NEXUS:PlayerUse(player, entity)
622 if ( player:IsRagdolled(RAGDOLL_FALLENOVER) ) then
623 return false;
624 else
625 return true;
626 end;
627end;
628
629-- Called when a player's move data is set up.
630function 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;
648end;
649
650-- Called when a player throws a punch.
651function NEXUS:PlayerPunchThrown(player) end;
652
653-- Called when a player knocks on a door.
654function NEXUS:PlayerKnockOnDoor(player, door) end;
655
656-- Called when a player attempts to knock on a door.
657function NEXUS:PlayerCanKnockOnDoor(player, door) return true; end;
658
659-- Called when a player punches an entity.
660function NEXUS:PlayerPunchEntity(player, entity) end;
661
662-- Called when a player orders an item shipment.
663function NEXUS:PlayerOrderShipment(player, itemTable, entity) end;
664
665-- Called when a player holsters a weapon.
666function NEXUS:PlayerHolsterWeapon(player, itemTable, forced)
667 if (itemTable.OnHolster) then
668 itemTable:OnHolster(player, forced);
669 end;
670end;
671
672-- Called when a player attempts to save a recognised name.
673function NEXUS:PlayerCanSaveRecognisedName(player, target)
674 if (player != target) then return true; end;
675end;
676
677-- Called when a player attempts to restore a recognised name.
678function NEXUS:PlayerCanRestoreRecognisedName(player, target)
679 if (player != target) then return true; end;
680end;
681
682-- Called when a player attempts to order an item shipment.
683function NEXUS:PlayerCanOrderShipment(player, itemTable)
684 return true;
685end;
686
687-- Called when a player attempts to get up.
688function NEXUS:PlayerCanGetUp(player) return true; end;
689
690-- Called when a player knocks out a player with a punch.
691function NEXUS:PlayerPunchKnockout(player, target) end;
692
693-- Called when a player attempts to throw a punch.
694function NEXUS:PlayerCanThrowPunch(player) return true; end;
695
696-- Called when a player attempts to punch an entity.
697function NEXUS:PlayerCanPunchEntity(player, entity) return true; end;
698
699-- Called when a player attempts to knock a player out with a punch.
700function NEXUS:PlayerCanPunchKnockout(player, target) return true; end;
701
702-- Called when a player attempts to bypass the faction limit.
703function NEXUS:PlayerCanBypassFactionLimit(player, character) return false; end;
704
705-- Called when a player attempts to bypass the class limit.
706function NEXUS:PlayerCanBypassClassLimit(player, class) return false; end;
707
708-- Called when a player's pain sound should be played.
709function 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";
725end;
726
727-- Called when a player's data has loaded.
728function 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;
737end;
738
739-- Called when a player attempts to be given a weapon.
740function NEXUS:PlayerCanBeGivenWeapon(player, class, uniqueID, forceReturn)
741 return true;
742end;
743
744-- Called when a player has been given a weapon.
745function NEXUS:PlayerGivenWeapon(player, class, uniqueID, forceReturn)
746 nexus.inventory.Rebuild(player);
747end;
748
749-- Called when a player attempts to create a character.
750function 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;
756end;
757
758-- Called when a player attempts to interact with a character.
759function 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;
765end;
766
767-- Called when a player's fall damage is needed.
768function 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;
797end;
798
799-- Called when a player's data stream info has been sent.
800function 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;
898end;
899
900-- Called when a player's data stream info should be sent.
901function NEXUS:PlayerSendDataStreamInfo(player) end;
902
903-- Called when a player's death sound should be played.
904function NEXUS:PlayerPlayDeathSound(player, gender)
905 return "vo/npc/"..string.lower(gender).."01/pain0"..math.random(1, 9)..".wav";
906end;
907
908-- Called when a player's character data should be restored.
909function NEXUS:PlayerRestoreCharacterData(player, data)
910 if ( data["physdesc"] ) then
911 data["physdesc"] = self:ModifyPhysDesc( data["physdesc"] );
912 end;
913end;
914
915-- Called when a player's character data should be saved.
916function 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;
931end;
932
933-- Called when a player's data should be saved.
934function NEXUS:PlayerSaveData(player, data)
935 if (data["whitelisted"] and #data["whitelisted"] == 0) then
936 data["whitelisted"] = nil;
937 end;
938end;
939
940-- Called when a player's storage should close.
941function 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;
949end;
950
951-- Called when a player attempts to pickup a weapon.
952function 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;
958end;
959
960-- Called each tick.
961function 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;
1007end;
1008
1009-- Called each frame.
1010function NEXUS:Think()
1011 self:CallTimerThink( CurTime() );
1012end;
1013
1014-- Called when a player's shared variables should be set.
1015function 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;
1068end;
1069
1070-- Called at an interval while a player is connected.
1071function 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);
1113end;
1114
1115-- Called when a player uses an item.
1116function NEXUS:PlayerUseItem(player, itemTable, itemEntity) end;
1117
1118-- Called when a player drops an item.
1119function 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;
1132end;
1133
1134-- Called when a player destroys an item.
1135function NEXUS:PlayerDestroyItem(player, itemTable) end;
1136
1137-- Called when a player drops a weapon.
1138function 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;
1151end;
1152
1153-- Called when a player charges generator.
1154function NEXUS:PlayerChargeGenerator(player, entity, generator) end;
1155
1156-- Called when a player destroys generator.
1157function NEXUS:PlayerDestroyGenerator(player, entity, generator) end;
1158
1159-- Called when a player's data should be restored.
1160function NEXUS:PlayerRestoreData(player, data)
1161 if ( !data["whitelisted"] ) then
1162 data["whitelisted"] = {};
1163 end;
1164end;
1165
1166-- Called when a player's temporary info should be saved.
1167function NEXUS:PlayerSaveTempData(player, tempData) end;
1168
1169-- Called when a player's temporary info should be restored.
1170function NEXUS:PlayerRestoreTempData(player, tempData) end;
1171
1172-- Called when a player selects a custom character option.
1173function NEXUS:PlayerSelectCharacterOption(player, character, option) end;
1174
1175-- Called when a player attempts to see another player's status.
1176function NEXUS:PlayerCanSeeStatus(player, target)
1177 return "# "..target:UserID().." | "..target:Name().." | "..target:SteamName().." | "..target:SteamID().." | "..target:IPAddress();
1178end;
1179
1180-- Called when a player attempts to see a player's chat.
1181function NEXUS:PlayerCanSeePlayersChat(text, teamOnly, listener, speaker)
1182 return true;
1183end;
1184
1185-- Called when a player attempts to hear another player's voice.
1186function 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;
1198end;
1199
1200-- Called when a player attempts to delete a character.
1201function 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;
1209end;
1210
1211-- Called when a player attempts to switch to a character.
1212function 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;
1225end;
1226
1227-- Called when a player attempts to use a character.
1228function NEXUS:PlayerCanUseCharacter(player, character)
1229 if ( character.data["banned"] ) then
1230 return character.name.." is banned and cannot be used!";
1231 end;
1232end;
1233
1234-- Called when a player's weapons should be given.
1235function NEXUS:PlayerGiveWeapons(player) end;
1236
1237-- Called when a player deletes a character.
1238function NEXUS:PlayerDeleteCharacter(player, character) end;
1239
1240-- Called when a player's armor is set.
1241function NEXUS:PlayerArmorSet(player, armor)
1242 if ( player:IsRagdolled() ) then
1243 player:GetRagdollTable().armor = armor;
1244 end;
1245end;
1246
1247-- Called when a player's health is set.
1248function NEXUS:PlayerHealthSet(player, health)
1249 if ( player:IsRagdolled() ) then
1250 player:GetRagdollTable().health = health;
1251 end;
1252end;
1253
1254-- Called when a player attempts to own a door.
1255function NEXUS:PlayerCanOwnDoor(player, door)
1256 if ( nexus.entity.IsDoorUnownable(door) ) then
1257 return false;
1258 else
1259 return true;
1260 end;
1261end;
1262
1263-- Called when a player attempts to view a door.
1264function NEXUS:PlayerCanViewDoor(player, door)
1265 if ( nexus.entity.IsDoorUnownable(door) ) then
1266 return false;
1267 end;
1268
1269 return true;
1270end;
1271
1272-- Called when a player attempts to holster a weapon.
1273function 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;
1285end;
1286
1287-- Called when a player attempts to drop a weapon.
1288function 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;
1300end;
1301
1302-- Called when a player attempts to use an item.
1303function 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;
1313end;
1314
1315-- Called when a player attempts to drop an item.
1316function NEXUS:PlayerCanDropItem(player, itemTable, noMessage) return true; end;
1317
1318-- Called when a player attempts to destroy an item.
1319function NEXUS:PlayerCanDestroyItem(player, itemTable, noMessage) return true; end;
1320
1321-- Called when a player attempts to destroy generator.
1322function NEXUS:PlayerCanDestroyGenerator(player, entity, generator) return true; end;
1323
1324-- Called when a player attempts to knockout a player.
1325function NEXUS:PlayerCanKnockout(player, target) return true; end;
1326
1327-- Called when a player attempts to use the radio.
1328function NEXUS:PlayerCanRadio(player, text, listeners, eavesdroppers) return true; end;
1329
1330-- Called when death attempts to clear a player's name.
1331function NEXUS:PlayerCanDeathClearName(player, attacker, damageInfo) return false; end;
1332
1333-- Called when death attempts to clear a player's recognised names.
1334function NEXUS:PlayerCanDeathClearRecognisedNames(player, attacker, damageInfo) return false; end;
1335
1336-- Called when a player's ragdoll attempts to take damage.
1337function 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;
1345end;
1346
1347-- Called when a player has been authenticated.
1348function 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;
1385end;
1386
1387-- Called when the player attempts to be ragdolled.
1388function NEXUS:PlayerCanRagdoll(player, state, delay, decay, ragdoll)
1389 return true;
1390end;
1391
1392-- Called when the player attempts to be unragdolled.
1393function NEXUS:PlayerCanUnragdoll(player, state, ragdoll)
1394 return true;
1395end;
1396
1397-- Called when a player has been ragdolled.
1398function NEXUS:PlayerRagdolled(player, state, ragdoll)
1399 player:SetSharedVar("sh_FallenOver", false);
1400end;
1401
1402-- Called when a player has been unragdolled.
1403function NEXUS:PlayerUnragdolled(player, state, ragdoll)
1404 player:SetSharedVar("sh_FallenOver", false);
1405end;
1406
1407-- Called to check if a player does have an flag.
1408function NEXUS:PlayerDoesHaveFlag(player, flag)
1409 if ( string.find(nexus.config.Get("default_flags"):Get(), flag) ) then
1410 return true;
1411 end;
1412end;
1413
1414-- Called to check if a player does have door access.
1415function 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;
1431end;
1432
1433-- Called to check if a player does know another player.
1434function NEXUS:PlayerDoesRecognisePlayer(player, target, status, simple, default)
1435 return default;
1436end;
1437
1438-- Called to check if a player does have an item.
1439function NEXUS:PlayerDoesHaveItem(player, itemTable) return false; end;
1440
1441-- Called when a player attempts to lock an entity.
1442function 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;
1448end;
1449
1450-- Called when a player's class has been set.
1451function NEXUS:PlayerClassSet(player, newClass, oldClass, noRespawn, addDelay, noModelChange) end;
1452
1453-- Called when a player attempts to unlock an entity.
1454function 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;
1460end;
1461
1462-- Called when a player attempts to use a door.
1463function 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;
1473end;
1474
1475-- Called when a player uses a door.
1476function NEXUS:PlayerUseDoor(player, door) end;
1477
1478-- Called when a player attempts to use an entity in a vehicle.
1479function NEXUS:PlayerCanUseEntityInVehicle(player, entity, vehicle)
1480 if ( entity.UsableInVehicle or nexus.entity.IsDoor(entity) ) then
1481 return true;
1482 end;
1483end;
1484
1485-- Called when a player's ragdoll attempts to decay.
1486function NEXUS:PlayerCanRagdollDecay(player, ragdoll, seconds)
1487 return true;
1488end;
1489
1490-- Called when a player attempts to exit a vehicle.
1491function 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;
1525end;
1526
1527-- Called when a player leaves a vehicle.
1528function 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);
1548end;
1549
1550-- Called when a player enters a vehicle.
1551function 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);
1570end;
1571
1572-- Called when a player attempts to change class.
1573function 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;
1583end;
1584
1585-- Called when a player attempts to earn generator cash.
1586function NEXUS:PlayerCanEarnGeneratorCash(player, info, cash)
1587 return true;
1588end;
1589
1590-- Called when a player earns generator cash.
1591function NEXUS:PlayerEarnGeneratorCash(player, info, cash) end;
1592
1593-- Called when a player attempts to earn wages cash.
1594function NEXUS:PlayerCanEarnWagesCash(player, cash)
1595 return true;
1596end;
1597
1598-- Called when a player is given wages cash.
1599function NEXUS:PlayerGiveWagesCash(player, cash, wagesName)
1600 return true;
1601end;
1602
1603-- Called when a player earns wages cash.
1604function NEXUS:PlayerEarnWagesCash(player, cash) end;
1605
1606-- Called when Nexus has loaded all of the entities.
1607function NEXUS:NexusInitPostEntity() end;
1608
1609-- Called when the map has loaded all the entities.
1610function 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;
1634end;
1635
1636-- Called when a player attempts to say something in-character.
1637function 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;
1645end;
1646
1647-- Called when a player attempts to say something out-of-character.
1648function NEXUS:PlayerCanSayOOC(player, text) return true; end;
1649
1650-- Called when a player attempts to say something locally out-of-character.
1651function NEXUS:PlayerCanSayLOOC(player, text) return true; end;
1652
1653-- Called when attempts to use a command.
1654function NEXUS:PlayerCanUseCommand(player, commandTable, arguments) return true; end;
1655
1656-- Called when a player says something.
1657function 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 "";
1726end;
1727
1728-- Called when a player attempts to suicide.
1729function NEXUS:CanPlayerSuicide(player) return false; end;
1730
1731-- Called when a player attempts to punt an entity with the gravity gun.
1732function NEXUS:GravGunPunt(player, entity)
1733 return nexus.config.Get("enable_gravgun_punt"):Get();
1734end;
1735
1736-- Called when a player attempts to pickup an entity with the gravity gun.
1737function 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;
1747end;
1748
1749-- Called when a player picks up an entity with the gravity gun.
1750function NEXUS:GravGunOnPickedUp(player, entity)
1751 player.isHoldingEntity = entity;
1752 entity.isBeingHeld = player;
1753end;
1754
1755-- Called when a player drops an entity with the gravity gun.
1756function NEXUS:GravGunOnDropped(player, entity)
1757 player.isHoldingEntity = nil;
1758 entity.isBeingHeld = nil;
1759end;
1760
1761-- Called when a player attempts to unfreeze an entity.
1762function 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;
1784end;
1785
1786-- Called when a player attempts to freeze an entity with the physics gun.
1787function 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;
1821end;
1822
1823-- Called when a player attempts to pickup an entity with the physics gun.
1824function 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;
1891end;
1892
1893-- Called when a player attempts to drop an entity with the physics gun.
1894function 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;
1906end;
1907
1908-- Called when a player attempts to spawn an NPC.
1909function 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;
1925end;
1926
1927-- Called when an NPC has been killed.
1928function NEXUS:OnNPCKilled(entity, attacker, inflictor) end;
1929
1930-- Called to get whether an entity is being held.
1931function NEXUS:GetEntityBeingHeld(entity)
1932 return entity.isBeingHeld or entity:IsPlayerHolding();
1933end;
1934
1935-- Called when an entity is removed.
1936function 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;
1952end;
1953
1954-- Called when an entity's menu option should be handled.
1955function 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;
2083end;
2084
2085-- Called when a player has spawned a prop.
2086function 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;
2121end;
2122
2123-- Called when a player attempts to spawn a prop.
2124function 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);
2140end;
2141
2142-- Called when a player attempts to spawn a ragdoll.
2143function 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;
2157end;
2158
2159-- Called when a player attempts to spawn an effect.
2160function 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;
2172end;
2173
2174-- Called when a player attempts to spawn a vehicle.
2175function 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);
2195end;
2196
2197-- Called when a player attempts to use a tool.
2198function 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;
2275end;
2276
2277-- Called when a player attempts to NoClip.
2278function 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;
2286end;
2287
2288-- Called when a player's character has initialized.
2289function 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;
2353end;
2354
2355-- Called when a player has used their death code.
2356function NEXUS:PlayerDeathCodeUsed(player, commandTable, arguments) end;
2357
2358-- Called when a player has created a character.
2359function NEXUS:PlayerCharacterCreated(player, character) end;
2360
2361-- Called when a player's character has unloaded.
2362function 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);
2369end;
2370
2371-- Called when a player's character has loaded.
2372function 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;
2420end;
2421
2422-- Called when a player's property should be restored.
2423function NEXUS:PlayerReturnProperty(player) end;
2424
2425-- Called when config has initialized for a player.
2426function 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;
2439end;
2440
2441-- Called when a player initially spawns.
2442function 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;
2460end;
2461
2462-- Called each frame that a player is dead.
2463function 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;
2475end;
2476
2477-- Called when a player has used their radio.
2478function NEXUS:PlayerRadioUsed(player, text, listeners, eavesdroppers) end;
2479
2480-- Called when a player's drop weapon info should be adjusted.
2481function NEXUS:PlayerAdjustDropWeaponInfo(player, info)
2482 return true;
2483end;
2484
2485-- Called when a player's character creation info should be adjusted.
2486function NEXUS:PlayerAdjustCharacterCreationInfo(player, info, data) end;
2487
2488-- Called when a player's earn generator info should be adjusted.
2489function NEXUS:PlayerAdjustEarnGeneratorInfo(player, info) end;
2490
2491-- Called when a player's order item should be adjusted.
2492function NEXUS:PlayerAdjustOrderItemTable(player, itemTable) end;
2493
2494-- Called when a player's next punch info should be adjusted.
2495function NEXUS:PlayerAdjustNextPunchInfo(player, info) end;
2496
2497-- Called when a player has an unknown inventory item.
2498function NEXUS:PlayerHasUnknownInventoryItem(player, inventory, item, amount) end;
2499
2500-- Called when a player uses an unknown item function.
2501function NEXUS:PlayerUseUnknownItemFunction(player, itemTable, itemFunction) end;
2502
2503-- Called when a player has an unknown attribute.
2504function NEXUS:PlayerHasUnknownAttribute(player, attributes, attribute, amount, progress) end;
2505
2506-- Called when a player's character table should be adjusted.
2507function 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;
2516end;
2517
2518-- Called when a player's character screen info should be adjusted.
2519function NEXUS:PlayerAdjustCharacterScreenInfo(player, character, info) end;
2520
2521-- Called when a player's prop cost info should be adjusted.
2522function NEXUS:PlayerAdjustPropCostInfo(player, entity, info) end;
2523
2524-- Called when a player's death info should be adjusted.
2525function NEXUS:PlayerAdjustDeathInfo(player, info) end;
2526
2527-- Called when debug info should be adjusted.
2528function NEXUS:DebugAdjustInfo(info) end;
2529
2530-- Called when chat box info should be adjusted.
2531function NEXUS:ChatBoxAdjustInfo(info) end;
2532
2533-- Called when a chat box message has been added.
2534function NEXUS:ChatBoxMessageAdded(info) end;
2535
2536-- Called when a player's radio text should be adjusted.
2537function NEXUS:PlayerAdjustRadioInfo(player, info) end;
2538
2539-- Called when a player should gain a frag.
2540function NEXUS:PlayerCanGainFrag(player, victim) return true; end;
2541
2542-- Called when a player's model should be set.
2543function NEXUS:PlayerSetModel(player)
2544 nexus.player.SetDefaultModel(player);
2545 nexus.player.SetDefaultSkin(player);
2546end;
2547
2548-- Called just after a player spawns.
2549function 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;
2575end;
2576
2577-- Called when a player spawns.
2578function 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;
2641end;
2642
2643-- Called when a player should take damage.
2644function NEXUS:PlayerShouldTakeDamage(player, attacker, inflictor, damageInfo)
2645 if ( nexus.player.IsNoClipping(player) ) then
2646 return false;
2647 end;
2648
2649 return true;
2650end;
2651
2652-- Called when a player is attacked by a trace.
2653function NEXUS:PlayerTraceAttack(player, damageInfo, direction, trace)
2654 player.lastHitGroup = trace.HitGroup;
2655
2656 return false;
2657end;
2658
2659-- Called just before a player dies.
2660function 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;
2708end;
2709
2710-- Called when a player dies.
2711function 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;
2735end;
2736
2737-- Called when a player's weapons should be given.
2738function 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");
2774end
2775
2776-- Called when the server shuts down.
2777function NEXUS:ShutDown()
2778 self.ShuttingDown = true;
2779end;
2780
2781-- Called when a player presses F1.
2782function NEXUS:ShowHelp(player)
2783 umsg.Start("nx_MenuToggle", player);
2784 umsg.End();
2785end;
2786
2787-- Called when a player presses F2.
2788function 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;
2840end;
2841
2842NEXUS: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;
2885end);
2886
2887-- Called when a player selects a custom character option.
2888function NEXUS:PlayerSelectCustomCharacterOption(player, action, character) end;
2889
2890-- Called when a player takes damage.
2891function NEXUS:PlayerTakeDamage(player, inflictor, attacker, hitGroup, damageInfo) end;
2892
2893-- Called when an entity takes damage.
2894function 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;
3062end;
3063
3064-- Called when the death sound for a player should be played.
3065function NEXUS:PlayerDeathSound(player) return true; end;
3066
3067-- Called when a player attempts to spawn a SWEP.
3068function NEXUS:PlayerSpawnSWEP(player, class, weapon)
3069 if ( !player:IsSuperAdmin() ) then
3070 return false;
3071 else
3072 return true;
3073 end;
3074end;
3075
3076-- Called when a player is given a SWEP.
3077function NEXUS:PlayerGiveSWEP(player, class, weapon)
3078 if ( !player:IsSuperAdmin() ) then
3079 return false;
3080 else
3081 return true;
3082 end;
3083end;
3084
3085-- Called when attempts to spawn a SENT.
3086function NEXUS:PlayerSpawnSENT(player, class)
3087 if ( !player:IsSuperAdmin() ) then
3088 return false;
3089 else
3090 return true;
3091 end;
3092end;
3093
3094-- Called when a player presses a key.
3095function 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;
3140end;
3141
3142-- Called when a player releases a key.
3143function NEXUS:KeyRelease(player, key)
3144 if (key == IN_RELOAD and player.reloadHoldTime) then
3145 player.reloadHoldTime = nil;
3146 end;
3147end;
3148
3149NEXUS: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;
3248end);
3249
3250NEXUS: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;
3263end);
3264
3265NEXUS: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;
3273end);
3274
3275NEXUS: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;
3297end);
3298
3299NEXUS: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;
3303end);
3304
3305NEXUS: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;
3318end);
3319
3320NEXUS: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;
3518end);
3519
3520NEXUS: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;
3549end);
3550
3551NEXUS: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;
3562end);
3563
3564NEXUS: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;
3584end);
3585
3586NEXUS: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;
3596end);
3597
3598local playerMeta = FindMetaTable("Player");
3599local entityMeta = FindMetaTable("Entity");
3600
3601playerMeta.NexusSetCrouchedWalkSpeed = playerMeta.SetCrouchedWalkSpeed;
3602playerMeta.NexusLastHitGroup = playerMeta.LastHitGroup;
3603playerMeta.NexusSetJumpPower = playerMeta.SetJumpPower;
3604playerMeta.NexusSetWalkSpeed = playerMeta.SetWalkSpeed;
3605playerMeta.NexusStripWeapons = playerMeta.StripWeapons;
3606playerMeta.NexusSetRunSpeed = playerMeta.SetRunSpeed;
3607entityMeta.NexusSetMaterial = entityMeta.SetMaterial;
3608playerMeta.NexusStripWeapon = playerMeta.StripWeapon;
3609playerMeta.NexusGodDisable = playerMeta.GodDisable;
3610entityMeta.NexusExtinguish = entityMeta.Extinguish;
3611entityMeta.NexusWaterLevel = entityMeta.WaterLevel;
3612playerMeta.NexusGodEnable = playerMeta.GodEnable;
3613entityMeta.NexusSetHealth = entityMeta.SetHealth;
3614entityMeta.NexusSetColor = entityMeta.SetColor;
3615entityMeta.NexusIsOnFire = entityMeta.IsOnFire;
3616entityMeta.NexusSetModel = entityMeta.SetModel;
3617playerMeta.NexusSetArmor = playerMeta.SetArmor;
3618entityMeta.NexusSetSkin = entityMeta.SetSkin;
3619entityMeta.NexusAlive = playerMeta.Alive;
3620playerMeta.NexusGive = playerMeta.Give;
3621playerMeta.SteamName = playerMeta.Name;
3622
3623-- A function to get a player's name.
3624function playerMeta:Name()
3625 return self:QueryCharacter( "name", self:SteamName() );
3626end;
3627
3628-- A function to get whether a player is alive.
3629function playerMeta:Alive()
3630 if (!self.fakingDeath) then
3631 return self:NexusAlive();
3632 else
3633 return false;
3634 end;
3635end;
3636
3637-- A function to set whether a player is faking death.
3638function playerMeta:SetFakingDeath(fakingDeath, killSilent)
3639 self.fakingDeath = fakingDeath;
3640
3641 if (!fakingDeath and killSilent) then
3642 self:KillSilent();
3643 end;
3644end;
3645
3646-- A function to save a player's character.
3647function playerMeta:SaveCharacter()
3648 nexus.player.SaveCharacter(self);
3649end;
3650
3651-- A function to give a player an item weapon.
3652function playerMeta:GiveItemWeapon(item)
3653 nexus.player.GiveItemWeapon(self, item);
3654end;
3655
3656-- A function to give a weapon to a player.
3657function 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);
3716end;
3717
3718-- A function to get a player's data.
3719function 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;
3729end;
3730
3731-- A function to set a player's data.
3732function playerMeta:SetData(key, value)
3733 if (self.data) then
3734 self.data[key] = value;
3735 end;
3736end;
3737
3738-- A function to get a player's playback rate.
3739function playerMeta:GetPlaybackRate()
3740 return self.playbackRate or 1;
3741end;
3742
3743-- A function to set an entity's skin.
3744function entityMeta:SetSkin(skin)
3745 if ( self:IsPlayer() and self:IsRagdolled() ) then
3746 self:GetRagdollEntity():SetSkin(skin);
3747 end;
3748
3749 self:NexusSetSkin(skin);
3750end;
3751
3752-- A function to set an entity's model.
3753function 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);
3760end;
3761
3762-- A function to get an entity's owner key.
3763function entityMeta:GetOwnerKey()
3764 return self.ownerKey;
3765end;
3766
3767-- A function to set an entity's owner key.
3768function entityMeta:SetOwnerKey(key)
3769 self.ownerKey = key;
3770end;
3771
3772-- A function to get whether an entity is a map entity.
3773function entityMeta:IsMapEntity()
3774 return nexus.entity.IsMapEntity(self);
3775end;
3776
3777-- A function to get an entity's start position.
3778function entityMeta:GetStartPosition()
3779 return nexus.entity.GetStartPosition(self);
3780end;
3781
3782-- A function to set an entity's material.
3783function entityMeta:SetMaterial(material)
3784 if ( self:IsPlayer() and self:IsRagdolled() ) then
3785 self:GetRagdollEntity():SetMaterial(material);
3786 end;
3787
3788 self:NexusSetMaterial(material);
3789end;
3790
3791-- A function to set an entity's color.
3792function 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);
3798end;
3799
3800-- A function to set a player's armor.
3801function playerMeta:SetArmor(armor)
3802 nexus.mount.Call("PlayerArmorSet", self, armor);
3803
3804 self:NexusSetArmor(armor);
3805end;
3806
3807-- A function to set a player's health.
3808function playerMeta:SetHealth(health)
3809 nexus.mount.Call("PlayerHealthSet", self, health);
3810
3811 self:NexusSetHealth(health);
3812end;
3813
3814-- A function to get whether a player is running.
3815function 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;
3826end;
3827
3828-- A function to get whether a player is jogging.
3829function 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;
3840end;
3841
3842-- A function to strip a weapon from a player.
3843function 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;
3855end;
3856
3857-- A function to handle a player's attribute progress.
3858function 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;
3877end;
3878
3879-- A function to handle a player's attribute boosts.
3880function 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;
3900end;
3901
3902-- A function to strip a player's weapons.
3903function playerMeta:StripWeapons(ragdollForce)
3904 if (self:IsRagdolled() and !ragdollForce) then
3905 self:GetRagdollTable().weapons = {};
3906 else
3907 self:NexusStripWeapons();
3908 end;
3909end;
3910
3911-- A function to enable God for a player.
3912function playerMeta:GodEnable()
3913 self.godMode = true; self:NexusGodEnable();
3914end;
3915
3916-- A function to disable God for a player.
3917function playerMeta:GodDisable()
3918 self.godMode = nil; self:NexusGodDisable();
3919end;
3920
3921-- A function to get whether a player has God mode enabled.
3922function playerMeta:IsInGodMode()
3923 return self.godMode;
3924end;
3925
3926-- A function to update whether a player's weapon is raised.
3927function playerMeta:UpdateWeaponRaised()
3928 nexus.player.UpdateWeaponRaised(self);
3929end;
3930
3931-- A function to get a player's water level.
3932function playerMeta:WaterLevel()
3933 if ( self:IsRagdolled() ) then
3934 return self:GetRagdollEntity():WaterLevel();
3935 else
3936 return self:NexusWaterLevel();
3937 end;
3938end;
3939
3940-- A function to get whether a player is on fire.
3941function playerMeta:IsOnFire()
3942 if ( self:IsRagdolled() ) then
3943 return self:GetRagdollEntity():IsOnFire();
3944 else
3945 return self:NexusIsOnFire();
3946 end;
3947end;
3948
3949-- A function to extinguish a player.
3950function playerMeta:Extinguish()
3951 if ( self:IsRagdolled() ) then
3952 return self:GetRagdollEntity():Extinguish();
3953 else
3954 return self:NexusExtinguish();
3955 end;
3956end;
3957
3958-- A function to get whether a player is using their hands.
3959function playerMeta:IsUsingHands()
3960 return nexus.player.GetWeaponClass(self) == "nx_hands";
3961end;
3962
3963-- A function to get whether a player is using their hands.
3964function playerMeta:IsUsingKeys()
3965 return nexus.player.GetWeaponClass(self) == "nx_keys";
3966end;
3967
3968-- A function to get a player's wages.
3969function playerMeta:GetWages()
3970 return nexus.player.GetWages(self);
3971end;
3972
3973-- A function to get a player's community ID.
3974function 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;
3982end;
3983
3984-- A function to get whether a player is ragdolled.
3985function playerMeta:IsRagdolled(exception, entityless)
3986 return nexus.player.IsRagdolled(self, exception, entityless);
3987end;
3988
3989-- A function to get whether a player is kicked.
3990function playerMeta:IsKicked()
3991 return self.isKicked;
3992end;
3993
3994-- A function to get whether a player has spawned.
3995function playerMeta:HasSpawned()
3996 return self.hasSpawned;
3997end;
3998
3999-- A function to kick a player.
4000function 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;
4021end;
4022
4023-- A function to ban a player.
4024function playerMeta:Ban(duration, reason)
4025 NEXUS:AddBan(self:SteamID(), duration * 60, reason);
4026end;
4027
4028-- A function to get a player's character table.
4029function playerMeta:GetCharacter() return nexus.player.GetCharacter(self); end;
4030
4031-- A function to get a player's storage table.
4032function playerMeta:GetStorageTable() return nexus.player.GetStorageTable(self); end;
4033
4034-- A function to get a player's ragdoll table.
4035function playerMeta:GetRagdollTable() return nexus.player.GetRagdollTable(self); end;
4036
4037-- A function to get a player's ragdoll state.
4038function playerMeta:GetRagdollState() return nexus.player.GetRagdollState(self); end;
4039
4040-- A function to get a player's storage entity.
4041function playerMeta:GetStorageEntity() return nexus.player.GetStorageEntity(self); end;
4042
4043-- A function to get a player's ragdoll entity.
4044function playerMeta:GetRagdollEntity() return nexus.player.GetRagdollEntity(self); end;
4045
4046-- A function to get a player's ragdoll weapons.
4047function playerMeta:GetRagdollWeapons()
4048 return self:GetRagdollTable().weapons or {};
4049end;
4050
4051-- A function to get whether a player's ragdoll has a weapon.
4052function 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;
4062end;
4063
4064-- A function to set a player's maximum armor.
4065function playerMeta:SetMaxArmor(armor)
4066 self:SetSharedVar("sh_MaxArmor", armor);
4067end;
4068
4069-- A function to get a player's maximum armor.
4070function 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;
4078end;
4079
4080-- A function to set a player's maximum health.
4081function playerMeta:SetMaxHealth(health)
4082 self:SetSharedVar("sh_MaxHealth", health);
4083end;
4084
4085-- A function to get a player's maximum health.
4086function 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;
4094end;
4095
4096-- A function to get whether a player is viewing the starter hints.
4097function playerMeta:IsViewingStarterHints()
4098 return self.isViewingStarterHints;
4099end;
4100
4101-- A function to get a player's last hit group.
4102function playerMeta:LastHitGroup()
4103 return self.lastHitGroup or self:NexusLastHitGroup();
4104end;
4105
4106-- A function to get whether an entity is being held.
4107function entityMeta:IsBeingHeld()
4108 if ( IsValid(self) ) then
4109 return nexus.mount.Call("GetEntityBeingHeld", self);
4110 end;
4111end;
4112
4113-- A function to run a command on a player.
4114function playerMeta:RunCommand(...)
4115 NEXUS:StartDataStream( self, "RunCommand", {...} );
4116end;
4117
4118-- A function to get a player's wages name.
4119function playerMeta:GetWagesName()
4120 return nexus.player.GetWagesName(self);
4121end;
4122
4123-- A function to set a player's forced animation.
4124function 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;
4172end;
4173
4174-- A function to set whether a player's config has initialized.
4175function playerMeta:SetConfigInitialized(initialized)
4176 self.configInitialized = initialized;
4177end;
4178
4179-- A function to get whether a player's config has initialized.
4180function playerMeta:HasConfigInitialized()
4181 return self.configInitialized;
4182end;
4183
4184-- A function to get a player's forced animation.
4185function playerMeta:GetForcedAnimation()
4186 return self.forcedAnimation;
4187end;
4188
4189-- A function to get a player's item entity.
4190function playerMeta:GetItemEntity()
4191 if ( IsValid(self.itemEntity) ) then
4192 return self.itemEntity;
4193 end;
4194end;
4195
4196-- A function to set a player's item entity.
4197function playerMeta:SetItemEntity(entity)
4198 self.itemEntity = entity;
4199end;
4200
4201-- A function to create a player's temporary data.
4202function 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];
4210end;
4211
4212-- A function to make a player fake pickup an entity.
4213function 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;
4229end;
4230
4231-- A function to set a player's temporary data.
4232function playerMeta:SetTempData(key, value)
4233 local tempData = self:CreateTempData();
4234
4235 if (tempData) then
4236 tempData[key] = value;
4237 end;
4238end;
4239
4240-- A function to get a player's temporary data.
4241function 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;
4249end;
4250
4251-- A function to get whether a player has an item.
4252function playerMeta:HasItem(item, anywhere)
4253 return nexus.inventory.HasItem(self, item, anywhere);
4254end;
4255
4256-- A function to get a player's attribute boosts.
4257function playerMeta:GetAttributeBoosts()
4258 return self.attributeBoosts;
4259end;
4260
4261-- A function to rebuild a player's inventory.
4262function playerMeta:RebuildInventory()
4263 nexus.inventory.Rebuild(self);
4264end;
4265
4266-- A function to update a player's inventory.
4267function playerMeta:UpdateInventory(item, amount, force, noMessage)
4268 return nexus.inventory.Update(self, item, amount, force, noMessage);
4269end;
4270
4271-- A function to update a player's attribute.
4272function playerMeta:UpdateAttribute(attribute, amount)
4273 return nexus.attributes.Update(self, attribute, amount);
4274end;
4275
4276-- A function to progress a player's attribute.
4277function playerMeta:ProgressAttribute(attribute, amount, gradual)
4278 return nexus.attributes.Progress(self, attribute, amount, gradual);
4279end;
4280
4281-- A function to boost a player's attribute.
4282function playerMeta:BoostAttribute(identifier, attribute, amount, duration)
4283 return nexus.attributes.Boost(self, identifier, attribute, amount, duration);
4284end;
4285
4286-- A function to get whether a boost is active for a player.
4287function playerMeta:IsBoostActive(identifier, attribute, amount, duration)
4288 return nexus.attributes.IsBoostActive(self, identifier, attribute, amount, duration);
4289end;
4290
4291-- A function to get a player's characters.
4292function playerMeta:GetCharacters()
4293 return self.characters;
4294end;
4295
4296-- A function to set a player's run speed.
4297function playerMeta:SetRunSpeed(speed, nexus)
4298 if (!nexus) then self.runSpeed = speed; end;
4299
4300 self:NexusSetRunSpeed(speed);
4301end;
4302
4303-- A function to set a player's walk speed.
4304function playerMeta:SetWalkSpeed(speed, nexus)
4305 if (!nexus) then self.walkSpeed = speed; end;
4306
4307 self:NexusSetWalkSpeed(speed);
4308end;
4309
4310-- A function to set a player's jump power.
4311function playerMeta:SetJumpPower(power, nexus)
4312 if (!nexus) then self.jumpPower = power; end;
4313
4314 self:NexusSetJumpPower(power);
4315end;
4316
4317-- A function to set a player's crouched walk speed.
4318function playerMeta:SetCrouchedWalkSpeed(speed, nexus)
4319 if (!nexus) then self.crouchedSpeed = speed; end;
4320
4321 self:NexusSetCrouchedWalkSpeed(speed);
4322end;
4323
4324-- A function to get whether a player has initialized.
4325function playerMeta:HasInitialized()
4326 return self.initialized;
4327end;
4328
4329-- A function to query a player's character table.
4330function playerMeta:QueryCharacter(key, default)
4331 if ( self:GetCharacter() ) then
4332 return nexus.player.Query(self, key, default);
4333 else
4334 return default;
4335 end;
4336end;
4337
4338-- A function to get a player's shared variable.
4339function 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;
4345end;
4346
4347-- A function to set a shared variable for a player.
4348function 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;
4354end;
4355
4356-- A function to get a player's character data.
4357function 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;
4369end;
4370
4371-- A function to get a player's time joined.
4372function playerMeta:TimeJoined()
4373 return self.timeJoined or os.time();
4374end;
4375
4376-- A function to get when a player last played.
4377function playerMeta:LastPlayed()
4378 return self.lastPlayed or os.time();
4379end;
4380
4381-- A function to set a player's character data.
4382function 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;
4394end;
4395
4396-- A function to get the entity a player is holding.
4397function playerMeta:GetHoldingEntity()
4398 return self.isHoldingEntity;
4399end;
4400
4401playerMeta.GetName = playerMeta.Name;
4402playerMeta.Nick = playerMeta.Name;
4403--[[
4404Name: "sv_auto.lua".
4405Product: "Nexus".
4406--]]
4407
4408for k, v in pairs( file.Find("../materials/decals/flesh/blood*") ) do
4409 resource.AddFile("materials/decals/flesh/"..v);
4410end;
4411
4412for k, v in pairs( file.Find("../materials/decals/blood*") ) do
4413 resource.AddFile("materials/decals/"..v);
4414end;
4415
4416for k, v in pairs( file.Find("../materials/effects/blood*") ) do
4417 resource.AddFile("materials/effects/"..v);
4418end;
4419
4420for k, v in pairs( file.Find("../materials/sprites/blood*") ) do
4421 resource.AddFile("materials/sprites/"..v);
4422end;
4423
4424resource.AddFile("materials/gui/silkicons/information.vtf");
4425resource.AddFile("materials/gui/silkicons/information.vmt");
4426resource.AddFile("materials/gui/silkicons/user_delete.vtf");
4427resource.AddFile("materials/gui/silkicons/user_delete.vmt");
4428resource.AddFile("materials/gui/silkicons/newspaper.vtf");
4429resource.AddFile("materials/gui/silkicons/newspaper.vmt");
4430resource.AddFile("materials/gui/silkicons/user_add.vtf");
4431resource.AddFile("materials/gui/silkicons/user_add.vmt");
4432resource.AddFile("materials/gui/silkicons/comment.vtf");
4433resource.AddFile("materials/gui/silkicons/comment.vmt");
4434resource.AddFile("materials/gui/silkicons/error.vtf");
4435resource.AddFile("materials/gui/silkicons/error.vmt");
4436resource.AddFile("materials/gui/silkicons/help.vtf");
4437resource.AddFile("materials/gui/silkicons/help.vmt");
4438resource.AddFile("models/humans/female_gestures.ani");
4439resource.AddFile("models/humans/female_gestures.mdl");
4440resource.AddFile("models/humans/female_postures.ani");
4441resource.AddFile("models/humans/female_postures.mdl");
4442resource.AddFile("models/combine_soldier_anims.ani");
4443resource.AddFile("models/combine_soldier_anims.mdl");
4444resource.AddFile("models/humans/female_shared.ani");
4445resource.AddFile("models/humans/female_shared.mdl");
4446resource.AddFile("models/humans/male_gestures.ani");
4447resource.AddFile("models/humans/male_gestures.mdl");
4448resource.AddFile("models/humans/male_postures.ani");
4449resource.AddFile("models/humans/male_postures.mdl");
4450resource.AddFile("models/humans/male_shared.ani");
4451resource.AddFile("models/humans/male_shared.mdl");
4452resource.AddFile("materials/nexus/xhlogo.vtf");
4453resource.AddFile("materials/nexus/xhlogo.vmt");
4454resource.AddFile("models/police_animations.ani");
4455resource.AddFile("models/police_animations.mdl");
4456resource.AddFile("models/humans/female_ss.ani");
4457resource.AddFile("models/humans/female_ss.mdl");
4458resource.AddFile("materials/nexus/unknown.vtf");
4459resource.AddFile("materials/nexus/unknown.vmt");
4460resource.AddFile("models/humans/male_ss.ani");
4461resource.AddFile("models/humans/male_ss.mdl");
4462resource.AddFile("models/police_ss.ani");
4463resource.AddFile("models/police_ss.mdl");
4464
4465CreateConVar("npc_thinknow", 1);
4466
4467AddCSLuaFile("sh_enums.lua");
4468AddCSLuaFile("sh_core.lua");
4469AddCSLuaFile("sh_auto.lua");
4470AddCSLuaFile("cl_auto.lua");
4471
4472include("sh_auto.lua");
4473
4474local gradientTexture = nexus.schema.GetOption("gradient");
4475local introImage = nexus.schema.GetOption("intro_image");
4476local CurTime = CurTime;
4477local hook = hook;
4478
4479if (gradientTexture != "gui/gradient_up") then
4480 resource.AddFile("materials/"..gradientTexture..".vtf");
4481 resource.AddFile("materials/"..gradientTexture..".vmt");
4482end;
4483
4484if (introImage != "") then
4485 resource.AddFile("materials/"..introImage..".vtf");
4486 resource.AddFile("materials/"..introImage..".vmt");
4487end;
4488
4489_R["CRecipientFilter"].IsValid = function()
4490 return true;
4491end;
4492
4493hook.NexusCall = hook.Call;
4494
4495-- A function to call a hook.
4496function 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;
4528end;
4529
4530-- Called when the server initializes.
4531function 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();
4597end;
4598
4599-- Called when a player has disconnected.
4600function 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;
4616end;
4617
4618-- Called when the Nexus core has loaded.
4619function NEXUS:NexusCoreLoaded()
4620 nexus.config.Import("nexus/mysql.cfg");
4621end;
4622
4623-- Called when Nexus has initialized.
4624function 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;
4636end;
4637
4638-- Called when a player is banned.
4639function NEXUS:PlayerBanned(player, duration, reason) end;
4640
4641-- Called when a player's model has changed.
4642function NEXUS:PlayerModelChanged(player, model) end;
4643
4644-- Called when a player's inventory string is needed.
4645function 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;
4680end;
4681
4682-- Called when a player's unlock info is needed.
4683function 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;
4692end;
4693
4694-- Called when a player's lock info is needed.
4695function 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;
4704end;
4705
4706-- Called when data should be saved.
4707function 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;
4721end;
4722
4723-- Called when a player attempts to fire a weapon.
4724function 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;
4739end;
4740
4741-- Called when a player attempts to use a lowered weapon.
4742function 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;
4748end;
4749
4750-- Called when a player's recognised names have been cleared.
4751function NEXUS:PlayerRecognisedNamesCleared(player, status, simple) end;
4752
4753-- Called when a player's name has been cleared.
4754function NEXUS:PlayerNameCleared(player, status, simple) end;
4755
4756-- Called when an offline player has been given property.
4757function NEXUS:PlayerPropertyGivenOffline(key, uniqueID, entity, networked, removeDelay) end;
4758
4759-- Called when an offline player has had property taken.
4760function NEXUS:PlayerPropertyTakenOffline(key, uniqueID, entity) end;
4761
4762-- Called when a player has been given property.
4763function NEXUS:PlayerPropertyGiven(player, entity, networked, removeDelay) end;
4764
4765-- Called when a player has had property taken.
4766function NEXUS:PlayerPropertyTaken(player, entity) end;
4767
4768-- Called when a player's visibility should be set up.
4769function 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;
4790end;
4791
4792-- Called when a player has been given flags.
4793function 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") );
4803end;
4804
4805-- Called when a player has had flags taken.
4806function 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") );
4820end;
4821
4822-- Called when the game description is needed.
4823function NEXUS:GetGameDescription()
4824 if (SCHEMA and SCHEMA.name != "Base") then
4825 return SCHEMA.name;
4826 else
4827 return self.Name;
4828 end;
4829end;
4830
4831-- Called when a player's phys desc override is needed.
4832function NEXUS:GetPlayerPhysDescOverride(player, physDesc) end;
4833
4834-- Called when a player's default skin is needed.
4835function NEXUS:GetPlayerDefaultSkin(player)
4836 local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
4837
4838 return skin;
4839end;
4840
4841-- Called when a player's default model is needed.
4842function NEXUS:GetPlayerDefaultModel(player)
4843 local model, skin = nexus.class.GetAppropriateModel(player:Team(), player);
4844
4845 return model;
4846end;
4847
4848-- Called when a player's default inventory is needed.
4849function NEXUS:GetPlayerDefaultInventory(player, character, inventory) end;
4850
4851-- Called to get whether a player's weapon is raised.
4852function 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;
4880end;
4881
4882-- Called when a player's attribute has been updated.
4883function NEXUS:PlayerAttributeUpdated(player, attributeTable, amount) end;
4884
4885-- Called when a player's inventory item has been updated.
4886function NEXUS:PlayerInventoryItemUpdated(player, itemTable, amount, force)
4887 nexus.player.UpdateStorageForPlayer(player, itemTable.uniqueID);
4888end;
4889
4890-- Called when a player's cash has been updated.
4891function NEXUS:PlayerCashUpdated(player, amount, reason, noMessage)
4892 nexus.player.UpdateStorageForPlayer(player);
4893end;
4894
4895-- A function to scale damage by hit group.
4896function 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;
4900end;
4901
4902-- Called when a player switches their flashlight on or off.
4903function 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;
4913end;
4914
4915-- Called when time has passed.
4916function NEXUS:TimePassed(quantity) end;
4917
4918-- Called when Nexus config has initialized.
4919function 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;
4938end;
4939
4940-- Called when a Nexus ConVar has changed.
4941function NEXUS:NexusConVarChanged(name, previousValue, newValue)
4942 if (name == "local_voice" and newValue) then
4943 RunConsoleCommand("sv_alltalk", "1");
4944 end;
4945end;
4946
4947-- Called when Nexus config has changed.
4948function 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;
4998end;
4999
5000-- Called when a player's name has changed.
5001function NEXUS:PlayerNameChanged(player, previousName, newName) end;
5002
5003-- Called when a player attempts to sprays their tag.
5004function 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;
5010end;
5011
5012-- Called when a player attempts to use an entity.
5013function NEXUS:PlayerUse(player, entity)
5014 if ( player:IsRagdolled(RAGDOLL_FALLENOVER) ) then
5015 return false;
5016 else
5017 return true;
5018 end;
5019end;
5020
5021-- Called when a player's move data is set up.
5022function 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;
5040end;
5041
5042-- Called when a player throws a punch.
5043function NEXUS:PlayerPunchThrown(player) end;
5044
5045-- Called when a player knocks on a door.
5046function NEXUS:PlayerKnockOnDoor(player, door) end;
5047
5048-- Called when a player attempts to knock on a door.
5049function NEXUS:PlayerCanKnockOnDoor(player, door) return true; end;
5050
5051-- Called when a player punches an entity.
5052function NEXUS:PlayerPunchEntity(player, entity) end;
5053
5054-- Called when a player orders an item shipment.
5055function NEXUS:PlayerOrderShipment(player, itemTable, entity) end;
5056
5057-- Called when a player holsters a weapon.
5058function NEXUS:PlayerHolsterWeapon(player, itemTable, forced)
5059 if (itemTable.OnHolster) then
5060 itemTable:OnHolster(player, forced);
5061 end;
5062end;
5063
5064-- Called when a player attempts to save a recognised name.
5065function NEXUS:PlayerCanSaveRecognisedName(player, target)
5066 if (player != target) then return true; end;
5067end;
5068
5069-- Called when a player attempts to restore a recognised name.
5070function NEXUS:PlayerCanRestoreRecognisedName(player, target)
5071 if (player != target) then return true; end;
5072end;
5073
5074-- Called when a player attempts to order an item shipment.
5075function NEXUS:PlayerCanOrderShipment(player, itemTable)
5076 return true;
5077end;
5078
5079-- Called when a player attempts to get up.
5080function NEXUS:PlayerCanGetUp(player) return true; end;
5081
5082-- Called when a player knocks out a player with a punch.
5083function NEXUS:PlayerPunchKnockout(player, target) end;
5084
5085-- Called when a player attempts to throw a punch.
5086function NEXUS:PlayerCanThrowPunch(player) return true; end;
5087
5088-- Called when a player attempts to punch an entity.
5089function NEXUS:PlayerCanPunchEntity(player, entity) return true; end;
5090
5091-- Called when a player attempts to knock a player out with a punch.
5092function NEXUS:PlayerCanPunchKnockout(player, target) return true; end;
5093
5094-- Called when a player attempts to bypass the faction limit.
5095function NEXUS:PlayerCanBypassFactionLimit(player, character) return false; end;
5096
5097-- Called when a player attempts to bypass the class limit.
5098function NEXUS:PlayerCanBypassClassLimit(player, class) return false; end;
5099
5100-- Called when a player's pain sound should be played.
5101function 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";
5117end;
5118
5119-- Called when a player's data has loaded.
5120function 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;
5129end;
5130
5131-- Called when a player attempts to be given a weapon.
5132function NEXUS:PlayerCanBeGivenWeapon(player, class, uniqueID, forceReturn)
5133 return true;
5134end;
5135
5136-- Called when a player has been given a weapon.
5137function NEXUS:PlayerGivenWeapon(player, class, uniqueID, forceReturn)
5138 nexus.inventory.Rebuild(player);
5139end;
5140
5141-- Called when a player attempts to create a character.
5142function 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;
5148end;
5149
5150-- Called when a player attempts to interact with a character.
5151function 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;
5157end;
5158
5159-- Called when a player's fall damage is needed.
5160function 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;
5189end;
5190
5191-- Called when a player's data stream info has been sent.
5192function 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;
5290end;
5291
5292-- Called when a player's data stream info should be sent.
5293function NEXUS:PlayerSendDataStreamInfo(player) end;
5294
5295-- Called when a player's death sound should be played.
5296function NEXUS:PlayerPlayDeathSound(player, gender)
5297 return "vo/npc/"..string.lower(gender).."01/pain0"..math.random(1, 9)..".wav";
5298end;
5299
5300-- Called when a player's character data should be restored.
5301function NEXUS:PlayerRestoreCharacterData(player, data)
5302 if ( data["physdesc"] ) then
5303 data["physdesc"] = self:ModifyPhysDesc( data["physdesc"] );
5304 end;
5305end;
5306
5307-- Called when a player's character data should be saved.
5308function 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;
5323end;
5324
5325-- Called when a player's data should be saved.
5326function NEXUS:PlayerSaveData(player, data)
5327 if (data["whitelisted"] and #data["whitelisted"] == 0) then
5328 data["whitelisted"] = nil;
5329 end;
5330end;
5331
5332-- Called when a player's storage should close.
5333function 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;
5341end;
5342
5343-- Called when a player attempts to pickup a weapon.
5344function 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;
5350end;
5351
5352-- Called each tick.
5353function 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;
5399end;
5400
5401-- Called each frame.
5402function NEXUS:Think()
5403 self:CallTimerThink( CurTime() );
5404end;
5405
5406-- Called when a player's shared variables should be set.
5407function 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;
5460end;
5461
5462-- Called at an interval while a player is connected.
5463function 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);
5505end;
5506
5507-- Called when a player uses an item.
5508function NEXUS:PlayerUseItem(player, itemTable, itemEntity) end;
5509
5510-- Called when a player drops an item.
5511function 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;
5524end;
5525
5526-- Called when a player destroys an item.
5527function NEXUS:PlayerDestroyItem(player, itemTable) end;
5528
5529-- Called when a player drops a weapon.
5530function 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;
5543end;
5544
5545-- Called when a player charges generator.
5546function NEXUS:PlayerChargeGenerator(player, entity, generator) end;
5547
5548-- Called when a player destroys generator.
5549function NEXUS:PlayerDestroyGenerator(player, entity, generator) end;
5550
5551-- Called when a player's data should be restored.
5552function NEXUS:PlayerRestoreData(player, data)
5553 if ( !data["whitelisted"] ) then
5554 data["whitelisted"] = {};
5555 end;
5556end;
5557
5558-- Called when a player's temporary info should be saved.
5559function NEXUS:PlayerSaveTempData(player, tempData) end;
5560
5561-- Called when a player's temporary info should be restored.
5562function NEXUS:PlayerRestoreTempData(player, tempData) end;
5563
5564-- Called when a player selects a custom character option.
5565function NEXUS:PlayerSelectCharacterOption(player, character, option) end;
5566
5567-- Called when a player attempts to see another player's status.
5568function NEXUS:PlayerCanSeeStatus(player, target)
5569 return "# "..target:UserID().." | "..target:Name().." | "..target:SteamName().." | "..target:SteamID().." | "..target:IPAddress();
5570end;
5571
5572-- Called when a player attempts to see a player's chat.
5573function NEXUS:PlayerCanSeePlayersChat(text, teamOnly, listener, speaker)
5574 return true;
5575end;
5576
5577-- Called when a player attempts to hear another player's voice.
5578function 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;
5590end;
5591
5592-- Called when a player attempts to delete a character.
5593function 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;
5601end;
5602
5603-- Called when a player attempts to switch to a character.
5604function 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;
5617end;
5618
5619-- Called when a player attempts to use a character.
5620function NEXUS:PlayerCanUseCharacter(player, character)
5621 if ( character.data["banned"] ) then
5622 return character.name.." is banned and cannot be used!";
5623 end;
5624end;
5625
5626-- Called when a player's weapons should be given.
5627function NEXUS:PlayerGiveWeapons(player) end;
5628
5629-- Called when a player deletes a character.
5630function NEXUS:PlayerDeleteCharacter(player, character) end;
5631
5632-- Called when a player's armor is set.
5633function NEXUS:PlayerArmorSet(player, armor)
5634 if ( player:IsRagdolled() ) then
5635 player:GetRagdollTable().armor = armor;
5636 end;
5637end;
5638
5639-- Called when a player's health is set.
5640function NEXUS:PlayerHealthSet(player, health)
5641 if ( player:IsRagdolled() ) then
5642 player:GetRagdollTable().health = health;
5643 end;
5644end;
5645
5646-- Called when a player attempts to own a door.
5647function NEXUS:PlayerCanOwnDoor(player, door)
5648 if ( nexus.entity.IsDoorUnownable(door) ) then
5649 return false;
5650 else
5651 return true;
5652 end;
5653end;
5654
5655-- Called when a player attempts to view a door.
5656function NEXUS:PlayerCanViewDoor(player, door)
5657 if ( nexus.entity.IsDoorUnownable(door) ) then
5658 return false;
5659 end;
5660
5661 return true;
5662end;
5663
5664-- Called when a player attempts to holster a weapon.
5665function 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;
5677end;
5678
5679-- Called when a player attempts to drop a weapon.
5680function 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;
5692end;
5693
5694-- Called when a player attempts to use an item.
5695function 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;
5705end;
5706
5707-- Called when a player attempts to drop an item.
5708function NEXUS:PlayerCanDropItem(player, itemTable, noMessage) return true; end;
5709
5710-- Called when a player attempts to destroy an item.
5711function NEXUS:PlayerCanDestroyItem(player, itemTable, noMessage) return true; end;
5712
5713-- Called when a player attempts to destroy generator.
5714function NEXUS:PlayerCanDestroyGenerator(player, entity, generator) return true; end;
5715
5716-- Called when a player attempts to knockout a player.
5717function NEXUS:PlayerCanKnockout(player, target) return true; end;
5718
5719-- Called when a player attempts to use the radio.
5720function NEXUS:PlayerCanRadio(player, text, listeners, eavesdroppers) return true; end;
5721
5722-- Called when death attempts to clear a player's name.
5723function NEXUS:PlayerCanDeathClearName(player, attacker, damageInfo) return false; end;
5724
5725-- Called when death attempts to clear a player's recognised names.
5726function NEXUS:PlayerCanDeathClearRecognisedNames(player, attacker, damageInfo) return false; end;
5727
5728-- Called when a player's ragdoll attempts to take damage.
5729function 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;
5737end;
5738
5739-- Called when a player has been authenticated.
5740function 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;
5777end;
5778
5779-- Called when the player attempts to be ragdolled.
5780function NEXUS:PlayerCanRagdoll(player, state, delay, decay, ragdoll)
5781 return true;
5782end;
5783
5784-- Called when the player attempts to be unragdolled.
5785function NEXUS:PlayerCanUnragdoll(player, state, ragdoll)
5786 return true;
5787end;
5788
5789-- Called when a player has been ragdolled.
5790function NEXUS:PlayerRagdolled(player, state, ragdoll)
5791 player:SetSharedVar("sh_FallenOver", false);
5792end;
5793
5794-- Called when a player has been unragdolled.
5795function NEXUS:PlayerUnragdolled(player, state, ragdoll)
5796 player:SetSharedVar("sh_FallenOver", false);
5797end;
5798
5799-- Called to check if a player does have an flag.
5800function NEXUS:PlayerDoesHaveFlag(player, flag)
5801 if ( string.find(nexus.config.Get("default_flags"):Get(), flag) ) then
5802 return true;
5803 end;
5804end;
5805
5806-- Called to check if a player does have door access.
5807function 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;
5823end;
5824
5825-- Called to check if a player does know another player.
5826function NEXUS:PlayerDoesRecognisePlayer(player, target, status, simple, default)
5827 return default;
5828end;
5829
5830-- Called to check if a player does have an item.
5831function NEXUS:PlayerDoesHaveItem(player, itemTable) return false; end;
5832
5833-- Called when a player attempts to lock an entity.
5834function 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;
5840end;
5841
5842-- Called when a player's class has been set.
5843function NEXUS:PlayerClassSet(player, newClass, oldClass, noRespawn, addDelay, noModelChange) end;
5844
5845-- Called when a player attempts to unlock an entity.
5846function 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;
5852end;
5853
5854-- Called when a player attempts to use a door.
5855function 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;
5865end;
5866
5867-- Called when a player uses a door.
5868function NEXUS:PlayerUseDoor(player, door) end;
5869
5870-- Called when a player attempts to use an entity in a vehicle.
5871function NEXUS:PlayerCanUseEntityInVehicle(player, entity, vehicle)
5872 if ( entity.UsableInVehicle or nexus.entity.IsDoor(entity) ) then
5873 return true;
5874 end;
5875end;
5876
5877-- Called when a player's ragdoll attempts to decay.
5878function NEXUS:PlayerCanRagdollDecay(player, ragdoll, seconds)
5879 return true;
5880end;
5881
5882-- Called when a player attempts to exit a vehicle.
5883function 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;
5917end;
5918
5919-- Called when a player leaves a vehicle.
5920function 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);
5940end;
5941
5942-- Called when a player enters a vehicle.
5943function 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);
5962end;
5963
5964-- Called when a player attempts to change class.
5965function 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;
5975end;
5976
5977-- Called when a player attempts to earn generator cash.
5978function NEXUS:PlayerCanEarnGeneratorCash(player, info, cash)
5979 return true;
5980end;
5981
5982-- Called when a player earns generator cash.
5983function NEXUS:PlayerEarnGeneratorCash(player, info, cash) end;
5984
5985-- Called when a player attempts to earn wages cash.
5986function NEXUS:PlayerCanEarnWagesCash(player, cash)
5987 return true;
5988end;
5989
5990-- Called when a player is given wages cash.
5991function NEXUS:PlayerGiveWagesCash(player, cash, wagesName)
5992 return true;
5993end;
5994
5995-- Called when a player earns wages cash.
5996function NEXUS:PlayerEarnWagesCash(player, cash) end;
5997
5998-- Called when Nexus has loaded all of the entities.
5999function NEXUS:NexusInitPostEntity() end;
6000
6001-- Called when the map has loaded all the entities.
6002function 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;
6026end;
6027
6028-- Called when a player attempts to say something in-character.
6029function 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;
6037end;
6038
6039-- Called when a player attempts to say something out-of-character.
6040function NEXUS:PlayerCanSayOOC(player, text) return true; end;
6041
6042-- Called when a player attempts to say something locally out-of-character.
6043function NEXUS:PlayerCanSayLOOC(player, text) return true; end;
6044
6045-- Called when attempts to use a command.
6046function NEXUS:PlayerCanUseCommand(player, commandTable, arguments) return true; end;
6047
6048-- Called when a player says something.
6049function 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 "";
6118end;
6119
6120-- Called when a player attempts to suicide.
6121function NEXUS:CanPlayerSuicide(player) return false; end;
6122
6123-- Called when a player attempts to punt an entity with the gravity gun.
6124function NEXUS:GravGunPunt(player, entity)
6125 return nexus.config.Get("enable_gravgun_punt"):Get();
6126end;
6127
6128-- Called when a player attempts to pickup an entity with the gravity gun.
6129function 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;
6139end;
6140
6141-- Called when a player picks up an entity with the gravity gun.
6142function NEXUS:GravGunOnPickedUp(player, entity)
6143 player.isHoldingEntity = entity;
6144 entity.isBeingHeld = player;
6145end;
6146
6147-- Called when a player drops an entity with the gravity gun.
6148function NEXUS:GravGunOnDropped(player, entity)
6149 player.isHoldingEntity = nil;
6150 entity.isBeingHeld = nil;
6151end;
6152
6153-- Called when a player attempts to unfreeze an entity.
6154function 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;
6176end;
6177
6178-- Called when a player attempts to freeze an entity with the physics gun.
6179function 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;
6213end;
6214
6215-- Called when a player attempts to pickup an entity with the physics gun.
6216function 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;
6283end;
6284
6285-- Called when a player attempts to drop an entity with the physics gun.
6286function 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;
6298end;
6299
6300-- Called when a player attempts to spawn an NPC.
6301function 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;
6317end;
6318
6319-- Called when an NPC has been killed.
6320function NEXUS:OnNPCKilled(entity, attacker, inflictor) end;
6321
6322-- Called to get whether an entity is being held.
6323function NEXUS:GetEntityBeingHeld(entity)
6324 return entity.isBeingHeld or entity:IsPlayerHolding();
6325end;
6326
6327-- Called when an entity is removed.
6328function 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;
6344end;
6345
6346-- Called when an entity's menu option should be handled.
6347function 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;
6475end;
6476
6477-- Called when a player has spawned a prop.
6478function 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;
6513end;
6514
6515-- Called when a player attempts to spawn a prop.
6516function 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);
6532end;
6533
6534-- Called when a player attempts to spawn a ragdoll.
6535function 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;
6549end;
6550
6551-- Called when a player attempts to spawn an effect.
6552function 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;
6564end;
6565
6566-- Called when a player attempts to spawn a vehicle.
6567function 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);
6587end;
6588
6589-- Called when a player attempts to use a tool.
6590function 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;
6667end;
6668
6669-- Called when a player attempts to NoClip.
6670function 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;
6678end;
6679
6680-- Called when a player's character has initialized.
6681function 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;
6745end;
6746
6747-- Called when a player has used their death code.
6748function NEXUS:PlayerDeathCodeUsed(player, commandTable, arguments) end;
6749
6750-- Called when a player has created a character.
6751function NEXUS:PlayerCharacterCreated(player, character) end;
6752
6753-- Called when a player's character has unloaded.
6754function 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);
6761end;
6762
6763-- Called when a player's character has loaded.
6764function 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;
6812end;
6813
6814-- Called when a player's property should be restored.
6815function NEXUS:PlayerReturnProperty(player) end;
6816
6817-- Called when config has initialized for a player.
6818function 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;
6831end;
6832
6833-- Called when a player initially spawns.
6834function 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;
6852end;
6853
6854-- Called each frame that a player is dead.
6855function 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;
6867end;
6868
6869-- Called when a player has used their radio.
6870function NEXUS:PlayerRadioUsed(player, text, listeners, eavesdroppers) end;
6871
6872-- Called when a player's drop weapon info should be adjusted.
6873function NEXUS:PlayerAdjustDropWeaponInfo(player, info)
6874 return true;
6875end;
6876
6877-- Called when a player's character creation info should be adjusted.
6878function NEXUS:PlayerAdjustCharacterCreationInfo(player, info, data) end;
6879
6880-- Called when a player's earn generator info should be adjusted.
6881function NEXUS:PlayerAdjustEarnGeneratorInfo(player, info) end;
6882
6883-- Called when a player's order item should be adjusted.
6884function NEXUS:PlayerAdjustOrderItemTable(player, itemTable) end;
6885
6886-- Called when a player's next punch info should be adjusted.
6887function NEXUS:PlayerAdjustNextPunchInfo(player, info) end;
6888
6889-- Called when a player has an unknown inventory item.
6890function NEXUS:PlayerHasUnknownInventoryItem(player, inventory, item, amount) end;
6891
6892-- Called when a player uses an unknown item function.
6893function NEXUS:PlayerUseUnknownItemFunction(player, itemTable, itemFunction) end;
6894
6895-- Called when a player has an unknown attribute.
6896function NEXUS:PlayerHasUnknownAttribute(player, attributes, attribute, amount, progress) end;
6897
6898-- Called when a player's character table should be adjusted.
6899function 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;
6908end;
6909
6910-- Called when a player's character screen info should be adjusted.
6911function NEXUS:PlayerAdjustCharacterScreenInfo(player, character, info) end;
6912
6913-- Called when a player's prop cost info should be adjusted.
6914function NEXUS:PlayerAdjustPropCostInfo(player, entity, info) end;
6915
6916-- Called when a player's death info should be adjusted.
6917function NEXUS:PlayerAdjustDeathInfo(player, info) end;
6918
6919-- Called when debug info should be adjusted.
6920function NEXUS:DebugAdjustInfo(info) end;
6921
6922-- Called when chat box info should be adjusted.
6923function NEXUS:ChatBoxAdjustInfo(info) end;
6924
6925-- Called when a chat box message has been added.
6926function NEXUS:ChatBoxMessageAdded(info) end;
6927
6928-- Called when a player's radio text should be adjusted.
6929function NEXUS:PlayerAdjustRadioInfo(player, info) end;
6930
6931-- Called when a player should gain a frag.
6932function NEXUS:PlayerCanGainFrag(player, victim) return true; end;
6933
6934-- Called when a player's model should be set.
6935function NEXUS:PlayerSetModel(player)
6936 nexus.player.SetDefaultModel(player);
6937 nexus.player.SetDefaultSkin(player);
6938end;
6939
6940-- Called just after a player spawns.
6941function 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;
6967end;
6968
6969-- Called when a player spawns.
6970function 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;
7033end;
7034
7035-- Called when a player should take damage.
7036function NEXUS:PlayerShouldTakeDamage(player, attacker, inflictor, damageInfo)
7037 if ( nexus.player.IsNoClipping(player) ) then
7038 return false;
7039 end;
7040
7041 return true;
7042end;
7043
7044-- Called when a player is attacked by a trace.
7045function NEXUS:PlayerTraceAttack(player, damageInfo, direction, trace)
7046 player.lastHitGroup = trace.HitGroup;
7047
7048 return false;
7049end;
7050
7051-- Called just before a player dies.
7052function 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;
7100end;
7101
7102-- Called when a player dies.
7103function 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;
7127end;
7128
7129-- Called when a player's weapons should be given.
7130function 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");
7166end
7167
7168-- Called when the server shuts down.
7169function NEXUS:ShutDown()
7170 self.ShuttingDown = true;
7171end;
7172
7173-- Called when a player presses F1.
7174function NEXUS:ShowHelp(player)
7175 umsg.Start("nx_MenuToggle", player);
7176 umsg.End();
7177end;
7178
7179-- Called when a player presses F2.
7180function 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;
7232end;
7233
7234NEXUS: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;
7277end);
7278
7279-- Called when a player selects a custom character option.
7280function NEXUS:PlayerSelectCustomCharacterOption(player, action, character) end;
7281
7282-- Called when a player takes damage.
7283function NEXUS:PlayerTakeDamage(player, inflictor, attacker, hitGroup, damageInfo) end;
7284
7285-- Called when an entity takes damage.
7286function 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;
7454end;
7455
7456-- Called when the death sound for a player should be played.
7457function NEXUS:PlayerDeathSound(player) return true; end;
7458
7459-- Called when a player attempts to spawn a SWEP.
7460function NEXUS:PlayerSpawnSWEP(player, class, weapon)
7461 if ( !player:IsSuperAdmin() ) then
7462 return false;
7463 else
7464 return true;
7465 end;
7466end;
7467
7468-- Called when a player is given a SWEP.
7469function NEXUS:PlayerGiveSWEP(player, class, weapon)
7470 if ( !player:IsSuperAdmin() ) then
7471 return false;
7472 else
7473 return true;
7474 end;
7475end;
7476
7477-- Called when attempts to spawn a SENT.
7478function NEXUS:PlayerSpawnSENT(player, class)
7479 if ( !player:IsSuperAdmin() ) then
7480 return false;
7481 else
7482 return true;
7483 end;
7484end;
7485
7486-- Called when a player presses a key.
7487function 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;
7532end;
7533
7534-- Called when a player releases a key.
7535function NEXUS:KeyRelease(player, key)
7536 if (key == IN_RELOAD and player.reloadHoldTime) then
7537 player.reloadHoldTime = nil;
7538 end;
7539end;
7540
7541NEXUS: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;
7640end);
7641
7642NEXUS: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;
7655end);
7656
7657NEXUS: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;
7665end);
7666
7667NEXUS: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;
7689end);
7690
7691NEXUS: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;
7695end);
7696
7697NEXUS: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;
7710end);
7711
7712NEXUS: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;
7910end);
7911
7912NEXUS: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;
7941end);
7942
7943NEXUS: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;
7954end);
7955
7956NEXUS: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;
7976end);
7977
7978NEXUS: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;
7988end);
7989
7990local playerMeta = FindMetaTable("Player");
7991local entityMeta = FindMetaTable("Entity");
7992
7993playerMeta.NexusSetCrouchedWalkSpeed = playerMeta.SetCrouchedWalkSpeed;
7994playerMeta.NexusLastHitGroup = playerMeta.LastHitGroup;
7995playerMeta.NexusSetJumpPower = playerMeta.SetJumpPower;
7996playerMeta.NexusSetWalkSpeed = playerMeta.SetWalkSpeed;
7997playerMeta.NexusStripWeapons = playerMeta.StripWeapons;
7998playerMeta.NexusSetRunSpeed = playerMeta.SetRunSpeed;
7999entityMeta.NexusSetMaterial = entityMeta.SetMaterial;
8000playerMeta.NexusStripWeapon = playerMeta.StripWeapon;
8001playerMeta.NexusGodDisable = playerMeta.GodDisable;
8002entityMeta.NexusExtinguish = entityMeta.Extinguish;
8003entityMeta.NexusWaterLevel = entityMeta.WaterLevel;
8004playerMeta.NexusGodEnable = playerMeta.GodEnable;
8005entityMeta.NexusSetHealth = entityMeta.SetHealth;
8006entityMeta.NexusSetColor = entityMeta.SetColor;
8007entityMeta.NexusIsOnFire = entityMeta.IsOnFire;
8008entityMeta.NexusSetModel = entityMeta.SetModel;
8009playerMeta.NexusSetArmor = playerMeta.SetArmor;
8010entityMeta.NexusSetSkin = entityMeta.SetSkin;
8011entityMeta.NexusAlive = playerMeta.Alive;
8012playerMeta.NexusGive = playerMeta.Give;
8013playerMeta.SteamName = playerMeta.Name;
8014
8015-- A function to get a player's name.
8016function playerMeta:Name()
8017 return self:QueryCharacter( "name", self:SteamName() );
8018end;
8019
8020-- A function to get whether a player is alive.
8021function playerMeta:Alive()
8022 if (!self.fakingDeath) then
8023 return self:NexusAlive();
8024 else
8025 return false;
8026 end;
8027end;
8028
8029-- A function to set whether a player is faking death.
8030function playerMeta:SetFakingDeath(fakingDeath, killSilent)
8031 self.fakingDeath = fakingDeath;
8032
8033 if (!fakingDeath and killSilent) then
8034 self:KillSilent();
8035 end;
8036end;
8037
8038-- A function to save a player's character.
8039function playerMeta:SaveCharacter()
8040 nexus.player.SaveCharacter(self);
8041end;
8042
8043-- A function to give a player an item weapon.
8044function playerMeta:GiveItemWeapon(item)
8045 nexus.player.GiveItemWeapon(self, item);
8046end;
8047
8048-- A function to give a weapon to a player.
8049function 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);
8108end;
8109
8110-- A function to get a player's data.
8111function 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;
8121end;
8122
8123-- A function to set a player's data.
8124function playerMeta:SetData(key, value)
8125 if (self.data) then
8126 self.data[key] = value;
8127 end;
8128end;
8129
8130-- A function to get a player's playback rate.
8131function playerMeta:GetPlaybackRate()
8132 return self.playbackRate or 1;
8133end;
8134
8135-- A function to set an entity's skin.
8136function entityMeta:SetSkin(skin)
8137 if ( self:IsPlayer() and self:IsRagdolled() ) then
8138 self:GetRagdollEntity():SetSkin(skin);
8139 end;
8140
8141 self:NexusSetSkin(skin);
8142end;
8143
8144-- A function to set an entity's model.
8145function 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);
8152end;
8153
8154-- A function to get an entity's owner key.
8155function entityMeta:GetOwnerKey()
8156 return self.ownerKey;
8157end;
8158
8159-- A function to set an entity's owner key.
8160function entityMeta:SetOwnerKey(key)
8161 self.ownerKey = key;
8162end;
8163
8164-- A function to get whether an entity is a map entity.
8165function entityMeta:IsMapEntity()
8166 return nexus.entity.IsMapEntity(self);
8167end;
8168
8169-- A function to get an entity's start position.
8170function entityMeta:GetStartPosition()
8171 return nexus.entity.GetStartPosition(self);
8172end;
8173
8174-- A function to set an entity's material.
8175function entityMeta:SetMaterial(material)
8176 if ( self:IsPlayer() and self:IsRagdolled() ) then
8177 self:GetRagdollEntity():SetMaterial(material);
8178 end;
8179
8180 self:NexusSetMaterial(material);
8181end;
8182
8183-- A function to set an entity's color.
8184function 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);
8190end;
8191
8192-- A function to set a player's armor.
8193function playerMeta:SetArmor(armor)
8194 nexus.mount.Call("PlayerArmorSet", self, armor);
8195
8196 self:NexusSetArmor(armor);
8197end;
8198
8199-- A function to set a player's health.
8200function playerMeta:SetHealth(health)
8201 nexus.mount.Call("PlayerHealthSet", self, health);
8202
8203 self:NexusSetHealth(health);
8204end;
8205
8206-- A function to get whether a player is running.
8207function 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;
8218end;
8219
8220-- A function to get whether a player is jogging.
8221function 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;
8232end;
8233
8234-- A function to strip a weapon from a player.
8235function 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;
8247end;
8248
8249-- A function to handle a player's attribute progress.
8250function 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;
8269end;
8270
8271-- A function to handle a player's attribute boosts.
8272function 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;
8292end;
8293
8294-- A function to strip a player's weapons.
8295function playerMeta:StripWeapons(ragdollForce)
8296 if (self:IsRagdolled() and !ragdollForce) then
8297 self:GetRagdollTable().weapons = {};
8298 else
8299 self:NexusStripWeapons();
8300 end;
8301end;
8302
8303-- A function to enable God for a player.
8304function playerMeta:GodEnable()
8305 self.godMode = true; self:NexusGodEnable();
8306end;
8307
8308-- A function to disable God for a player.
8309function playerMeta:GodDisable()
8310 self.godMode = nil; self:NexusGodDisable();
8311end;
8312
8313-- A function to get whether a player has God mode enabled.
8314function playerMeta:IsInGodMode()
8315 return self.godMode;
8316end;
8317
8318-- A function to update whether a player's weapon is raised.
8319function playerMeta:UpdateWeaponRaised()
8320 nexus.player.UpdateWeaponRaised(self);
8321end;
8322
8323-- A function to get a player's water level.
8324function playerMeta:WaterLevel()
8325 if ( self:IsRagdolled() ) then
8326 return self:GetRagdollEntity():WaterLevel();
8327 else
8328 return self:NexusWaterLevel();
8329 end;
8330end;
8331
8332-- A function to get whether a player is on fire.
8333function playerMeta:IsOnFire()
8334 if ( self:IsRagdolled() ) then
8335 return self:GetRagdollEntity():IsOnFire();
8336 else
8337 return self:NexusIsOnFire();
8338 end;
8339end;
8340
8341-- A function to extinguish a player.
8342function playerMeta:Extinguish()
8343 if ( self:IsRagdolled() ) then
8344 return self:GetRagdollEntity():Extinguish();
8345 else
8346 return self:NexusExtinguish();
8347 end;
8348end;
8349
8350-- A function to get whether a player is using their hands.
8351function playerMeta:IsUsingHands()
8352 return nexus.player.GetWeaponClass(self) == "nx_hands";
8353end;
8354
8355-- A function to get whether a player is using their hands.
8356function playerMeta:IsUsingKeys()
8357 return nexus.player.GetWeaponClass(self) == "nx_keys";
8358end;
8359
8360-- A function to get a player's wages.
8361function playerMeta:GetWages()
8362 return nexus.player.GetWages(self);
8363end;
8364
8365-- A function to get a player's community ID.
8366function 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;
8374end;
8375
8376-- A function to get whether a player is ragdolled.
8377function playerMeta:IsRagdolled(exception, entityless)
8378 return nexus.player.IsRagdolled(self, exception, entityless);
8379end;
8380
8381-- A function to get whether a player is kicked.
8382function playerMeta:IsKicked()
8383 return self.isKicked;
8384end;
8385
8386-- A function to get whether a player has spawned.
8387function playerMeta:HasSpawned()
8388 return self.hasSpawned;
8389end;
8390
8391-- A function to kick a player.
8392function 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;
8413end;
8414
8415-- A function to ban a player.
8416function playerMeta:Ban(duration, reason)
8417 NEXUS:AddBan(self:SteamID(), duration * 60, reason);
8418end;
8419
8420-- A function to get a player's character table.
8421function playerMeta:GetCharacter() return nexus.player.GetCharacter(self); end;
8422
8423-- A function to get a player's storage table.
8424function playerMeta:GetStorageTable() return nexus.player.GetStorageTable(self); end;
8425
8426-- A function to get a player's ragdoll table.
8427function playerMeta:GetRagdollTable() return nexus.player.GetRagdollTable(self); end;
8428
8429-- A function to get a player's ragdoll state.
8430function playerMeta:GetRagdollState() return nexus.player.GetRagdollState(self); end;
8431
8432-- A function to get a player's storage entity.
8433function playerMeta:GetStorageEntity() return nexus.player.GetStorageEntity(self); end;
8434
8435-- A function to get a player's ragdoll entity.
8436function playerMeta:GetRagdollEntity() return nexus.player.GetRagdollEntity(self); end;
8437
8438-- A function to get a player's ragdoll weapons.
8439function playerMeta:GetRagdollWeapons()
8440 return self:GetRagdollTable().weapons or {};
8441end;
8442
8443-- A function to get whether a player's ragdoll has a weapon.
8444function 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;
8454end;
8455
8456-- A function to set a player's maximum armor.
8457function playerMeta:SetMaxArmor(armor)
8458 self:SetSharedVar("sh_MaxArmor", armor);
8459end;
8460
8461-- A function to get a player's maximum armor.
8462function 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;
8470end;
8471
8472-- A function to set a player's maximum health.
8473function playerMeta:SetMaxHealth(health)
8474 self:SetSharedVar("sh_MaxHealth", health);
8475end;
8476
8477-- A function to get a player's maximum health.
8478function 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;
8486end;
8487
8488-- A function to get whether a player is viewing the starter hints.
8489function playerMeta:IsViewingStarterHints()
8490 return self.isViewingStarterHints;
8491end;
8492
8493-- A function to get a player's last hit group.
8494function playerMeta:LastHitGroup()
8495 return self.lastHitGroup or self:NexusLastHitGroup();
8496end;
8497
8498-- A function to get whether an entity is being held.
8499function entityMeta:IsBeingHeld()
8500 if ( IsValid(self) ) then
8501 return nexus.mount.Call("GetEntityBeingHeld", self);
8502 end;
8503end;
8504
8505-- A function to run a command on a player.
8506function playerMeta:RunCommand(...)
8507 NEXUS:StartDataStream( self, "RunCommand", {...} );
8508end;
8509
8510-- A function to get a player's wages name.
8511function playerMeta:GetWagesName()
8512 return nexus.player.GetWagesName(self);
8513end;
8514
8515-- A function to set a player's forced animation.
8516function 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;
8564end;
8565
8566-- A function to set whether a player's config has initialized.
8567function playerMeta:SetConfigInitialized(initialized)
8568 self.configInitialized = initialized;
8569end;
8570
8571-- A function to get whether a player's config has initialized.
8572function playerMeta:HasConfigInitialized()
8573 return self.configInitialized;
8574end;
8575
8576-- A function to get a player's forced animation.
8577function playerMeta:GetForcedAnimation()
8578 return self.forcedAnimation;
8579end;
8580
8581-- A function to get a player's item entity.
8582function playerMeta:GetItemEntity()
8583 if ( IsValid(self.itemEntity) ) then
8584 return self.itemEntity;
8585 end;
8586end;
8587
8588-- A function to set a player's item entity.
8589function playerMeta:SetItemEntity(entity)
8590 self.itemEntity = entity;
8591end;
8592
8593-- A function to create a player's temporary data.
8594function 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];
8602end;
8603
8604-- A function to make a player fake pickup an entity.
8605function 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;
8621end;
8622
8623-- A function to set a player's temporary data.
8624function playerMeta:SetTempData(key, value)
8625 local tempData = self:CreateTempData();
8626
8627 if (tempData) then
8628 tempData[key] = value;
8629 end;
8630end;
8631
8632-- A function to get a player's temporary data.
8633function 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;
8641end;
8642
8643-- A function to get whether a player has an item.
8644function playerMeta:HasItem(item, anywhere)
8645 return nexus.inventory.HasItem(self, item, anywhere);
8646end;
8647
8648-- A function to get a player's attribute boosts.
8649function playerMeta:GetAttributeBoosts()
8650 return self.attributeBoosts;
8651end;
8652
8653-- A function to rebuild a player's inventory.
8654function playerMeta:RebuildInventory()
8655 nexus.inventory.Rebuild(self);
8656end;
8657
8658-- A function to update a player's inventory.
8659function playerMeta:UpdateInventory(item, amount, force, noMessage)
8660 return nexus.inventory.Update(self, item, amount, force, noMessage);
8661end;
8662
8663-- A function to update a player's attribute.
8664function playerMeta:UpdateAttribute(attribute, amount)
8665 return nexus.attributes.Update(self, attribute, amount);
8666end;
8667
8668-- A function to progress a player's attribute.
8669function playerMeta:ProgressAttribute(attribute, amount, gradual)
8670 return nexus.attributes.Progress(self, attribute, amount, gradual);
8671end;
8672
8673-- A function to boost a player's attribute.
8674function playerMeta:BoostAttribute(identifier, attribute, amount, duration)
8675 return nexus.attributes.Boost(self, identifier, attribute, amount, duration);
8676end;
8677
8678-- A function to get whether a boost is active for a player.
8679function playerMeta:IsBoostActive(identifier, attribute, amount, duration)
8680 return nexus.attributes.IsBoostActive(self, identifier, attribute, amount, duration);
8681end;
8682
8683-- A function to get a player's characters.
8684function playerMeta:GetCharacters()
8685 return self.characters;
8686end;
8687
8688-- A function to set a player's run speed.
8689function playerMeta:SetRunSpeed(speed, nexus)
8690 if (!nexus) then self.runSpeed = speed; end;
8691
8692 self:NexusSetRunSpeed(speed);
8693end;
8694
8695-- A function to set a player's walk speed.
8696function playerMeta:SetWalkSpeed(speed, nexus)
8697 if (!nexus) then self.walkSpeed = speed; end;
8698
8699 self:NexusSetWalkSpeed(speed);
8700end;
8701
8702-- A function to set a player's jump power.
8703function playerMeta:SetJumpPower(power, nexus)
8704 if (!nexus) then self.jumpPower = power; end;
8705
8706 self:NexusSetJumpPower(power);
8707end;
8708
8709-- A function to set a player's crouched walk speed.
8710function playerMeta:SetCrouchedWalkSpeed(speed, nexus)
8711 if (!nexus) then self.crouchedSpeed = speed; end;
8712
8713 self:NexusSetCrouchedWalkSpeed(speed);
8714end;
8715
8716-- A function to get whether a player has initialized.
8717function playerMeta:HasInitialized()
8718 return self.initialized;
8719end;
8720
8721-- A function to query a player's character table.
8722function playerMeta:QueryCharacter(key, default)
8723 if ( self:GetCharacter() ) then
8724 return nexus.player.Query(self, key, default);
8725 else
8726 return default;
8727 end;
8728end;
8729
8730-- A function to get a player's shared variable.
8731function 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;
8737end;
8738
8739-- A function to set a shared variable for a player.
8740function 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;
8746end;
8747
8748-- A function to get a player's character data.
8749function 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;
8761end;
8762
8763-- A function to get a player's time joined.
8764function playerMeta:TimeJoined()
8765 return self.timeJoined or os.time();
8766end;
8767
8768-- A function to get when a player last played.
8769function playerMeta:LastPlayed()
8770 return self.lastPlayed or os.time();
8771end;
8772
8773-- A function to set a player's character data.
8774function 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;
8786end;
8787
8788-- A function to get the entity a player is holding.
8789function playerMeta:GetHoldingEntity()
8790 return self.isHoldingEntity;
8791end;
8792
8793playerMeta.GetName = playerMeta.Name;
8794playerMeta.Nick = playerMeta.Name;
8795
8796nexus.mount.Call("NexusCoreLoaded");
8797nexus.mount.Call("NexusCoreLoaded"); 2.62467192), math.min(size, 14) ), size);
8798end;
8799
8800-- A function to hook a data stream.
8801function NEXUS:HookDataStream(name, Callback)
8802 self.DataStreamHooks[name] = Callback;
8803end;
8804
8805-- A function to get the schema folder.
8806function NEXUS:GetSchemaFolder()
8807 local folder = string.gsub(self.SchemaFolder, "gamemodes/", "");
8808
8809 if (folder) then
8810 return folder;
8811 end;
8812end;
8813
8814-- A function to get the mount directory.
8815function NEXUS:GetMountDirectory()
8816 return MOUNT_DIRECTORY;
8817end;
8818
8819-- A function to get the Nexus folder.
8820function NEXUS:GetNexusFolder()
8821 local folder = string.gsub(self.NexusFolder, "gamemodes/", "");
8822
8823 if (folder) then
8824 return folder;
8825 end;
8826end;
8827
8828-- A function to save schema data.
8829function NEXUS:SaveSchemaData(fileName, data)
8830 g_File.Write( "nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt", glon.encode(data) );
8831end;
8832
8833-- A function to delete schema data.
8834function NEXUS:DeleteSchemaData(fileName)
8835 g_File.Delete("nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
8836end;
8837
8838-- A function to check if schema data exists.
8839function NEXUS:SchemaDataExists(fileName)
8840 return g_File.Exists("nexus/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
8841end;
8842
8843-- A function to restore schema data.
8844function 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;
8868end;
8869
8870-- A function to save Nexus data.
8871function NEXUS:SaveNexusData(fileName, data)
8872 g_File.Write( "nexus/"..fileName..".txt", glon.encode(data) );
8873end;
8874
8875-- A function to check if Nexus data exists.
8876function NEXUS:NexusDataExists(fileName)
8877 return g_File.Exists("nexus/"..fileName..".txt");
8878end;
8879
8880-- A function to delete Nexus data.
8881function NEXUS:DeleteNexusData(fileName)
8882 g_File.Delete("nexus/"..fileName..".txt");
8883end;
8884
8885-- A function to convert a string to a boolean.
8886function NEXUS:ToBool(text)
8887 if (text == "true" or text == "yes" or text == "1") then
8888 return true;
8889 else
8890 return false;
8891 end;
8892end;
8893
8894-- A function to split a string.
8895function 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;
8907end;
8908
8909-- Called when the player's jumping animation should be handled.
8910function 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;
8941end;
8942
8943-- Called when the player's ducking animation should be handled.
8944function 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;
8977end;
8978
8979-- Called when the player's swimming animation should be handled.
8980function 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;
8997end;
8998
8999-- Called when the player's driving animation should be handled.
9000function 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;
9008end;
9009
9010-- Called when a player's animation is updated.
9011function 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);
9021end;
9022
9023-- Called when the main activity should be calculated.
9024function 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;
9083end;
9084
9085local IdleActivity = ACT_HL2MP_IDLE;
9086local 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.
9100function 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;
9115end;
9116
9117-- Called when the animation event is supposed to be done.
9118function 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;
9171end;
9172
9173if (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;
9937else
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;
11115end;
11116
11117-- A function to explode a string by tags.
11118function 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;
11157end;
11158
11159-- A function to modify a physical description.
11160function 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;
11170end;
11171
11172-- A function to explode a string.
11173function 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;
11181end;
11182
11183-- A function to create a new meta table.
11184function NEXUS:NewMetaTable(base)
11185 local object = {};
11186
11187 setmetatable(object, base);
11188
11189 base.__index = base;
11190
11191 return object;
11192end;
11193
11194-- A function to set whether a string should be in camel case.
11195function 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;
11201end;
11202
11203-- A function to include files in a directory.
11204function 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;
11212end;
11213
11214-- A function to include a prefixed g_File.
11215function 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);
11229end;
11230
11231-- A function to include mounts in a directory.
11232function 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;
11250end;
11251
11252-- A function to perform the timer think.
11253function 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;
11273end;
11274
11275-- A function to get whether a timer exists.
11276function NEXUS:TimerExists(name)
11277 return self.Timers[name];
11278end;
11279
11280-- A function to start a timer.
11281function 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;
11286end;
11287
11288-- A function to pause a timer.
11289function 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;
11294end;
11295
11296
11297-- A function to destroy a timer.
11298function NEXUS:DestroyTimer(name)
11299 self.Timers[name] = nil;
11300end;
11301
11302-- A function to create a timer.
11303function 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 };
11312end;
11313
11314-- A function to get whether a player has access to an object.
11315function 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;
11380end;
11381
11382-- A function to derive from Sandbox.
11383function 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;
11409end;
11410
11411-- A function to get the sorted commands.
11412function 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;
11425end;
11426
11427-- A function to zero a number to an amount of digits.
11428function NEXUS:ZeroNumberToDigits(number, digits)
11429 return string.rep( "0", math.Clamp(digits - string.len( tostring(number) ), 0, digits) )..number;
11430end;
11431
11432-- A function to get a short CRC from a value.
11433function NEXUS:GetShortCRC(value)
11434 return math.ceil(util.CRC(value) / 100000);
11435end;
11436
11437-- A function to validate a table's keys.
11438function NEXUS:ValidateTableKeys(base)
11439 for i = 1, #base do
11440 if ( !base[i] ) then
11441 table.remove(base, i);
11442 end;
11443 end;
11444end;
11445
11446-- A function to get the map's physics entities.
11447function 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;
11463end;
11464
11465-- A function to create a multicall table (by Deco Da Man).
11466function 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;
11481end;
11482
11483-- A function to check if the shared variables have initialized.
11484function NEXUS:SharedVarsHaveInitialized()
11485 local worldEntity = GetWorldEntity();
11486
11487 if ( worldEntity and worldEntity.IsWorld and worldEntity:IsWorld() ) then
11488 return true;
11489 end;
11490end;
11491
11492-- A function to convert a user message class.
11493function 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];
11505end;
11506
11507-- A function to get a default networked value.
11508function 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];
11520end;
11521
11522-- A function to convert a networked class.
11523function 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];
11535end;
11536
11537-- A function to get the default class value.
11538function 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];
11550end;
11551
11552-- A function to set a shared variable.
11553function 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;
11571end;
11572
11573-- A function to get a shared variable.
11574function 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;
11588end;
11589
11590-- A function to register a global shared variable.
11591function NEXUS:RegisterGlobalSharedVar(name, class)
11592 self.GlobalSharedVars[#self.GlobalSharedVars + 1] = {name, class};
11593end;
11594
11595-- A function to create fake damage info.
11596function 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;
11608end;
11609
11610-- A function to unpack a color.
11611function NEXUS:UnpackColor(color)
11612 return color.r, color.g, color.b, color.a;
11613end;
11614
11615-- A function to parse data in text.
11616function 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);
11647end;