· 8 years ago · Jan 25, 2018, 07:48 PM
1--[[
2 © 2011 CloudSixteen.com do not share, re-distribute or modify
3 without permission of its author (kurozael@gmail.com).
4--]]
5
6openAura.Timers = {};
7openAura.DataStreamHooks = {};
8openAura.GlobalSharedVars = {};
9
10-- A function to scale a size to wide screen.
11function ScaleToWideScreen(size)
12 return math.min(math.max( ScreenScale(size / 2.62467192), math.min(size, 16) ), size);
13end;
14
15-- A function to encode a URL.
16function openAura:URLEncode(url)
17 local output = "";
18
19 for i = 1, string.len(url) do
20 local c = string.sub(url, i, i);
21 local a = string.byte(c);
22
23 if (a < 128) then
24 if (a == 32 or a >= 34 and a <= 38 or a == 43 or a == 44 or a == 47 or a >= 58
25 and a <= 64 or a >= 91 and a <= 94 or a == 96 or a >= 123 and a <= 126) then
26 output = output.."%"..string.format("%x", a);
27 else
28 output = output..c;
29 end;
30 end;
31 end;
32
33 return output;
34end;
35
36-- A function to hook a data stream.
37function openAura:HookDataStream(name, Callback)
38 self.DataStreamHooks[name] = Callback;
39end;
40
41-- A function to get whether a weapon is a default weapon.
42function openAura:IsDefaultWeapon(weapon)
43 if ( IsValid(weapon) ) then
44 local class = string.lower( weapon:GetClass() );
45
46 if (class == "weapon_physgun" or class == "gmod_physcannon"
47 or class == "gmod_tool") then
48 return true;
49 end;
50 end;
51
52 return false;
53end;
54
55-- A function to get a log type color.
56function openAura:GetLogTypeColor(logType)
57 local logTypes = {
58 Color(255, 50, 50, 255),
59 Color(255, 150, 0, 255),
60 Color(255, 200, 0, 255),
61 Color(0, 150, 255, 255),
62 Color(0, 255, 125, 255)
63 };
64
65 return logTypes[logType] or logTypes[5];
66end;
67
68-- A function to get the core version.
69function openAura:GetCoreVersion()
70 return self.CoreVersion;
71end;
72
73-- A function to get the auth version.
74function openAura:GetAuthVersion()
75 return self.AuthVersion;
76end;
77
78-- A function to get the schema folder.
79function openAura:GetSchemaFolder()
80 local folder = string.gsub(self.SchemaFolder, "gamemodes/", "");
81
82 if (folder) then
83 return folder;
84 end;
85end;
86
87-- A function to get the plugin directory.
88function openAura:GetPluginDirectory()
89 return PLUGIN_DIRECTORY;
90end;
91
92-- A function to get the OpenAura folder.
93function openAura:GetOpenAuraFolder()
94 local folder = string.gsub(self.OpenAuraFolder, "gamemodes/", "");
95
96 if (folder) then
97 return folder;
98 end;
99end;
100
101-- A function to convert a string to a boolean.
102function openAura:ToBool(text)
103 if (text == "true" or text == "yes" or text == "1") then
104 return true;
105 else
106 return false;
107 end;
108end;
109
110-- A function to split a string.
111function openAura:SplitString(text, interval)
112 local length = string.len(text);
113 local base = {};
114 local i = 0;
115
116 while (i * interval < length) do
117 base[i + 1] = string.sub(text, i * interval + 1, (i + 1) * interval);
118
119 i = i + 1;
120 end;
121
122 return base;
123end;
124
125-- A function to get ammo information from a weapon.
126function openAura:GetAmmoInformation(weapon)
127 if ( IsValid(weapon) and IsValid(weapon.Owner) and weapon.Primary and weapon.Secondary) then
128 if (!weapon.AmmoInfo) then
129 weapon.AmmoInfo = {
130 primary = {
131 ammoType = weapon:GetPrimaryAmmoType(),
132 clipSize = weapon.Primary.ClipSize
133 },
134 secondary = {
135 ammoType = weapon:GetSecondaryAmmoType(),
136 clipSize = weapon.Secondary.ClipSize
137 }
138 };
139 end;
140
141 weapon.AmmoInfo.primary.ownerAmmo = weapon.Owner:GetAmmoCount(weapon.AmmoInfo.primary.ammoType);
142 weapon.AmmoInfo.primary.clipBullets = weapon:Clip1();
143 weapon.AmmoInfo.primary.doesNotShoot = (weapon.AmmoInfo.primary.clipBullets == -1);
144 weapon.AmmoInfo.secondary.ownerAmmo = weapon.Owner:GetAmmoCount(weapon.AmmoInfo.secondary.ammoType);
145 weapon.AmmoInfo.secondary.clipBullets = weapon:Clip2();
146 weapon.AmmoInfo.secondary.doesNotShoot = (weapon.AmmoInfo.secondary.clipBullets == -1);
147
148 if (!weapon.AmmoInfo.primary.doesNotShoot and weapon.AmmoInfo.primary.ownerAmmo > 0) then
149 weapon.AmmoInfo.primary.ownerClips = math.ceil(weapon.AmmoInfo.primary.clipSize / weapon.AmmoInfo.primary.ownerAmmo);
150 else
151 weapon.AmmoInfo.primary.ownerClips = 0;
152 end;
153
154 if (!weapon.AmmoInfo.secondary.doesNotShoot and weapon.AmmoInfo.secondary.ownerAmmo > 0) then
155 weapon.AmmoInfo.secondary.ownerClips = math.ceil(weapon.AmmoInfo.secondary.clipSize / weapon.AmmoInfo.secondary.ownerAmmo);
156 else
157 weapon.AmmoInfo.secondary.ownerClips = 0;
158 end;
159
160 return weapon.AmmoInfo;
161 end;
162end;
163
164-- Called when the player's jumping animation should be handled.
165function openAura:HandlePlayerJumping(player)
166 if (!player.m_bJumping and !player:OnGround() and player:WaterLevel() <= 0) then
167 player.m_bJumping = true;
168 player.m_bFirstJumpFrame = false;
169 player.m_flJumpStartTime = 0;
170 end
171
172 if (player.m_bJumping) then
173 if (player.m_bFirstJumpFrame) then
174 player.m_bFirstJumpFrame = false;
175 player:AnimRestartMainSequence();
176 end;
177
178 if (player:WaterLevel() >= 2) then
179 player.m_bJumping = false;
180 player:AnimRestartMainSequence();
181 elseif (CurTime() - player.m_flJumpStartTime > 0.2) then
182 if ( player:OnGround() ) then
183 player.m_bJumping = false;
184 player:AnimRestartMainSequence();
185 end
186 end
187
188 if (player.m_bJumping) then
189 player.CalcIdeal = self.animation:GetForModel(player:GetModel(), "jump");
190
191 return true;
192 end;
193 end;
194
195 return false;
196end;
197
198-- Called when the player's ducking animation should be handled.
199function openAura:HandlePlayerDucking(player, velocity)
200 if ( player:Crouching() ) then
201 local model = player:GetModel();
202 local weapon = player:GetActiveWeapon();
203 local raised = self.player:GetWeaponRaised(player, true);
204 local velLength = velocity:Length2D();
205 local animationAct = "crouch";
206 local weaponHoldType = "pistol";
207
208 if ( IsValid(weapon) ) then
209 weaponHoldType = self.animation:GetWeaponHoldType(player, weapon);
210
211 if (weaponHoldType) then
212 animationAct = animationAct.."_"..weaponHoldType;
213 end;
214 end;
215
216 if (raised) then
217 animationAct = animationAct.."_aim";
218 end;
219
220 if (velLength > 0.5) then
221 animationAct = animationAct.."_walk";
222 else
223 animationAct = animationAct.."_idle";
224 end;
225
226 player.CalcIdeal = self.animation:GetForModel(model, animationAct);
227
228 return true;
229 end;
230
231 return false;
232end;
233
234-- Called when the player's swimming animation should be handled.
235function openAura:HandlePlayerSwimming(player)
236 if (player:WaterLevel() >= 2) then
237 if (player.m_bFirstSwimFrame) then
238 player:AnimRestartMainSequence();
239 player.m_bFirstSwimFrame = false;
240 end;
241
242 player.m_bInSwim = true;
243 else
244 player.m_bInSwim = false;
245
246 if (!player.m_bFirstSwimFrame) then
247 player.m_bFirstSwimFrame = true;
248 end;
249 end;
250
251 return false;
252end;
253
254-- Called when the player's driving animation should be handled.
255function openAura:HandlePlayerDriving(player)
256 if ( player:InVehicle() ) then
257 player.CalcIdeal = self.animation:GetForModel(player:GetModel(), "sit");
258
259 return true;
260 end;
261
262 return false;
263end;
264
265-- Called when a player's animation is updated.
266function openAura:UpdateAnimation(player, velocity, maxSeqGroundSpeed)
267 local velLength = velocity:Length2D();
268 local rate = 1.0;
269
270 if (velLength > 0.5) then
271 rate = ( ( velLength * 0.8 ) / maxSeqGroundSpeed );
272 end
273
274 player.playbackRate = math.Clamp(rate, 0, 1.5);
275 player:SetPlaybackRate(player.playbackRate);
276
277 if (player:InVehicle() and CLIENT) then
278 local vehicle = player:GetVehicle();
279
280 if ( IsValid(vehicle) ) then
281 local velocity = vehicle:GetVelocity();
282 local steer = (vehicle:GetPoseParameter("vehicle_steer") * 2) - 1;
283
284 player:SetPoseParameter("vertical_velocity", velocity.z * 0.01);
285 player:SetPoseParameter("vehicle_steer", steer);
286 end;
287 end;
288
289 --[[
290 self.plugin:Call("PlayerShouldMoveMouth", player)
291 is for the speaking pose parameter (todo).
292 --]]
293end;
294
295-- Called when the main activity should be calculated.
296function openAura:CalcMainActivity(player, velocity)
297 local model = player:GetModel();
298
299 if ( string.find(model, "/player/") ) then
300 return self.BaseClass:CalcMainActivity(player, velocity);
301 end;
302
303 ANIMATION_PLAYER = player;
304
305 local weapon = player:GetActiveWeapon();
306 local raised = self.player:GetWeaponRaised(player, true);
307 local animationAct = "stand";
308 local weaponHoldType = "pistol";
309 local forcedAnimation = player:GetForcedAnimation();
310
311 if ( IsValid(weapon) ) then
312 weaponHoldType = self.animation:GetWeaponHoldType(player, weapon);
313
314 if (weaponHoldType) then
315 animationAct = animationAct.."_"..weaponHoldType;
316 end;
317 end;
318
319 if (raised) then
320 animationAct = animationAct.."_aim";
321 end;
322
323 player.CalcIdeal = self.animation:GetForModel(model, animationAct.."_idle");
324 player.CalcSeqOverride = -1;
325
326 if ( !self:HandlePlayerDriving(player)
327 and !self:HandlePlayerJumping(player)
328 and !self:HandlePlayerDucking(player, velocity)
329 and !self:HandlePlayerSwimming(player) ) then
330 local velLength = velocity:Length2D();
331
332 if ( player:IsRunning() or player:IsJogging() ) then
333 player.CalcIdeal = self.animation:GetForModel(model, animationAct.."_run");
334 elseif (velLength > 0.5) then
335 player.CalcIdeal = self.animation:GetForModel(model, animationAct.."_walk");
336 end;
337 end;
338
339 if (forcedAnimation) then
340 player.CalcSeqOverride = forcedAnimation.animation;
341
342 if (forcedAnimation.onAnimate) then
343 forcedAnimation.onAnimate(player);
344 forcedAnimation.onAnimate = nil;
345 end;
346 end;
347
348 if (type(player.CalcSeqOverride) == "string") then
349 player.CalcSeqOverride = player:LookupSequence(player.CalcSeqOverride);
350 end;
351
352 if (type(player.CalcIdeal) == "string") then
353 player.CalcSeqOverride = player:LookupSequence(player.CalcIdeal);
354 end;
355
356 ANIMATION_PLAYER = nil;
357
358 return player.CalcIdeal, player.CalcSeqOverride;
359end;
360
361local IdleActivity = ACT_HL2MP_IDLE;
362local IdleActivityTranslate = {
363 ACT_MP_ATTACK_CROUCH_PRIMARYFIRE = IdleActivity + 5,
364 ACT_MP_ATTACK_STAND_PRIMARYFIRE = IdleActivity + 5,
365 ACT_MP_RELOAD_CROUCH = IdleActivity + 6,
366 ACT_MP_RELOAD_STAND = IdleActivity + 6,
367 ACT_MP_CROUCH_IDLE = IdleActivity + 3,
368 ACT_MP_STAND_IDLE = IdleActivity,
369 ACT_MP_CROUCHWALK = IdleActivity + 4,
370 ACT_MP_JUMP = ACT_HL2MP_JUMP_SLAM,
371 ACT_MP_WALK = IdleActivity + 1,
372 ACT_MP_RUN = IdleActivity + 2,
373};
374
375-- Called when a player's activity is supposed to be translated.
376function openAura:TranslateActivity(player, act)
377 local model = player:GetModel();
378 local raised = self.player:GetWeaponRaised(player, true);
379
380 if ( string.find(model, "/player/") ) then
381 local newAct = player:TranslateWeaponActivity(act);
382
383 if (!raised or act == newAct) then
384 return IdleActivityTranslate[act];
385 else
386 return newAct;
387 end;
388 end;
389
390 return act;
391end;
392
393-- Called when the animation event is supposed to be done.
394function openAura:DoAnimationEvent(player, event, data)
395 local model = player:GetModel();
396
397 if ( string.find(model, "/player/") ) then
398 return self.BaseClass:DoAnimationEvent(player, event, data);
399 end;
400
401 local weapon = player:GetActiveWeapon();
402 local animationAct = "pistol";
403
404 if ( IsValid(weapon) ) then
405 weaponHoldType = self.animation:GetWeaponHoldType(player, weapon);
406
407 if (weaponHoldType) then
408 animationAct = weaponHoldType;
409 end;
410 end;
411
412 if (event == PLAYERANIMEVENT_ATTACK_PRIMARY) then
413 local gestureSequence = self.animation:GetForModel(model, animationAct.."_attack");
414
415 if ( player:Crouching() ) then
416 player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
417 else
418 player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
419 end;
420
421 return ACT_VM_PRIMARYATTACK;
422 elseif (event == PLAYERANIMEVENT_RELOAD) then
423 local gestureSequence = self.animation:GetForModel(model, animationAct.."_reload");
424
425 if ( player:Crouching() ) then
426 player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
427 else
428 player:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, gestureSequence);
429 end;
430
431 return ACT_INVALID;
432 elseif event == PLAYERANIMEVENT_JUMP then
433 player.m_bJumping = true;
434 player.m_bFirstJumpFrame = true;
435 player.m_flJumpStartTime = CurTime();
436
437 player:AnimRestartMainSequence();
438
439 return ACT_INVALID;
440 elseif (event == PLAYERANIMEVENT_CANCEL_RELOAD) then
441 player:AnimResetGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD);
442
443 return ACT_INVALID;
444 end;
445
446 return nil;
447end;
448
449if (SERVER) then
450 openAura.Entities = {};
451 openAura.TempPlayerData = {};
452 openAura.HitGroupBonesCache = {
453 {"ValveBiped.Bip01_R_UpperArm", HITGROUP_RIGHTARM},
454 {"ValveBiped.Bip01_R_Forearm", HITGROUP_RIGHTARM},
455 {"ValveBiped.Bip01_L_UpperArm", HITGROUP_LEFTARM},
456 {"ValveBiped.Bip01_L_Forearm", HITGROUP_LEFTARM},
457 {"ValveBiped.Bip01_R_Thigh", HITGROUP_RIGHTLEG},
458 {"ValveBiped.Bip01_R_Calf", HITGROUP_RIGHTLEG},
459 {"ValveBiped.Bip01_R_Foot", HITGROUP_RIGHTLEG},
460 {"ValveBiped.Bip01_R_Hand", HITGROUP_RIGHTARM},
461 {"ValveBiped.Bip01_L_Thigh", HITGROUP_LEFTLEG},
462 {"ValveBiped.Bip01_L_Calf", HITGROUP_LEFTLEG},
463 {"ValveBiped.Bip01_L_Foot", HITGROUP_LEFTLEG},
464 {"ValveBiped.Bip01_L_Hand", HITGROUP_LEFTARM},
465 {"ValveBiped.Bip01_Pelvis", HITGROUP_STOMACH},
466 {"ValveBiped.Bip01_Spine2", HITGROUP_CHEST},
467 {"ValveBiped.Bip01_Spine1", HITGROUP_CHEST},
468 {"ValveBiped.Bip01_Head1", HITGROUP_HEAD},
469 {"ValveBiped.Bip01_Neck1", HITGROUP_HEAD}
470 };
471 openAura.MeleeTranslation = {
472 [ACT_HL2MP_GESTURE_RANGE_ATTACK] = ACT_HL2MP_GESTURE_RANGE_ATTACK_MELEE2,
473 [ACT_HL2MP_GESTURE_RELOAD] = ACT_HL2MP_GESTURE_RELOAD_MELEE2,
474 [ACT_HL2MP_WALK_CROUCH] = ACT_HL2MP_WALK_CROUCH_MELEE2,
475 [ACT_HL2MP_IDLE_CROUCH] = ACT_HL2MP_IDLE_CROUCH_MELEE2,
476 [ACT_RANGE_ATTACK1] = ACT_RANGE_ATTACK1_MELEE2,
477 [ACT_HL2MP_IDLE] = ACT_HL2MP_IDLE_MELEE2,
478 [ACT_HL2MP_WALK] = ACT_HL2MP_WALK_MELEE2,
479 [ACT_HL2MP_JUMP] = ACT_HL2MP_JUMP_MELEE2,
480 [ACT_HL2MP_RUN] = ACT_HL2MP_RUN_MELEE2
481 };
482
483 -- A function to load the bans.
484 function openAura:LoadBans()
485 self.BanList = self:RestoreOpenAuraData("bans");
486
487 local unixTime = os.time();
488
489 for k, v in pairs(self.BanList) do
490 if (type(v) == "table") then
491 if (v.unbanTime > 0 and unixTime >= v.unbanTime) then
492 self:RemoveBan(k, true);
493 end;
494 else
495 self.BanList[k] = nil;
496 end;
497 end;
498
499 self:SaveOpenAuraData("bans", self.BanList);
500 end;
501
502 -- A function to add a ban.
503 function openAura:AddBan(identifier, duration, reason, Callback, saveless)
504 local steamName = nil;
505 local playerGet = self.player:Get(identifier);
506
507 if (identifier) then
508 identifier = string.upper(identifier);
509 end;
510
511 for k, v in ipairs( _player.GetAll() ) do
512 local playerIP = v:IPAddress();
513 local playerSteam = v:SteamID();
514
515 if (playerSteam == identifier or playerIP == identifier or playerGet == v) then
516 self.plugin:Call("PlayerBanned", v, duration, reason);
517
518 if (playerIP == identifier) then
519 identifier = playerIP;
520 else
521 identifier = playerSteam;
522 end;
523
524 steamName = v:SteamName();
525 v:Kick(reason);
526 end;
527 end;
528
529 if (!reason) then
530 reason = "Banned for an unspecified reason.";
531 end;
532
533 if (!steamName) then
534 local playersTable = self.config:Get("mysql_players_table"):Get();
535 local newIdentifier = tmysql.escape(identifier);
536
537 if ( string.find(identifier, "STEAM") ) then
538 tmysql.query("SELECT * FROM "..playersTable.." WHERE _SteamID = \""..newIdentifier.."\"", function(result)
539 local steamName = identifier;
540
541 if (result and type(result) == "table" and #result > 0) then
542 steamName = result[1]._SteamName;
543 end;
544
545 if (duration == 0) then
546 self.BanList[identifier] = {
547 unbanTime = 0,
548 steamName = steamName,
549 duration = duration,
550 reason = reason
551 };
552 else
553 self.BanList[identifier] = {
554 unbanTime = os.time() + duration,
555 steamName = steamName,
556 duration = duration,
557 reason = reason
558 };
559 end;
560
561 if (!saveless) then
562 self:SaveOpenAuraData("bans", self.BanList);
563 end;
564
565 if (Callback) then
566 Callback(steamName, duration, reason);
567 end;
568 end, 1);
569 elseif ( string.find(identifier, "%d+%.%d+%.%d+%.%d+") ) then
570 tmysql.query("SELECT * FROM "..playersTable.." WHERE _IPAddress = \""..newIdentifier.."\"", function(result)
571 local steamName = identifier;
572
573 if (result and type(result) == "table" and #result > 0) then
574 steamName = result[1]._SteamName;
575 end;
576
577 if (duration == 0) then
578 self.BanList[identifier] = {
579 unbanTime = 0,
580 steamName = steamName,
581 duration = duration,
582 reason = reason
583 };
584 else
585 self.BanList[identifier] = {
586 unbanTime = os.time() + duration,
587 steamName = steamName,
588 duration = duration,
589 reason = reason
590 };
591 end;
592
593 if (!saveless) then
594 self:SaveOpenAuraData("bans", self.BanList);
595 end;
596
597 if (Callback) then
598 Callback(steamName, duration, reason);
599 end;
600 end, 1);
601 elseif (Callback) then
602 Callback();
603 end;
604 else
605 if (duration == 0) then
606 self.BanList[identifier] = {
607 unbanTime = 0,
608 steamName = steamName,
609 duration = duration,
610 reason = reason
611 };
612 else
613 self.BanList[identifier] = {
614 unbanTime = os.time() + duration,
615 steamName = steamName,
616 duration = duration,
617 reason = reason
618 };
619 end;
620
621 if (!saveless) then
622 self:SaveOpenAuraData("bans", self.BanList);
623 end;
624
625 if (Callback) then
626 Callback(steamName, duration, reason);
627 end;
628 end;
629 end;
630
631 -- A function to remove a ban.
632 function openAura:RemoveBan(identifier, saveless)
633 if ( self.BanList[identifier] ) then
634 self.BanList[identifier] = nil;
635
636 if (!saveless) then
637 self:SaveOpenAuraData("bans", self.BanList);
638 end;
639 end;
640 end;
641
642 -- A function to start a data stream.
643 function openAura:StartDataStream(player, name, data)
644 if (type(player) != "table") then
645 if (!player) then
646 player = _player.GetAll();
647 else
648 player = {player};
649 end;
650 end;
651
652 local encodedData = glon.encode(data);
653 local splitTable = self:SplitString(encodedData, 128);
654 local players = RecipientFilter();
655
656 for k, v in pairs(player) do
657 if (type(v) == "Player") then
658 players:AddPlayer(v);
659 elseif (type(k) == "Player") then
660 players:AddPlayer(k);
661 end;
662 end;
663
664 if (#splitTable > 0) then
665 umsg.Start("aura_dsStart", players);
666 umsg.String(name);
667 umsg.String( splitTable[1] );
668 umsg.Short(#splitTable);
669 umsg.End();
670
671 if (#splitTable > 1) then
672 for k, v in ipairs(splitTable) do
673 if (k > 1) then
674 umsg.Start("aura_dsData", players);
675 umsg.String(v);
676 umsg.Short(k);
677 umsg.End();
678 end;
679 end;
680 end;
681 end;
682 end;
683
684 -- A function to save schema data.
685 function openAura:SaveSchemaData(fileName, data)
686 fileio.Write( self:SetupFullDirectory("settings/openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".aura"), glon.encode(data) );
687 end;
688
689 -- A function to delete schema data.
690 function openAura:DeleteSchemaData(fileName)
691 fileio.Delete( self:SetupFullDirectory("settings/openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".aura") );
692 end;
693
694 -- A function to check if schema data exists.
695 function openAura:SchemaDataExists(fileName)
696 return _file.Exists("../settings/openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".aura");
697 end;
698
699 -- A function to restore schema data.
700 function openAura:RestoreSchemaData(fileName, default)
701 if ( self:SchemaDataExists(fileName) ) then
702 local data = fileio.Read( self:SetupFullDirectory("settings/openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".aura") );
703
704 if (data) then
705 local success, value = pcall(glon.decode, data);
706
707 if (success and value != nil) then
708 return value;
709 else
710 local success, value = pcall(Json.Decode, data);
711
712 if (success and value != nil) then
713 return value;
714 end;
715 end;
716 end;
717 end;
718
719 if (default != nil) then
720 return default;
721 else
722 return {};
723 end;
724 end;
725
726 -- A function to restore OpenAura data.
727 function openAura:RestoreOpenAuraData(fileName, default)
728 if ( self:OpenAuraDataExists(fileName) ) then
729 local data = fileio.Read( self:SetupFullDirectory("settings/openaura/"..fileName..".aura") );
730
731 if (data) then
732 local success, value = pcall(glon.decode, data);
733
734 if (success and value != nil) then
735 return value;
736 end;
737 end;
738 end;
739
740 if (default != nil) then
741 return default;
742 else
743 return {};
744 end;
745 end;
746
747 -- A function to setup a full directory.
748 function openAura:SetupFullDirectory(filePath)
749 local directory = string.gsub(relative.Get()..filePath, "\\", "/");
750 local exploded = string.Explode("/", directory);
751 local currentPath = "";
752
753 for k, v in ipairs(exploded) do
754 if (k < #exploded) then
755 currentPath = currentPath..v.."/";
756 fileio.MakeDirectory(currentPath);
757 end;
758 end;
759
760 return currentPath..exploded[#exploded];
761 end;
762
763 -- A function to save OpenAura data.
764 function openAura:SaveOpenAuraData(fileName, data)
765 fileio.Write( self:SetupFullDirectory("settings/openaura/"..fileName..".aura"), glon.encode(data) );
766 end;
767
768 -- A function to check if OpenAura data exists.
769 function openAura:OpenAuraDataExists(fileName)
770 return _file.Exists("../settings/openaura/"..fileName..".aura");
771 end;
772
773 -- A function to delete OpenAura data.
774 function openAura:DeleteOpenAuraData(fileName)
775 fileio.Delete( self:SetupFullDirectory("settings/openaura/"..fileName..".aura") );
776 end;
777
778 -- A function to convert a force.
779 function openAura:ConvertForce(force, limit)
780 local forceLength = force:Length();
781
782 if (forceLength == 0) then
783 return Vector(0, 0, 0);
784 end;
785
786 if (!limit) then
787 limit = 800;
788 end;
789
790 if (forceLength > limit) then
791 return force / (forceLength / limit);
792 else
793 return force;
794 end;
795 end;
796
797 -- A function to save a player's attribute boosts.
798 function openAura:SavePlayerAttributeBoosts(player, data)
799 local attributeBoosts = player:GetAttributeBoosts();
800 local curTime = CurTime();
801
802 if ( data["attributeboosts"] ) then
803 data["attributeboosts"] = nil;
804 end;
805
806 if (table.Count(attributeBoosts) > 0) then
807 data["attributeboosts"] = {};
808
809 for k, v in pairs(attributeBoosts) do
810 data["attributeboosts"][k] = {};
811
812 for k2, v2 in pairs(v) do
813 if (v2.duration) then
814 if (curTime < v2.endTime) then
815 data["attributeboosts"][k][k2] = {
816 duration = math.ceil(v2.endTime - curTime),
817 amount = v2.amount
818 };
819 end;
820 else
821 data["attributeboosts"][k][k2] = {
822 amount = v2.amount
823 };
824 end;
825 end;
826 end;
827 end;
828 end;
829
830 -- A function to calculate a player's spawn time.
831 function openAura:CalculateSpawnTime(player, inflictor, attacker, damageInfo)
832 local info = {
833 attacker = attacker,
834 inflictor = inflictor,
835 spawnTime = self.config:Get("spawn_time"):Get(),
836 damageInfo = damageInfo
837 };
838
839 self.plugin:Call("PlayerAdjustDeathInfo", player, info);
840
841 if (info.spawnTime and info.spawnTime > 0) then
842 self.player:SetAction(player, "spawn", info.spawnTime, 3);
843 end;
844 end;
845
846 -- A function to create a decal.
847 function openAura:CreateDecal(texture, position, temporary)
848 local decal = ents.Create("infodecal");
849
850 if (temporary) then
851 decal:SetKeyValue("LowPriority", "true");
852 end;
853
854 decal:SetKeyValue("Texture", texture);
855 decal:SetPos(position);
856 decal:Spawn();
857 decal:Fire("activate");
858
859 return decal;
860 end;
861
862 -- A function to handle a player's weapon fire delay.
863 function openAura:HandleWeaponFireDelay(player, raised, weapon, curTime)
864 local delaySecondaryFire = nil;
865 local delayPrimaryFire = nil;
866
867 if ( !self.plugin:Call("PlayerCanFireWeapon", player, raised, weapon, true) ) then
868 delaySecondaryFire = curTime + 60;
869 end;
870
871 if ( !self.plugin:Call("PlayerCanFireWeapon", player, raised, weapon) ) then
872 delayPrimaryFire = curTime + 60;
873 end;
874
875 if (delaySecondaryFire == nil and weapon.secondaryFireDelayed) then
876 weapon:SetNextSecondaryFire(weapon.secondaryFireDelayed);
877 weapon.secondaryFireDelayed = nil;
878 end;
879
880 if (delayPrimaryFire == nil and weapon.primaryFireDelayed) then
881 weapon:SetNextPrimaryFire(weapon.primaryFireDelayed);
882 weapon.primaryFireDelayed = nil;
883 end;
884
885 if (delaySecondaryFire) then
886 if (!weapon.secondaryFireDelayed) then
887 weapon.secondaryFireDelayed = weapon:GetNextSecondaryFire();
888 end;
889
890 weapon:SetNextSecondaryFire(delaySecondaryFire);
891 end;
892
893 if (delayPrimaryFire) then
894 if (!weapon.primaryFireDelayed) then
895 weapon.primaryFireDelayed = weapon:GetNextPrimaryFire();
896 end;
897
898 weapon:SetNextPrimaryFire(delayPrimaryFire);
899 end;
900 end;
901
902 -- A function to scale damage by hit group.
903 function openAura:ScaleDamageByHitGroup(player, attacker, hitGroup, damageInfo, baseDamage)
904 if ( !damageInfo:IsFallDamage() and !damageInfo:IsDamageType(DMG_CRUSH) ) then
905 if (hitGroup == HITGROUP_HEAD) then
906 damageInfo:ScaleDamage( self.config:Get("scale_head_dmg"):Get() );
907 elseif (hitGroup == HITGROUP_CHEST or hitGroup == HITGROUP_GENERIC) then
908 damageInfo:ScaleDamage( self.config:Get("scale_chest_dmg"):Get() );
909 elseif (hitGroup == HITGROUP_LEFTARM or hitGroup == HITGROUP_RIGHTARM or hitGroup == HITGROUP_LEFTLEG
910 or hitGroup == HITGROUP_RIGHTLEG or hitGroup == HITGROUP_GEAR) then
911 damageInfo:ScaleDamage( self.config:Get("scale_limb_dmg"):Get() );
912 end;
913 end;
914
915 self.plugin:Call("PlayerScaleDamageByHitGroup", player, attacker, hitGroup, damageInfo, baseDamage);
916 end;
917
918 -- A function to calculate player damage.
919 function openAura:CalculatePlayerDamage(player, hitGroup, damageInfo)
920 local damageIsValid = damageInfo:IsBulletDamage() or damageInfo:IsDamageType(DMG_CLUB) or damageInfo:IsDamageType(DMG_SLASH);
921 local hitGroupIsValid = true;
922
923 if ( self.config:Get("armor_chest_only"):Get() ) then
924 if (hitGroup != HITGROUP_CHEST and hitGroup != HITGROUP_GENERIC) then
925 hitGroupIsValid = nil;
926 end;
927 end;
928
929 if (player:Armor() > 0 and damageIsValid and hitGroupIsValid) then
930 local armor = player:Armor() - damageInfo:GetDamage();
931
932 if (armor < 0) then
933 player:SetHealth( math.max(player:Health() - math.abs(armor), 1) );
934 player:SetArmor( math.max(armor, 0) );
935 else
936 player:SetArmor( math.max(armor, 0) );
937 end;
938 else
939 player:SetHealth( math.max(player:Health() - damageInfo:GetDamage(), 1) );
940 end;
941 end;
942
943 -- A function to get a ragdoll's hit bone.
944 function openAura:GetRagdollHitBone(entity, position, default, minimum)
945 local closest = {};
946
947 for k, v in ipairs(self.HitGroupBonesCache) do
948 local bone = entity:LookupBone( v[1] );
949
950 if (bone) then
951 local bonePosition = entity:GetBonePosition(bone);
952
953 if (bonePosition) then
954 local distance = bonePosition:Distance(position);
955
956 if ( !closest[1] or distance < closest[1] ) then
957 if (!minimum or distance <= minimum) then
958 closest[1] = distance;
959 closest[2] = bone;
960 end;
961 end;
962 end;
963 end;
964 end;
965
966 if ( closest[2] ) then
967 return closest[2];
968 else
969 return default;
970 end;
971 end;
972
973 -- A function to get a ragdoll's hit group.
974 function openAura:GetRagdollHitGroup(entity, position)
975 local closest = {nil, HITGROUP_GENERIC};
976
977 for k, v in ipairs(self.HitGroupBonesCache) do
978 local bone = entity:LookupBone( v[1] );
979
980 if (bone) then
981 local bonePosition = entity:GetBonePosition(bone);
982
983 if (position) then
984 local distance = bonePosition:Distance(position);
985
986 if ( !closest[1] or distance < closest[1] ) then
987 closest[1] = distance;
988 closest[2] = v[2];
989 end;
990 end;
991 end;
992 end;
993
994 return closest[2];
995 end;
996
997 -- A function to create blood effects at a position.
998 function openAura:CreateBloodEffects(position, decals, entity, force)
999 if (!force) then
1000 force = VectorRand() * 80;
1001 end;
1002
1003 local effectData = EffectData();
1004 effectData:SetOrigin(position);
1005 effectData:SetNormal(force);
1006 effectData:SetScale(0.5);
1007 util.Effect("aura_bloodsmoke", effectData, true, true);
1008
1009 local effectData = EffectData();
1010 effectData:SetOrigin(position);
1011 effectData:SetEntity(entity);
1012 effectData:SetStart(position);
1013 effectData:SetScale(0.5);
1014 util.Effect("BloodImpact", effectData, true, true);
1015
1016 for i = 1, decals do
1017 local trace = {};
1018 trace.start = position;
1019 trace.endpos = trace.start;
1020 trace.filter = entity;
1021 trace = util.TraceLine(trace);
1022
1023 util.Decal("Blood", trace.HitPos + trace.HitNormal, trace.HitPos - trace.HitNormal);
1024 end;
1025 end;
1026
1027 -- A function to do the entity take damage hook.
1028 function openAura:DoEntityTakeDamageHook(gamemode, arguments)
1029 if ( arguments[4] != arguments[5]:GetDamage() ) then
1030 arguments[4] = arguments[5]:GetDamage();
1031 end;
1032
1033 local player = self.entity:GetPlayer( arguments[1] );
1034
1035 if (player) then
1036 local ragdoll = player:GetRagdollEntity();
1037
1038 if ( !hook.Call( "PlayerShouldTakeDamage", gamemode, player, arguments[3], arguments[2], arguments[5] ) or player:IsInGodMode() ) then
1039 arguments[5]:SetDamage(0);
1040
1041 return true;
1042 end;
1043
1044 if (ragdoll and arguments[1] != ragdoll) then
1045 hook.Call( "EntityTakeDamage", gamemode, ragdoll, arguments[2], arguments[3], arguments[4], arguments[5] );
1046
1047 arguments[5]:SetDamage(0);
1048
1049 return true;
1050 elseif (arguments[1] == ragdoll) then
1051 local physicsObject = arguments[1]:GetPhysicsObject();
1052
1053 if ( IsValid(physicsObject) ) then
1054 local velocity = physicsObject:GetVelocity():Length();
1055 local curTime = CurTime();
1056
1057 if ( arguments[5]:IsDamageType(DMG_CRUSH) ) then
1058 if (arguments[1].nextFallDamage and curTime < arguments[1].nextFallDamage) then
1059 arguments[5]:SetDamage(0);
1060
1061 return true;
1062 end;
1063
1064 arguments[4] = hook.Call("GetFallDamage", gamemode, player, velocity);
1065 arguments[1].nextFallDamage = curTime + 1;
1066 arguments[5]:SetDamage( arguments[4] )
1067 end;
1068 end;
1069 end;
1070 end;
1071 end;
1072
1073 -- A function to perform the date and time think.
1074 function openAura:PerformDateTimeThink()
1075 local defaultDays = self.option:GetKey("default_days");
1076 local minute = self.time:GetMinute();
1077 local month = self.date:GetMonth();
1078 local year = self.date:GetYear();
1079 local hour = self.time:GetHour();
1080 local day = self.time:GetDay();
1081
1082 self.time.minute = self.time:GetMinute() + 1;
1083
1084 if (self.time:GetMinute() == 60) then
1085 self.time.minute = 0;
1086 self.time.hour = self.time:GetHour() + 1;
1087
1088 if (self.time:GetHour() == 24) then
1089 self.time.hour = 0;
1090 self.time.day = self.time:GetDay() + 1;
1091 self.date.day = self.date:GetDay() + 1;
1092
1093 if (self.time:GetDay() == #defaultDays + 1) then
1094 self.time.day = 1;
1095 end;
1096
1097 if (self.date:GetDay() == 31) then
1098 self.date.day = 1;
1099 self.date.month = self.date:GetMonth() + 1;
1100
1101 if (self.date:GetMonth() == 13) then
1102 self.date.month = 1;
1103 self.date.year = self.date:GetYear() + 1;
1104 end;
1105 end;
1106 end;
1107 end;
1108
1109 if (self.time:GetMinute() != minute) then
1110 self.plugin:Call("TimePassed", TIME_MINUTE);
1111 end;
1112
1113 if (self.time:GetHour() != hour) then
1114 self.plugin:Call("TimePassed", TIME_HOUR);
1115 end;
1116
1117 if (self.time:GetDay() != day) then
1118 self.plugin:Call("TimePassed", TIME_DAY);
1119 end;
1120
1121 if (self.date:GetMonth() != month) then
1122 self.plugin:Call("TimePassed", TIME_MONTH);
1123 end;
1124
1125 if (self.date:GetYear() != year) then
1126 self.plugin:Call("TimePassed", TIME_YEAR);
1127 end;
1128
1129 local month = self:ZeroNumberToDigits(self.date:GetMonth(), 2);
1130 local day = self:ZeroNumberToDigits(self.date:GetDay(), 2);
1131
1132 self:SetSharedVar( "minute", self.time:GetMinute() );
1133 self:SetSharedVar( "hour", self.time:GetHour() );
1134 self:SetSharedVar( "date", day.."/"..month.."/"..self.date:GetYear() );
1135 self:SetSharedVar( "day", self.time:GetDay() );
1136 end;
1137
1138 -- A function to create a ConVar.
1139 function openAura:CreateConVar(name, value, flags, Callback)
1140 local conVar = CreateConVar(name, value, flags or FCVAR_REPLICATED + FCVAR_NOTIFY + FCVAR_ARCHIVE);
1141
1142 cvars.AddChangeCallback(name, function(conVar, previousValue, newValue)
1143 self.plugin:Call("OpenAuraConVarChanged", conVar, previousValue, newValue);
1144
1145 if (Callback) then
1146 Callback(conVar, previousValue, newValue);
1147 end;
1148 end);
1149
1150 return conVar;
1151 end;
1152
1153 -- A function to check if the server is shutting down.
1154 function openAura:IsShuttingDown()
1155 return self.ShuttingDown;
1156 end;
1157
1158 -- A function to distribute wages cash.
1159 function openAura:DistributeWagesCash()
1160 for k, v in ipairs( _player.GetAll() ) do
1161 if ( v:HasInitialized() and v:Alive() ) then
1162 local wages = v:GetWages();
1163
1164 if ( self.plugin:Call("PlayerCanEarnWagesCash", v, wages) ) then
1165 if (wages > 0) then
1166 if ( self.plugin:Call("PlayerGiveWagesCash", v, wages, v:GetWagesName() ) ) then
1167 self.player:GiveCash( v, wages, v:GetWagesName() );
1168 end;
1169 end;
1170
1171 self.plugin:Call("PlayerEarnWagesCash", v, wages);
1172 end;
1173 end;
1174 end;
1175 end;
1176
1177 -- A function to distribute generator cash.
1178 -- Decrypted: openAuth.LoadDLC("833-0392033103-5039703380336033107-0336039-03-603310580392039903-20440540338039803970399033803-40392039703-605603-6033103-6039903-203970336039905203-2039803390710760930310350334033603-503-2033407-033303-6033103-6039903-20397033603990550331039703380397033803-6039807-04607-03830388045093031035093031035033-0336039907-033202907-039407-0338033107-039-03-2033803990398071039803-60334033-027033303-6033103-6039903-2039703360399027039803970336039903-603-107607-03-10336093031035035039703-203-4033403-602705803-103-107107-033303-6033103-6039903-20397033603990550331039703380397033803-6039802907-03-60331039703980270510338033103-10570396052033403-203980398071033207607-07604509303103503-6033103-1045093031035093031035033-0336039907-033202907-039407-0338033107-039-03-2033803990398071033303-6033103-6039903-20397033603990550331039703380397033803-6039807607-03-103360930310350350334033603-503-2033407-033303-6033103-6039903-203970336039907-04607-039803-60334033-027033303-6033103-6039903-203970336039904405603-6039707107-039404405603-60397052033403-20398039807107607-0760450930310350350334033603-503-2033407-039-033403-2039603-6039907-04607-039404405603-60397011033403-2039603-603990710760450930310350350930310350350338033-07-07107-013039806703-20334033803-1071039-033403-2039603-6039907607-07607-0397033903-603310930310350350350338033-07-071039404405603-603970110336039503-6039907107607-07304607-02407607-0397033903-603310930310350350350350334033603-503-2033407-03380331033-033607-04607-0383093031035035035035035033303-6033103-6039903-203970336039907-04607-033303-6033103-6039903-203970336039902909303103503503503503503-60331039703380397039607-04607-039402909303103503503503503503-503-20398033907-04607-033303-6033103-6039903-203970336039902703-503-203980339029093031035035035035035033103-2033503-607-04607-07905603-6033103-6039903-20397033603990790930310350350350350388045093031035035035035093031035035035035039404406303-603970540690130331039707107-079039-0336039503-6039907902907-033503-203970339027033503-20391071039404405603-603970110336039503-6039907107607-02807-02502907-02407607-076045093031035035035035093031035035035035039803-60334033-027039-0334039203330338033104405203-203340334071079011033403-2039603-6039905803-1033703920398039705503-20399033105603-6033103-6039903-20397033603990130331033-033607902907-039-033403-2039603-6039902907-03380331033-03360760450930310350350350350930310350350350350338033-07-07107-039803-60334033-027039-0334039203330338033104405203-203340334071079011033403-2039603-6039905203-2033105503-20399033105603-6033103-6039903-203970336039905203-20398033907902907-039-033403-2039603-6039902907-03380331033-033602907-03380331033-033602703-503-20398033907607-07607-0397033903-603310930310350350350350350338033-07-0710394027015033105503-20399033103-603-107607-0397033903-603310930310350350350350350350334033603-503-2033407-039903-6039803920334039707-04607-0394044015033105503-20399033103-603-1071039-033403-2039603-6039902907-03380331033-033602703-503-2039803390760450930310350350350350350350930310350350350350350350338033-07-07103970396039-03-6071039903-6039803920334039707607-04604607-07903310392033503-403-6039907907607-0397033903-6033109303103503503503503503503503380331033-033602703-503-20398033907-04607-039903-6039803920334039704509303103503503503503503503-6033103-10450930310350350350350350350930310350350350350350350338033-07-071039903-6039803920334039707-07304607-033-03-20334039803-607607-0397033903-603310930310350350350350350350350338033-07-071039903-6039803920334039707-07304607-03970399039203-607607-0397033903-60331093031035035035035035035035035039803-60334033-027039-033403-2039603-603990440560338039403-605203-203980339071033202907-03380331033-033602703-503-20398033902907-03380331033-0336027033103-2033503-607604509303103503503503503503503503-6033103-1045093031035035035035035035035093031035035035035035035035039803-60334033-027039-0334039203330338033104405203-203340334071079011033403-2039603-6039905503-20399033105603-6033103-6039903-203970336039905203-20398033907902907-039-033403-2039603-6039902907-03380331033-033602907-03380331033-033602703-503-20398033907604509303103503503503503503503-6033103-104509303103503503503503503-60334039803-6093031035035035035035035039803-60334033-027039-033403-2039603-603990440560338039403-605203-203980339071033202907-03380331033-033602703-503-20398033902907-03380331033-0336027033103-2033503-6076045093031035035035035035035093031035035035035035035039803-60334033-027039-0334039203330338033104405203-203340334071079011033403-2039603-6039905503-20399033105603-6033103-6039903-203970336039905203-20398033907902907-039-033403-2039603-6039902907-03380331033-033602907-03380331033-033602703-503-20398033907604509303103503503503503503-6033103-104509303103503503503503-6033103-104509303103503503503-6033103-104509303103503503-6033103-104509303103503-6033103-104509303103-6033103-1045");
1179 function openAura:DistributeGeneratorCash()
1180 local generatorEntities = {};
1181
1182 for k, v in pairs(self.generator.stored) do
1183 table.Add( generatorEntities, ents.FindByClass(k) );
1184 end;
1185
1186 for k, v in pairs(generatorEntities) do
1187 local generator = self.generator:Get( v:GetClass() );
1188 local player = v:GetPlayer();
1189
1190 if ( IsValid(player) ) then
1191 if (v:GetPower() != 0) then
1192 local info = {
1193 generator = generator,
1194 entity = v,
1195 cash = generator.cash,
1196 name = "Generator"
1197 };
1198
1199 v:SetDTInt( "power", math.max(v:GetPower() - 1, 0) );
1200
1201 self.plugin:Call("PlayerAdjustEarnGeneratorInfo", player, info);
1202
1203 if ( self.plugin:Call("PlayerCanEarnGeneratorCash", player, info, info.cash) ) then
1204 if (v.OnEarned) then
1205 local result = v:OnEarned(player, info.cash);
1206
1207 if (type(result) == "number") then
1208 info.cash = result;
1209 end;
1210
1211 if (result != false) then
1212 if (result != true) then
1213 self.player:GiveCash(k, info.cash, info.name);
1214 end;
1215
1216 self.plugin:Call("PlayerEarnGeneratorCash", player, info, info.cash);
1217 end;
1218 else
1219 self.player:GiveCash(k, info.cash, info.name);
1220
1221 self.plugin:Call("PlayerEarnGeneratorCash", player, info, info.cash);
1222 end;
1223 end;
1224 end;
1225 end;
1226 end;
1227 end;
1228
1229 -- A function to include the schema.
1230 function openAura:IncludeSchema()
1231 local schemaFolder = self:GetSchemaFolder();
1232
1233 if (schemaFolder and type(schemaFolder) == "string") then
1234 self.config:Load(nil, true);
1235 self.plugin:Include(schemaFolder.."/gamemode/schema", true);
1236 self.config:Load();
1237 end;
1238 end;
1239
1240 -- A function to print a log message.
1241 function openAura:PrintLog(logType, text)
1242 local recipientFilter = RecipientFilter();
1243
1244 for k, v in ipairs( _player.GetAll() ) do
1245 if (v:HasInitialized() and v:GetInfoNum("aura_showlog", 0) == 1) then
1246 if ( self.player:IsAdmin(v) ) then
1247 recipientFilter:AddPlayer(v);
1248 end;
1249 end;
1250 end;
1251
1252 umsg.Start("aura_Log", recipientFilter);
1253 umsg.Short(logType or 5);
1254 umsg.String(text);
1255 umsg.End();
1256
1257 if ( AURA_CONVAR_LOG:GetInt() == 1 and isDedicatedServer() ) then
1258 self:ServerLog(text);
1259 end;
1260 end;
1261
1262 -- A function to log to the server.
1263 function openAura:ServerLog(text)
1264 ServerLog(text.."\n");
1265
1266 if ( isDedicatedServer() ) then
1267 print(text);
1268 end;
1269 end;
1270else
1271 openAura.ProgressBarColor = Color(50, 100, 150, 200);
1272 openAura.TargetPlayerText = { text = {} };
1273 openAura.BackgroundBlurs = {};
1274 openAura.RecognisedNames = {};
1275 openAura.PlayerInfoText = { text = {}, width = 0, subText = {} };
1276 openAura.NetworkProxies = {};
1277 openAura.InfoMenuOpen = false;
1278 openAura.ColorModify = {};
1279 openAura.Cinematics = {};
1280 openAura.MenuItems = { items = {} };
1281 openAura.ESPInfo = {};
1282 openAura.Hints = {};
1283 openAura.Bars = { x = 0, y = 0, width = 0, height = 0, bars = {} };
1284
1285 -- A function to register a network proxy.
1286 function openAura:RegisterNetworkProxy(entity, name, Callback)
1287 if ( !self.NetworkProxies[entity] ) then
1288 self.NetworkProxies[entity] = {};
1289 end;
1290
1291 self.NetworkProxies[entity][name] = {
1292 Callback = Callback,
1293 oldValue = nil
1294 };
1295 end;
1296
1297 -- A function to get whether the info menu is open.
1298 function openAura:IsInfoMenuOpen()
1299 return self.InfoMenuOpen;
1300 end;
1301
1302 -- A function to get some a menu item.
1303 function openAura.MenuItems:Get(text)
1304 for k, v in pairs(self.items) do
1305 if (v.text == text) then
1306 return v;
1307 end;
1308 end;
1309 end;
1310
1311 -- A function to add a menu item.
1312 function openAura.MenuItems:Add(text, panel, tip)
1313 self.items[#self.items + 1] = {text = text, panel = panel, tip = tip};
1314 end;
1315
1316 -- A function to destroy a menu item.
1317 function openAura.MenuItems:Destroy(text)
1318 for k, v in pairs(self.items) do
1319 if (v.text == text) then
1320 table.remove(self.items, k);
1321 end;
1322 end;
1323 end;
1324
1325 -- A function to add some target player text.
1326 function openAura.TargetPlayerText:Add(uniqueID, text, color)
1327 self.text[#self.text + 1] = {
1328 uniqueID = uniqueID,
1329 color = color,
1330 text = text
1331 };
1332 end;
1333
1334 -- A function to get some target player text.
1335 function openAura.TargetPlayerText:Get(uniqueID)
1336 for k, v in pairs(self.text) do
1337 if (v.uniqueID == uniqueID) then
1338 return v;
1339 end;
1340 end;
1341 end;
1342
1343 -- A function to destroy some target player text.
1344 function openAura.TargetPlayerText:Destroy(uniqueID)
1345 for k, v in pairs(self.text) do
1346 if (v.uniqueID == uniqueID) then
1347 table.remove(self.text, k);
1348 end;
1349 end;
1350 end;
1351
1352 -- A function to get whether any player info text exists.
1353 function openAura.PlayerInfoText:DoesAnyExist()
1354 return (#self.text > 0 or #self.subText > 0);
1355 end;
1356
1357 -- A function to add some player info text.
1358 function openAura.PlayerInfoText:Add(uniqueID, text)
1359 if (text) then
1360 self.text[#self.text + 1] = {
1361 uniqueID = uniqueID,
1362 text = text
1363 };
1364 end;
1365 end;
1366
1367 -- A function to get some player info text.
1368 function openAura.PlayerInfoText:Get(uniqueID)
1369 for k, v in pairs(self.text) do
1370 if (v.uniqueID == uniqueID) then
1371 return v;
1372 end;
1373 end;
1374 end;
1375
1376 -- A function to add some sub player info text.
1377 function openAura.PlayerInfoText:AddSub(uniqueID, text, priority)
1378 if (text) then
1379 self.subText[#self.subText + 1] = {
1380 priority = priority or 0,
1381 uniqueID = uniqueID,
1382 text = text
1383 };
1384 end;
1385 end;
1386
1387 -- A function to get some sub player info text.
1388 function openAura.PlayerInfoText:GetSub(uniqueID)
1389
1390 for k, v in pairs(self.subText) do
1391 if (v.uniqueID == uniqueID) then
1392 return v;
1393 end;
1394 end;
1395 end;
1396
1397 -- A function to destroy some player info text.
1398 function openAura.PlayerInfoText:Destroy(uniqueID)
1399
1400 for k, v in pairs(self.text) do
1401 if (v.uniqueID == uniqueID) then
1402 table.remove(self.text, k);
1403 end;
1404 end;
1405 end;
1406
1407 -- A function to destroy some sub player info text.
1408 function openAura.PlayerInfoText:DestroySub(uniqueID)
1409
1410 for k, v in pairs(self.subText) do
1411 if (v.uniqueID == uniqueID) then
1412 table.remove(self.subText, k);
1413 end;
1414 end;
1415 end;
1416
1417 -- A function to get a top bar.
1418 function openAura.Bars:Get(uniqueID)
1419 for k, v in pairs(self.bars) do
1420 if (v.uniqueID == uniqueID) then return v; end;
1421 end;
1422 end;
1423
1424 -- A function to add a top bar.
1425 function openAura.Bars:Add(uniqueID, color, text, value, maximum, flash, priority)
1426 self.bars[#self.bars + 1] = {
1427 uniqueID = uniqueID,
1428 priority = priority or 0,
1429 maximum = maximum,
1430 color = color,
1431 class = class,
1432 value = value,
1433 flash = flash,
1434 text = text,
1435 };
1436 end;
1437
1438 -- A function to destroy a top bar.
1439 function openAura.Bars:Destroy(uniqueID)
1440 for k, v in pairs(self.bars) do
1441 if (v.uniqueID == uniqueID) then
1442 table.remove(self.bars, k);
1443 end;
1444 end;
1445 end;
1446
1447 -- A function to create a client ConVar.
1448 function openAura:CreateClientConVar(name, value, save, userData, Callback)
1449 local conVar = CreateClientConVar(name, value, save, userData);
1450
1451 cvars.AddChangeCallback(name, function(conVar, previousValue, newValue)
1452 self.plugin:Call("OpenAuraConVarChanged", conVar, previousValue, newValue);
1453
1454 if (Callback) then
1455 Callback(conVar, previousValue, newValue);
1456 end;
1457 end);
1458
1459 return conVar;
1460 end;
1461
1462 -- A function to get the size of text.
1463 function openAura:GetTextSize(font, text)
1464 local defaultWidth, defaultHeight = self:GetCachedTextSize(font, "U");
1465 local height = defaultHeight;
1466 local width = 0;
1467
1468 for i = 1, string.len(text) do
1469 local textWidth, textHeight = self:GetCachedTextSize( font, string.sub(text, i, i) );
1470
1471 if (textWidth == 0) then
1472 textWidth = defaultWidth;
1473 end;
1474
1475 if (textHeight > height) then
1476 height = textHeight;
1477 end;
1478
1479 width = width + textWidth;
1480 end;
1481
1482 return width, height;
1483 end;
1484
1485 -- A function to calculate alpha from a distance.
1486 function openAura:CalculateAlphaFromDistance(maximum, start, finish)
1487 if (type(start) == "Player") then
1488 start = start:GetShootPos();
1489 elseif (type(start) == "Entity") then
1490 start = start:GetPos();
1491 end;
1492
1493 if (type(finish) == "Player") then
1494 finish = finish:GetShootPos();
1495 elseif (type(finish) == "Entity") then
1496 finish = finish:GetPos();
1497 end;
1498
1499 return math.Clamp(255 - ( (255 / maximum) * ( start:Distance(finish) ) ), 0, 255);
1500 end;
1501
1502 -- A function to wrap text into a table.
1503 function openAura:WrapText(text, font, width, baseTable)
1504 if (width <= 0 or !text or text == "") then
1505 return;
1506 end;
1507
1508 if (self:GetTextSize(font, text) > width) then
1509 local length = 0;
1510 local exploded = {};
1511 local seperator = "";
1512
1513 if ( string.find(text, " ") ) then
1514 exploded = string.Explode(" ", text);
1515 seperator = " ";
1516 else
1517 exploded = string.ToTable(text);
1518 seperator = "";
1519 end;
1520
1521 local i = 1;
1522
1523 while (length < width) do
1524 if ( !exploded[i] ) then
1525 break;
1526 end;
1527
1528 length = self:GetTextSize( font, table.concat(exploded, seperator, 1, i) );
1529
1530 i = i + 1;
1531 end;
1532
1533 baseTable[#baseTable + 1] = table.concat(exploded, seperator, 1, i - 2);
1534
1535 text = table.concat(exploded, seperator, i - 1);
1536
1537 if (self:GetTextSize(font, text) > width) then
1538 self:WrapText(text, font, width, baseTable);
1539 else
1540 baseTable[#baseTable + 1] = text;
1541 end;
1542 else
1543 baseTable[#baseTable + 1] = text;
1544 end;
1545 end;
1546
1547 -- A function to handle an entity's menu.
1548 function openAura:HandleEntityMenu(entity)
1549 local options = {};
1550 local menu = nil;
1551
1552 self.plugin:Call("GetEntityMenuOptions", entity, options);
1553
1554 if (table.Count(options) > 0) then
1555 menu = self:AddMenuFromData(nil, options, function(menu, option, arguments)
1556 menu:AddOption(option, function()
1557 if (type(arguments) == "table" and arguments.arguments) then
1558 if (!arguments.Callback) then
1559 self.entity:ForceMenuOption(entity, option, arguments.uniqueID);
1560 else
1561 arguments.Callback(entity);
1562 end;
1563 else
1564 self.entity:ForceMenuOption(entity, option, arguments);
1565 end;
1566
1567 timer.Simple(FrameTime(), function()
1568 self:RemoveActiveToolTip();
1569 end);
1570 end);
1571
1572 local panel = menu.Items[#menu.Items];
1573
1574 if ( IsValid(panel) ) then
1575 if (type(arguments) == "table") then
1576 if (arguments.order) then
1577 menu.Items[#menu.Items] = nil;
1578
1579 table.insert(menu.Items, 1, panel);
1580 end;
1581
1582 if (arguments.toolTip) then
1583 panel:SetToolTip(arguments.toolTip);
1584 end;
1585 end;
1586 end;
1587 end);
1588
1589 return menu;
1590 end;
1591 end;
1592
1593 -- A function to get the gradient texture.
1594 function openAura:GetGradientTexture()
1595 return self.GradientTexture;
1596 end;
1597
1598 -- A function to add a menu from data.
1599 function openAura:AddMenuFromData(menu, data, Callback)
1600 local options = {};
1601 local created;
1602
1603 if (!menu) then
1604 created = true; menu = DermaMenu();
1605 end;
1606
1607 for k, v in pairs(data) do
1608 options[#options + 1] = {k, v};
1609 end;
1610
1611 table.sort(options, function(a, b)
1612 return a[1] < b[1];
1613 end);
1614
1615 for k, v in pairs(options) do
1616 if (type( v[2] ) == "table" and !v[2].arguments) then
1617 if (table.Count( v[2] ) > 0) then
1618 self:AddMenuFromData(menu:AddSubMenu( v[1] ), v[2], Callback);
1619 end;
1620 elseif (type( v[2] ) == "function") then
1621 menu:AddOption( v[1], v[2] );
1622 elseif (Callback) then
1623 Callback( menu, v[1], v[2] );
1624 end;
1625 end;
1626
1627 if (created) then
1628 if (#options > 0) then
1629 menu:Open();
1630 else
1631 menu:Remove();
1632 end;
1633
1634 return menu;
1635 end;
1636 end;
1637
1638 -- A function to adjust the width of text.
1639 function openAura:AdjustMaximumWidth(font, text, width, addition, extra)
1640 local textString = tostring( openAura:Replace(text, "&", "U") );
1641 local textWidth = self:GetCachedTextSize(font, textString) + (extra or 0);
1642
1643 if (textWidth > width) then
1644 width = textWidth + (addition or 0);
1645 end;
1646
1647 return width;
1648 end;
1649
1650 -- A function to add a top hint.
1651 function openAura:AddTopHint(text, delay, color, noSound)
1652 local colorWhite = self.option:GetColor("white");
1653
1654 if (color) then
1655 if (type(color) == "string") then
1656 color = self.option:GetColor(color);
1657 end;
1658 else
1659 color = colorWhite;
1660 end;
1661
1662 for k, v in ipairs(self.Hints) do
1663 if (v.text == text) then
1664 return;
1665 end;
1666 end;
1667
1668 if (table.Count(self.Hints) == 10) then
1669 table.remove(self.Hints, 10);
1670 end;
1671
1672 if (!noSound) then
1673 self.option:PlaySound("rollover");
1674 end;
1675
1676 table.insert( self.Hints, 1, {
1677 targetAlpha = 255,
1678 alphaSpeed = 64,
1679 color = color,
1680 delay = delay,
1681 alpha = 0,
1682 text = text
1683 } );
1684 end;
1685
1686 -- A function to calculate the top hints.
1687 function openAura:CalculateHints()
1688 local frameTime = FrameTime();
1689 local curTime = UnPredictedCurTime();
1690
1691 for k, v in pairs(self.Hints) do
1692 if (!v.nextChangeTarget or curTime >= v.nextChangeTarget) then
1693 v.alpha = math.Approach(v.alpha, v.targetAlpha, v.alphaSpeed * frameTime);
1694
1695 if (v.alpha == v.targetAlpha) then
1696 if (v.targetAlpha == 0) then
1697 table.remove(self.Hints, k);
1698 else
1699 v.nextChangeTarget = curTime + v.delay;
1700 v.targetAlpha = 0;
1701 v.alphaSpeed = 16;
1702 end;
1703 end;
1704 end;
1705 end;
1706 end;
1707
1708 -- A function to draw the date and time.
1709 function openAura:DrawDateTime()
1710 local backgroundColor = self.option:GetColor("background");
1711 local mainTextFont = self.option:GetFont("main_text");
1712 local colorWhite = self.option:GetColor("white");
1713 local colorInfo = self.option:GetColor("information");
1714 local scrW = ScrW();
1715 local scrH = ScrH();
1716 local info = {
1717 width = scrW * 0.1,
1718 x = scrW / 2,
1719 y = scrH * 0.2
1720 };
1721
1722 info.originalX = info.x;
1723 info.originalY = info.y;
1724
1725 if (self.LastDateTimeInfo and self.LastDateTimeInfo.y > info.y) then
1726 local height = (self.LastDateTimeInfo.y - info.y) + 8;
1727 local width = self.LastDateTimeInfo.width + 16;
1728 local x = self.LastDateTimeInfo.x - (self.LastDateTimeInfo.width / 2) - 8;
1729 local y = self.LastDateTimeInfo.y - height;
1730
1731 self:OverrideMainFont( self.option:GetFont("menu_text_tiny") );
1732 self:DrawInfo("CHARACTER AND ROLEPLAY INFO", x, y + 4, colorInfo, nil, true, function(x, y, width, height)
1733 return x, y - height;
1734 end);
1735
1736 self:DrawSimpleGradientBox(2, x, y + 8, width, height, backgroundColor);
1737 y = y + height + 16;
1738
1739 if ( self:CanCreateInfoMenuPanel() and self:IsInfoMenuOpen() ) then
1740 local menuPanelX = x;
1741 local menuPanelY = y;
1742
1743 self:DrawInfo("SELECT A QUICK MENU OPTION", x, y, colorInfo, nil, true, function(x, y, width, height)
1744 menuPanelY = menuPanelY + height + 4;
1745 return x, y;
1746 end);
1747
1748 self:CreateInfoMenuPanel(menuPanelX, menuPanelY, width);
1749 self:DrawSimpleGradientBox(2, self.InfoMenuPanel.x - 4, self.InfoMenuPanel.y - 4, self.InfoMenuPanel:GetWide() + 8, self.InfoMenuPanel:GetTall() + 8, backgroundColor);
1750 self.InfoMenuPanel:SetSize( width, self.InfoMenuPanel:GetTall() );
1751
1752 if (!self.InfoMenuPanel.VisibilitySet) then
1753 self.InfoMenuPanel.VisibilitySet = true;
1754
1755 timer.Simple(FrameTime() * 2, function()
1756 if ( IsValid(self.InfoMenuPanel) ) then
1757 self.InfoMenuPanel:SetVisible(true);
1758 end;
1759 end);
1760 end;
1761 end;
1762 self:OverrideMainFont(false);
1763 end;
1764
1765 if ( self.plugin:Call("PlayerCanSeeDateTime") ) then
1766 local dateTimeFont = self.option:GetFont("date_time_text");
1767 local dateString = self.date:GetString();
1768 local timeString = self.time:GetString();
1769 local dayName = self.time:GetDayName();
1770 local text = string.upper(dateString..". "..dayName..", "..timeString..".");
1771
1772 self:OverrideMainFont(dateTimeFont);
1773 info.y = self:DrawInfo(text, info.x, info.y, colorWhite, 255);
1774 self:OverrideMainFont(false);
1775
1776 local textWidth, textHeight = openAura:GetCachedTextSize(dateTimeFont, text);
1777
1778 if (textWidth and textHeight) then
1779 info.width = textWidth;
1780 end;
1781 end;
1782
1783 self:DrawBars(info, "tab");
1784 self.plugin:Call("OpenAuraDateTimeDrawn", info);
1785 self.PlayerInfoBox = self:DrawPlayerInfo(info);
1786
1787 self.LastDateTimeInfo = info;
1788
1789 if ( self.plugin:Call("PlayerCanSeeLimbDamage") ) then
1790 local tipHeight = 0;
1791 local tipWidth = 0;
1792 local limbInfo = {};
1793 local height = 192;
1794 local width = 96;
1795 local texInfo = {
1796 shouldDisplay = true,
1797 textures = {
1798 [HITGROUP_RIGHTARM] = self.limb:GetTexture(HITGROUP_RIGHTARM),
1799 [HITGROUP_RIGHTLEG] = self.limb:GetTexture(HITGROUP_RIGHTLEG),
1800 [HITGROUP_LEFTARM] = self.limb:GetTexture(HITGROUP_LEFTARM),
1801 [HITGROUP_LEFTLEG] = self.limb:GetTexture(HITGROUP_LEFTLEG),
1802 [HITGROUP_STOMACH] = self.limb:GetTexture(HITGROUP_STOMACH),
1803 [HITGROUP_CHEST] = self.limb:GetTexture(HITGROUP_CHEST),
1804 [HITGROUP_HEAD] = self.limb:GetTexture(HITGROUP_HEAD),
1805 ["body"] = self.limb:GetTexture("body")
1806 },
1807 names = {
1808 [HITGROUP_RIGHTARM] = self.limb:GetName(HITGROUP_RIGHTARM),
1809 [HITGROUP_RIGHTLEG] = self.limb:GetName(HITGROUP_RIGHTLEG),
1810 [HITGROUP_LEFTARM] = self.limb:GetName(HITGROUP_LEFTARM),
1811 [HITGROUP_LEFTLEG] = self.limb:GetName(HITGROUP_LEFTLEG),
1812 [HITGROUP_STOMACH] = self.limb:GetName(HITGROUP_STOMACH),
1813 [HITGROUP_CHEST] = self.limb:GetName(HITGROUP_CHEST),
1814 [HITGROUP_HEAD] = self.limb:GetName(HITGROUP_HEAD),
1815 }
1816 };
1817 local x = info.x + (info.width / 2) + 32;
1818 local y = info.originalY + 8;
1819
1820 openAura.plugin:Call("GetPlayerLimbInfo", texInfo);
1821
1822 if (texInfo.shouldDisplay) then
1823 surface.SetDrawColor(255, 255, 255, 150);
1824 surface.SetTexture( texInfo.textures["body"] );
1825 surface.DrawTexturedRect(x, y, width, height);
1826
1827 for k, v in pairs(self.limb.hitGroups) do
1828 local limbHealth = self.limb:GetHealth(k);
1829 local limbColor = self.limb:GetColor(limbHealth);
1830 local newIndex = #limbInfo + 1;
1831
1832 surface.SetDrawColor(limbColor.r, limbColor.g, limbColor.b, 150);
1833 surface.SetTexture( texInfo.textures[k] );
1834 surface.DrawTexturedRect(x, y, width, height);
1835
1836 limbInfo[newIndex] = {
1837 color = limbColor,
1838 text = texInfo.names[k]..": "..limbHealth.."%"
1839 };
1840
1841 local textWidth, textHeight = self:GetCachedTextSize(mainTextFont, limbInfo[newIndex].text);
1842 tipHeight = tipHeight + textHeight + 4;
1843
1844 if (textWidth > tipWidth) then
1845 tipWidth = textWidth;
1846 end;
1847
1848 limbInfo[newIndex].textHeight = textHeight;
1849 end;
1850
1851 local mouseX = gui.MouseX();
1852 local mouseY = gui.MouseY();
1853
1854 if (mouseX >= x and mouseX <= x + width
1855 and mouseY >= y and mouseY <= y + height) then
1856 local tipX = mouseX + 16;
1857 local tipY = mouseY + 16;
1858
1859 self:DrawSimpleGradientBox(2, tipX - 8, tipY - 8, tipWidth + 16, tipHeight + 12, backgroundColor);
1860
1861 for k, v in pairs(limbInfo) do
1862 self:DrawInfo(v.text, tipX, tipY, v.color, 255, true);
1863
1864 if (k < #limbInfo) then
1865 tipY = tipY + v.textHeight + 4;
1866 else
1867 tipY = tipY + v.textHeight;
1868 end;
1869 end;
1870 end;
1871 end;
1872 end;
1873 end;
1874
1875 -- A function to draw the top hints.
1876 function openAura:DrawHints()
1877 local x = ScrW();
1878 local y = 8;
1879
1880 if ( self.plugin:Call("PlayerCanSeeHints") ) then
1881 for k, v in pairs(self.Hints) do
1882 self:OverrideMainFont( self.option:GetFont("hints_text") );
1883 y = self:DrawInfo(string.upper(v.text), x, y, v.color, v.alpha, true, function(x, y, width, height)
1884 return x - width - 8, y;
1885 end);
1886 self:OverrideMainFont(false);
1887 end;
1888 end;
1889 end;
1890
1891 -- A function to draw the top bars.
1892 function openAura:DrawBars(info, class)
1893 if ( self.plugin:Call("PlayerCanSeeBars", class) ) then
1894 local barTextFont = self.option:GetFont("bar_text");
1895
1896 self.Bars.width = info.width;
1897 self.Bars.height = 12;
1898 self.Bars.y = info.y;
1899
1900 if (class == "tab") then
1901 self.Bars.x = info.x - (info.width / 2);
1902 else
1903 self.Bars.x = info.x;
1904 end;
1905
1906 self.option:SetFont( "bar_text", self.option:GetFont("auto_bar_text") );
1907 for k, v in ipairs(self.Bars.bars) do
1908 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);
1909 end;
1910 self.option:SetFont("bar_text", barTextFont);
1911
1912 info.y = self.Bars.y;
1913 end;
1914 end;
1915
1916 -- A function to get the ESP info.
1917 function openAura:GetESPInfo()
1918 return self.ESPInfo;
1919 end;
1920
1921 -- A function to draw the admin ESP.
1922 function openAura:DrawAdminESP()
1923 local colorWhite = self.option:GetColor("white");
1924 local curTime = UnPredictedCurTime();
1925
1926 if (!self.NextGetESPInfo) then
1927 self.NextGetESPInfo = curTime + 1;
1928 end;
1929
1930 if (curTime >= self.NextGetESPInfo) then
1931 self.NextGetESPInfo = curTime + 1;
1932 self.ESPInfo = {};
1933
1934 self.plugin:Call("GetAdminESPInfo", self.ESPInfo);
1935 end;
1936
1937 for k, v in pairs(self.ESPInfo) do
1938 local position = v.position:ToScreen();
1939
1940 if (position) then
1941 self:DrawSimpleText(v.text, position.x, position.y, v.color or colorWhite, 1, 1);
1942 end;
1943 end;
1944 end;
1945
1946 -- A function to draw a bar with a value and a maximum.
1947 function openAura:DrawBar(x, y, width, height, color, text, value, maximum, flash, barInfo)
1948 local backgroundColor = self.option:GetColor("background");
1949 local progressWidth = math.Clamp( ( (width - 2) / maximum ) * value, 0, width - 2 );
1950 local colorWhite = self.option:GetColor("white");
1951 local newBarInfo = {
1952 progressWidth = progressWidth,
1953 drawBackground = true,
1954 drawProgress = true,
1955 cornerSize = 4,
1956 maximum = maximum,
1957 height = height,
1958 width = width,
1959 color = color,
1960 value = value,
1961 flash = flash,
1962 text = text,
1963 x = x,
1964 y = y
1965 };
1966
1967 if (barInfo) then
1968 for k, v in pairs(newBarInfo) do
1969 if ( !barInfo[k] ) then
1970 barInfo[k] = v;
1971 end;
1972 end;
1973 else
1974 barInfo = newBarInfo;
1975 end;
1976
1977 if ( !self.plugin:Call("PreDrawBar", barInfo) ) then
1978 if (barInfo.drawBackground) then
1979 self:DrawTexturedGradientBox(barInfo.cornerSize, barInfo.x, barInfo.y, barInfo.width, barInfo.height, backgroundColor);
1980 end;
1981
1982 if (barInfo.drawProgress) then
1983 self:DrawTexturedGradientBox(0, barInfo.x + 1, barInfo.y + 1, barInfo.progressWidth, barInfo.height - 2, barInfo.color);
1984 end;
1985
1986 if (barInfo.flash) then
1987 local alpha = math.Clamp(math.abs(math.sin( UnPredictedCurTime() ) * 50), 0, 50);
1988
1989 if (alpha > 0) then
1990 draw.RoundedBox( 0, barInfo.x + 2, barInfo.y + 2, barInfo.width - 4, barInfo.height - 4, Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha) );
1991 end;
1992 end;
1993 end;
1994
1995 if ( !self.plugin:Call("PostDrawBar", barInfo) ) then
1996 if (barInfo.text and barInfo.text != "") then
1997 self:OverrideMainFont( self.option:GetFont("bar_text") );
1998 self:DrawSimpleText(barInfo.text, barInfo.x + (barInfo.width / 2), barInfo.y + (barInfo.height / 2), Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha), 1, 1);
1999 self:OverrideMainFont(false);
2000 end;
2001 end;
2002
2003 return barInfo.y;
2004 end;
2005
2006 -- A function to set the recognise menu.
2007 function openAura:SetRecogniseMenu(menu)
2008 self.RecogniseMenu = menu;
2009 end;
2010
2011 -- A function to get the recognise menu.
2012 function openAura:GetRecogniseMenu(menu)
2013 return self.RecogniseMenu;
2014 end;
2015
2016 -- A function to override the main font.
2017 function openAura:OverrideMainFont(font)
2018 if (font) then
2019 if (!self.PreviousMainFont) then
2020 self.PreviousMainFont = self.option:GetFont("main_text");
2021 end;
2022
2023 self.option:SetFont("main_text", font);
2024 elseif (self.PreviousMainFont) then
2025 self.option:SetFont("main_text", self.PreviousMainFont)
2026 end;
2027 end;
2028
2029 -- A function to get the screen's center.
2030 function openAura:GetScreenCenter()
2031 return ScrW() / 2, (ScrH() / 2) + 32;
2032 end;
2033
2034 -- A function to draw some simple text.
2035 function openAura:DrawSimpleText(text, x, y, color, alignX, alignY, shadowless, shadowDepth)
2036 local mainTextFont = self.option:GetFont("main_text");
2037 local realX = math.Round(x);
2038 local realY = math.Round(y);
2039
2040 if (!shadowless) then
2041 local outlineColor = Color( 25, 25, 25, math.min(225, color.a) );
2042 local depth = shadowDepth or 1;
2043
2044 draw.SimpleText(text, mainTextFont, realX + -depth, realY + -depth, outlineColor, alignX, alignY);
2045 draw.SimpleText(text, mainTextFont, realX + -depth, realY + depth, outlineColor, alignX, alignY);
2046 draw.SimpleText(text, mainTextFont, realX + depth, realY + -depth, outlineColor, alignX, alignY);
2047 draw.SimpleText(text, mainTextFont, realX + depth, realY + depth, outlineColor, alignX, alignY);
2048 end;
2049
2050 local width, height = draw.SimpleText(text, mainTextFont, realX, realY, color, alignX, alignY);
2051
2052 if (width and height) then
2053 if (height == 0) then
2054 height = draw.GetFontHeight(mainTextFont);
2055 end;
2056
2057 return realY + height + 2;
2058 else
2059 return realY;
2060 end;
2061 end;
2062
2063 -- A function to get the black fade alpha.
2064 function openAura:GetBlackFadeAlpha()
2065 return self.BlackFadeIn or self.BlackFadeOut or 0;
2066 end;
2067
2068 -- A function to get whether the screen is faded black.
2069 function openAura:IsScreenFadedBlack()
2070 return (self.BlackFadeIn == 255);
2071 end;
2072
2073 --[[
2074 A function to print colored text to the console.
2075 Sure, it's hacky, but Garry is being a douche.
2076 --]]
2077 function openAura:PrintColoredText(...)
2078 local currentColor = nil;
2079 local colorWhite = openAura.option:GetColor("white");
2080 local text = {};
2081
2082 for k, v in ipairs( {...} ) do
2083 if (type(v) == "Player") then
2084 text[#text + 1] = _team.GetColor( v:Team() );
2085 text[#text + 1] = v:Name();
2086 elseif (type(v) == "table") then
2087 currentColor = v;
2088 elseif (currentColor) then
2089 text[#text + 1] = currentColor;
2090 text[#text + 1] = v;
2091 currentColor = nil;
2092 else
2093 text[#text + 1] = colorWhite;
2094 text[#text + 1] = v;
2095 end;
2096 end;
2097
2098 chat.OpenAuraAddText( unpack(text) );
2099 end;
2100
2101 -- A function to get whether a custom crosshair is used.
2102 function openAura:UsingCustomCrosshair()
2103 return self.CustomCrosshair;
2104 end;
2105
2106 -- A function to get a cached text size.
2107 function openAura:GetCachedTextSize(font, text)
2108 if (!self.CachedTextSizes) then
2109 self.CachedTextSizes = {};
2110 end;
2111
2112 if ( !self.CachedTextSizes[font] ) then
2113 self.CachedTextSizes[font] = {};
2114 end;
2115
2116 if ( !self.CachedTextSizes[font][text] ) then
2117 surface.SetFont(font);
2118
2119 self.CachedTextSizes[font][text] = { surface.GetTextSize(text) };
2120 end;
2121
2122 return unpack( self.CachedTextSizes[font][text] );
2123 end;
2124
2125 -- A function to draw information at a position.
2126 function openAura:DrawInfo(text, x, y, color, alpha, alignLeft, Callback, shadowDepth)
2127 local mainTextFont = self.option:GetFont("main_text");
2128 local width, height = self:GetCachedTextSize(mainTextFont, text);
2129
2130 if (width and height) then
2131 if (!alignLeft) then
2132 x = x - (width / 2);
2133 end;
2134
2135 if (Callback) then
2136 x, y = Callback(x, y, width, height);
2137 end;
2138
2139 return self:DrawSimpleText(text, x, y, Color(color.r, color.g, color.b, alpha or color.a), nil, nil, nil, shadowDepth);
2140 end;
2141 end;
2142
2143 -- A function to get the player info box.
2144 function openAura:GetPlayerInfoBox()
2145 return self.PlayerInfoBox;
2146 end;
2147
2148 -- A function to draw the local player's information.
2149 function openAura:DrawPlayerInfo(info)
2150 if ( self.plugin:Call("PlayerCanSeePlayerInfo") ) then
2151 local backgroundColor = self.option:GetColor("background");
2152 local subInformation = self.PlayerInfoText.subText;
2153 local information = self.PlayerInfoText.text;
2154 local colorWhite = self.option:GetColor("white");
2155 local textWidth, textHeight = self:GetCachedTextSize(self.option:GetFont("player_info_text"), "U");
2156 local width = self.PlayerInfoText.width;
2157
2158 if (width < info.width) then
2159 width = info.width;
2160 elseif (width > width) then
2161 info.width = width;
2162 end;
2163
2164 if (#information > 0 or #subInformation > 0) then
2165 local height = (textHeight * #information) + ( (textHeight + 4) * #subInformation );
2166 local scrW = ScrW();
2167 local scrH = ScrH();
2168
2169 if (#information > 0) then
2170 height = height + 8;
2171 end;
2172
2173 local y = info.y + 8;
2174 local x = info.x - (width / 2);
2175
2176 local boxInfo = {
2177 subInformation = subInformation,
2178 drawBackground = true,
2179 information = information,
2180 textHeight = textHeight,
2181 cornerSize = 2,
2182 textWidth = textWidth,
2183 height = height,
2184 width = width,
2185 x = x,
2186 y = y
2187 };
2188
2189 if ( !self.plugin:Call("PreDrawPlayerInfo", boxInfo, information, subInformation) ) then
2190 self:OverrideMainFont( self.option:GetFont("player_info_text") );
2191 for k, v in ipairs(subInformation) do
2192 x, y = self:DrawPlayerInfoSubBox(v.text, x, y, width, boxInfo);
2193 end;
2194
2195 if (#information > 0) then
2196 if (boxInfo.drawBackground) then
2197 self:DrawTexturedGradientBox(boxInfo.cornerSize, x, y, width, height - ( (textHeight + 4) * #subInformation ), backgroundColor);
2198 end;
2199 end;
2200
2201 if (#information > 0) then
2202 x = x + 8
2203 y = y + 4;
2204 end;
2205
2206 for k, v in ipairs(information) do
2207 self:DrawInfo(v.text, x, y - 1, colorWhite, 255, true);
2208 y = y + textHeight;
2209 end;
2210 self:OverrideMainFont(false);
2211 end;
2212
2213 self.plugin:Call("PostDrawPlayerInfo", boxInfo, information, subInformation);
2214 info.y = info.y + boxInfo.height + 16;
2215
2216 return boxInfo;
2217 end;
2218 end;
2219 end;
2220
2221 -- A function to get whether the info menu panel can be created.
2222 function openAura:CanCreateInfoMenuPanel()
2223 return (table.Count(self.quickmenu.stored) > 0 or table.Count(self.quickmenu.categories) > 0);
2224 end;
2225
2226 -- A function to create the info menu panel.
2227 function openAura:CreateInfoMenuPanel(x, y, w)
2228 if ( !IsValid(self.InfoMenuPanel) ) then
2229 local options = {};
2230
2231 for k, v in pairs(self.quickmenu.categories) do
2232 options[k] = {};
2233
2234 for k2, v2 in pairs(v) do
2235 local info = v2.GetInfo();
2236
2237 if (type(info) == "table") then
2238 options[k][k2] = info;
2239 options[k][k2].arguments = true;
2240 end;
2241 end;
2242 end;
2243
2244 for k, v in pairs(self.quickmenu.stored) do
2245 local info = v.GetInfo();
2246
2247 if (type(info) == "table") then
2248 options[k] = info;
2249 options[k].arguments = true;
2250 end;
2251 end;
2252
2253 self.InfoMenuPanel = self:AddMenuFromData(nil, options, function(menu, option, arguments)
2254 if (arguments.name) then
2255 option = arguments.name;
2256 end;
2257
2258 if (arguments.options) then
2259 local subMenu = menu:AddSubMenu(option);
2260
2261 for k, v in ipairs(arguments.options) do
2262 local name = v;
2263
2264 if (type(v) == "table") then
2265 name = v[1];
2266 end;
2267
2268 subMenu:AddOption(name, function()
2269 if (arguments.Callback) then
2270 if (type(v) == "table") then
2271 arguments.Callback( v[2] );
2272 else
2273 arguments.Callback(v);
2274 end;
2275 end;
2276
2277 self:RemoveActiveToolTip();
2278 self:CloseActiveDermaMenus();
2279 end);
2280 end;
2281
2282 if ( IsValid(subMenu) ) then
2283 if (arguments.toolTip) then
2284 subMenu:SetToolTip(arguments.toolTip);
2285 end;
2286 end;
2287 else
2288 menu:AddOption(option, function()
2289 if (arguments.Callback) then
2290 arguments.Callback();
2291 end;
2292
2293 self:RemoveActiveToolTip();
2294 self:CloseActiveDermaMenus();
2295 end);
2296
2297 local panel = menu.Items[#menu.Items];
2298
2299 if (IsValid(panel) and arguments.toolTip) then
2300 panel:SetToolTip(arguments.toolTip);
2301 end;
2302 end;
2303 end);
2304
2305 if ( IsValid(self.InfoMenuPanel) ) then
2306 self.InfoMenuPanel:SetVisible(false);
2307 self.InfoMenuPanel:SetSize( w, self.InfoMenuPanel:GetTall() );
2308 self.InfoMenuPanel:SetPos(x, y);
2309 end;
2310 end;
2311 end;
2312
2313 -- A function to get the ragdoll eye angles.
2314 function openAura:GetRagdollEyeAngles()
2315 if (!self.RagdollEyeAngles) then
2316 self.RagdollEyeAngles = Angle(0, 0, 0);
2317 end;
2318
2319 return self.RagdollEyeAngles;
2320 end;
2321
2322 -- A function to draw a simple gradient box.
2323 function openAura:DrawSimpleGradientBox(cornerSize, x, y, width, height, color, alphaMax, bNoBox)
2324 local gradientAlpha = math.min(color.a, alphaMax or 100);
2325
2326 if (!bNoBox) then
2327 draw.RoundedBox( cornerSize, x, y, width, height, Color(color.r, color.g, color.b, color.a * 0.75) );
2328 end;
2329
2330 if (x + cornerSize < x + width and y + cornerSize < y + height) then
2331 surface.SetDrawColor(gradientAlpha, gradientAlpha, gradientAlpha, gradientAlpha);
2332 surface.SetTexture(self.DefaultGradient);
2333 surface.DrawTexturedRect( x + cornerSize, y + cornerSize, width - (cornerSize * 2), height - (cornerSize * 2) );
2334 end;
2335 end;
2336
2337 -- A function to draw a textured gradient.
2338 function openAura:DrawTexturedGradientBox(cornerSize, x, y, width, height, color, alphaMax, bNoBox)
2339 local gradientAlpha = math.min(color.a, alphaMax or 150);
2340
2341 if (!bNoBox) then
2342 draw.RoundedBox( cornerSize, x, y, width, height, Color(color.r, color.g, color.b, color.a * 0.75) );
2343 end;
2344
2345 if (x + cornerSize < x + width and y + cornerSize < y + height) then
2346 surface.SetDrawColor(gradientAlpha, gradientAlpha, gradientAlpha, gradientAlpha);
2347 surface.SetTexture( self:GetGradientTexture() );
2348 surface.DrawTexturedRect( x + cornerSize, y + cornerSize, width - (cornerSize * 2), height - (cornerSize * 2) );
2349 end;
2350 end;
2351
2352 -- Adding some backwards compatability here.
2353 openAura.DrawRoundedGradient = openAura.DrawTexturedGradientBox;
2354
2355 -- A function to draw a player information sub box.
2356 function openAura:DrawPlayerInfoSubBox(text, x, y, width, boxInfo)
2357 local backgroundColor = self.option:GetColor("background");
2358 local colorInfo = self.option:GetColor("information");
2359
2360 if (boxInfo.drawBackground) then
2361 self:DrawTexturedGradientBox( boxInfo.cornerSize, x, y, width, boxInfo.textHeight + 2, backgroundColor );
2362 end;
2363
2364 self:DrawInfo(text, x + 8, y + 1, colorInfo, 255, true);
2365
2366 if (boxInfo) then
2367 return x, y + boxInfo.textHeight + 4;
2368 else
2369 return x, y + 20;
2370 end;
2371 end;
2372
2373 -- A function to create a colored spawn icon.
2374 function openAura:CreateColoredSpawnIcon(parent)
2375 local spawnIcon = vgui.Create("SpawnIcon", parent);
2376
2377 -- A function to set the spawn icon's color.
2378 function spawnIcon.SetColor(spawnIcon, color)
2379 spawnIcon.BorderColor = color;
2380 end;
2381
2382 -- A function to set the spawn icon's cooldown.
2383 function spawnIcon.SetCooldown(spawnIcon, expireTime, textureID)
2384 spawnIcon.Cooldown = {
2385 expireTime = expireTime,
2386 textureID = textureID or surface.GetTextureID("vgui/white"),
2387 duration = expireTime - CurTime()
2388 }
2389 end;
2390
2391 -- Called after the spawn icon's children are painted.
2392 function spawnIcon.Icon.PaintOver()
2393 local curTime = CurTime();
2394
2395 if (spawnIcon.Cooldown and spawnIcon.Cooldown.expireTime > curTime) then
2396 local timeLeft = spawnIcon.Cooldown.expireTime - curTime;
2397 local progress = 100 - ( (100 / spawnIcon.Cooldown.duration) * timeLeft );
2398
2399 openAura.cooldown:DrawBox(
2400 spawnIcon.x,
2401 spawnIcon.y,
2402 spawnIcon:GetWide(),
2403 spawnIcon:GetTall(),
2404 progress, Color( 255, 255, 255, 255 - ( (255 / 100) * progress) ),
2405 spawnIcon.Cooldown.textureID
2406 );
2407 end;
2408
2409 if (spawnIcon.BorderColor) then
2410 local alpha = math.min( spawnIcon.BorderColor.a, spawnIcon:GetAlpha() );
2411
2412 self.SpawnIconMaterial:SetMaterialVector( "$color", Vector(spawnIcon.BorderColor.r / 255, spawnIcon.BorderColor.g / 255, spawnIcon.BorderColor.b / 255) );
2413 self.SpawnIconMaterial:SetMaterialFloat("$alpha", alpha / 255);
2414 surface.SetDrawColor(spawnIcon.BorderColor.r, spawnIcon.BorderColor.g, spawnIcon.BorderColor.b, alpha);
2415 surface.SetMaterial(self.SpawnIconMaterial);
2416 spawnIcon:DrawTexturedRect();
2417 self.SpawnIconMaterial:SetMaterialFloat("$alpha", 1);
2418 self.SpawnIconMaterial:SetMaterialVector( "$color", Vector(1, 1, 1) );
2419 end;
2420 end;
2421
2422 return spawnIcon;
2423 end;
2424
2425 -- A function to draw the armor bar.
2426 function openAura:DrawArmorBar()
2427 local armor = math.Clamp( self.Client:Armor(), 0, self.Client:GetMaxArmor() );
2428
2429 if (armor > 0) then
2430 self.Bars:Add("ARMOR", Color(139, 174, 179, 255), "", armor, self.Client:GetMaxArmor(), armor < 10, 1);
2431 end;
2432 end;
2433
2434 -- A function to draw the health bar.
2435 function openAura:DrawHealthBar()
2436 local health = math.Clamp( self.Client:Health(), 0, self.Client:GetMaxHealth() );
2437
2438 if (health > 0) then
2439 self.Bars:Add("HEALTH", Color(179, 46, 49, 255), "", health, self.Client:GetMaxHealth(), health < 10, 2);
2440 end;
2441 end;
2442
2443 -- A function to remove the active tool tip.
2444 function openAura:RemoveActiveToolTip()
2445 ChangeTooltip();
2446 end;
2447
2448 -- A function to close active Derma menus.
2449 function openAura:CloseActiveDermaMenus()
2450 CloseDermaMenus();
2451 end;
2452
2453 -- A function to register a background blur.
2454 function openAura:RegisterBackgroundBlur(panel, createTime, iScale)
2455 self.BackgroundBlurs[panel] = {createTime, iScale or 1};
2456 end;
2457
2458 -- A function to remove a background blur.
2459 function openAura:RemoveBackgroundBlur(panel)
2460 self.BackgroundBlurs[panel] = nil;
2461 end;
2462
2463 -- A function to draw the background blurs.
2464 function openAura:DrawBackgroundBlurs()
2465 local sysTime = SysTime();
2466 local scrH = ScrH();
2467 local scrW = ScrW();
2468
2469 for k, v in pairs(self.BackgroundBlurs) do
2470 if ( type(k) == "string" or ( IsValid(k) and k:IsVisible() ) ) then
2471 local fraction = math.Clamp( ( sysTime - v[1] ) / 1, 0, 1 ) * v[2];
2472 local x, y = 0, 0;
2473
2474 surface.SetMaterial(self.ScreenBlur);
2475 surface.SetDrawColor(255, 255, 255, 255);
2476
2477 for i = 0.33, 1, 0.33 do
2478 self.ScreenBlur:SetMaterialFloat("$blur", fraction * 5 * i);
2479
2480 if (render) then
2481 render.UpdateScreenEffectTexture();
2482 end;
2483
2484 surface.DrawTexturedRect(x, y, scrW, scrH);
2485 end;
2486
2487 surface.SetDrawColor(10, 10, 10, 200 * fraction);
2488 surface.DrawRect(x, y, scrW, scrH);
2489 end;
2490 end;
2491 end;
2492
2493 -- A function to get the notice panel.
2494 function openAura:GetNoticePanel()
2495 if ( IsValid(self.NoticePanel) and self.NoticePanel:IsVisible() ) then
2496 return self.NoticePanel;
2497 end;
2498 end;
2499
2500 -- A function to set the notice panel.
2501 function openAura:SetNoticePanel(noticePanel)
2502 self.NoticePanel = noticePanel;
2503 end;
2504
2505 -- A function to add some cinematic text.
2506 function openAura:AddCinematicText(text, color, barLength, hangTime, font, bThisOnly)
2507 local colorWhite = self.option:GetColor("white");
2508 local cinematicTable = {
2509 barLength = barLength,
2510 hangTime = hangTime or 3,
2511 color = color or colorWhite,
2512 font = font,
2513 text = text,
2514 add = 0
2515 };
2516
2517 if (bThisOnly) then
2518 self.Cinematics[1] = cinematicTable;
2519 else
2520 self.Cinematics[#self.Cinematics + 1] = cinematicTable;
2521 end;
2522 end;
2523
2524 -- A function to add a notice.
2525 function openAura:AddNotify(text, class, length)
2526 if (class != NOTIFY_HINT or string.sub(text, 1, 6) != "#Hint_") then
2527 if (self.BaseClass.AddNotify) then
2528 self.BaseClass:AddNotify(text, class, length);
2529 end;
2530 end;
2531 end;
2532
2533 -- A function to get whether the local player is using the tool gun.
2534 function openAura:IsUsingTool()
2535 if (IsValid( self.Client:GetActiveWeapon() )
2536 and self.Client:GetActiveWeapon():GetClass() == "gmod_tool") then
2537 return true;
2538 else
2539 return false;
2540 end;
2541 end;
2542
2543 -- A function to get whether the local player is using the camera.
2544 function openAura:IsUsingCamera()
2545 if (IsValid( self.Client:GetActiveWeapon() )
2546 and self.Client:GetActiveWeapon():GetClass() == "gmod_camera") then
2547 return true;
2548 else
2549 return false;
2550 end;
2551 end;
2552
2553 -- A function to get the target ID data.
2554 function openAura:GetTargetIDData()
2555 return self.TargetIDData;
2556 end;
2557
2558 -- A function to calculate the screen fading.
2559 function openAura:CalculateScreenFading()
2560 if ( self.plugin:Call("ShouldPlayerScreenFadeBlack") ) then
2561 if (!self.BlackFadeIn) then
2562 if (self.BlackFadeOut) then
2563 self.BlackFadeIn = self.BlackFadeOut;
2564 else
2565 self.BlackFadeIn = 0;
2566 end;
2567 end;
2568
2569 self.BlackFadeIn = math.Clamp(self.BlackFadeIn + (FrameTime() * 20), 0, 255);
2570 self.BlackFadeOut = nil;
2571 self:DrawSimpleGradientBox( 0, 0, 0, ScrW(), ScrH(), Color(0, 0, 0, self.BlackFadeIn) );
2572 else
2573 if (self.BlackFadeIn) then
2574 self.BlackFadeOut = self.BlackFadeIn;
2575 end;
2576
2577 self.BlackFadeIn = nil;
2578
2579 if (self.BlackFadeOut) then
2580 self.BlackFadeOut = math.Clamp(self.BlackFadeOut - (FrameTime() * 40), 0, 255);
2581 self:DrawSimpleGradientBox( 0, 0, 0, ScrW(), ScrH(), Color(0, 0, 0, self.BlackFadeOut) );
2582
2583 if (self.BlackFadeOut == 0) then
2584 self.BlackFadeOut = nil;
2585 end;
2586 end;
2587 end;
2588 end;
2589
2590 -- A function to draw a cinematic.
2591 function openAura:DrawCinematic(cinematicTable, curTime)
2592 local maxBarLength = cinematicTable.barLength or (ScrH() / 13);
2593 local font = cinematicTable.font or self.option:GetFont("cinematic_text");
2594
2595 if (cinematicTable.goBack and curTime > cinematicTable.goBack) then
2596 cinematicTable.add = math.Clamp(cinematicTable.add - 2, 0, maxBarLength);
2597
2598 if (cinematicTable.add == 0) then
2599 table.remove(self.Cinematics, 1);
2600 cinematicTable = nil;
2601 end;
2602 else
2603 cinematicTable.add = math.Clamp(cinematicTable.add + 1, 0, maxBarLength);
2604
2605 if (cinematicTable.add == maxBarLength and !cinematicTable.goBack) then
2606 cinematicTable.goBack = curTime + cinematicTable.hangTime;
2607 end;
2608 end;
2609
2610 if (cinematicTable) then
2611 draw.RoundedBox( 0, 0, -maxBarLength + cinematicTable.add, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
2612 draw.RoundedBox( 0, 0, ScrH() - cinematicTable.add, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
2613
2614 draw.SimpleText(cinematicTable.text, font, ScrW() / 2, (ScrH() - cinematicTable.add) + (maxBarLength / 2), cinematicTable.color, 1, 1);
2615 end
2616 end;
2617
2618 -- A function to draw the cinematic introduction.
2619 function openAura:DrawCinematicIntro(curTime)
2620 local cinematicInfo = self.plugin:Call("GetCinematicIntroInfo");
2621 local colorWhite = self.option:GetColor("white");
2622
2623 if (cinematicInfo) then
2624 if (self.CinematicScreenAlpha and self.CinematicScreenTarget) then
2625 self.CinematicScreenAlpha = math.Approach(self.CinematicScreenAlpha, self.CinematicScreenTarget, 1);
2626
2627 if (self.CinematicScreenAlpha == self.CinematicScreenTarget) then
2628 if (self.CinematicScreenTarget == 255) then
2629 if (!self.CinematicScreenGoBack) then
2630 self.CinematicScreenGoBack = curTime + 2.5;
2631 self.option:PlaySound("rollover");
2632 end;
2633 else
2634 self.CinematicScreenDone = true;
2635 end;
2636 end;
2637
2638 if (self.CinematicScreenGoBack and curTime >= self.CinematicScreenGoBack) then
2639 self.CinematicScreenGoBack = nil;
2640 self.CinematicScreenTarget = 0;
2641 self.option:PlaySound("rollover");
2642 end;
2643
2644 if (!self.CinematicScreenDone and cinematicInfo.credits) then
2645 local alpha = math.Clamp(self.CinematicScreenAlpha, 0, 255);
2646
2647 self:OverrideMainFont( self.option:GetFont("intro_text_tiny") );
2648 if (self.CinematicScreenTarget == 255) then
2649 self:DrawSimpleText( cinematicInfo.credits, ScrW() / 8, ScrH() * 0.75, Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha) );
2650 else
2651 self:DrawSimpleText( cinematicInfo.credits, ScrW() / 8, ScrH() * 0.75, Color(colorWhite.r, colorWhite.g, colorWhite.b, alpha) );
2652 end;
2653 self:OverrideMainFont(false);
2654 end;
2655 else
2656 self.CinematicScreenAlpha = 0;
2657 self.CinematicScreenTarget = 255;
2658 self.option:PlaySound("rollover");
2659 end;
2660 end;
2661 end;
2662
2663 -- A function to draw the cinematic introduction bars.
2664 function openAura:DrawCinematicIntroBars()
2665 local maxBarLength = ScrH() / 13;
2666
2667 if (!self.CinematicBarsTarget and !self.CinematicBarsAlpha) then
2668 self.CinematicBarsAlpha = 0;
2669 self.CinematicBarsTarget = 255;
2670 self.option:PlaySound("rollover");
2671 end;
2672
2673 self.CinematicBarsAlpha = math.Approach(self.CinematicBarsAlpha, self.CinematicBarsTarget, 1);
2674
2675 if (self.CinematicScreenDone) then
2676 if (self.CinematicScreenBarLength != 0) then
2677 self.CinematicScreenBarLength = math.Clamp( (maxBarLength / 255) * self.CinematicBarsAlpha, 0, maxBarLength );
2678 end;
2679
2680 if (self.CinematicBarsTarget != 0) then
2681 self.CinematicBarsTarget = 0;
2682 self.option:PlaySound("rollover");
2683 end;
2684
2685 if (self.CinematicBarsAlpha == 0) then
2686 self.CinematicBarsDrawn = true;
2687 end;
2688 elseif (self.CinematicScreenBarLength != maxBarLength) then
2689 if (!self.IntroBarsMultiplier) then
2690 self.IntroBarsMultiplier = 1;
2691 else
2692 self.IntroBarsMultiplier = math.Clamp(self.IntroBarsMultiplier + (FrameTime() * 8), 1, 12);
2693 end;
2694
2695 self.CinematicScreenBarLength = math.Clamp( (maxBarLength / 255) * math.Clamp(self.CinematicBarsAlpha * self.IntroBarsMultiplier, 0, 255), 0, maxBarLength );
2696 end;
2697
2698 draw.RoundedBox( 0, 0, 0, ScrW(), self.CinematicScreenBarLength, Color(0, 0, 0, 255) );
2699 draw.RoundedBox( 0, 0, ScrH() - self.CinematicScreenBarLength, ScrW(), maxBarLength, Color(0, 0, 0, 255) );
2700 end;
2701
2702 -- A function to draw the cinematic info.
2703 function openAura:DrawCinematicInfo()
2704 if (!self.CinematicInfoAlpha and !self.CinematicInfoSlide) then
2705 self.CinematicInfoAlpha = 255;
2706 self.CinematicInfoSlide = 0;
2707 end;
2708
2709 self.CinematicInfoSlide = math.Approach(self.CinematicInfoSlide, 255, 1);
2710
2711 if (self.CinematicScreenAlpha and self.CinematicScreenTarget) then
2712 self.CinematicInfoAlpha = math.Approach(self.CinematicInfoAlpha, 0, 1);
2713
2714 if (self.CinematicInfoAlpha == 0) then
2715 self.CinematicInfoDrawn = true;
2716 end;
2717 end;
2718
2719 local cinematicInfo = self.plugin:Call("GetCinematicIntroInfo");
2720 local colorWhite = self.option:GetColor("white");
2721 local colorInfo = self.option:GetColor("information");
2722
2723 if (cinematicInfo) then
2724 local textPos = ScrW() / 2;
2725
2726 if (cinematicInfo.title) then
2727 local cinematicInfoTitle = string.upper(cinematicInfo.title);
2728 local introTextBigFont = self.option:GetFont("intro_text_big");
2729 local textWidth, textHeight = self:GetCachedTextSize(introTextBigFont, cinematicInfoTitle);
2730
2731 self:OverrideMainFont(introTextBigFont);
2732 self:DrawSimpleText(cinematicInfoTitle, textPos, ScrH() * 0.6, Color(colorInfo.r, colorInfo.g, colorInfo.b, self.CinematicInfoAlpha), 1);
2733 self:OverrideMainFont(nil);
2734
2735 if (cinematicInfo.text) then
2736 self:OverrideMainFont(introTextBigSmall);
2737 self:DrawSimpleText( string.upper(cinematicInfo.text), textPos - (textWidth / 2), (ScrH() * 0.6) + (textHeight / 2) + 32, Color(colorWhite.r, colorWhite.g, colorWhite.b, self.CinematicInfoAlpha) );
2738 self:OverrideMainFont(nil);
2739 end;
2740 elseif (cinematicInfo.text) then
2741 self:OverrideMainFont( self.option:GetFont("introTextBigSmall") );
2742 self:DrawSimpleText(string.upper(cinematicInfo.text), textPos, ScrH() * 0.6, Color(colorWhite.r, colorWhite.g, colorWhite.b, self.CinematicInfoAlpha), 1);
2743 self:OverrideMainFont(nil);
2744 end;
2745 end;
2746 end;
2747
2748 -- A function to draw some door text.
2749 function openAura:DrawDoorText(entity, eyePos, eyeAngles, font, nameColor, textColor)
2750 local r, g, b, a = entity:GetColor();
2751
2752 if ( a > 0 and !entity:IsEffectActive(EF_NODRAW) ) then
2753 local doorData = self.entity:CalculateDoorTextPosition(entity);
2754
2755 if (!doorData.hitWorld) then
2756 local frontY = -26;
2757 local backY = -26;
2758 local alpha = self:CalculateAlphaFromDistance( 256, eyePos, entity:GetPos() );
2759
2760 if (alpha > 0) then
2761 local owner = self.entity:GetOwner(entity);
2762 local name = self.plugin:Call("GetDoorInfo", entity, DOOR_INFO_NAME);
2763 local text = self.plugin:Call("GetDoorInfo", entity, DOOR_INFO_TEXT);
2764
2765 if (name or text) then
2766 local nameWidth = self:GetCachedTextSize(font, name or "");
2767 local textWidth = self:GetCachedTextSize(font, text or "");
2768 local longWidth = nameWidth;
2769
2770 if (textWidth > longWidth) then
2771 longWidth = textWidth;
2772 end;
2773
2774 local scale = math.abs( (doorData.width * 0.75) / longWidth );
2775 local nameScale = math.min(scale, 0.05);
2776 local textScale = math.min(scale, 0.03);
2777
2778 if (name) then
2779 if (!text or text == "") then
2780 nameColor = textColor or nameColor;
2781 end;
2782
2783 cam.Start3D2D(doorData.position, doorData.angles, nameScale);
2784 self:OverrideMainFont(font);
2785 frontY = self:DrawInfo(name, 0, frontY, nameColor, alpha, nil, nil, 3);
2786 self:OverrideMainFont(false);
2787 cam.End3D2D();
2788
2789 cam.Start3D2D(doorData.positionBack, doorData.anglesBack, nameScale);
2790 self:OverrideMainFont(font);
2791 backY = self:DrawInfo(name, 0, backY, nameColor, alpha, nil, nil, 3);
2792 self:OverrideMainFont(false);
2793 cam.End3D2D();
2794 end;
2795
2796 if (text) then
2797 cam.Start3D2D(doorData.position, doorData.angles, textScale);
2798 self:OverrideMainFont(font);
2799 frontY = self:DrawInfo(text, 0, frontY, textColor, alpha, nil, nil, 3);
2800 self:OverrideMainFont(false);
2801 cam.End3D2D();
2802
2803 cam.Start3D2D(doorData.positionBack, doorData.anglesBack, textScale);
2804 self:OverrideMainFont(font);
2805 backY = self:DrawInfo(text, 0, backY, textColor, alpha, nil, nil, 3);
2806 self:OverrideMainFont(false);
2807 cam.End3D2D();
2808 end;
2809 end;
2810 end;
2811 end;
2812 end;
2813 end;
2814
2815 -- A function to get whether the local player's character screen is open.
2816 function openAura:IsCharacterScreenOpen(isVisible)
2817 if ( self.character:IsPanelOpen() ) then
2818 local panel = self.character:GetPanel();
2819
2820 if (isVisible) then
2821 if (panel) then
2822 return panel:IsVisible();
2823 end;
2824 else
2825 return panel != nil;
2826 end;
2827 end;
2828 end;
2829
2830 -- A function to save schema data.
2831 function openAura:SaveSchemaData(fileName, data)
2832 _file.Write( "openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt", glon.encode(data) );
2833 end;
2834
2835 -- A function to delete schema data.
2836 function openAura:DeleteSchemaData(fileName)
2837 _file.Delete("openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
2838 end;
2839
2840 -- A function to check if schema data exists.
2841 function openAura:SchemaDataExists(fileName)
2842 return _file.Exists("openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
2843 end;
2844
2845 -- A function to restore schema data.
2846 function openAura:RestoreSchemaData(fileName, default)
2847 if ( self:SchemaDataExists(fileName) ) then
2848 local data = _file.Read("openaura/schemas/"..self:GetSchemaFolder().."/"..fileName..".txt");
2849
2850 if (data) then
2851 local success, value = pcall(glon.decode, data);
2852
2853 if (success and value != nil) then
2854 return value;
2855 else
2856 local success, value = pcall(Json.Decode, data);
2857
2858 if (success and value != nil) then
2859 return value;
2860 end;
2861 end;
2862 end;
2863 end;
2864
2865 if (default != nil) then
2866 return default;
2867 else
2868 return {};
2869 end;
2870 end;
2871
2872 -- A function to restore OpenAura data.
2873 function openAura:RestoreOpenAuraData(fileName, default)
2874 if ( self:OpenAuraDataExists(fileName) ) then
2875 local data = _file.Read("openaura/"..fileName..".txt");
2876
2877 if (data) then
2878 local success, value = pcall(glon.decode, data);
2879
2880 if (success and value != nil) then
2881 return value;
2882 end;
2883 end;
2884 end;
2885
2886 if (default != nil) then
2887 return default;
2888 else
2889 return {};
2890 end;
2891 end;
2892
2893 -- A function to save OpenAura data.
2894 function openAura:SaveOpenAuraData(fileName, data)
2895 _file.Write( "openaura/"..fileName..".txt", glon.encode(data) );
2896 end;
2897
2898 -- A function to check if OpenAura data exists.
2899 function openAura:OpenAuraDataExists(fileName)
2900 return _file.Exists("openaura/"..fileName..".txt");
2901 end;
2902
2903 -- A function to delete OpenAura data.
2904 function openAura:DeleteOpenAuraData(fileName)
2905 _file.Delete("openaura/"..fileName..".txt");
2906 end;
2907
2908 -- A function to run a OpenAura command.
2909 function openAura:RunCommand(command, ...)
2910 RunConsoleCommand("aura", command, ...);
2911 end;
2912
2913 -- A function to get whether the local player is choosing a character.
2914 function openAura:IsChoosingCharacter()
2915 if ( self.character:GetPanel() ) then
2916 return self.character:IsPanelOpen();
2917 else
2918 return true;
2919 end;
2920 end;
2921
2922 -- A function to include the schema.
2923 function openAura:IncludeSchema()
2924 local schemaFolder = self:GetSchemaFolder();
2925
2926 if (schemaFolder and type(schemaFolder) == "string") then
2927 self.plugin:Include(schemaFolder.."/gamemode/schema", true);
2928 end;
2929 end;
2930
2931 -- A function to start a data stream.
2932 function openAura:StartDataStream(name, data)
2933 local encodedData = glon.encode(data);
2934 local splitTable = self:SplitString(string.gsub(string.gsub(encodedData, "\\", "\\\\"), "\n", "\\n"), 128);
2935
2936 if (#splitTable > 0) then
2937 RunConsoleCommand( "aura_dsStart", name, tostring(#splitTable) );
2938
2939 for k, v in ipairs(splitTable) do
2940 RunConsoleCommand( "aura_dsData", v, tostring(k) );
2941 end;
2942 end;
2943 end;
2944end;
2945
2946-- A function to explode a string by tags.
2947function openAura:ExplodeByTags(text, seperator, open, close, hide)
2948 local results = {};
2949 local current = "";
2950 local tag = nil;
2951
2952 for i = 1, string.len(text) do
2953 local character = string.sub(text, i, i);
2954
2955 if (!tag) then
2956 if (character == open) then
2957 if (!hide) then
2958 current = current..character;
2959 end;
2960
2961 tag = true;
2962 elseif (character == seperator) then
2963 results[#results + 1] = current; current = "";
2964 else
2965 current = current..character;
2966 end;
2967 else
2968 if (character == close) then
2969 if (!hide) then
2970 current = current..character;
2971 end;
2972
2973 tag = nil;
2974 else
2975 current = current..character;
2976 end;
2977 end;
2978 end;
2979
2980 if (current != "") then
2981 results[#results + 1] = current;
2982 end;
2983
2984 return results;
2985end;
2986
2987-- A function to modify a physical description.
2988function openAura:ModifyPhysDesc(description)
2989 if (string.len(description) <= 128) then
2990 if ( !string.find(string.sub(description, -2), "%p") ) then
2991 return description..".";
2992 else
2993 return description;
2994 end;
2995 else
2996 return string.sub(description, 1, 125).."...";
2997 end;
2998end;
2999
3000--[[
3001 Obsolete! Use string.Explode as it is faster and better.
3002--]]
3003function openAura:ExplodeString(seperator, text)
3004 return string.Explode(seperator, text);
3005end;
3006
3007local MAGIC_CHARACTERS = "([%(%)%.%%%+%-%*%?%[%^%$])";
3008
3009-- A function to replace something in text without pattern matching.
3010function openAura:Replace(text, find, replace)
3011 return ( text:gsub(find:gsub(MAGIC_CHARACTERS, "%%%1"), replace) );
3012end;
3013
3014-- A function to create a new meta table.
3015function openAura:NewMetaTable(base)
3016 local object = {};
3017
3018 setmetatable(object, base);
3019
3020 base.__index = base;
3021
3022 return object;
3023end;
3024
3025-- A function to set whether a string should be in camel case.
3026function openAura:SetCamelCase(text, camelCase)
3027 if (camelCase) then
3028 return string.gsub(text, "^.", string.lower);
3029 else
3030 return string.gsub(text, "^.", string.upper);
3031 end;
3032end;
3033
3034-- A function to include files in a directory.
3035function openAura:IncludeDirectory(directory)
3036 if (string.sub(directory, -1) != "/") then
3037 directory = directory.."/";
3038 end;
3039
3040 for k, v in pairs( _file.FindInLua(directory.."*.lua") ) do
3041 openAura:IncludePrefixed(directory..v);
3042 end;
3043end;
3044
3045-- A function to include a prefixed _file.
3046function openAura:IncludePrefixed(fileName)
3047 if (string.find(fileName, "sv_") and !SERVER) then
3048 return;
3049 end;
3050
3051 if (string.find(fileName, "sh_") and SERVER) then
3052 AddCSLuaFile(fileName);
3053 elseif (string.find(fileName, "cl_") and SERVER) then
3054 AddCSLuaFile(fileName);
3055
3056 return;
3057 end;
3058
3059 include(fileName);
3060end;
3061
3062-- A function to include plugins in a directory.
3063function openAura:IncludePlugins(directory)
3064 if (string.sub(directory, -1) != "/") then
3065 directory = directory.."/";
3066 end;
3067
3068 for k, v in pairs( _file.FindInLua(directory.."*") ) do
3069 if (v != ".." and v != ".") then
3070 if (CLIENT) then
3071 if ( _file.IsDir("../lua_temp/"..directory..v) ) then
3072 self.plugin:Include(directory..v);
3073 end;
3074 elseif ( _file.IsDir("../gamemodes/"..directory..v) ) then
3075 self.plugin:Include(directory..v);
3076 end;
3077 end;
3078 end;
3079
3080 return true;
3081end;
3082
3083-- A function to perform the timer think.
3084function openAura:CallTimerThink(curTime)
3085 for k, v in pairs(self.Timers) do
3086 if (!v.paused) then
3087 if (curTime >= v.nextCall) then
3088 local success, value = pcall( v.Callback, unpack(v.arguments) );
3089
3090 if (!success) then
3091 ErrorNoHalt("OpenAura -> the "..tostring(k).." timer has failed to run.");
3092 ErrorNoHalt(value);
3093 end;
3094
3095 v.nextCall = curTime + v.delay;
3096 v.calls = v.calls + 1;
3097
3098 if (v.calls == v.repetitions) then
3099 self.Timers[k] = nil;
3100 end;
3101 end;
3102 end;
3103 end;
3104end;
3105
3106-- A function to get whether a timer exists.
3107function openAura:TimerExists(name)
3108 return self.Timers[name];
3109end;
3110
3111-- A function to start a timer.
3112function openAura:StartTimer(name)
3113 if (self.Timers[name] and self.Timers[name].paused) then
3114 self.Timers[name].nextCall = CurTime() + self.Timers[name].timeLeft;
3115 self.Timers[name].paused = nil;
3116 end;
3117end;
3118
3119-- A function to pause a timer.
3120function openAura:PauseTimer(name)
3121 if (self.Timers[name] and !self.Timers[name].paused) then
3122 self.Timers[name].timeLeft = self.Timers[name].nextCall - CurTime();
3123 self.Timers[name].paused = true;
3124 end;
3125end;
3126
3127
3128-- A function to destroy a timer.
3129function openAura:DestroyTimer(name)
3130 self.Timers[name] = nil;
3131end;
3132
3133-- A function to create a timer.
3134function openAura:CreateTimer(name, delay, repetitions, Callback, ...)
3135 self.Timers[name] = {
3136 calls = 0,
3137 delay = delay,
3138 nextCall = CurTime() + delay,
3139 Callback = Callback,
3140 arguments = {...},
3141 repetitions = repetitions
3142 };
3143end;
3144
3145-- A function to get whether a player has access to an object.
3146function openAura:HasObjectAccess(player, object)
3147 local hasAccess = false;
3148 local faction = nil;
3149
3150 if (SERVER) then
3151 faction = player:QueryCharacter("faction");
3152 else
3153 faction = self.player:GetFaction(player);
3154 end;
3155
3156 if (object.access) then
3157 if ( self.player:HasAnyFlags(player, object.access) ) then
3158 hasAccess = true;
3159 end;
3160 end;
3161
3162 if (object.factions) then
3163 if ( table.HasValue(object.factions, faction) ) then
3164 hasAccess = true;
3165 end;
3166 end;
3167
3168 if (object.classes) then
3169 local team = player:Team();
3170 local class = self.class:Get(team);
3171
3172 if (class) then
3173 if ( table.HasValue(object.classes, team) or table.HasValue(object.classes, class.name) ) then
3174 hasAccess = true;
3175 end;
3176 end;
3177 end;
3178
3179 if (!object.access and !object.factions and !object.classes) then
3180 hasAccess = true;
3181 end;
3182
3183 if (object.blacklist) then
3184 local team = player:Team();
3185 local class = self.class:Get(team);
3186
3187 if ( table.HasValue(object.blacklist, faction) ) then
3188 hasAccess = false;
3189 elseif (class) then
3190 if ( table.HasValue(object.blacklist, team) or table.HasValue(object.blacklist, class.name) ) then
3191 hasAccess = false;
3192 end;
3193 else
3194 for k, v in ipairs(object.blacklist) do
3195 if (type(v) == "string") then
3196 if ( self.player:HasAnyFlags(player, v) ) then
3197 hasAccess = false;
3198
3199 break;
3200 end;
3201 end;
3202 end;
3203 end;
3204 end;
3205
3206 if (object.HasObjectAccess) then
3207 return object:HasObjectAccess(player, hasAccess);
3208 end;
3209
3210 return hasAccess;
3211end;
3212
3213-- A function to derive from Sandbox.
3214function openAura:DeriveFromSandbox()
3215 DeriveGamemode("Sandbox");
3216
3217 if (!self.IsSandboxDerived) then
3218 GM = {Folder = "gamemodes/sandbox"};
3219
3220 if (CLIENT) then
3221 include("sandbox/gamemode/cl_init.lua");
3222 else
3223 include("sandbox/gamemode/init.lua");
3224 end;
3225
3226 local sandboxGamemode = GM;
3227 local baseGamemode = gamemode.Get("base");
3228
3229 if (sandboxGamemode and baseGamemode) then
3230 table.Inherit(sandboxGamemode, baseGamemode);
3231 table.Inherit(openAura, sandboxGamemode);
3232
3233 timer.Simple(FrameTime(), function()
3234 self.BaseClass = sandboxGamemode;
3235 end);
3236
3237 GM = openAura;
3238 end;
3239 end;
3240end;
3241
3242-- A function to get the sorted commands.
3243function openAura:GetSortedCommands()
3244 local commands = {};
3245 local source = self.command.stored;
3246
3247 for k, v in pairs(source) do
3248 commands[#commands + 1] = k;
3249 end;
3250
3251 table.sort(commands, function(a, b)
3252 return a < b;
3253 end);
3254
3255 return commands;
3256end;
3257
3258-- A function to zero a number to an amount of digits.
3259function openAura:ZeroNumberToDigits(number, digits)
3260 return string.rep( "0", math.Clamp(digits - string.len( tostring(number) ), 0, digits) )..number;
3261end;
3262
3263-- A function to get a short CRC from a value.
3264function openAura:GetShortCRC(value)
3265 return math.ceil(util.CRC(value) / 100000);
3266end;
3267
3268-- A function to validate a table's keys.
3269function openAura:ValidateTableKeys(base)
3270 for i = 1, #base do
3271 if ( !base[i] ) then
3272 table.remove(base, i);
3273 end;
3274 end;
3275end;
3276
3277-- A function to get the map's physics entities.
3278function openAura:GetPhysicsEntities()
3279 local entities = {};
3280
3281 for k, v in ipairs( ents.FindByClass("prop_physics_multiplayer") ) do
3282 if ( IsValid(v) ) then
3283 entities[#entities + 1] = v;
3284 end;
3285 end;
3286
3287 for k, v in ipairs( ents.FindByClass("prop_physics") ) do
3288 if ( IsValid(v) ) then
3289 entities[#entities + 1] = v;
3290 end;
3291 end;
3292
3293 return entities;
3294end;
3295
3296-- A function to create a multicall table (by Deco Da Man).
3297function openAura:CreateMulticallTable(base, object)
3298 local metaTable = getmetatable(base) or {};
3299
3300 -- Called when an index is needed.
3301 function metaTable.__index(base, key)
3302 return function(base, ...)
3303 for k, v in pairs(base) do
3304 object[key](v, ...);
3305 end;
3306 end
3307 end
3308
3309 setmetatable(base, metaTable);
3310
3311 return base;
3312end;
3313
3314-- A function to check if the shared variables have initialized.
3315function openAura:SharedVarsHaveInitialized()
3316 local worldEntity = GetWorldEntity();
3317
3318 if ( worldEntity and worldEntity.IsWorld and worldEntity:IsWorld() ) then
3319 return true;
3320 end;
3321end;
3322
3323-- A function to convert a user message class.
3324function openAura:ConvertUserMessageClass(class)
3325 local convertTable = {
3326 [NWTYPE_STRING] = "String",
3327 [NWTYPE_ENTITY] = "Entity",
3328 [NWTYPE_VECTOR] = "Vector",
3329 [NWTYPE_NUMBER] = "Long",
3330 [NWTYPE_ANGLE] = "Angle",
3331 [NWTYPE_FLOAT] = "Float",
3332 [NWTYPE_BOOL] = "Bool"
3333 };
3334
3335 return convertTable[class];
3336end;
3337
3338local NETWORKED_VALUE_TABLE = {
3339 [NWTYPE_STRING] = "",
3340 [NWTYPE_ENTITY] = NULL,
3341 [NWTYPE_VECTOR] = Vector(0, 0, 0),
3342 [NWTYPE_NUMBER] = 0,
3343 [NWTYPE_ANGLE] = Angle(0, 0, 0),
3344 [NWTYPE_FLOAT] = 0.0,
3345 [NWTYPE_BOOL] = false
3346};
3347
3348-- A function to get a default networked value.
3349function openAura:GetDefaultNetworkedValue(class)
3350 return NETWORKED_VALUE_TABLE[class];
3351end;
3352
3353local NETWORKED_CLASS_TABLE = {
3354 [NWTYPE_STRING] = "String",
3355 [NWTYPE_ENTITY] = "Entity",
3356 [NWTYPE_VECTOR] = "Vector",
3357 [NWTYPE_NUMBER] = "Int",
3358 [NWTYPE_ANGLE] = "Angle",
3359 [NWTYPE_FLOAT] = "Float",
3360 [NWTYPE_BOOL] = "Bool"
3361};
3362
3363-- A function to convert a networked class.
3364function openAura:ConvertNetworkedClass(class)
3365 return NETWORKED_CLASS_TABLE[class];
3366end;
3367
3368-- A function to get the default class value.
3369function openAura:GetDefaultClassValue(class)
3370 local convertTable = {
3371 ["String"] = "",
3372 ["Entity"] = NULL,
3373 ["Vector"] = Vector(0, 0, 0),
3374 ["Int"] = 0,
3375 ["Angle"] = Angle(0, 0, 0),
3376 ["Float"] = 0.0,
3377 ["Bool"] = false
3378 };
3379
3380 return convertTable[class];
3381end;
3382
3383-- A function to set a shared variable.
3384function openAura:SetSharedVar(key, value)
3385 local entity = GetWorldEntity();
3386
3387 if ( entity.sharedVars and entity.sharedVars[key] ) then
3388 local class = self:ConvertNetworkedClass( entity.sharedVars[key] );
3389
3390 if (class) then
3391 if (value == nil) then
3392 value = openAura:GetDefaultClassValue(class);
3393 end;
3394
3395 entity["SetNetworked"..class](entity, key, value);
3396 end;
3397 end;
3398
3399 entity:SetNetworkedVar(key, value);
3400end;
3401
3402-- A function to get a shared variable.
3403function openAura:GetSharedVar(key)
3404 local entity = GetWorldEntity();
3405
3406 if ( entity.sharedVars and entity.sharedVars[key] ) then
3407 local class = self:ConvertNetworkedClass( entity.sharedVars[key] );
3408
3409 if (class) then
3410 return entity["GetNetworked"..class](entity, key);
3411 end;
3412 end;
3413
3414 return entity:GetNetworkedVar(key);
3415end;
3416
3417-- A function to register a global shared variable.
3418function openAura:RegisterGlobalSharedVar(name, class)
3419 self.GlobalSharedVars[#self.GlobalSharedVars + 1] = {name, class};
3420end;
3421
3422-- A function to create fake damage info.
3423function openAura:FakeDamageInfo(damage, inflictor, attacker, position, damageType, damageForce)
3424 local damageInfo = DamageInfo();
3425 local realDamage = math.ceil( math.max(damage, 0) );
3426
3427 damageInfo:SetDamagePosition(position);
3428 damageInfo:SetDamageForce(Vector() * damageForce);
3429 damageInfo:SetDamageType(damageType);
3430 damageInfo:SetInflictor(inflictor);
3431 damageInfo:SetAttacker(attacker);
3432 damageInfo:SetDamage(realDamage);
3433
3434 return damageInfo;
3435end;
3436
3437-- A function to unpack a color.
3438function openAura:UnpackColor(color)
3439 return color.r, color.g, color.b, color.a;
3440end;
3441
3442-- A function to parse data in text.
3443function openAura:ParseData(text)
3444 local classes = {"%^", "%!"};
3445
3446 for k, v in ipairs(classes) do
3447 for key in string.gmatch(text, v.."(.-)"..v) do
3448 local lower = false;
3449 local amount;
3450
3451 if (string.sub(key, 1, 1) == "(" and string.sub(key, -1) == ")") then
3452 lower = true;
3453 amount = tonumber( string.sub(key, 2, -2) );
3454 else
3455 amount = tonumber(key);
3456 end;
3457
3458 if (amount) then
3459 text = string.gsub( text, v..string.gsub(key, "([%(%)])", "%%%1")..v, tostring( FORMAT_CASH(amount, k == 2, lower) ) );
3460 end;
3461 end;
3462 end;
3463
3464 for k in string.gmatch(text, "%*(.-)%*") do
3465 k = string.gsub(k, "[%(%)]", "");
3466
3467 if (k != "") then
3468 text = string.gsub( text, "%*%("..k.."%)%*", tostring( self.option:GetKey(k, true) ) );
3469 text = string.gsub( text, "%*"..k.."%*", tostring( self.option:GetKey(k) ) );
3470 end;
3471 end;
3472
3473 if (CLIENT) then
3474 for k in string.gmatch(text, ":(.-):") do
3475 if ( k != "" and input.LookupBinding(k) ) then
3476 text = openAura:Replace(text, ":"..k..":", "<"..string.upper( tostring( input.LookupBinding(k) ) )..">");
3477 end;
3478 end;
3479 end;
3480
3481 return self.config:Parse(text);
3482end;