add sborka
This commit is contained in:
993
garrysmod/gamemodes/helix/gamemode/core/hooks/cl_hooks.lua
Normal file
993
garrysmod/gamemodes/helix/gamemode/core/hooks/cl_hooks.lua
Normal file
@@ -0,0 +1,993 @@
|
||||
function GM:ForceDermaSkin()
|
||||
return "helix"
|
||||
end
|
||||
|
||||
function GM:ScoreboardShow()
|
||||
if (LocalPlayer():GetCharacter()) then
|
||||
vgui.Create("ixMenu")
|
||||
end
|
||||
end
|
||||
|
||||
function GM:ScoreboardHide()
|
||||
end
|
||||
|
||||
function GM:LoadFonts(font, genericFont)
|
||||
surface.CreateFont("ix3D2DFont", {
|
||||
font = font,
|
||||
size = 128,
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ix3D2DMediumFont", {
|
||||
font = font,
|
||||
size = 48,
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ix3D2DSmallFont", {
|
||||
font = font,
|
||||
size = 24,
|
||||
extended = true,
|
||||
weight = 400
|
||||
})
|
||||
|
||||
surface.CreateFont("ixTitleFont", {
|
||||
font = font,
|
||||
size = ScreenScale(30),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixSubTitleFont", {
|
||||
font = font,
|
||||
size = ScreenScale(16),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuMiniFont", {
|
||||
font = "Roboto",
|
||||
size = math.max(ScreenScale(4), 18),
|
||||
weight = 300,
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuButtonFont", {
|
||||
font = "Roboto Th",
|
||||
size = ScreenScale(14),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuButtonFontSmall", {
|
||||
font = "Roboto Th",
|
||||
size = ScreenScale(10),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuButtonFontThick", {
|
||||
font = "Roboto",
|
||||
size = ScreenScale(14),
|
||||
extended = true,
|
||||
weight = 300
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuButtonLabelFont", {
|
||||
font = "Roboto Th",
|
||||
size = 28,
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMenuButtonHugeFont", {
|
||||
font = "Roboto Th",
|
||||
size = ScreenScale(24),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixToolTipText", {
|
||||
font = font,
|
||||
size = 20,
|
||||
extended = true,
|
||||
weight = 500
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMonoSmallFont", {
|
||||
font = "Consolas",
|
||||
size = 12,
|
||||
extended = true,
|
||||
weight = 800
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMonoMediumFont", {
|
||||
font = "Consolas",
|
||||
size = 22,
|
||||
extended = true,
|
||||
weight = 800
|
||||
})
|
||||
|
||||
-- The more readable font.
|
||||
font = genericFont
|
||||
|
||||
surface.CreateFont("ixBigFont", {
|
||||
font = font,
|
||||
size = 36,
|
||||
extended = true,
|
||||
weight = 1000
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMediumFont", {
|
||||
font = font,
|
||||
size = 25,
|
||||
extended = true,
|
||||
weight = 1000
|
||||
})
|
||||
|
||||
surface.CreateFont("ixNoticeFont", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(8), 18),
|
||||
weight = 100,
|
||||
extended = true,
|
||||
antialias = true
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMediumLightFont", {
|
||||
font = font,
|
||||
size = 25,
|
||||
extended = true,
|
||||
weight = 200
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMediumLightBlurFont", {
|
||||
font = font,
|
||||
size = 25,
|
||||
extended = true,
|
||||
weight = 200,
|
||||
blursize = 4
|
||||
})
|
||||
|
||||
surface.CreateFont("ixGenericFont", {
|
||||
font = font,
|
||||
size = 20,
|
||||
extended = true,
|
||||
weight = 1000
|
||||
})
|
||||
|
||||
surface.CreateFont("ixChatFont", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(7), 17) * ix.option.Get("chatFontScale", 1),
|
||||
extended = true,
|
||||
weight = 600,
|
||||
antialias = true
|
||||
})
|
||||
|
||||
surface.CreateFont("ixChatFontItalics", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(7), 17) * ix.option.Get("chatFontScale", 1),
|
||||
extended = true,
|
||||
weight = 600,
|
||||
antialias = true,
|
||||
italic = true
|
||||
})
|
||||
|
||||
surface.CreateFont("ixSmallTitleFont", {
|
||||
font = "Roboto Th",
|
||||
size = math.max(ScreenScale(12), 24),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixMinimalTitleFont", {
|
||||
font = "Roboto",
|
||||
size = math.max(ScreenScale(8), 22),
|
||||
extended = true,
|
||||
weight = 800
|
||||
})
|
||||
|
||||
surface.CreateFont("ixSmallFont", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(6), 17),
|
||||
extended = true,
|
||||
weight = 500
|
||||
})
|
||||
|
||||
surface.CreateFont("ixItemDescFont", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(6), 17),
|
||||
extended = true,
|
||||
shadow = true,
|
||||
weight = 500
|
||||
})
|
||||
|
||||
surface.CreateFont("ixSmallBoldFont", {
|
||||
font = font,
|
||||
size = math.max(ScreenScale(8), 20),
|
||||
extended = true,
|
||||
weight = 800
|
||||
})
|
||||
|
||||
surface.CreateFont("ixItemBoldFont", {
|
||||
font = font,
|
||||
shadow = true,
|
||||
size = math.max(ScreenScale(8), 20),
|
||||
extended = true,
|
||||
weight = 800
|
||||
})
|
||||
|
||||
-- Introduction fancy font.
|
||||
font = "Roboto Th"
|
||||
|
||||
surface.CreateFont("ixIntroTitleFont", {
|
||||
font = font,
|
||||
size = math.min(ScreenScale(128), 128),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIntroTitleBlurFont", {
|
||||
font = font,
|
||||
size = math.min(ScreenScale(128), 128),
|
||||
extended = true,
|
||||
weight = 100,
|
||||
blursize = 4
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIntroSubtitleFont", {
|
||||
font = font,
|
||||
size = ScreenScale(24),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIntroSmallFont", {
|
||||
font = font,
|
||||
size = ScreenScale(14),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIconsSmall", {
|
||||
font = "fontello",
|
||||
size = 22,
|
||||
extended = true,
|
||||
weight = 500
|
||||
})
|
||||
|
||||
surface.CreateFont("ixSmallTitleIcons", {
|
||||
font = "fontello",
|
||||
size = math.max(ScreenScale(11), 23),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIconsMedium", {
|
||||
font = "fontello",
|
||||
extended = true,
|
||||
size = 28,
|
||||
weight = 500
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIconsMenuButton", {
|
||||
font = "fontello",
|
||||
size = ScreenScale(14),
|
||||
extended = true,
|
||||
weight = 100
|
||||
})
|
||||
|
||||
surface.CreateFont("ixIconsBig", {
|
||||
font = "fontello",
|
||||
extended = true,
|
||||
size = 48,
|
||||
weight = 500
|
||||
})
|
||||
end
|
||||
|
||||
function GM:OnCharacterMenuCreated(panel)
|
||||
if (IsValid(ix.gui.notices)) then
|
||||
ix.gui.notices:Clear()
|
||||
end
|
||||
end
|
||||
|
||||
local LOWERED_ANGLES = Angle(30, 0, -25)
|
||||
|
||||
function GM:CalcViewModelView(weapon, viewModel, oldEyePos, oldEyeAngles, eyePos, eyeAngles)
|
||||
if (!IsValid(weapon)) then
|
||||
return
|
||||
end
|
||||
|
||||
local client = LocalPlayer()
|
||||
local bWepRaised = client:IsWepRaised()
|
||||
|
||||
-- update tween if the raised state is out of date
|
||||
if (client.ixWasWeaponRaised != bWepRaised) then
|
||||
local fraction = bWepRaised and 0 or 1
|
||||
|
||||
client.ixRaisedFraction = 1 - fraction
|
||||
client.ixRaisedTween = ix.tween.new(0.75, client, {
|
||||
ixRaisedFraction = fraction
|
||||
}, "outQuint")
|
||||
|
||||
client.ixWasWeaponRaised = bWepRaised
|
||||
end
|
||||
|
||||
local fraction = client.ixRaisedFraction
|
||||
local rotation = weapon.LowerAngles or LOWERED_ANGLES
|
||||
|
||||
if (ix.option.Get("altLower", true) and weapon.LowerAngles2) then
|
||||
rotation = weapon.LowerAngles2
|
||||
end
|
||||
|
||||
eyeAngles:RotateAroundAxis(eyeAngles:Up(), rotation.p * fraction)
|
||||
eyeAngles:RotateAroundAxis(eyeAngles:Forward(), rotation.y * fraction)
|
||||
eyeAngles:RotateAroundAxis(eyeAngles:Right(), rotation.r * fraction)
|
||||
|
||||
viewModel:SetAngles(eyeAngles)
|
||||
return self.BaseClass:CalcViewModelView(weapon, viewModel, oldEyePos, oldEyeAngles, eyePos, eyeAngles)
|
||||
end
|
||||
|
||||
function GM:LoadIntro()
|
||||
if (!IsValid(ix.gui.intro)) then
|
||||
vgui.Create("ixIntro")
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CharacterLoaded()
|
||||
local menu = ix.gui.characterMenu
|
||||
|
||||
if (IsValid(menu)) then
|
||||
menu:Close((LocalPlayer().GetCharacter and LocalPlayer():GetCharacter()) and true or nil)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:InitializedConfig()
|
||||
local color = ix.config.Get("color")
|
||||
|
||||
hook.Run("LoadFonts", ix.config.Get("font"), ix.config.Get("genericFont"))
|
||||
hook.Run("ColorSchemeChanged", color)
|
||||
|
||||
if (!ix.config.loaded and !IsValid(ix.gui.loading)) then
|
||||
local loader = vgui.Create("EditablePanel")
|
||||
loader:ParentToHUD()
|
||||
loader:Dock(FILL)
|
||||
loader.Paint = function(this, w, h)
|
||||
surface.SetDrawColor(0, 0, 0)
|
||||
surface.DrawRect(0, 0, w, h)
|
||||
end
|
||||
|
||||
local statusLabel = loader:Add("DLabel")
|
||||
statusLabel:Dock(FILL)
|
||||
statusLabel:SetText(L"loading")
|
||||
statusLabel:SetFont("ixTitleFont")
|
||||
statusLabel:SetContentAlignment(5)
|
||||
statusLabel:SetTextColor(color_white)
|
||||
|
||||
timer.Simple(5, function()
|
||||
if (IsValid(ix.gui.loading)) then
|
||||
local fault = GetNetVar("dbError")
|
||||
|
||||
if (fault) then
|
||||
statusLabel:SetText(fault and L"dbError" or L"loading")
|
||||
|
||||
local label = loader:Add("DLabel")
|
||||
label:DockMargin(0, 64, 0, 0)
|
||||
label:Dock(TOP)
|
||||
label:SetFont("ixSubTitleFont")
|
||||
label:SetText(fault)
|
||||
label:SetContentAlignment(5)
|
||||
label:SizeToContentsY()
|
||||
label:SetTextColor(Color(255, 50, 50))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
ix.gui.loading = loader
|
||||
ix.config.loaded = true
|
||||
|
||||
if (ix.config.Get("intro", true) and ix.option.Get("showIntro", true)) then
|
||||
hook.Run("LoadIntro")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:InitPostEntity()
|
||||
ix.joinTime = RealTime() - 0.9716
|
||||
ix.option.Sync()
|
||||
|
||||
ix.gui.bars = vgui.Create("ixInfoBarManager")
|
||||
end
|
||||
|
||||
function GM:NetworkEntityCreated(entity)
|
||||
if (entity:IsPlayer()) then
|
||||
entity:SetIK(false)
|
||||
|
||||
-- we've just discovered a new player, so we need to update their animation state
|
||||
if (entity != LocalPlayer()) then
|
||||
-- we don't need to call the PlayerWeaponChanged hook here since it'll be handled below,
|
||||
-- when this player's weapon has been discovered
|
||||
hook.Run("PlayerModelChanged", entity, entity:GetModel())
|
||||
end
|
||||
elseif (entity:IsWeapon()) then
|
||||
local owner = entity:GetOwner()
|
||||
|
||||
if (IsValid(owner) and owner:IsPlayer() and entity == owner:GetActiveWeapon()) then
|
||||
hook.Run("PlayerWeaponChanged", owner, entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vignette = ix.util.GetMaterial("helix/gui/vignette.png")
|
||||
local vignetteAlphaGoal = 0
|
||||
local vignetteAlphaDelta = 0
|
||||
local vignetteTraceHeight = Vector(0, 0, 768)
|
||||
local blurGoal = 0
|
||||
local blurDelta = 0
|
||||
local hasVignetteMaterial = !vignette:IsError()
|
||||
|
||||
timer.Create("ixVignetteChecker", 1, 0, function()
|
||||
local client = LocalPlayer()
|
||||
|
||||
if (IsValid(client)) then
|
||||
local data = {}
|
||||
data.start = client:GetPos()
|
||||
data.endpos = data.start + vignetteTraceHeight
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
|
||||
-- this timer could run before InitPostEntity is called, so we have to check for the validity of the trace table
|
||||
if (trace and trace.Hit) then
|
||||
vignetteAlphaGoal = 80
|
||||
else
|
||||
vignetteAlphaGoal = 0
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function GM:CalcView(client, origin, angles, fov)
|
||||
local view = self.BaseClass:CalcView(client, origin, angles, fov) or {}
|
||||
local entity = Entity(client:GetLocalVar("ragdoll", 0))
|
||||
local ragdoll = IsValid(client:GetRagdollEntity()) and client:GetRagdollEntity() or entity
|
||||
|
||||
if ((!client:ShouldDrawLocalPlayer() and IsValid(entity) and entity:IsRagdoll())
|
||||
or (!LocalPlayer():Alive() and IsValid(ragdoll))) then
|
||||
local ent = LocalPlayer():Alive() and entity or ragdoll
|
||||
local index = ent:LookupAttachment("eyes")
|
||||
|
||||
if (index) then
|
||||
local data = ent:GetAttachment(index)
|
||||
|
||||
if (data) then
|
||||
view.origin = data.Pos
|
||||
view.angles = data.Ang
|
||||
end
|
||||
|
||||
return view
|
||||
end
|
||||
end
|
||||
|
||||
local menu = ix.gui.menu
|
||||
local entityMenu = ix.menu.panel
|
||||
|
||||
if (IsValid(menu) and menu:IsVisible() and menu:GetCharacterOverview()) then
|
||||
local newOrigin, newAngles, newFOV, bDrawPlayer = menu:GetOverviewInfo(origin, angles, fov)
|
||||
|
||||
view.drawviewer = bDrawPlayer
|
||||
view.fov = newFOV
|
||||
view.origin = newOrigin
|
||||
view.angles = newAngles
|
||||
elseif (IsValid(entityMenu)) then
|
||||
view.angles = entityMenu:GetOverviewInfo(origin, angles)
|
||||
end
|
||||
|
||||
return view
|
||||
end
|
||||
|
||||
local hookRun = hook.Run
|
||||
|
||||
do
|
||||
local aimLength = 0.35
|
||||
local aimTime = 0
|
||||
local aimEntity
|
||||
local lastEntity
|
||||
local lastTrace = {}
|
||||
|
||||
timer.Create("ixCheckTargetEntity", 0.1, 0, function()
|
||||
local client = LocalPlayer()
|
||||
local time = SysTime()
|
||||
|
||||
if (!IsValid(client)) then
|
||||
return
|
||||
end
|
||||
|
||||
local character = client:GetCharacter()
|
||||
|
||||
if (!character) then
|
||||
return
|
||||
end
|
||||
|
||||
lastTrace.start = client:GetShootPos()
|
||||
lastTrace.endpos = lastTrace.start + client:GetAimVector(client) * 160
|
||||
lastTrace.filter = client
|
||||
lastTrace.mask = MASK_SHOT_HULL
|
||||
|
||||
lastEntity = util.TraceHull(lastTrace).Entity
|
||||
|
||||
if (lastEntity != aimEntity) then
|
||||
aimTime = time + aimLength
|
||||
aimEntity = lastEntity
|
||||
end
|
||||
|
||||
local panel = ix.gui.entityInfo
|
||||
local bShouldShow = time >= aimTime and (!IsValid(ix.gui.menu) or ix.gui.menu.bClosing) and
|
||||
(!IsValid(ix.gui.characterMenu) or ix.gui.characterMenu.bClosing)
|
||||
local bShouldPopulate = lastEntity.OnShouldPopulateEntityInfo and lastEntity:OnShouldPopulateEntityInfo() or true
|
||||
|
||||
if (bShouldShow and IsValid(lastEntity) and hookRun("ShouldPopulateEntityInfo", lastEntity) != false and
|
||||
(lastEntity.PopulateEntityInfo or bShouldPopulate)) then
|
||||
|
||||
if (!IsValid(panel) or (IsValid(panel) and panel:GetEntity() != lastEntity)) then
|
||||
if (IsValid(ix.gui.entityInfo)) then
|
||||
ix.gui.entityInfo:Remove()
|
||||
end
|
||||
|
||||
local infoPanel = vgui.Create(ix.option.Get("minimalTooltips", false) and "ixTooltipMinimal" or "ixTooltip")
|
||||
local entityPlayer = lastEntity:GetNetVar("player")
|
||||
|
||||
if (entityPlayer) then
|
||||
infoPanel:SetEntity(entityPlayer)
|
||||
infoPanel.entity = lastEntity
|
||||
else
|
||||
infoPanel:SetEntity(lastEntity)
|
||||
end
|
||||
|
||||
infoPanel:SetDrawArrow(true)
|
||||
ix.gui.entityInfo = infoPanel
|
||||
end
|
||||
elseif (IsValid(panel)) then
|
||||
panel:Remove()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local mathApproach = math.Approach
|
||||
local surface = surface
|
||||
|
||||
function GM:HUDPaintBackground()
|
||||
local client = LocalPlayer()
|
||||
|
||||
if (!client:GetCharacter()) then
|
||||
return
|
||||
end
|
||||
|
||||
local frameTime = FrameTime()
|
||||
local scrW, scrH = ScrW(), ScrH()
|
||||
|
||||
if (hasVignetteMaterial and ix.config.Get("vignette")) then
|
||||
vignetteAlphaDelta = mathApproach(vignetteAlphaDelta, vignetteAlphaGoal, frameTime * 30)
|
||||
|
||||
surface.SetDrawColor(0, 0, 0, 175 + vignetteAlphaDelta)
|
||||
surface.SetMaterial(vignette)
|
||||
surface.DrawTexturedRect(0, 0, scrW, scrH)
|
||||
end
|
||||
|
||||
blurGoal = client:GetLocalVar("blur", 0) + (hookRun("AdjustBlurAmount", blurGoal) or 0)
|
||||
|
||||
if (blurDelta != blurGoal) then
|
||||
blurDelta = mathApproach(blurDelta, blurGoal, frameTime * 20)
|
||||
end
|
||||
|
||||
if (blurDelta > 0 and !client:ShouldDrawLocalPlayer()) then
|
||||
ix.util.DrawBlurAt(0, 0, scrW, scrH, blurDelta)
|
||||
end
|
||||
|
||||
self.BaseClass:PaintWorldTips()
|
||||
|
||||
local weapon = client:GetActiveWeapon()
|
||||
|
||||
if (IsValid(weapon) and hook.Run("CanDrawAmmoHUD", weapon) != false and weapon.DrawAmmo != false) then
|
||||
local clip = weapon:Clip1()
|
||||
local clipMax = weapon:GetMaxClip1()
|
||||
local count = client:GetAmmoCount(weapon:GetPrimaryAmmoType())
|
||||
local secondary = client:GetAmmoCount(weapon:GetSecondaryAmmoType())
|
||||
local x, y = scrW - 80, scrH - 80
|
||||
|
||||
if (secondary > 0) then
|
||||
ix.util.DrawBlurAt(x, y, 64, 64)
|
||||
|
||||
surface.SetDrawColor(255, 255, 255, 5)
|
||||
surface.DrawRect(x, y, 64, 64)
|
||||
surface.SetDrawColor(255, 255, 255, 3)
|
||||
surface.DrawOutlinedRect(x, y, 64, 64)
|
||||
|
||||
ix.util.DrawText(secondary, x + 32, y + 32, nil, 1, 1, "ixBigFont")
|
||||
end
|
||||
|
||||
if (weapon:GetClass() != "weapon_slam" and clip > 0 or count > 0) then
|
||||
x = x - (secondary > 0 and 144 or 64)
|
||||
|
||||
ix.util.DrawBlurAt(x, y, 128, 64)
|
||||
|
||||
surface.SetDrawColor(255, 255, 255, 5)
|
||||
surface.DrawRect(x, y, 128, 64)
|
||||
surface.SetDrawColor(255, 255, 255, 3)
|
||||
surface.DrawOutlinedRect(x, y, 128, 64)
|
||||
|
||||
ix.util.DrawText((clip == -1 or clipMax == -1) and count or clip.."/"..count, x + 64, y + 32, nil, 1, 1, "ixBigFont")
|
||||
end
|
||||
end
|
||||
|
||||
if (client:GetLocalVar("restricted") and !client:GetLocalVar("restrictNoMsg")) then
|
||||
ix.util.DrawText(L"restricted", scrW * 0.5, scrH * 0.33, nil, 1, 1, "ixBigFont")
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PostDrawOpaqueRenderables(bDepth, bSkybox)
|
||||
if (bDepth or bSkybox or #ix.blurRenderQueue == 0) then
|
||||
return
|
||||
end
|
||||
|
||||
ix.util.ResetStencilValues()
|
||||
render.SetStencilEnable(true)
|
||||
render.SetStencilWriteMask(27)
|
||||
render.SetStencilTestMask(27)
|
||||
render.SetStencilFailOperation(STENCILOPERATION_KEEP)
|
||||
render.SetStencilZFailOperation(STENCILOPERATION_KEEP)
|
||||
render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
|
||||
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
|
||||
render.SetStencilReferenceValue(27)
|
||||
|
||||
for i = 1, #ix.blurRenderQueue do
|
||||
ix.blurRenderQueue[i]()
|
||||
end
|
||||
|
||||
render.SetStencilReferenceValue(34)
|
||||
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
|
||||
render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
|
||||
render.SetStencilReferenceValue(27)
|
||||
|
||||
cam.Start2D()
|
||||
ix.util.DrawBlurAt(0, 0, ScrW(), ScrH())
|
||||
cam.End2D()
|
||||
render.SetStencilEnable(false)
|
||||
|
||||
ix.blurRenderQueue = {}
|
||||
end
|
||||
|
||||
function GM:PostDrawHUD()
|
||||
cam.Start2D()
|
||||
ix.hud.DrawAll()
|
||||
|
||||
if (!IsValid(ix.gui.deathScreen) and (!IsValid(ix.gui.characterMenu) or ix.gui.characterMenu:IsClosing())) then
|
||||
ix.bar.DrawAction()
|
||||
end
|
||||
cam.End2D()
|
||||
end
|
||||
|
||||
function GM:ShouldPopulateEntityInfo(entity)
|
||||
local client = LocalPlayer()
|
||||
local ragdoll = Entity(client:GetLocalVar("ragdoll", 0))
|
||||
local entityPlayer = entity:GetNetVar("player")
|
||||
|
||||
if (vgui.CursorVisible() or !client:Alive() or IsValid(ragdoll) or entity == client or entityPlayer == client) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local injTextTable = {
|
||||
[.3] = {"injMajor", Color(192, 57, 43)},
|
||||
[.6] = {"injLittle", Color(231, 76, 60)},
|
||||
}
|
||||
|
||||
function GM:GetInjuredText(client)
|
||||
local health = client:Health()
|
||||
|
||||
for k, v in pairs(injTextTable) do
|
||||
if ((health / client:GetMaxHealth()) < k) then
|
||||
return v[1], v[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PopulateImportantCharacterInfo(client, character, container)
|
||||
local color = team.GetColor(client:Team())
|
||||
container:SetArrowColor(color)
|
||||
|
||||
-- name
|
||||
local name = container:AddRow("name")
|
||||
name:SetImportant()
|
||||
name:SetText(hookRun("GetCharacterName", client) or character:GetName())
|
||||
name:SetBackgroundColor(color)
|
||||
name:SizeToContents()
|
||||
|
||||
-- injured text
|
||||
local injureText, injureTextColor = hookRun("GetInjuredText", client)
|
||||
|
||||
if (injureText) then
|
||||
local injure = container:AddRow("injureText")
|
||||
|
||||
injure:SetText(L(injureText))
|
||||
injure:SetBackgroundColor(injureTextColor)
|
||||
injure:SizeToContents()
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PopulateCharacterInfo(client, character, container)
|
||||
-- description
|
||||
local descriptionText = character:GetDescription()
|
||||
descriptionText = (descriptionText:utf8len() > 128 and
|
||||
string.format("%s...", descriptionText:utf8sub(1, 125)) or
|
||||
descriptionText)
|
||||
|
||||
if (descriptionText != "") then
|
||||
local description = container:AddRow("description")
|
||||
description:SetText(descriptionText)
|
||||
description:SizeToContents()
|
||||
end
|
||||
end
|
||||
|
||||
function GM:KeyRelease(client, key)
|
||||
if (!IsFirstTimePredicted()) then
|
||||
return
|
||||
end
|
||||
|
||||
if (key == IN_USE) then
|
||||
if (!ix.menu.IsOpen()) then
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
|
||||
local entity = util.TraceLine(data).Entity
|
||||
|
||||
if (IsValid(entity) and isfunction(entity.GetEntityMenu)) then
|
||||
hook.Run("ShowEntityMenu", entity)
|
||||
end
|
||||
end
|
||||
|
||||
timer.Remove("ixItemUse")
|
||||
|
||||
client.ixInteractionTarget = nil
|
||||
client.ixInteractionStartTime = nil
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PlayerBindPress(client, bind, pressed)
|
||||
bind = bind:lower()
|
||||
|
||||
if (bind:find("use") and pressed) then
|
||||
local pickupTime = ix.config.Get("itemPickupTime", 0.5)
|
||||
|
||||
if (pickupTime > 0) then
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local entity = util.TraceLine(data).Entity
|
||||
|
||||
if (IsValid(entity) and entity.ShowPlayerInteraction and !ix.menu.IsOpen()) then
|
||||
client.ixInteractionTarget = entity
|
||||
client.ixInteractionStartTime = SysTime()
|
||||
|
||||
timer.Create("ixItemUse", pickupTime, 1, function()
|
||||
client.ixInteractionTarget = nil
|
||||
client.ixInteractionStartTime = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
elseif (bind:find("jump")) then
|
||||
local entity = Entity(client:GetLocalVar("ragdoll", 0))
|
||||
|
||||
if (IsValid(entity)) then
|
||||
ix.command.Send("CharGetUp")
|
||||
end
|
||||
elseif (bind:find("speed") and client:KeyDown(IN_WALK) and pressed) then
|
||||
if (LocalPlayer():Crouching()) then
|
||||
RunConsoleCommand("-duck")
|
||||
else
|
||||
RunConsoleCommand("+duck")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CreateMove(command)
|
||||
if ((IsValid(ix.gui.characterMenu) and !ix.gui.characterMenu.bClosing) or
|
||||
(IsValid(ix.gui.menu) and !ix.gui.menu.bClosing and ix.gui.menu:GetActiveTab() == "you")) then
|
||||
command:ClearButtons()
|
||||
command:ClearMovement()
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when use has been pressed on an item.
|
||||
function GM:ShowEntityMenu(entity)
|
||||
local options = entity:GetEntityMenu(LocalPlayer())
|
||||
|
||||
if (istable(options) and !table.IsEmpty(options)) then
|
||||
ix.menu.Open(options, entity)
|
||||
end
|
||||
end
|
||||
|
||||
local hidden = {}
|
||||
hidden["CHudHealth"] = true
|
||||
hidden["CHudBattery"] = true
|
||||
hidden["CHudAmmo"] = true
|
||||
hidden["CHudSecondaryAmmo"] = true
|
||||
hidden["CHudCrosshair"] = true
|
||||
hidden["CHudHistoryResource"] = true
|
||||
hidden["CHudPoisonDamageIndicator"] = true
|
||||
hidden["CHudSquadStatus"] = true
|
||||
hidden["CHUDQuickInfo"] = true
|
||||
|
||||
function GM:HUDShouldDraw(element)
|
||||
if (hidden[element]) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:ShouldDrawLocalPlayer(client)
|
||||
if (IsValid(ix.gui.characterMenu) and ix.gui.characterMenu:IsVisible()) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PostProcessPermitted(class)
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:RenderScreenspaceEffects()
|
||||
local menu = ix.gui.menu
|
||||
|
||||
if (IsValid(menu) and menu:GetCharacterOverview()) then
|
||||
local client = LocalPlayer()
|
||||
local target = client:GetObserverTarget()
|
||||
local weapon = client:GetActiveWeapon()
|
||||
|
||||
cam.Start3D()
|
||||
ix.util.ResetStencilValues()
|
||||
render.SetStencilEnable(true)
|
||||
render.SuppressEngineLighting(true)
|
||||
cam.IgnoreZ(true)
|
||||
render.SetColorModulation(1, 1, 1)
|
||||
render.SetStencilWriteMask(28)
|
||||
render.SetStencilTestMask(28)
|
||||
render.SetStencilReferenceValue(28)
|
||||
|
||||
render.SetStencilCompareFunction(STENCIL_ALWAYS)
|
||||
render.SetStencilPassOperation(STENCIL_REPLACE)
|
||||
render.SetStencilFailOperation(STENCIL_KEEP)
|
||||
render.SetStencilZFailOperation(STENCIL_KEEP)
|
||||
|
||||
if (IsValid(target)) then
|
||||
target:DrawModel()
|
||||
else
|
||||
client:DrawModel()
|
||||
end
|
||||
|
||||
if (IsValid(weapon)) then
|
||||
weapon:DrawModel()
|
||||
end
|
||||
|
||||
hook.Run("DrawCharacterOverview")
|
||||
|
||||
render.SetStencilCompareFunction(STENCIL_NOTEQUAL)
|
||||
render.SetStencilPassOperation(STENCIL_KEEP)
|
||||
|
||||
cam.Start2D()
|
||||
derma.SkinFunc("DrawCharacterStatusBackground", menu, menu.overviewFraction)
|
||||
cam.End2D()
|
||||
cam.IgnoreZ(false)
|
||||
render.SuppressEngineLighting(false)
|
||||
render.SetStencilEnable(false)
|
||||
cam.End3D()
|
||||
end
|
||||
end
|
||||
|
||||
function GM:ShowPlayerOptions(client, options)
|
||||
options["viewProfile"] = {"icon16/user.png", function()
|
||||
if (IsValid(client)) then
|
||||
client:ShowProfile()
|
||||
end
|
||||
end}
|
||||
options["Copy Steam ID"] = {"icon16/user.png", function()
|
||||
if (IsValid(client)) then
|
||||
SetClipboardText(client:SteamID())
|
||||
end
|
||||
end}
|
||||
end
|
||||
|
||||
function GM:DrawHelixModelView(panel, ent)
|
||||
if (ent.weapon and IsValid(ent.weapon)) then
|
||||
ent.weapon:DrawModel()
|
||||
end
|
||||
end
|
||||
|
||||
net.Receive("ixStringRequest", function()
|
||||
local time = net.ReadUInt(32)
|
||||
local title, subTitle = net.ReadString(), net.ReadString()
|
||||
local default = net.ReadString()
|
||||
|
||||
if (title:sub(1, 1) == "@") then
|
||||
title = L(title:sub(2))
|
||||
end
|
||||
|
||||
if (subTitle:sub(1, 1) == "@") then
|
||||
subTitle = L(subTitle:sub(2))
|
||||
end
|
||||
|
||||
Derma_StringRequest(title, subTitle, default or "", function(text)
|
||||
net.Start("ixStringRequest")
|
||||
net.WriteUInt(time, 32)
|
||||
net.WriteString(text)
|
||||
net.SendToServer()
|
||||
end)
|
||||
end)
|
||||
|
||||
net.Receive("ixPlayerDeath", function()
|
||||
if (IsValid(ix.gui.deathScreen)) then
|
||||
ix.gui.deathScreen:Remove()
|
||||
end
|
||||
|
||||
ix.gui.deathScreen = vgui.Create("ixDeathScreen")
|
||||
end)
|
||||
|
||||
function GM:Think()
|
||||
local client = LocalPlayer()
|
||||
|
||||
if (IsValid(client) and client:Alive() and client.ixRaisedTween) then
|
||||
client.ixRaisedTween:update(FrameTime())
|
||||
end
|
||||
end
|
||||
|
||||
function GM:ScreenResolutionChanged(oldW, oldH)
|
||||
hook.Run("LoadFonts", ix.config.Get("font"), ix.config.Get("genericFont"))
|
||||
|
||||
if (IsValid(ix.gui.notices)) then
|
||||
ix.gui.notices:Remove()
|
||||
ix.gui.notices = vgui.Create("ixNoticeManager")
|
||||
end
|
||||
|
||||
if (IsValid(ix.gui.bars)) then
|
||||
ix.gui.bars:Remove()
|
||||
ix.gui.bars = vgui.Create("ixInfoBarManager")
|
||||
end
|
||||
end
|
||||
|
||||
function GM:DrawDeathNotice()
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:HUDAmmoPickedUp()
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:HUDDrawPickupHistory()
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:HUDDrawTargetID()
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:BuildBusinessMenu()
|
||||
if (!ix.config.Get("allowBusiness", true)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
gameevent.Listen("player_spawn")
|
||||
hook.Add("player_spawn", "ixPlayerSpawn", function(data)
|
||||
local client = Player(data.userid)
|
||||
|
||||
if (IsValid(client)) then
|
||||
-- GetBoneName returns __INVALIDBONE__ for everything the first time you use it, so we'll force an update to make them valid
|
||||
client:SetupBones()
|
||||
client:SetIK(false)
|
||||
|
||||
if (client == LocalPlayer() and (IsValid(ix.gui.deathScreen) and !ix.gui.deathScreen:IsClosing())) then
|
||||
ix.gui.deathScreen:Close()
|
||||
end
|
||||
end
|
||||
end)
|
||||
657
garrysmod/gamemodes/helix/gamemode/core/hooks/sh_hooks.lua
Normal file
657
garrysmod/gamemodes/helix/gamemode/core/hooks/sh_hooks.lua
Normal file
@@ -0,0 +1,657 @@
|
||||
|
||||
function GM:PlayerNoClip(client)
|
||||
return client:IsAdmin()
|
||||
end
|
||||
|
||||
-- luacheck: globals HOLDTYPE_TRANSLATOR
|
||||
HOLDTYPE_TRANSLATOR = {}
|
||||
HOLDTYPE_TRANSLATOR[""] = "normal"
|
||||
HOLDTYPE_TRANSLATOR["physgun"] = "smg"
|
||||
HOLDTYPE_TRANSLATOR["ar2"] = "smg"
|
||||
HOLDTYPE_TRANSLATOR["crossbow"] = "shotgun"
|
||||
HOLDTYPE_TRANSLATOR["rpg"] = "shotgun"
|
||||
HOLDTYPE_TRANSLATOR["slam"] = "normal"
|
||||
HOLDTYPE_TRANSLATOR["grenade"] = "grenade"
|
||||
HOLDTYPE_TRANSLATOR["fist"] = "normal"
|
||||
HOLDTYPE_TRANSLATOR["melee2"] = "melee"
|
||||
HOLDTYPE_TRANSLATOR["passive"] = "normal"
|
||||
HOLDTYPE_TRANSLATOR["knife"] = "melee"
|
||||
HOLDTYPE_TRANSLATOR["duel"] = "pistol"
|
||||
HOLDTYPE_TRANSLATOR["camera"] = "smg"
|
||||
HOLDTYPE_TRANSLATOR["magic"] = "normal"
|
||||
HOLDTYPE_TRANSLATOR["revolver"] = "pistol"
|
||||
|
||||
-- luacheck: globals PLAYER_HOLDTYPE_TRANSLATOR
|
||||
PLAYER_HOLDTYPE_TRANSLATOR = {}
|
||||
PLAYER_HOLDTYPE_TRANSLATOR[""] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["fist"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["pistol"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["grenade"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["melee"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["slam"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["melee2"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["passive"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["knife"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["duel"] = "normal"
|
||||
PLAYER_HOLDTYPE_TRANSLATOR["bugbait"] = "normal"
|
||||
|
||||
local PLAYER_HOLDTYPE_TRANSLATOR = PLAYER_HOLDTYPE_TRANSLATOR
|
||||
local HOLDTYPE_TRANSLATOR = HOLDTYPE_TRANSLATOR
|
||||
local animationFixOffset = Vector(16.5438, -0.1642, -20.5493)
|
||||
|
||||
function GM:TranslateActivity(client, act)
|
||||
local clientInfo = client:GetTable()
|
||||
local modelClass = clientInfo.ixAnimModelClass or "player"
|
||||
local bRaised = client:IsWepRaised()
|
||||
|
||||
if (modelClass == "player") then
|
||||
local weapon = client:GetActiveWeapon()
|
||||
local bAlwaysRaised = ix.config.Get("weaponAlwaysRaised")
|
||||
weapon = IsValid(weapon) and weapon or nil
|
||||
|
||||
if (!bAlwaysRaised and weapon and !bRaised and client:OnGround()) then
|
||||
local model = string.lower(client:GetModel())
|
||||
|
||||
if (string.find(model, "zombie")) then
|
||||
local tree = ix.anim.zombie
|
||||
|
||||
if (string.find(model, "fast")) then
|
||||
tree = ix.anim.fastZombie
|
||||
end
|
||||
|
||||
if (tree[act]) then
|
||||
return tree[act]
|
||||
end
|
||||
end
|
||||
|
||||
local holdType = weapon and (weapon.HoldType or weapon:GetHoldType()) or "normal"
|
||||
|
||||
if (!bAlwaysRaised and weapon and !bRaised and client:OnGround()) then
|
||||
holdType = PLAYER_HOLDTYPE_TRANSLATOR[holdType] or "passive"
|
||||
end
|
||||
|
||||
local tree = ix.anim.player[holdType]
|
||||
|
||||
if (tree and tree[act]) then
|
||||
if (isstring(tree[act])) then
|
||||
clientInfo.CalcSeqOverride = client:LookupSequence(tree[act])
|
||||
|
||||
return
|
||||
else
|
||||
return tree[act]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self.BaseClass:TranslateActivity(client, act)
|
||||
end
|
||||
|
||||
if (clientInfo.ixAnimTable) then
|
||||
local glide = clientInfo.ixAnimGlide
|
||||
|
||||
if (client:InVehicle()) then
|
||||
act = clientInfo.ixAnimTable[1]
|
||||
|
||||
local fixVector = clientInfo.ixAnimTable[2]
|
||||
|
||||
if (isvector(fixVector)) then
|
||||
client:SetLocalPos(animationFixOffset)
|
||||
end
|
||||
|
||||
if (isstring(act)) then
|
||||
clientInfo.CalcSeqOverride = client:LookupSequence(act)
|
||||
else
|
||||
return act
|
||||
end
|
||||
elseif (client:OnGround()) then
|
||||
if (clientInfo.ixAnimTable[act]) then
|
||||
local act2 = clientInfo.ixAnimTable[act][bRaised and 2 or 1]
|
||||
|
||||
if (isstring(act2)) then
|
||||
clientInfo.CalcSeqOverride = client:LookupSequence(act2)
|
||||
else
|
||||
return act2
|
||||
end
|
||||
end
|
||||
elseif (glide) then
|
||||
if (isstring(glide)) then
|
||||
clientInfo.CalcSeqOverride = client:LookupSequence(glide)
|
||||
else
|
||||
return clientInfo.ixAnimGlide
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanPlayerUseBusiness(client, uniqueID)
|
||||
if (!ix.config.Get("allowBusiness", true)) then
|
||||
return false
|
||||
end
|
||||
|
||||
local itemTable = ix.item.list[uniqueID]
|
||||
|
||||
if (!client:GetCharacter()) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable.noBusiness) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (itemTable.factions) then
|
||||
local allowed = false
|
||||
|
||||
if (istable(itemTable.factions)) then
|
||||
for _, v in pairs(itemTable.factions) do
|
||||
if (client:Team() == v) then
|
||||
allowed = true
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif (client:Team() != itemTable.factions) then
|
||||
allowed = false
|
||||
end
|
||||
|
||||
if (!allowed) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if (itemTable.classes) then
|
||||
local allowed = false
|
||||
|
||||
if (istable(itemTable.classes)) then
|
||||
for _, v in pairs(itemTable.classes) do
|
||||
if (client:GetCharacter():GetClass() == v) then
|
||||
allowed = true
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif (client:GetCharacter():GetClass() == itemTable.classes) then
|
||||
allowed = true
|
||||
end
|
||||
|
||||
if (!allowed) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if (itemTable.flag) then
|
||||
if (!client:GetCharacter():HasFlags(itemTable.flag)) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:DoAnimationEvent(client, event, data)
|
||||
local class = client.ixAnimModelClass
|
||||
|
||||
if (class == "player") then
|
||||
return self.BaseClass:DoAnimationEvent(client, event, data)
|
||||
else
|
||||
local weapon = client:GetActiveWeapon()
|
||||
|
||||
if (IsValid(weapon)) then
|
||||
local animation = client.ixAnimTable
|
||||
|
||||
if (event == PLAYERANIMEVENT_ATTACK_PRIMARY) then
|
||||
client:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, animation.attack or ACT_GESTURE_RANGE_ATTACK_SMG1, true)
|
||||
|
||||
return ACT_VM_PRIMARYATTACK
|
||||
elseif (event == PLAYERANIMEVENT_ATTACK_SECONDARY) then
|
||||
client:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, animation.attack or ACT_GESTURE_RANGE_ATTACK_SMG1, true)
|
||||
|
||||
return ACT_VM_SECONDARYATTACK
|
||||
elseif (event == PLAYERANIMEVENT_RELOAD) then
|
||||
client:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, animation.reload or ACT_GESTURE_RELOAD_SMG1, true)
|
||||
|
||||
return ACT_INVALID
|
||||
elseif (event == PLAYERANIMEVENT_JUMP) then
|
||||
client:AnimRestartMainSequence()
|
||||
|
||||
return ACT_INVALID
|
||||
elseif (event == PLAYERANIMEVENT_CANCEL_RELOAD) then
|
||||
client:AnimResetGestureSlot(GESTURE_SLOT_ATTACK_AND_RELOAD)
|
||||
|
||||
return ACT_INVALID
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ACT_INVALID
|
||||
end
|
||||
|
||||
function GM:EntityEmitSound(data)
|
||||
if (data.Entity.ixIsMuted) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function GM:EntityRemoved(entity)
|
||||
if (SERVER) then
|
||||
entity:ClearNetVars()
|
||||
elseif (entity:IsWeapon()) then
|
||||
local owner = entity:GetOwner()
|
||||
|
||||
-- GetActiveWeapon is the player's new weapon at this point so we'll assume
|
||||
-- that the player switched away from this weapon
|
||||
if (IsValid(owner) and owner:IsPlayer()) then
|
||||
hook.Run("PlayerWeaponChanged", owner, owner:GetActiveWeapon())
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdatePlayerHoldType(client, weapon)
|
||||
weapon = weapon or client:GetActiveWeapon()
|
||||
local holdType = "normal"
|
||||
|
||||
if (IsValid(weapon)) then
|
||||
holdType = weapon.HoldType or weapon:GetHoldType()
|
||||
holdType = HOLDTYPE_TRANSLATOR[holdType] or holdType
|
||||
end
|
||||
|
||||
client.ixAnimHoldType = holdType
|
||||
end
|
||||
|
||||
local function UpdateAnimationTable(client, vehicle)
|
||||
local baseTable = ix.anim[client.ixAnimModelClass] or {}
|
||||
|
||||
if (IsValid(client) and IsValid(vehicle)) then
|
||||
local vehicleClass = vehicle:IsChair() and "chair" or vehicle:GetClass()
|
||||
|
||||
if (baseTable.vehicle and baseTable.vehicle[vehicleClass]) then
|
||||
client.ixAnimTable = baseTable.vehicle[vehicleClass]
|
||||
else
|
||||
client.ixAnimTable = baseTable.normal[ACT_MP_CROUCH_IDLE]
|
||||
end
|
||||
else
|
||||
client.ixAnimTable = baseTable[client.ixAnimHoldType]
|
||||
end
|
||||
|
||||
client.ixAnimGlide = baseTable["glide"]
|
||||
end
|
||||
|
||||
function GM:PlayerWeaponChanged(client, weapon)
|
||||
UpdatePlayerHoldType(client, weapon)
|
||||
UpdateAnimationTable(client)
|
||||
|
||||
if (CLIENT) then
|
||||
return
|
||||
end
|
||||
|
||||
-- update weapon raise state
|
||||
if (weapon.IsAlwaysRaised or ALWAYS_RAISED[weapon:GetClass()]) then
|
||||
client:SetWepRaised(true, weapon)
|
||||
return
|
||||
elseif (weapon.IsAlwaysLowered or weapon.NeverRaised) then
|
||||
client:SetWepRaised(false, weapon)
|
||||
return
|
||||
end
|
||||
|
||||
-- If the player has been forced to have their weapon lowered.
|
||||
if (client:IsRestricted()) then
|
||||
client:SetWepRaised(false, weapon)
|
||||
return
|
||||
end
|
||||
|
||||
-- Let the config decide before actual results.
|
||||
if (ix.config.Get("weaponAlwaysRaised")) then
|
||||
client:SetWepRaised(true, weapon)
|
||||
return
|
||||
end
|
||||
|
||||
client:SetWepRaised(false, weapon)
|
||||
end
|
||||
|
||||
function GM:PlayerSwitchWeapon(client, oldWeapon, weapon)
|
||||
if (!IsFirstTimePredicted()) then
|
||||
return
|
||||
end
|
||||
|
||||
-- the player switched weapon themself (i.e not through SelectWeapon), so we have to network it here
|
||||
if (SERVER) then
|
||||
net.Start("PlayerSelectWeapon")
|
||||
net.WriteEntity(client)
|
||||
net.WriteString(weapon:GetClass())
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
hook.Run("PlayerWeaponChanged", client, weapon)
|
||||
end
|
||||
|
||||
function GM:PlayerModelChanged(client, model)
|
||||
client.ixAnimModelClass = ix.anim.GetModelClass(model)
|
||||
|
||||
UpdateAnimationTable(client)
|
||||
end
|
||||
|
||||
do
|
||||
local vectorAngle = FindMetaTable("Vector").Angle
|
||||
local normalizeAngle = math.NormalizeAngle
|
||||
|
||||
function GM:CalcMainActivity(client, velocity)
|
||||
local clientInfo = client:GetTable()
|
||||
local forcedSequence = client:GetNetVar("forcedSequence")
|
||||
|
||||
if (forcedSequence) then
|
||||
if (client:GetSequence() != forcedSequence) then
|
||||
client:SetCycle(0)
|
||||
end
|
||||
|
||||
return -1, forcedSequence
|
||||
end
|
||||
|
||||
client:SetPoseParameter("move_yaw", normalizeAngle(vectorAngle(velocity)[2] - client:EyeAngles()[2]))
|
||||
|
||||
local sequenceOverride = clientInfo.CalcSeqOverride
|
||||
clientInfo.CalcSeqOverride = -1
|
||||
clientInfo.CalcIdeal = ACT_MP_STAND_IDLE
|
||||
|
||||
-- we could call the baseclass function, but it's faster to do it this way
|
||||
local BaseClass = self.BaseClass
|
||||
|
||||
if (BaseClass:HandlePlayerNoClipping(client, velocity) or
|
||||
BaseClass:HandlePlayerDriving(client) or
|
||||
BaseClass:HandlePlayerVaulting(client, velocity) or
|
||||
BaseClass:HandlePlayerJumping(client, velocity) or
|
||||
BaseClass:HandlePlayerSwimming(client, velocity) or
|
||||
BaseClass:HandlePlayerDucking(client, velocity)) then -- luacheck: ignore 542
|
||||
else
|
||||
local length = velocity:Length2DSqr()
|
||||
|
||||
if (length > 22500) then
|
||||
clientInfo.CalcIdeal = ACT_MP_RUN
|
||||
elseif (length > 0.25) then
|
||||
clientInfo.CalcIdeal = ACT_MP_WALK
|
||||
end
|
||||
end
|
||||
|
||||
clientInfo.m_bWasOnGround = client:OnGround()
|
||||
clientInfo.m_bWasNoclipping = (client:GetMoveType() == MOVETYPE_NOCLIP and !client:InVehicle())
|
||||
|
||||
return clientInfo.CalcIdeal, sequenceOverride or clientInfo.CalcSeqOverride or -1
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local KEY_BLACKLIST = IN_ATTACK + IN_ATTACK2
|
||||
|
||||
function GM:StartCommand(client, command)
|
||||
if (!client:CanShootWeapon() and !IsValid(client:GetHoldingEntity())) then
|
||||
command:RemoveKey(KEY_BLACKLIST)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CharacterVarChanged(char, varName, oldVar, newVar)
|
||||
if (ix.char.varHooks[varName]) then
|
||||
for _, v in pairs(ix.char.varHooks[varName]) do
|
||||
v(char, oldVar, newVar)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanPlayerThrowPunch(client)
|
||||
if (!client:IsWepRaised()) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:OnCharacterCreated(client, character)
|
||||
local faction = ix.faction.Get(character:GetFaction())
|
||||
|
||||
if (faction and faction.OnCharacterCreated) then
|
||||
faction:OnCharacterCreated(client, character)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:GetDefaultCharacterName(client, faction)
|
||||
local info = ix.faction.indices[faction]
|
||||
|
||||
if (info and info.GetDefaultName) then
|
||||
return info:GetDefaultName(client)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanPlayerUseCharacter(client, character)
|
||||
local banned = character:GetData("banned")
|
||||
|
||||
if (banned) then
|
||||
if (!isnumber(banned)) then
|
||||
return false, "@charBanned"
|
||||
else
|
||||
if (banned > os.time()) then
|
||||
return false, "@charBannedTemp"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local bHasWhitelist = client:HasWhitelist(character:GetFaction())
|
||||
|
||||
if (!bHasWhitelist) then
|
||||
return false, "@noWhitelist"
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanProperty(client, property, entity)
|
||||
if (client:IsAdmin()) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (CLIENT and (property == "remover" or property == "collision")) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:PhysgunPickup(client, entity)
|
||||
local bPickup = self.BaseClass:PhysgunPickup(client, entity)
|
||||
|
||||
if (!bPickup and entity:IsPlayer() and (client:IsSuperAdmin() or client:IsAdmin() and !entity:IsSuperAdmin())) then
|
||||
bPickup = true
|
||||
end
|
||||
|
||||
if (bPickup) then
|
||||
if (entity:IsPlayer()) then
|
||||
entity:SetMoveType(MOVETYPE_NONE)
|
||||
elseif (!entity.ixCollisionGroup) then
|
||||
entity.ixCollisionGroup = entity:GetCollisionGroup()
|
||||
entity:SetCollisionGroup(COLLISION_GROUP_WEAPON)
|
||||
end
|
||||
end
|
||||
|
||||
return bPickup
|
||||
end
|
||||
|
||||
function GM:PhysgunDrop(client, entity)
|
||||
if (entity:IsPlayer()) then
|
||||
entity:SetMoveType(MOVETYPE_WALK)
|
||||
elseif (entity.ixCollisionGroup) then
|
||||
entity:SetCollisionGroup(entity.ixCollisionGroup)
|
||||
entity.ixCollisionGroup = nil
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local TOOL_DANGEROUS = {}
|
||||
TOOL_DANGEROUS["dynamite"] = true
|
||||
TOOL_DANGEROUS["duplicator"] = true
|
||||
|
||||
function GM:CanTool(client, trace, tool)
|
||||
if (client:IsAdmin()) then
|
||||
return true
|
||||
end
|
||||
|
||||
if (TOOL_DANGEROUS[tool]) then
|
||||
return false
|
||||
end
|
||||
|
||||
return self.BaseClass:CanTool(client, trace, tool)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:Move(client, moveData)
|
||||
local char = client:GetCharacter()
|
||||
|
||||
if (char) then
|
||||
if (client:GetNetVar("actEnterAngle")) then
|
||||
moveData:SetForwardSpeed(0)
|
||||
moveData:SetSideSpeed(0)
|
||||
moveData:SetVelocity(vector_origin)
|
||||
end
|
||||
|
||||
if (client:GetMoveType() == MOVETYPE_WALK and moveData:KeyDown(IN_WALK)) then
|
||||
local mf, ms = 0, 0
|
||||
local speed = client:GetWalkSpeed()
|
||||
local ratio = ix.config.Get("walkRatio")
|
||||
|
||||
if (moveData:KeyDown(IN_FORWARD)) then
|
||||
mf = ratio
|
||||
elseif (moveData:KeyDown(IN_BACK)) then
|
||||
mf = -ratio
|
||||
end
|
||||
|
||||
if (moveData:KeyDown(IN_MOVELEFT)) then
|
||||
ms = -ratio
|
||||
elseif (moveData:KeyDown(IN_MOVERIGHT)) then
|
||||
ms = ratio
|
||||
end
|
||||
|
||||
moveData:SetForwardSpeed(mf * speed)
|
||||
moveData:SetSideSpeed(ms * speed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanTransferItem(itemObject, curInv, inventory)
|
||||
if (SERVER) then
|
||||
local client = itemObject.GetOwner and itemObject:GetOwner() or nil
|
||||
|
||||
if (IsValid(client) and curInv.GetReceivers) then
|
||||
local bAuthorized = false
|
||||
|
||||
for _, v in ipairs(curInv:GetReceivers()) do
|
||||
if (client == v) then
|
||||
bAuthorized = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if (!bAuthorized) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- we can transfer anything that isn't a bag
|
||||
if (!itemObject or !itemObject.isBag) then
|
||||
return
|
||||
end
|
||||
|
||||
-- don't allow bags to be put inside bags
|
||||
if (inventory.id != 0 and curInv.id != inventory.id) then
|
||||
if (inventory.vars and inventory.vars.isBag) then
|
||||
local owner = itemObject:GetOwner()
|
||||
|
||||
if (IsValid(owner)) then
|
||||
owner:NotifyLocalized("nestedBags")
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
elseif (inventory.id != 0 and curInv.id == inventory.id) then
|
||||
-- we are simply moving items around if we're transferring to the same inventory
|
||||
return
|
||||
end
|
||||
|
||||
inventory = ix.item.inventories[itemObject:GetData("id")]
|
||||
|
||||
-- don't allow transferring items that are in use
|
||||
if (inventory) then
|
||||
for k, _ in inventory:Iter() do
|
||||
if (k:GetData("equip") == true) then
|
||||
local owner = itemObject:GetOwner()
|
||||
|
||||
if (owner and IsValid(owner)) then
|
||||
owner:NotifyLocalized("equippedBag")
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanPlayerEquipItem(client, item)
|
||||
return item.invID == client:GetCharacter():GetInventory():GetID()
|
||||
end
|
||||
|
||||
function GM:CanPlayerUnequipItem(client, item)
|
||||
return item.invID == client:GetCharacter():GetInventory():GetID()
|
||||
end
|
||||
|
||||
function GM:OnItemTransferred(item, curInv, inventory)
|
||||
local bagInventory = item.GetInventory and item:GetInventory()
|
||||
|
||||
if (!bagInventory) then
|
||||
return
|
||||
end
|
||||
|
||||
-- we need to retain the receiver if the owner changed while viewing as storage
|
||||
if (inventory.storageInfo and isfunction(curInv.GetOwner)) then
|
||||
bagInventory:AddReceiver(curInv:GetOwner())
|
||||
end
|
||||
end
|
||||
|
||||
function GM:ShowHelp() end
|
||||
|
||||
function GM:PreGamemodeLoaded()
|
||||
hook.Remove("PostDrawEffects", "RenderWidgets")
|
||||
hook.Remove("PlayerTick", "TickWidgets")
|
||||
hook.Remove("RenderScene", "RenderStereoscopy")
|
||||
end
|
||||
|
||||
function GM:PostGamemodeLoaded()
|
||||
baseclass.Set("ix_character", ix.meta.character)
|
||||
baseclass.Set("ix_inventory", ix.meta.inventory)
|
||||
baseclass.Set("ix_item", ix.meta.item)
|
||||
end
|
||||
|
||||
if (SERVER) then
|
||||
util.AddNetworkString("PlayerVehicle")
|
||||
|
||||
function GM:PlayerEnteredVehicle(client, vehicle, role)
|
||||
UpdateAnimationTable(client)
|
||||
|
||||
net.Start("PlayerVehicle")
|
||||
net.WriteEntity(client)
|
||||
net.WriteEntity(vehicle)
|
||||
net.WriteBool(true)
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
function GM:PlayerLeaveVehicle(client, vehicle)
|
||||
UpdateAnimationTable(client)
|
||||
|
||||
net.Start("PlayerVehicle")
|
||||
net.WriteEntity(client)
|
||||
net.WriteEntity(vehicle)
|
||||
net.WriteBool(false)
|
||||
net.Broadcast()
|
||||
end
|
||||
else
|
||||
net.Receive("PlayerVehicle", function(length)
|
||||
local client = net.ReadEntity()
|
||||
local vehicle = net.ReadEntity()
|
||||
local bEntered = net.ReadBool()
|
||||
|
||||
UpdateAnimationTable(client, bEntered and vehicle or false)
|
||||
end)
|
||||
end
|
||||
910
garrysmod/gamemodes/helix/gamemode/core/hooks/sv_hooks.lua
Normal file
910
garrysmod/gamemodes/helix/gamemode/core/hooks/sv_hooks.lua
Normal file
@@ -0,0 +1,910 @@
|
||||
util.AddNetworkString("ixPlayerDeath")
|
||||
|
||||
function GM:PlayerInitialSpawn(client)
|
||||
client.ixJoinTime = RealTime()
|
||||
|
||||
if (client:IsBot()) then
|
||||
local botID = os.time() + client:EntIndex()
|
||||
local index = math.random(1, table.Count(ix.faction.indices))
|
||||
local faction = ix.faction.indices[index]
|
||||
|
||||
local character = ix.char.New({
|
||||
name = client:Name(),
|
||||
faction = faction and faction.uniqueID or "unknown",
|
||||
model = faction and table.Random(faction:GetModels(client)) or "models/gman.mdl"
|
||||
}, botID, client, client:SteamID64())
|
||||
character.isBot = true
|
||||
|
||||
local inventory = ix.inventory.Create(ix.config.Get("inventoryWidth"), ix.config.Get("inventoryHeight"), botID)
|
||||
inventory:SetOwner(botID)
|
||||
inventory.noSave = true
|
||||
|
||||
character.vars.inv = {inventory}
|
||||
|
||||
ix.char.loaded[botID] = character
|
||||
|
||||
character:Setup()
|
||||
client:Spawn()
|
||||
|
||||
ix.chat.Send(nil, "connect", client:SteamName())
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
ix.config.Send(client)
|
||||
ix.date.Send(client)
|
||||
|
||||
client:LoadData(function(data)
|
||||
if (!IsValid(client)) then return end
|
||||
|
||||
-- Don't use the character cache if they've connected to another server using the same database
|
||||
local address = ix.util.GetAddress()
|
||||
local bNoCache = client:GetData("lastIP", address) != address
|
||||
client:SetData("lastIP", address)
|
||||
|
||||
net.Start("ixDataSync")
|
||||
net.WriteTable(data or {})
|
||||
net.WriteUInt(client.ixPlayTime or 0, 32)
|
||||
net.Send(client)
|
||||
|
||||
ix.char.Restore(client, function(charList)
|
||||
if (!IsValid(client)) then return end
|
||||
|
||||
MsgN("Loaded (" .. table.concat(charList, ", ") .. ") for " .. client:Name())
|
||||
|
||||
for _, v in ipairs(charList) do
|
||||
ix.char.loaded[v]:Sync(client)
|
||||
end
|
||||
|
||||
client.ixCharList = charList
|
||||
|
||||
net.Start("ixCharacterMenu")
|
||||
net.WriteUInt(#charList, 6)
|
||||
|
||||
for _, v in ipairs(charList) do
|
||||
net.WriteUInt(v, 32)
|
||||
end
|
||||
|
||||
net.Send(client)
|
||||
|
||||
client.ixLoaded = true
|
||||
client:SetData("intro", true)
|
||||
|
||||
for _, v in player.Iterator() do
|
||||
if (v:GetCharacter()) then
|
||||
v:GetCharacter():Sync(client)
|
||||
end
|
||||
end
|
||||
end, bNoCache)
|
||||
|
||||
ix.chat.Send(nil, "connect", client:SteamName())
|
||||
end)
|
||||
|
||||
client:SetNoDraw(true)
|
||||
client:SetNotSolid(true)
|
||||
client:Lock()
|
||||
client:SyncVars()
|
||||
|
||||
timer.Simple(1, function()
|
||||
if (!IsValid(client)) then
|
||||
return
|
||||
end
|
||||
|
||||
client:KillSilent()
|
||||
client:StripAmmo()
|
||||
end)
|
||||
end
|
||||
|
||||
function GM:PlayerUse(client, entity)
|
||||
if (client:IsRestricted() or (isfunction(entity.GetEntityMenu) and entity:GetClass() != "ix_item")) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:KeyPress(client, key)
|
||||
if (key == IN_RELOAD) then
|
||||
timer.Create("ixToggleRaise"..client:SteamID(), ix.config.Get("weaponRaiseTime"), 1, function()
|
||||
if (IsValid(client)) then
|
||||
client:ToggleWepRaised()
|
||||
end
|
||||
end)
|
||||
elseif (key == IN_USE) then
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local entity = util.TraceLine(data).Entity
|
||||
|
||||
if (IsValid(entity) and hook.Run("PlayerUse", client, entity)) then
|
||||
if (entity:IsDoor()) then
|
||||
local result = hook.Run("CanPlayerUseDoor", client, entity)
|
||||
|
||||
if (result != false) then
|
||||
hook.Run("PlayerUseDoor", client, entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:KeyRelease(client, key)
|
||||
if (key == IN_RELOAD) then
|
||||
timer.Remove("ixToggleRaise" .. client:SteamID())
|
||||
elseif (key == IN_USE) then
|
||||
timer.Remove("ixCharacterInteraction" .. client:SteamID())
|
||||
end
|
||||
end
|
||||
|
||||
function GM:CanPlayerInteractItem(client, action, item, data)
|
||||
if (client:IsRestricted()) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (IsValid(client.ixRagdoll)) then
|
||||
client:NotifyLocalized("notNow")
|
||||
return false
|
||||
end
|
||||
|
||||
if (action == "drop" and hook.Run("CanPlayerDropItem", client, item) == false) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (action == "take" and hook.Run("CanPlayerTakeItem", client, item) == false) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (action == "combine") then
|
||||
local other = data[1]
|
||||
|
||||
if (hook.Run("CanPlayerCombineItem", client, item, other) == false) then
|
||||
return false
|
||||
end
|
||||
|
||||
local combineItem = ix.item.instances[other]
|
||||
|
||||
if (combineItem and combineItem.invID != 0) then
|
||||
local combineInv = ix.item.inventories[combineItem.invID]
|
||||
|
||||
if (!combineInv:OnCheckAccess(client)) then
|
||||
return false
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if (isentity(item) and item.ixSteamID and item.ixCharID
|
||||
and item.ixSteamID == client:SteamID() and item.ixCharID != client:GetCharacter():GetID()
|
||||
and !item:GetItemTable().bAllowMultiCharacterInteraction) then
|
||||
client:NotifyLocalized("itemOwned")
|
||||
return false
|
||||
end
|
||||
|
||||
return client:Alive()
|
||||
end
|
||||
|
||||
function GM:CanPlayerDropItem(client, item)
|
||||
|
||||
end
|
||||
|
||||
function GM:CanPlayerTakeItem(client, item)
|
||||
|
||||
end
|
||||
|
||||
function GM:CanPlayerCombineItem(client, item, other)
|
||||
|
||||
end
|
||||
|
||||
function GM:PlayerShouldTakeDamage(client, attacker)
|
||||
return client:GetCharacter() != nil
|
||||
end
|
||||
|
||||
function GM:GetFallDamage(client, speed)
|
||||
return math.max(0, (speed - 526.5) * 0.75)
|
||||
end
|
||||
|
||||
function GM:EntityTakeDamage(entity, dmgInfo)
|
||||
local inflictor = dmgInfo:GetInflictor()
|
||||
|
||||
if (IsValid(inflictor) and inflictor:GetClass() == "ix_item") then
|
||||
dmgInfo:SetDamage(0)
|
||||
return
|
||||
end
|
||||
|
||||
if (IsValid(entity.ixPlayer)) then
|
||||
if (IsValid(entity.ixHeldOwner)) then
|
||||
dmgInfo:SetDamage(0)
|
||||
return
|
||||
end
|
||||
|
||||
if (dmgInfo:IsDamageType(DMG_CRUSH)) then
|
||||
if ((entity.ixFallGrace or 0) < CurTime()) then
|
||||
if (dmgInfo:GetDamage() <= 10) then
|
||||
dmgInfo:SetDamage(0)
|
||||
end
|
||||
|
||||
entity.ixFallGrace = CurTime() + 0.5
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
entity.ixPlayer:TakeDamageInfo(dmgInfo)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PrePlayerLoadedCharacter(client, character, lastChar)
|
||||
-- Reset all bodygroups
|
||||
client:ResetBodygroups()
|
||||
|
||||
-- Remove all skins
|
||||
client:SetSkin(0)
|
||||
end
|
||||
|
||||
function GM:PlayerLoadedCharacter(client, character, lastChar)
|
||||
local query = mysql:Update("ix_characters")
|
||||
query:Where("id", character:GetID())
|
||||
query:Update("last_join_time", math.floor(os.time()))
|
||||
query:Execute()
|
||||
|
||||
if (lastChar) then
|
||||
local charEnts = lastChar:GetVar("charEnts") or {}
|
||||
|
||||
for _, v in ipairs(charEnts) do
|
||||
if (v and IsValid(v)) then
|
||||
v:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
lastChar:SetVar("charEnts", nil)
|
||||
end
|
||||
|
||||
if (character) then
|
||||
for _, v in pairs(ix.class.list) do
|
||||
if (v.faction == client:Team() and v.isDefault) then
|
||||
character:SetClass(v.index)
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (IsValid(client.ixRagdoll)) then
|
||||
client.ixRagdoll.ixNoReset = true
|
||||
client.ixRagdoll.ixIgnoreDelete = true
|
||||
client.ixRagdoll:Remove()
|
||||
end
|
||||
|
||||
local faction = ix.faction.indices[character:GetFaction()]
|
||||
local uniqueID = "ixSalary" .. client:UniqueID()
|
||||
|
||||
if (faction and faction.pay and faction.pay > 0) then
|
||||
timer.Create(uniqueID, faction.payTime or 300, 0, function()
|
||||
if (IsValid(client)) then
|
||||
if (hook.Run("CanPlayerEarnSalary", client, faction) != false) then
|
||||
local pay = hook.Run("GetSalaryAmount", client, faction) or faction.pay
|
||||
|
||||
character:GiveMoney(pay)
|
||||
client:NotifyLocalized("salary", ix.currency.Get(pay))
|
||||
end
|
||||
else
|
||||
timer.Remove(uniqueID)
|
||||
end
|
||||
end)
|
||||
elseif (timer.Exists(uniqueID)) then
|
||||
timer.Remove(uniqueID)
|
||||
end
|
||||
|
||||
hook.Run("PlayerLoadout", client)
|
||||
end
|
||||
|
||||
function GM:CharacterLoaded(character)
|
||||
local client = character:GetPlayer()
|
||||
|
||||
if (IsValid(client)) then
|
||||
local uniqueID = "ixSaveChar"..client:SteamID()
|
||||
|
||||
timer.Create(uniqueID, ix.config.Get("saveInterval"), 0, function()
|
||||
if (IsValid(client) and client:GetCharacter()) then
|
||||
client:GetCharacter():Save()
|
||||
else
|
||||
timer.Remove(uniqueID)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PlayerSay(client, text)
|
||||
local chatType, message, anonymous = ix.chat.Parse(client, text, true)
|
||||
|
||||
if (chatType == "ic") then
|
||||
if (ix.command.Parse(client, message)) then
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
text = ix.chat.Send(client, chatType, message, anonymous)
|
||||
|
||||
if (isstring(text) and chatType != "ic") then
|
||||
ix.log.Add(client, "chat", chatType and chatType:utf8upper() or "??", text)
|
||||
end
|
||||
|
||||
hook.Run("PostPlayerSay", client, chatType, message, anonymous)
|
||||
return ""
|
||||
end
|
||||
|
||||
function GM:CanAutoFormatMessage(client, chatType, message)
|
||||
return chatType == "ic" or chatType == "w" or chatType == "y"
|
||||
end
|
||||
|
||||
function GM:PlayerSpawn(client)
|
||||
client:SetNoDraw(false)
|
||||
client:UnLock()
|
||||
client:SetNotSolid(false)
|
||||
client:SetMoveType(MOVETYPE_WALK)
|
||||
client:SetRagdolled(false)
|
||||
client:SetAction()
|
||||
client:SetDSP(1)
|
||||
|
||||
hook.Run("PlayerLoadout", client)
|
||||
end
|
||||
|
||||
-- Shortcuts for (super)admin only things.
|
||||
local function IsAdmin(_, client)
|
||||
return client:IsAdmin()
|
||||
end
|
||||
|
||||
-- Set the gamemode hooks to the appropriate shortcuts.
|
||||
GM.PlayerGiveSWEP = IsAdmin
|
||||
GM.PlayerSpawnEffect = IsAdmin
|
||||
GM.PlayerSpawnSENT = IsAdmin
|
||||
|
||||
function GM:PlayerSpawnNPC(client, npcType, weapon)
|
||||
return client:IsAdmin() or client:GetCharacter():HasFlags("n")
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnSWEP(client, weapon, info)
|
||||
return client:IsAdmin()
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnProp(client)
|
||||
if (client:GetCharacter() and client:GetCharacter():HasFlags("e")) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnRagdoll(client)
|
||||
if (client:GetCharacter() and client:GetCharacter():HasFlags("r")) then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnVehicle(client, model, name, data)
|
||||
if (client:GetCharacter()) then
|
||||
if (data.Category == "Chairs") then
|
||||
return client:GetCharacter():HasFlags("c")
|
||||
else
|
||||
return client:GetCharacter():HasFlags("C")
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedEffect(client, model, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedNPC(client, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedProp(client, model, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedRagdoll(client, model, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedSENT(client, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedSWEP(client, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
function GM:PlayerSpawnedVehicle(client, entity)
|
||||
entity:SetNetVar("owner", client:GetCharacter():GetID())
|
||||
end
|
||||
|
||||
ix.allowedHoldableClasses = {
|
||||
["ix_item"] = true,
|
||||
["ix_money"] = true,
|
||||
["ix_shipment"] = true,
|
||||
["prop_physics"] = true,
|
||||
["prop_physics_override"] = true,
|
||||
["prop_physics_multiplayer"] = true,
|
||||
["prop_ragdoll"] = true
|
||||
}
|
||||
|
||||
function GM:CanPlayerHoldObject(client, entity)
|
||||
if (ix.allowedHoldableClasses[entity:GetClass()]) then
|
||||
return true
|
||||
end
|
||||
|
||||
return hook.Run("CanPlayerPickupEntity", client, entity) == true
|
||||
end
|
||||
|
||||
local voiceDistance = 360000
|
||||
local function CalcPlayerCanHearPlayersVoice(listener)
|
||||
if (!IsValid(listener)) then
|
||||
return
|
||||
end
|
||||
|
||||
listener.ixVoiceHear = listener.ixVoiceHear or {}
|
||||
|
||||
local eyePos = listener:EyePos()
|
||||
for _, speaker in player.Iterator() do
|
||||
local speakerEyePos = speaker:EyePos()
|
||||
listener.ixVoiceHear[speaker] = eyePos:DistToSqr(speakerEyePos) < voiceDistance
|
||||
end
|
||||
end
|
||||
|
||||
function GM:InitializedConfig()
|
||||
ix.date.Initialize()
|
||||
|
||||
voiceDistance = ix.config.Get("voiceDistance")
|
||||
voiceDistance = voiceDistance * voiceDistance
|
||||
end
|
||||
|
||||
function GM:VoiceToggled(bAllowVoice)
|
||||
for _, v in player.Iterator() do
|
||||
local uniqueID = v:SteamID64() .. "ixCanHearPlayersVoice"
|
||||
|
||||
if (bAllowVoice) then
|
||||
timer.Create(uniqueID, 0.5, 0, function()
|
||||
CalcPlayerCanHearPlayersVoice(v)
|
||||
end)
|
||||
else
|
||||
timer.Remove(uniqueID)
|
||||
|
||||
v.ixVoiceHear = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:VoiceDistanceChanged(distance)
|
||||
voiceDistance = distance * distance
|
||||
end
|
||||
|
||||
-- Called when weapons should be given to a player.
|
||||
function GM:PlayerLoadout(client)
|
||||
if (client.ixSkipLoadout) then
|
||||
client.ixSkipLoadout = nil
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
client:SetWeaponColor(Vector(client:GetInfo("cl_weaponcolor")))
|
||||
client:StripWeapons()
|
||||
client:StripAmmo()
|
||||
client:SetLocalVar("blur", nil)
|
||||
|
||||
local character = client:GetCharacter()
|
||||
|
||||
-- Check if they have loaded a character.
|
||||
if (character) then
|
||||
client:SetupHands()
|
||||
-- Set their player model to the character's model.
|
||||
client:SetModel(character:GetModel())
|
||||
client:Give("ix_hands")
|
||||
client:SetWalkSpeed(ix.config.Get("walkSpeed"))
|
||||
client:SetRunSpeed(ix.config.Get("runSpeed"))
|
||||
client:SetHealth(character:GetData("health", client:GetMaxHealth()))
|
||||
|
||||
local faction = ix.faction.indices[client:Team()]
|
||||
|
||||
if (faction) then
|
||||
-- If their faction wants to do something when the player spawns, let it.
|
||||
if (faction.OnSpawn) then
|
||||
faction:OnSpawn(client)
|
||||
end
|
||||
|
||||
-- @todo add docs for player:Give() failing if player already has weapon - which means if a player is given a weapon
|
||||
-- here due to the faction weapons table, the weapon's :Give call in the weapon base will fail since the player
|
||||
-- will already have it by then. This will cause issues for weapons that have pac data since the parts are applied
|
||||
-- only if the weapon returned by :Give() is valid
|
||||
|
||||
-- If the faction has default weapons, give them to the player.
|
||||
if (faction.weapons) then
|
||||
for _, v in ipairs(faction.weapons) do
|
||||
client:Give(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Ditto, but for classes.
|
||||
local class = ix.class.list[client:GetCharacter():GetClass()]
|
||||
|
||||
if (class) then
|
||||
if (class.OnSpawn) then
|
||||
class:OnSpawn(client)
|
||||
end
|
||||
|
||||
if (class.weapons) then
|
||||
for _, v in ipairs(class.weapons) do
|
||||
client:Give(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply any flags as needed.
|
||||
ix.flag.OnSpawn(client)
|
||||
ix.attributes.Setup(client)
|
||||
|
||||
hook.Run("PostPlayerLoadout", client)
|
||||
|
||||
client:SelectWeapon("ix_hands")
|
||||
else
|
||||
client:SetNoDraw(true)
|
||||
client:Lock()
|
||||
client:SetNotSolid(true)
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PostPlayerLoadout(client)
|
||||
-- Reload All Attrib Boosts
|
||||
local character = client:GetCharacter()
|
||||
if (!character) then return end
|
||||
|
||||
local inventory = character:GetInventory()
|
||||
|
||||
if (inventory and !isnumber(inventory)) then
|
||||
for k, _ in inventory:Iter() do
|
||||
k:Call("OnLoadout", client)
|
||||
|
||||
if (k:GetData("equip") and k.attribBoosts) then
|
||||
for attribKey, attribValue in pairs(k.attribBoosts) do
|
||||
character:AddBoost(k.uniqueID, attribKey, attribValue)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (ix.config.Get("allowVoice")) then
|
||||
timer.Create(client:SteamID64() .. "ixCanHearPlayersVoice", 0.5, 0, function()
|
||||
CalcPlayerCanHearPlayersVoice(client)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local painSounds = {
|
||||
Sound("vo/npc/male01/pain01.wav"),
|
||||
Sound("vo/npc/male01/pain02.wav"),
|
||||
Sound("vo/npc/male01/pain03.wav"),
|
||||
Sound("vo/npc/male01/pain04.wav"),
|
||||
Sound("vo/npc/male01/pain05.wav"),
|
||||
Sound("vo/npc/male01/pain06.wav")
|
||||
}
|
||||
|
||||
local drownSounds = {
|
||||
Sound("player/pl_drown1.wav"),
|
||||
Sound("player/pl_drown2.wav"),
|
||||
Sound("player/pl_drown3.wav"),
|
||||
}
|
||||
|
||||
function GM:GetPlayerPainSound(client)
|
||||
if (client:WaterLevel() >= 3) then
|
||||
return drownSounds[math.random(1, #drownSounds)]
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PlayerHurt(client, attacker, health, damage)
|
||||
if ((client.ixNextPain or 0) < CurTime() and health > 0) then
|
||||
local painSound = hook.Run("GetPlayerPainSound", client) or painSounds[math.random(1, #painSounds)]
|
||||
|
||||
if (client:IsFemale() and !painSound:find("female")) then
|
||||
painSound = painSound:gsub("male", "female")
|
||||
end
|
||||
|
||||
client:EmitSound(painSound)
|
||||
client.ixNextPain = CurTime() + 0.33
|
||||
end
|
||||
|
||||
ix.log.Add(client, "playerHurt", damage, attacker:GetName() ~= "" and attacker:GetName() or attacker:GetClass())
|
||||
end
|
||||
|
||||
function GM:PlayerDeathThink(client)
|
||||
if (client:GetCharacter()) then
|
||||
local deathTime = client:GetNetVar("deathTime")
|
||||
|
||||
if (deathTime and deathTime <= CurTime()) then
|
||||
client:Spawn()
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
hook.Add("PlayerDeath", "SyncDeathTimeWithScreen", function(ply)
|
||||
local duration = ix.config.Get("deathScreenDuration", 5.5)
|
||||
ply:SetNetVar("deathTime", CurTime() + duration)
|
||||
end)
|
||||
|
||||
function GM:PlayerDisconnected(client)
|
||||
client:SaveData()
|
||||
|
||||
local character = client:GetCharacter()
|
||||
|
||||
if (character) then
|
||||
local charEnts = character:GetVar("charEnts") or {}
|
||||
|
||||
for _, v in ipairs(charEnts) do
|
||||
if (v and IsValid(v)) then
|
||||
v:Remove()
|
||||
end
|
||||
end
|
||||
|
||||
hook.Run("OnCharacterDisconnect", client, character)
|
||||
character:Save()
|
||||
ix.chat.Send(nil, "disconnect", client:SteamName())
|
||||
end
|
||||
|
||||
if (IsValid(client.ixRagdoll)) then
|
||||
client.ixRagdoll:Remove()
|
||||
end
|
||||
|
||||
client:ClearNetVars()
|
||||
|
||||
if (!client.ixVoiceHear) then
|
||||
return
|
||||
end
|
||||
|
||||
for _, v in player.Iterator() do
|
||||
if (!v.ixVoiceHear) then
|
||||
continue
|
||||
end
|
||||
|
||||
v.ixVoiceHear[client] = nil
|
||||
end
|
||||
|
||||
timer.Remove(client:SteamID64() .. "ixCanHearPlayersVoice")
|
||||
end
|
||||
|
||||
function GM:InitPostEntity()
|
||||
local doors = ents.FindByClass("prop_door_rotating")
|
||||
|
||||
for _, v in ipairs(doors) do
|
||||
local parent = v:GetOwner()
|
||||
|
||||
if (IsValid(parent)) then
|
||||
v.ixPartner = parent
|
||||
parent.ixPartner = v
|
||||
else
|
||||
for _, v2 in ipairs(doors) do
|
||||
if (v2:GetOwner() == v) then
|
||||
v2.ixPartner = v
|
||||
v.ixPartner = v2
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
timer.Simple(2, function()
|
||||
ix.entityDataLoaded = true
|
||||
end)
|
||||
end
|
||||
|
||||
function GM:SaveData()
|
||||
ix.date.Save()
|
||||
end
|
||||
|
||||
function GM:ShutDown()
|
||||
ix.shuttingDown = true
|
||||
ix.config.Save()
|
||||
|
||||
hook.Run("SaveData")
|
||||
|
||||
for _, v in player.Iterator() do
|
||||
v:SaveData()
|
||||
|
||||
if (v:GetCharacter()) then
|
||||
v:GetCharacter():Save()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:GetGameDescription()
|
||||
return (Schema and Schema.name or "Unknown")
|
||||
end
|
||||
|
||||
function GM:OnPlayerUseBusiness(client, item)
|
||||
-- You can manipulate purchased items with this hook.
|
||||
-- does not requires any kind of return.
|
||||
-- ex) item:SetData("businessItem", true)
|
||||
-- then every purchased item will be marked as Business Item.
|
||||
end
|
||||
|
||||
function GM:PlayerDeathSound()
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:InitializedSchema()
|
||||
game.ConsoleCommand("sbox_persist ix_"..Schema.folder.."\n")
|
||||
end
|
||||
|
||||
function GM:PlayerCanHearPlayersVoice(listener, speaker)
|
||||
if (!speaker:Alive()) then
|
||||
return false
|
||||
end
|
||||
|
||||
local bCanHear = listener.ixVoiceHear and listener.ixVoiceHear[speaker]
|
||||
return bCanHear, true
|
||||
end
|
||||
|
||||
function GM:PlayerCanPickupWeapon(client, weapon)
|
||||
local data = {}
|
||||
data.start = client:GetShootPos()
|
||||
data.endpos = data.start + client:GetAimVector() * 96
|
||||
data.filter = client
|
||||
local trace = util.TraceLine(data)
|
||||
|
||||
if (trace.Entity == weapon and client:KeyDown(IN_USE)) then
|
||||
return true
|
||||
end
|
||||
|
||||
return client.ixWeaponGive
|
||||
end
|
||||
|
||||
function GM:OnPhysgunFreeze(weapon, physObj, entity, client)
|
||||
-- Validate the physObj, to prevent errors on entities who have no physics object
|
||||
if (!IsValid(physObj)) then return false end
|
||||
|
||||
-- Object is already frozen (!?)
|
||||
if (!physObj:IsMoveable()) then return false end
|
||||
if (entity:GetUnFreezable()) then return false end
|
||||
|
||||
physObj:EnableMotion(false)
|
||||
|
||||
-- With the jeep we need to pause all of its physics objects
|
||||
-- to stop it spazzing out and killing the server.
|
||||
if (entity:GetClass() == "prop_vehicle_jeep") then
|
||||
local objects = entity:GetPhysicsObjectCount()
|
||||
|
||||
for i = 0, objects - 1 do
|
||||
entity:GetPhysicsObjectNum(i):EnableMotion(false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Add it to the player's frozen props
|
||||
client:AddFrozenPhysicsObject(entity, physObj)
|
||||
client:SendHint("PhysgunUnfreeze", 0.3)
|
||||
client:SuppressHint("PhysgunFreeze")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function GM:CanPlayerSuicide(client)
|
||||
return false
|
||||
end
|
||||
|
||||
function GM:AllowPlayerPickup(client, entity)
|
||||
if (ix.allowedHoldableClasses[entity:GetClass()]) then
|
||||
return true
|
||||
end
|
||||
|
||||
return hook.Run("CanPlayerPickupEntity", client, entity) == true
|
||||
end
|
||||
|
||||
function GM:PreCleanupMap()
|
||||
hook.Run("SaveData")
|
||||
hook.Run("PersistenceSave")
|
||||
end
|
||||
|
||||
function GM:PostCleanupMap()
|
||||
ix.plugin.RunLoadData()
|
||||
end
|
||||
|
||||
function GM:CharacterPreSave(character)
|
||||
if (!character) then return end
|
||||
|
||||
local client = character:GetPlayer()
|
||||
local inventory = character:GetInventory()
|
||||
|
||||
if (inventory and !isnumber(inventory)) then
|
||||
for k, _ in inventory:Iter() do
|
||||
if (k.OnSave) then
|
||||
k:Call("OnSave", client)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
character:SetData("health", client:Alive() and client:Health() or nil)
|
||||
end
|
||||
|
||||
timer.Create("ixLifeGuard", 1, 0, function()
|
||||
for _, v in player.Iterator() do
|
||||
if (v:GetCharacter() and v:Alive() and hook.Run("ShouldPlayerDrowned", v) != false) then
|
||||
if (v:WaterLevel() >= 3) then
|
||||
if (!v.drowningTime) then
|
||||
v.drowningTime = CurTime() + 30
|
||||
v.nextDrowning = CurTime()
|
||||
v.drownDamage = v.drownDamage or 0
|
||||
end
|
||||
|
||||
if (v.drowningTime < CurTime()) then
|
||||
if (v.nextDrowning < CurTime()) then
|
||||
v:ScreenFade(1, Color(0, 0, 255, 100), 1, 0)
|
||||
v:TakeDamage(10)
|
||||
v.drownDamage = v.drownDamage + 10
|
||||
v.nextDrowning = CurTime() + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
if (v.drowningTime) then
|
||||
v.drowningTime = nil
|
||||
v.nextDrowning = nil
|
||||
v.nextRecover = CurTime() + 2
|
||||
end
|
||||
|
||||
if (v.nextRecover and v.nextRecover < CurTime() and v.drownDamage > 0) then
|
||||
v.drownDamage = v.drownDamage - 10
|
||||
v:SetHealth(math.Clamp(v:Health() + 10, 0, v:GetMaxHealth()))
|
||||
v.nextRecover = CurTime() + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("ixStringRequest", function(length, client)
|
||||
local time = net.ReadUInt(32)
|
||||
local text = net.ReadString()
|
||||
|
||||
if (client.ixStrReqs and client.ixStrReqs[time]) then
|
||||
client.ixStrReqs[time](text)
|
||||
client.ixStrReqs[time] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
function GM:GetPreferredCarryAngles(entity)
|
||||
if (entity:GetClass() == "ix_item") then
|
||||
local itemTable = entity:GetItemTable()
|
||||
|
||||
if (itemTable) then
|
||||
local preferedAngle = itemTable.preferedAngle
|
||||
|
||||
if (preferedAngle) then -- I don't want to return something
|
||||
return preferedAngle
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GM:PluginShouldLoad(uniqueID)
|
||||
return !ix.plugin.unloaded[uniqueID]
|
||||
end
|
||||
|
||||
function GM:DatabaseConnected()
|
||||
-- Create the SQL tables if they do not exist.
|
||||
ix.db.LoadTables()
|
||||
ix.log.LoadTables()
|
||||
|
||||
MsgC(Color(0, 255, 0), "Database Type: " .. ix.db.config.adapter .. ".\n")
|
||||
|
||||
timer.Create("ixDatabaseThink", 0.5, 0, function()
|
||||
mysql:Think()
|
||||
end)
|
||||
|
||||
ix.plugin.RunLoadData()
|
||||
end
|
||||
Reference in New Issue
Block a user