diff --git a/lua/autorun/!drc_shared.lua b/lua/autorun/!drc_shared.lua index 506a524..18c3433 100644 --- a/lua/autorun/!drc_shared.lua +++ b/lua/autorun/!drc_shared.lua @@ -15,9 +15,16 @@ list.Set( "DesktopWindows", "Draconic Menu", { icon = "icon64/draconic_base.png", init = function( icon, window ) DRCMenu(LocalPlayer()) + RunConsoleCommand("-menu_context") end } ) +-- Defining useful globals for content developers +SNDLVL_TALKING = 80 +SNDLVL_VEHICLE = 105 +SNDLVL_ENERGYFIRESILENCED = 90 +SNDLVL_ENERGYFIRE = 100 +SNDLVL_GUNFIRESILENCED = 115 SNDLVL_GUNFIRE = 140 -- Any code beyond this point is considered legacy and should NOT be used as reference, or at all. @@ -57,67 +64,4 @@ function GetSF2LightLevel(limiter) return SF2Scalar end else return 1 end -end - ---[[ -function GetDRCColours(ent) - local tbl = {} - tbl.Player = ent:GetNWVector("PlayerColour_DRC") - tbl.Weapon = ent:GetNWVector("WeaponColour_DRC") - tbl.Eye = ent:GetNWVector("EyeTintVec") - tbl.Energy = ent:GetNWVector("EnergyTintVec") - tbl.Tint1 = ent:GetNWVector("ColourTintVec1") - tbl.Tint2 = ent:GetNWVector("ColourTintVec2") - - return tbl -end - -function DRCNotify(source, type, severity, msg, enum, time, sound) - DRC:Notify(source, type, severity, msg, enum, time, sound) -end - -function DRCSound(source, near, far, distance, listener) - if CLIENT then return end - if !IsValid(source) then return end - - DRC:EmitSound(source, near, far, distance, listener) -end ---]] - ---[[ -hook.Add( "PopulateToolMenu", "DraconicSWEPSettings", function() - spawnmenu.AddToolMenuOption( "Options", "Draconic", "SWEP Base", "SWEP Base", "", "", function( panel ) - panel:ClearControls() - local button = panel:Button("Open Menu") - function button:OnMousePressed() - drc_settings() - end - -- panel:ControlHelp( "" ) - -- panel:ControlHelp( "Server / Admin-only Settings" ) - -- panel:CheckBox( "Enable Draconic Movement", "sv_drc_movement") - -- panel:CheckBox( "Enable Draconic Movement Sounds", "sv_drc_movesounds") - -- panel:CheckBox( "Allow Call of Duty Spread", "sv_drc_callofdutyspread") - -- panel:NumSlider( "NPC Accuracy Handicap", "sv_drc_npc_accuracy", 0, 10, 1 ) - -- panel:Help( "0 = Seal Team Six" ) - -- panel:Help( "2 = HL2 Accuracy" ) - -- panel:Help( "10 = Can't hit shit." ) - -- panel:ControlHelp( "" ) - -- panel:ControlHelp( "Client Settings" ) - -- panel:NumSlider( "Viewmodel sway", "cl_drc_sway", 0, 2, 1 ) - -- panel:CheckBox( "Enable Debug HUD", "cl_drc_debugmode") - -- panel:CheckBox( "Sell your soul to Vuthakral", "cl_drc_sell_soul") - end ) - - spawnmenu.AddToolMenuOption( "Options", "Draconic", "Playermodel Extensions", "Playermodel Extensions", "", "", function( panel ) - local button2 = panel:Button("Open Menu") - function button2:OnMousePressed() - PEXMenu( LocalPlayer() ) - end - end ) -end ) - - -function drc_GetPlayerColours(ply) - DRC:GetColours(ply) -end ---]] \ No newline at end of file +end \ No newline at end of file diff --git a/lua/autorun/drc_sounds.lua b/lua/autorun/drc_sounds.lua index ef35c50..eade665 100644 --- a/lua/autorun/drc_sounds.lua +++ b/lua/autorun/drc_sounds.lua @@ -65,13 +65,13 @@ sound.Add( { volume = 0.32, level = 80, pitch = { 95, 105 }, - sound = { "weapons/bat_draw.wav", - "player/taunt_surgeons_squeezebox_draw_clothes.wav", - "weapons/melee_inspect_movement3.wav", - "weapons/melee_inspect_movement4.wav", - "weapons/movement1.wav", - "weapons/movement2.wav", - "weapons/movement3.wav" } + sound = { "draconic/foley/generic7.wav ", + "draconic/foley/generic6.wav", + "draconic/foley/generic4.wav", + "draconic/foley/generic5.wav", + "draconic/foley/generic0.wav", + "draconic/foley/generic1.wav", + "draconic/foley/generic2.wav" } } ) sound.Add( { @@ -80,102 +80,59 @@ sound.Add( { volume = 0.32, level = 80, pitch = { 95, 105 }, - sound = { "weapons/bat_draw_swoosh1.wav", - "weapons/melee_inspect_movement2.wav", - "weapons/melee_inspect_movement2.wav", - "weapons/movement1.wav", - "weapons/movement2.wav", - "weapons/movement3.wav" } + sound = { "draconic/foley/generic9.wav", + "draconic/foley/generic3.wav", + "draconic/foley/generic3.wav", + "draconic/foley/generic0.wav", + "draconic/foley/generic1.wav", + "draconic/foley/generic2.wav", + "draconic/foley/generic8.wav" } } ) sound.Add( { - name = "draconic.BladeSwingSmall", - channel = CHAN_WEAPON, - volume = 0.96, - level = 60, - pitch = { 95, 105 }, - sound = { "physics/flesh/fist_swing_01.wav", - "physics/flesh/fist_swing_02.wav", - "physics/flesh/fist_swing_03.wav", - "physics/flesh/fist_swing_04.wav", - "physics/flesh/fist_swing_05.wav", - "physics/flesh/fist_swing_06.wav" } -} ) - -sound.Add( { - name = "draconic.BladeStabSmall", - channel = CHAN_WEAPON, - volume = 0.92, - level = 80, - pitch = { 95, 105 }, - sound = { "weapons/boxing_gloves_swing1.wav", - "weapons/melee_inspect_movement2.wav", - "weapons/movement1.wav", - "weapons/movement2.wav", - "weapons/movement3.wav" } -} ) - -sound.Add( { - name = "draconic.BladeSmallHitWorld", + name = "draconic.BatteryDepleted", channel = CHAN_AUTO, - volume = 0.62, + volume = 0.47, level = 80, pitch = { 95, 105 }, - sound = { "weapons/knife/knife_hitwall1.wav", - "weapons/knife/knife_hitwall4.wav", - "weapons/knife/knife_hit_05.wav", - "weapons/knife/knife_hit_02.wav", - "weapons/knife/knife_hit_01.wav", - "weapons/knife/knife_hit_03.wav", - "weapons/knife/knife_hitwall2.wav", - "weapons/knife/knife_hitwall3.wav", - "weapons/knife/knife_hit_04.wav" } + sound = { "draconic/weapons/dry_battery.wav" } } ) sound.Add( { - name = "draconic.BladeSmallHitFlesh", + name = "draconic.EmptyGeneric", channel = CHAN_AUTO, - volume = 0.62, - level = 80, - pitch = { 95, 105 }, - sound = { "weapons/knife/knife_hit1.wav", - "weapons/knife/knife_hit2.wav", - "weapons/knife/knife_hit3.wav", - "weapons/knife/knife_hit4.wav", - "weapons/spy_assassin_knife_impact_02.wav", - "weapons/spy_assassin_knife_impact_01.wav" } + volume = 0.69, + level = 90, + pitch = { 99, 102 }, + sound = { "weapons/clipempty_pistol.wav", + "weapons/clipempty_rifle.wav" } } ) sound.Add( { - name = "draconic.BladeSmallStabFlesh", + name = "draconic.dryfire_pistol", channel = CHAN_AUTO, - volume = 0.62, + volume = 0.47, level = 80, pitch = { 95, 105 }, - sound = { "weapons/knife/knife_hit1.wav", - "weapons/knife/knife_hit2.wav", - "weapons/knife/knife_hit3.wav", - "weapons/knife/knife_hit4.wav", - "weapons/axe_hit_flesh1.wav" } + sound = { "draconic/weapons/dry_pistol.wav" } } ) sound.Add( { - name = "draconic.BatteryDepleted", + name = "draconic.dryfire_rifle", channel = CHAN_AUTO, volume = 0.47, level = 80, - pitch = { 95, 105 }, - sound = { "weapons/sniper_railgun_dry_fire.wav", - "weapons/widow_maker_dry_fire.wav" } + pitch = { 100, 105 }, + sound = { "draconic/weapons/dry_rifle.wav" } } ) sound.Add( { - name = "draconic.PewPew", - channel = CHAN_WEAPON, + name = "draconic.dryfire_heavy", + channel = CHAN_AUTO, volume = 0.47, level = 80, pitch = { 95, 105 }, - sound = { "weapons/capper_shoot.wav" } + sound = { "draconic/weapons/dry_heavy.wav" } } ) sound.Add( { @@ -238,16 +195,6 @@ sound.Add( { sound = { "weapons/barret_arm_zap.wav" } } ) -sound.Add( { - name = "draconic.EmptyGeneric", - channel = CHAN_AUTO, - volume = 0.69, - level = 90, - pitch = { 99, 102 }, - sound = { "weapons/clipempty_pistol.wav", - "weapons/clipempty_rifle.wav" } -} ) - sound.Add( { name = "draconic.vFireStopGeneric", channel = CHAN_AUTO, diff --git a/lua/draconic/cl/experimental_fp.lua b/lua/draconic/cl/experimental_fp.lua index efc7dcb..344c525 100644 --- a/lua/draconic/cl/experimental_fp.lua +++ b/lua/draconic/cl/experimental_fp.lua @@ -1,11 +1,14 @@ local function EFPChecks() - if DRC:SightsDown(LocalPlayer():GetActiveWeapon()) then return true end +-- if DRC:SightsDown(LocalPlayer():GetActiveWeapon()) then return true end if !DRC:ThirdPersonEnabled(LocalPlayer()) == true then return false else return true end end local bobang = Angle() local offsetmul = 1 +local desiredpos = Vector() +local efplerppow +local offsetlerp hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf) if GetConVar("cl_drc_experimental_fp"):GetFloat() == 1 then if EFPChecks() == true then return end @@ -16,17 +19,27 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf local pos = eyes.Pos local curswep = ply:GetActiveWeapon() + local wpn = curswep local holdtype = "default" if IsValid(curswep) then holdtype = curswep:GetHoldType() end + local insightslerp if DRC:SightsDown(curswep) == true then pos = ply:EyePos() offsetmul = 0 + efplerppow = 1 + insightslerp = 100 else pos = eyes.Pos offsetmul = 1 + efplerppow = 0.33 + insightslerp = 1 end + offsetlerp = Lerp(0.1, offsetlerp or efplerppow, efplerppow) + desiredpos = Lerp(RealFrameTime()*20*insightslerp, desiredpos or pos, pos) + pos = desiredpos + DRC.CalcView.EFP_ISPow = Lerp(RealFrameTime() * 10, DRC.CalcView.EFP_ISPow or offsetmul, offsetmul) if curswep.Draconic then @@ -57,7 +70,7 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf if wpn.Loading == false && wpn.Inspecting == false then drc_vm_lerpang = Angle(oang.x, oang.y, Lerp(RealFrameTime() * drc_vm_angmedian, drc_vm_lerpang.z or 0, 0)) else - drc_vm_lerpang = LerpAngle(FrameTime(), oang or Angle(0, 0, 0), oang) + drc_vm_lerpang = LerpAngle(RealFrameTime(), oang or Angle(0, 0, 0), oang) end drc_vm_lerppos = Vector(Lerp(RealFrameTime() * 25, 0 or pos.x, 0), Lerp(RealFrameTime() * 25, 0 or pos.y, 0), Lerp(RealFrameTime() * 25, 0 or pos.z, 0)) @@ -71,7 +84,7 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf end if sights == true or (wpn.Loading == false && wpn.Inspecting == false && wpn.Idle == 1) then - local fr = math.Round(1 / FrameTime()) + local fr = math.Round(1 / RealFrameTime()) if fr > 15 then if ply:KeyDown(IN_SPEED) or sights == true then @@ -158,6 +171,53 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf angadd:RotateAroundAxis(angadd:Forward(), angdiff.z) end + if wpn.Draconic then + local swepmul = 50 + local loading, inspecting, idle, melee, firing = wpn.PlayingLoadAnimation, wpn:GetNWBool("InspectCamLerp"), (wpn.OwnerActivity == "standidle" or wpn.OwnerActivity == "crouchidle"), wpn:GetNWBool("IsDoingMelee"), wpn.PlayingShootAnimation + local swepmuls = { + ["idle"] = math.Clamp(wpn.CameraStabilityIdle, 0.1, 5), + ["move"] = math.Clamp(wpn.CameraStabilityMove, 0.1, 5), + ["reload"] = math.Clamp(wpn.CameraStabilityReload, 0.1, 5), + ["inspect"] = math.Clamp(wpn.CameraStabilityInspect, 0.1, 5), + ["melee"] = math.Clamp(wpn.CameraStabilityMelee, 0.1, 5), + } + local angmuls = { + ["idle"] = wpn.CameraAngleMulIdle, + ["move"] = wpn.CameraAngleMulMove, + ["reload"] = wpn.CameraAngleMulReload, + ["inspect"] = wpn.CameraAngleMulInspect, + ["melee"] = wpn.CameraAngleMulMelee, + ["firing"] = wpn.CameraAngleMulFiring or wpn.CameraAngleMulIdle + } + + drc_vm_lerppos = Vector(Lerp(FrameTime() * 25, 0 or pos.x, 0), Lerp(FrameTime() * 25, 0 or pos.y, 0), Lerp(FrameTime() * 25, 0 or pos.z, 0)) + if loading == true && !firing then + local val = swepmul * swepmuls.reload + drc_vm_angmul = angmuls.reload + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif firing && !loading then + local val = swepmul * swepmuls.idle + drc_vm_angmul = angmuls.firing + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif melee == true then + local val = swepmul * swepmuls.melee + drc_vm_angmul = angmuls.melee + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif inspecting == true then + local val = swepmul * swepmuls.inspect + drc_vm_angmul = angmuls.inspect + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif !loading && !inspecting && idle then + local val = swepmul * swepmuls.idle + drc_vm_angmul = angmuls.idle + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif !loading && !inspecting && !idle then + local val = swepmul * swepmuls.move + drc_vm_angmul = angmuls.move + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + end + end + if !DRC.CalcView.Ang then DRC.CalcView.Ang = ply:EyeAngles() end if !DRC.CrosshairAngMod then DRC.CrosshairAngMod = Angle() end if DRC.CalcView.Ang && DRC.CrosshairAngMod then @@ -174,9 +234,8 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf zfar = zfar, } - if base == "mwb" then - wep:CalcView(ply, DRC.CalcView.WorldPos, DRC.CalcView.AimCorrectAngle, ply:GetFOV()) - end + if base == "mwb" then wep:CalcView(ply, DRC.CalcView.WorldPos, DRC.CalcView.AimCorrectAngle, ply:GetFOV()) end + if base == "drc" then view.angles = DRC.CalcView.AimCorrectAngle - drc_vm_lerpang_final / drc_vm_lerpdiv end local shake, shakevert, shakeroll = DRC:GetCalcViewShake() view.origin = view.origin + (view.angles:Right() * shake) @@ -188,6 +247,11 @@ hook.Add( "CalcView", "DRC_EFP_CalcView", function(ply, origin, ang, fov, zn, zf end end) +local desiredviewpos +local specialweapons = { + ["mwb"] = "cawadoody", + ["drc"] = "dragons" +} hook.Add( "CalcViewModelView", "DRC_EFP_CalcViewModelView", function(wpn, vm, oldpos, oldang, eyepos, eyeang) if GetConVar("cl_drc_experimental_fp"):GetFloat() == 1 then if EFPChecks() == true then return end @@ -198,9 +262,12 @@ hook.Add( "CalcViewModelView", "DRC_EFP_CalcViewModelView", function(wpn, vm, ol local pos = eyes.Pos local diff = ply:EyePos() - pos local newpos = eyes.Pos - local hands = ply:GetHands() local et = DRC.CalcView.Trace + local sd = DRC:SightsDown(wpn) if !DRC.CalcView.EFP_ISPow then return end + + desiredviewpos = Lerp(offsetlerp, desiredviewpos or pos, pos) + pos = desiredviewpos newpos = pos + Vector(diff.x * .1, diff.y * .1, diff.z * .1) local holdtype = wpn:GetHoldType() @@ -215,15 +282,12 @@ hook.Add( "CalcViewModelView", "DRC_EFP_CalcViewModelView", function(wpn, vm, ol ply.drcfp_walllerpval = Lerp(RealFrameTime() * 100, ply.drcfp_walllerpval or hiv, hiv) local fuck = diff * ply:GetModelScale() - diff = diff - fuck / 3 - - if wpn.Draconic == true then newpos = newpos - (diff/6) + DRC.CalcView.wallpos else pos = pos + DRC.CalcView.wallpos end - if !wpn:IsScripted() or wpn.Draconic == nil then newpos = pos - diff * .1 end + diff = diff - fuck * 0.333 if wpn.Draconic == true && GetConVar("cl_drc_lowered_crosshair"):GetFloat() == 1 then DRC.CrosshairAngMod = Angle(-10, 0, 0) - if DRC:SightsDown(wpn) then - DRC.CalcView.LoweredAng = Angle(5, 0, 0) + if sd then + DRC.CalcView.LoweredAng = Angle(6.66, 0, 0) else DRC.CalcView.LoweredAng = Angle(5, 0, 0) end @@ -231,48 +295,53 @@ hook.Add( "CalcViewModelView", "DRC_EFP_CalcViewModelView", function(wpn, vm, ol DRC.CrosshairAngMod = Angle(0, 0, 0) DRC.CalcView.LoweredAng = Angle(0, 0, 0) end - + local calcvpos, calcvang = Vector(), Angle() + local addpos = newpos - pos if IsValid(wpn) then - local special = { - ["mwb"] = "cawadoody", - ["drc"] = "dragons" - } - if base != nil && !special[base] then + if base != nil && !specialweapons[base] then calcvpos, calcvang = wpn:GetViewModelPosition(eyepos, eyeang) eyeang = (DRC.CrosshairAngMod/1.5) + calcvang + DRC.CalcView.LoweredAng - newpos = (newpos * DRC.CalcView.EFP_ISPow) + calcvpos - (ply:EyePos() * DRC.CalcView.EFP_ISPow) + newpos = (desiredpos * DRC.CalcView.EFP_ISPow) + calcvpos - (ply:EyePos() * DRC.CalcView.EFP_ISPow) + DRC.CalcView.wallpos elseif base == "drc" then DRCSwepSway(wpn, vm, oldpos, oldang, eyepos, eyeang) + DRCSwepOffset(wpn, vm) + calcvpos, calcvang = wpn:GetViewModelPosition(eyepos, eyeang) + eyeang = (DRC.CrosshairAngMod/1.5) + calcvang + DRC.CalcView.LoweredAng + newpos = (desiredpos * DRC.CalcView.EFP_ISPow) + calcvpos - (ply:EyePos() * DRC.CalcView.EFP_ISPow) + DRC.CalcView.wallpos + elseif base == "mwb" then calcvpos, calcvang = wpn:GetViewModelPosition(eyepos, eyeang) eyeang = (DRC.CrosshairAngMod/1.5) + calcvang + DRC.CalcView.LoweredAng - newpos = (newpos * DRC.CalcView.EFP_ISPow) + calcvpos - (ply:EyePos() * DRC.CalcView.EFP_ISPow) + newpos = (desiredpos * DRC.CalcView.EFP_ISPow) + DRC.CalcView.wallpos + if sd then newpos = desiredpos else newpos = desiredpos end -- This fixes ADS transitioning, do NOT ask me why I do NOT KNOW. + else + newpos = desiredpos * DRC.CalcView.EFP_ISPow + DRC.CalcView.wallpos end + newpos = Lerp(0.4, newpos or newpos, newpos) end return newpos, eyeang end end) +local CSPos +local lerppos hook.Add("Think", "DRC_ExpFP_Body", function() if GetConVar("cl_drc_experimental_fp"):GetFloat() == 0 then return end if EFPChecks() == true then return end local ply = LocalPlayer() if !IsValid(ply) then return end if !ply:Alive() then return end + local pos = ply:GetPos() + + lerppos = Lerp(RealFrameTime()*20, lerppos or pos, pos) - local CSPos = ply:GetPos() if !IsValid(ply:GetVehicle()) then - CSPos = Vector(ply:GetPos().x + DRC.CalcView.wallpos.x, ply:GetPos().y + DRC.CalcView.wallpos.y, ply:GetPos().z) + CSPos = Vector(lerppos.x + DRC.CalcView.wallpos.x, lerppos.y + DRC.CalcView.wallpos.y, lerppos.z) else CSPos = Vector(ply:GetPos()) end - local curswep = ply:GetActiveWeapon() - if curswep.Draconic && curswep.SightsDown == true then - CSPos = Vector(0,0,0) - end - if !IsValid(DRC.CSPlayerModel) then DRC.CSPlayerModel = ents.CreateClientside("drc_csplayermodel") DRC.CSPlayerModel:SetModel(LocalPlayer():GetModel()) @@ -312,7 +381,11 @@ hook.Add("Think", "DRC_ExpFP_Body", function() local spine0 = ply:LookupBone(DRC.Skel.Spine.Name) local spine1 = ply:LookupBone(DRC.Skel.Spine1.Name) local spine2 = ply:LookupBone(DRC.Skel.Spine2.Name) - local spine4 = ply:LookupBone(DRC.Skel.Spine4.Name) + local spine4 = ply:LookupBone(DRC.Skel.Spine4.Name) + + local head = ply:GetAttachment(ply:LookupAttachment("eyes")).Bone + local headbones + if head != nil then headbones = ply:GetChildBones(head) end for k,ent in pairs(parents) do ent:SetNoDraw(false) @@ -382,6 +455,47 @@ hook.Add("Think", "DRC_ExpFP_Body", function() end ent:ManipulateBoneScale(spine4, s4scale) end + else + local head = ent:GetAttachment(ply:LookupAttachment("eyes")).Bone + local head1 = ply:GetChildBones(head) + local head2 = {} + for k,v in pairs(head1) do + ent:ManipulateBoneScale(v, Vector()) + head2[k] = ply:GetChildBones(v) + end + + local lh = ply:LookupAttachment("lefthand") + if lh == 0 then lh = ply:LookupAttachment("anim_attachment_LH") end + local rh = ply:LookupAttachment("righthand") + if rh == 0 then rh = ply:LookupAttachment("anim_attachment_RH") end + lh, rh = ent:GetAttachment(lh).Bone, ent:GetAttachment(rh).Bone + local lfore, rfore = ply:GetBoneParent(lh), ply:GetBoneParent(rh) + local lupper, rupper = ply:GetBoneParent(lfore), ply:GetBoneParent(rfore) + + local lp = ply:GetBonePosition(lupper) + local movebones = {lh, rh, lfore, rfore, lupper, rupper} + for k,v in pairs(movebones) do + ent:ManipulateBoneScale(v, Vector()) + local pdiff = ent:GetBonePosition(v) - lp + ent:ManipulateBonePosition(v, pdiff) + end + + ent:ManipulateBoneScale(head, Vector(0, 0, 0)) + for k,v in pairs(head1) do head2[k] = ply:GetChildBones(v) end + for k,v in pairs(head2) do + for k2,v2 in pairs(v) do + ent:ManipulateBoneScale(v2, Vector()) + local pdiff = ent:GetBonePosition(v2) - ply:GetBonePosition(head) + ent:ManipulateBonePosition(v2, pdiff) + end + + end + end + + if headbones != nil then + for k,v in pairs(headbones) do + ent:ManipulateBoneScale(v, DRC.Skel.Neck.Scale) + end end end end) \ No newline at end of file diff --git a/lua/draconic/cl/hud.lua b/lua/draconic/cl/hud.lua index f6248bb..21cd538 100644 --- a/lua/draconic/cl/hud.lua +++ b/lua/draconic/cl/hud.lua @@ -67,7 +67,7 @@ hook.Add("HUDShouldDraw", "DRC_HideBaseCrosshairThirdperson", function(str) if IsValid(ply) then if IsValid(ply:GetActiveWeapon()) then local wpn = string.lower(ply:GetActiveWeapon():GetClass()) - if DRC.HoldTypes.HardcodedWeapons[wpn] && !IsValid(ply:GetVehicle()) && ShouldDrawHLCrosshair() then + if !IsValid(ply:GetVehicle()) && ShouldDrawHLCrosshair() then if str == "CHudCrosshair" then return false end end end @@ -75,19 +75,33 @@ hook.Add("HUDShouldDraw", "DRC_HideBaseCrosshairThirdperson", function(str) end) -local function drc_Crosshair() - if GetConVar("cl_drawhud"):GetFloat() == 0 then return end - if GetConVar("cl_drc_disable_crosshairs"):GetFloat() == 1 then return end - if DRC.SV.drc_disable_crosshairs == 1 then return end +local function CrosshairLerp(fraction, from, to) + return Lerp(math.ease.OutQuart(fraction), from, to) +end + +local function ShouldDrawCrosshair(ply) + if GetConVar("cl_drawhud"):GetFloat() == 0 then return false end + if GetConVar("crosshair"):GetFloat() == 0 then return false end + if GetConVar("cl_drc_disable_crosshairs"):GetFloat() == 1 then return false end +-- if ply:GetActiveWeapon().CrosshairStatic == nil && ply:GetActiveWeapon().CrosshairDynamic == nil then return false end + if DRC.SV.drc_disable_crosshairs == 1 then return false end + local vehicle = ply:GetVehicle() + if IsValid(vehicle) then return false end + + return true +end + +local function drc_Crosshair() local ply = LocalPlayer() if !IsValid(ply) or !ply:Alive() then return end local curswep = ply:GetActiveWeapon() if !IsValid(curswep) then return end + if !ShouldDrawCrosshair(ply) then return end -- Replace base game crosshair with a duplicate that uses the actual hitpos, for compatibility with mods that offset the view (thirdperson, first person offsets, etc). local pos = DRC.CalcView.ToScreen - if DRC.HoldTypes.HardcodedWeapons[string.lower(curswep:GetClass())] && !IsValid(ply:GetVehicle()) && pos.x && pos.y then +--[[ if DRC.HoldTypes.HardcodedWeapons[string.lower(curswep:GetClass())] && !IsValid(ply:GetVehicle()) && pos.x && pos.y then local centered = (pos.x <= ScrW()/2 + 5 && pos.x >= ScrW()/2 - 5) && (pos.y <= ScrH()/2 + 5 && pos.y >= ScrH()/2 - 5) if centered then pos.x = ScrW()/2 pos.y = ScrH()/2 end if DRC.CalcView.ToScreen && GetConVar("crosshair"):GetInt() > 0 && ShouldDrawHLCrosshair() then @@ -96,7 +110,7 @@ local function drc_Crosshair() surface.SetTextColor( 255, 211, 64, 255 ) surface.DrawText("Q") end - end + end ]] -- Actual crosshair code. if !curswep.Draconic then return end @@ -114,7 +128,7 @@ local function drc_Crosshair() Xalpha = 0 end - surface.SetFont( "DermaLarge" ) + surface.SetFont("DermaLarge") surface.SetTextColor(255, 0, 0, Xalpha) surface.SetTextPos(math.Round(pos.x), math.Round(pos.y)) surface.DrawText("X", true) @@ -180,6 +194,8 @@ local function drc_Crosshair() if curswep.Base == "draconic_melee_base" then return end if curswep.PrimaryStats == nil then return end + + local spread = (curswep.PrimaryStats.Spread * modspread) local spreaddiv = (curswep.PrimaryStats.SpreadDiv * modspreaddiv) local cx = curswep.CrosshairCorrectX @@ -188,9 +204,11 @@ local function drc_Crosshair() local smathoffset = smath * 150 local b = math.Clamp(curswep.BloomValue * 100 or 0, 0, 100) * smath * 10 + b = math.Clamp(b, 0, 100) - LerpC = Lerp(FrameTime() * 20, DRCCrosshairLerp or b, b) + LerpC = CrosshairLerp(FrameTime() * 20, DRCCrosshairLerp or b, b) DRCCrosshairLerp = Lerp(FrameTime() * 10, DRCCrosshairLerp or LerpC, LerpC) + DRCCrosshairLerp = math.Clamp(DRCCrosshairLerp, 0 , 512 * smath) if DRC:DebugModeEnabled() then if chmode == 1 or chmode == 3 then @@ -203,14 +221,14 @@ local function drc_Crosshair() surface.DrawCircle((pos.x), (pos.y), 64 * smath * 10, 255, 255, 255, 255) surface.DrawCircle((pos.x), (pos.y), 64 * smath * 13.37, 255, 0, 0, 255) - surface.DrawCircle((pos.x), (pos.y), 64 * smath * 1, 0, 255, 0, 255) + surface.DrawCircle((pos.x), (pos.y), 64 * smath, 0, 255, 0, 255) surface.DrawCircle((pos.x), (pos.y), 64 * smath * 3, 120, 255, 120, 50) surface.DrawCircle((pos.x), (pos.y), 64 * DRCCrosshairLerp / 50.75, 0, 100, 255, 255) surface.DrawCircle((pos.x), (pos.y), 64 * DRCCrosshairLerp / 52, 0, 175, 255, 255) if curswep.Primary.AimAssist == true then - surface.DrawCircle((pos.x), (pos.y), 13 * curswep.SpreadCone * curswep.Primary.AimAssist_Mul, 0, 255, 255, 255) + surface.DrawCircle((pos.x), (pos.y), 13 * curswep.SpreadCone * curswep.Primary.AimAssist_Mul * DRC:GetFOVScale(), 0, 255, 255, 255) end end end @@ -225,6 +243,7 @@ local function drc_Crosshair() else surface.SetDrawColor( ccol.r, ccol.g, ccol.b, 255 ) end + if !ShouldDrawCrosshair(ply) then surface.SetDrawColor(ccol.r, ccol.g, ccol.b, 0) end surface.SetMaterial( Material("vgui/circle") ) surface.DrawTexturedRectRotated(pos.x, pos.y, 3, 3, 0) end @@ -453,41 +472,6 @@ local function drc_Scope() end hook.Add("HUDPaint", "drc_scope", drc_Scope) -hook.Add( "GetMotionBlurValues", "drc_scopeblur", function( horizontal, vertical, forward, rotational ) - local ply = LocalPlayer() - local wpn = ply:GetActiveWeapon() - if wpn.Draconic == nil then return end - - if wpn:CanUseSights() == false then forward = 0 return forward end - - local w = ScrW() - local h = ScrH() - - local ratio = w/h - - local ss = 4 * wpn.Secondary.ScopeScale - local sw = wpn.Secondary.ScopeWidth - local sh = wpn.Secondary.ScopeHeight - - local wi = w / 10 * ss - local hi = h / 10 * ss - - if wpn.Secondary.Scoped == true && wpn.Secondary.ScopeBlur == true && wpn.SightsDown == true then - if sw != 1 then - forward = forward + (ss * 0.015 / sw) * (wpn.Secondary.IronFOV * ratio * 0.05) - else - forward = forward + (ss * 0.0175) / (wpn.Secondary.IronFOV * ratio * 0.01) - end - -- rotational = rotational + 0.05 * math.sin( CurTime() * 3 ) - end - - if wpn.SightsDown == false or wpn.IsOverheated == true then - forward = 0 - if forward > 0 then forward = 0 end - end - return horizontal, vertical, forward, rotational -end ) - @@ -558,8 +542,8 @@ DRC.Inspection.DefaultTheme = { ["Enter"] = "garrysmod/ui_return.wav", ["Exit"] = "garrysmod/ui_return.wav", ["Select"] = "weapons/smg1/switch_single.wav", - ["Deny"] = "hl1/fvox/buzz.wav", - ["Dropdown"] = "npc/headcrab_poison/ph_step4.wav" + ["Deny"] = "draconic/ui/deny0.wav", + ["Dropdown"] = "draconic/ui/click0.wav" } } DRC.Inspection.Theme = DRC.Inspection.DefaultTheme @@ -576,8 +560,8 @@ local function drc_Inspect() local ply = LocalPlayer() local wpn = ply:GetActiveWeapon() if wpn.Draconic == nil then return end - if wpn.MulIns == nil then return end local bool = wpn:GetNWBool("Inspecting", false) + local b2 = wpn.Customizing local w = ScrW() local h = ScrH() @@ -599,20 +583,21 @@ local function drc_Inspect() attalphalerp = Lerp(0.25, attalphalerp or attalpha, attalpha) if bool == true then - alpha = Lerp(wpn.MulIns, 0, 1) - YOffset = Lerp(wpn.MulIns, h/2, 0) - XOffset = Lerp(wpn.MulIns, w/2, 0) + alpha = Lerp(1, 0, 1) + YOffset = Lerp(1, h/2, 0) + XOffset = Lerp(1, w/2, 0) drc_ins_offsetlerp_x = Lerp(0.025 * 10, drc_ins_offsetlerp_x or XOffset, XOffset) drc_ins_offsetlerp_y = Lerp(0.025 * 10, drc_ins_offsetlerp_y or YOffset, YOffset) else - alpha = Lerp(wpn.MulIns, 1, 0) - YOffset = Lerp(wpn.MulIns, 0, h ) - XOffset = Lerp(wpn.MulIns, 0, w ) + alpha = Lerp(0, 1, 0) + YOffset = Lerp(1, 0, h ) + XOffset = Lerp(1, 0, w ) drc_ins_offsetlerp_x = Lerp(0.025 * 2.5, drc_ins_offsetlerp_x or w/w2/2, w/2) drc_ins_offsetlerp_y = Lerp(0.025 * 2.5, drc_ins_offsetlerp_y or h/h2/2, h/2) end + if bool == false then return end DRC.Inspection.ThemeColours = {} for k,v in pairs(themecolours) do @@ -951,6 +936,7 @@ function DRC:ToggleAttachmentMenu(wpn, b) m.Sections = {} local function MakeSection(relevancy) + if #wpn.AttachmentTable[relevancy] < 2 then return end m[relevancy] = vgui.Create("DPanel", m) m[relevancy]:SetBackgroundColor(DRC.Inspection.ThemeColours_Attachments.Background) m[relevancy]:Dock(TOP) @@ -1075,6 +1061,132 @@ function DRC:ToggleAttachmentMenu(wpn, b) if k != "BaseClass" then MakeSection(k) end end + local function MakeSkinSelection() + local relevancy = "WeaponSkin" + m[relevancy] = vgui.Create("DPanel", m) + m[relevancy]:SetBackgroundColor(DRC.Inspection.ThemeColours_Attachments.Background) + m[relevancy]:Dock(TOP) + + table.insert(m.Sections, m[relevancy]) + + local label = " | None" + m[relevancy].Title = vgui.Create("DLabel", m[relevancy]) + local title = m[relevancy].Title + title:SetSize(500, m[relevancy]:GetTall()) + title:SetText(" Camo") + title:SetFont(DRC.Inspection.Theme.Fonts.Header) + title:Dock(TOP) + + m[relevancy].Selected = vgui.Create("DLabel", m[relevancy]) + local selected = m[relevancy].Selected + selected:SetSize(400, m[relevancy]:GetTall()) + selected:SetText(label) + selected:SetFont(DRC.Inspection.Theme.Fonts.Header) + selected:SetPos(125, 0) + + m[relevancy].Collapser = vgui.Create("DButton", m[relevancy]) + local cbutton = m[relevancy].Collapser + cbutton:SetPos(0, 0) + cbutton:SetSize(m[relevancy]:GetTall(), m[relevancy]:GetTall()) + cbutton:SetFont(DRC.Inspection.Theme.Fonts.Header) + cbutton:SetTextColor(DRC.Inspection.ThemeColours_Attachments.Text) + cbutton:SetText("+") + function cbutton:Paint(w,h) + draw.RoundedBox(0, 0, 0, w, h, DRC.Inspection.ThemeColours_Attachments.Background) + end + + m[relevancy].Section = vgui.Create("DPanelSelect", m) + local selection = m[relevancy].Section + selection.Panels = {} + selection:SetPos(0, m[relevancy].Title:GetTall()) + selection:SetSize(500, 0) + selection:SetBackgroundColor(DRC.Inspection.ThemeColours_Attachments.Background) + selection:Dock(TOP) + selection:SetVisible(false) + + cbutton.DoClick = function() + if selection:IsVisible() == true then + m[relevancy].Section:SetVisible(false) + m[relevancy].Section:SetTall(0) + cbutton:SetText("+") + else + m[relevancy].Section:SetVisible(true) + m[relevancy].Section:SetTall(400) + cbutton:SetText("-") + end + for k,v in pairs(m.Sections) do + v:Dock(TOP) + end + surface.PlaySound(DRC.Inspection.Theme.Sounds.Dropdown) + end + + function selection:OnActivePanelChanged( old, new ) + if ( old != new ) then + selected:SetText(" | ".. selection[new][1] .."") + if !new[3] then + net.Start("DRC_WeaponCamoSwitch") + net.WriteEntity(wpn) + net.WriteEntity(LocalPlayer()) + net.WriteString(selection[new][3]) + net.SendToServer() + end + -- surface.PlaySound(DRC.Inspection.Theme.Sounds.Select) + end + end + + local rbutton = vgui.Create("DImageButton", m[relevancy].Section) + rbutton:SetSize(64, 64) + rbutton:SetImage("gui/cross.png") + rbutton:SetTooltip("Remove applied weapon skin/camo.") + rbutton:SetColor(Color(255, 0, 0, 127)) + selection[rbutton] = {"None", "Remove applied weapon skin/camo.", ""} + + selection:AddPanel(rbutton) + + if wpn.WeaponSkinSpecialMats != nil then + for k,v in pairs(wpn.WeaponSkinSpecialMats) do + local name, desc = v.name, v.desc + if name && desc then + m[relevancy].Section[k] = vgui.Create("DImageButton", m[relevancy].Section) + local icon = m[relevancy].Section[k] + local img = k + icon:SetMaterial(img) + icon:SetSize(64, 64) + icon:SetTooltip("".. name .."\n\n".. desc .."") + + selection.Panels[k] = {icon, name, desc} + selection[icon] = {name, desc, k} + selection:AddPanel( icon ) + end + end + end + + for k,v in SortedPairs(DRC.WeaponSkins) do + local name, desc = v.name, v.desc + if name && desc && wpn.WeaponSkinDisallowUniversals != true then + m[relevancy].Section[k] = vgui.Create("DImageButton", m[relevancy].Section) + local icon = m[relevancy].Section[k] + local img = k + if v.icon then img = v.icon end + icon:SetMaterial(img) + icon:SetSize(64, 64) + icon:SetTooltip("".. name .."\n\n".. desc .."") + + selection.Panels[k] = {icon, name, desc} + selection[icon] = {name, desc, k} + selection:AddPanel( icon ) + end + end + + if (!table.IsEmpty(DRC.WeaponSkins) or (wpn.WeaponSkinSpecialMats && !table.IsEmpty(wpn.WeaponSkinSpecialMats))) && wpn.WeaponSkinApplied != nil then + if !table.IsEmpty(selection.Panels) then + selection:SelectPanel(selection.Panels[wpn.WeaponSkinApplied][1]) + end + end + end + + if wpn.WeaponSkinSubMaterials != nil && wpn.WeaponSkinDefaultMat != nil then MakeSkinSelection() end + m.cb = vgui.Create("DButton", m) m.cb:SetText("Commit Changes") m.cb:SetPos(m:GetWide()/3.5, m:GetTall()-36) @@ -1536,7 +1648,6 @@ hook.Add("PreDrawViewModel", "DrcLerp_Debug", function( vm, ply, wpn ) for k, v in pairs(vm:GetAttachments()) do DrawVMAttachments(v.name, vm) end - local attachment = vm:LookupAttachment("muzzle") local muz = vm:GetAttachment(attachment) @@ -1547,13 +1658,15 @@ hook.Add("PreDrawViewModel", "DrcLerp_Debug", function( vm, ply, wpn ) drc_vm_offangle = Angle(0, 0, 0) + ply:EyeAngles() local offs = pos - vm:GetPos() - drc_vmapos = Lerp(FrameTime() * 25, drc_vmapos or offs, offs) + drc_vmapos = Lerp(RealFrameTime() * 25, drc_vmapos or offs, offs) local offsb = ang - vm:GetAngles() - drc_vmoffset_angle_x = math.ApproachAngle(offsb.x, drc_vm_offangle.x, FrameTime() * drc_vm_angdiff_median) - drc_vmoffset_angle_y = math.ApproachAngle(offsb.y, drc_vm_offangle.y, FrameTime() * drc_vm_angdiff_median) - drc_vmoffset_angle_z = math.ApproachAngle(offsb.z, drc_vm_offangle.z, FrameTime() * drc_vm_angdiff_median) +-- ply:ChatPrint(tostring(offsb)) + + drc_vmoffset_angle_x = math.ApproachAngle(offsb.x, drc_vm_offangle.x, 0.1 * drc_vm_angdiff_median) + drc_vmoffset_angle_y = math.ApproachAngle(offsb.y, drc_vm_offangle.y, 0.1 * drc_vm_angdiff_median) + drc_vmoffset_angle_z = math.ApproachAngle(offsb.z, drc_vm_offangle.z, 0.1 * drc_vm_angdiff_median) drc_vm_angdiff_x = math.AngleDifference(drc_vmoffset_angle_x, drc_vm_offangle.x) drc_vm_angdiff_y = math.AngleDifference(drc_vmoffset_angle_y, drc_vm_offangle.y) @@ -1563,9 +1676,14 @@ hook.Add("PreDrawViewModel", "DrcLerp_Debug", function( vm, ply, wpn ) drc_vm_angdiff_median = math.Clamp(math.abs((drc_vm_angdiff_x + drc_vm_angdiff_y + drc_vm_angdiff_z) / 3), 16, 60) - drc_vm_angmedian = Lerp(FrameTime() * 5, drc_vm_angdiff_median / (drc_vm_lerpdivval / 6) or 0, drc_vm_angdiff_median / (drc_vm_lerpdivval / 6)) + drc_vm_angmedian = Lerp(RealFrameTime() * 5, drc_vm_angdiff_median / (drc_vm_lerpdivval / 6) or 0, drc_vm_angdiff_median / (drc_vm_lerpdivval / 6)) - drc_vmaangle = (drc_vm_offangle + drc_vm_angdiff) +-- drc_vmaangle = (drc_vm_offangle + drc_vm_angdiff) +-- drc_vmaangle = drc_vmaangle * drc_vm_angmul + offsb.x = offsb.x * drc_vm_angmul.x + offsb.y = offsb.y * drc_vm_angmul.y + offsb.z = offsb.z * drc_vm_angmul.z + drc_vmaangle = offsb end) hook.Add("Tick", "DRC_PreventBrokenHUD", function() diff --git a/lua/draconic/cl/library.lua b/lua/draconic/cl/library.lua index 6d70603..03668c7 100644 --- a/lua/draconic/cl/library.lua +++ b/lua/draconic/cl/library.lua @@ -13,6 +13,9 @@ DRC.Menu = {} DRC.CurrentRPModelOptions = {} DRC.CurrentSpecialModelOptions = {} +DRC.VolumeLights = {} + +language.Add( "SniperRound_ammo", "Sniper Ammo" ) -- give a string to base-game sniper ammo since it has none if game.SinglePlayer() then if GetConVar("cl_drc_debug_alwaysshowshields") == nil then @@ -23,7 +26,10 @@ end function DRC:PlayGesture(ply, slot, gesture, b) if ply:IsValid() && ply:IsPlayer() then timer.Simple(engine.TickInterval(), function() - if IsValid(ply) then ply:AnimRestartGesture(slot, gesture, b) end + if IsValid(ply) then + ply:AnimRestartGesture(slot, gesture, b) + ply.PSXCycle = 0 + end end) end end @@ -54,25 +60,14 @@ function DRC:GetCustomizationAllowed() local gamemode = tostring(engine.ActiveGamemode()) local svtoggle = DRC.SV.drc_playerrep_disallow local svtweaktoggle = DRC.SV.drc_playerrep_tweakonly + if svtweaktoggle == "" or !svtweaktoggle then svtweaktoggle = 0 end + + if !table.IsEmpty(DRC.CurrentRPModelOptions) then return true, svtweaktoggle end - if !table.IsEmpty(DRC.CurrentRPModelOptions) then return true end - - if svtoggle == 1 then return false end - if svtweaktoggle >= 1 then return nil, svtweaktoggle end - ---[[ local allowedGMs = { - ["sandbox"] = "E", - } - local tweakGMs = { - ["darkrp"] = "E", - ["helix"] = "E", - ["cwrp"] = "E", - } + if svtoggle == 1 then return false, svtweaktoggle end + if svtweaktoggle >= 1 then return true, svtweaktoggle end - if allowedGMs[gamemode] then return true, svtweaktoggle end - if tweakGMs[gamemode] then return nil, svtweaktoggle end - if !allowedGMs[gamemode] && !tweakGMs[gamemode] then return true end ]] - return true + return true, svtweaktoggle end function DRC:DistFromLocalPlayer(pos, sqr) @@ -248,6 +243,12 @@ surface.CreateFont("ApercuStatsTitle", { outline = true }) +surface.CreateFont("DraconicSpawnMenuCategory", { + font = "Verdana", + size = 46, + weight = 0, +}) + surface.CreateFont("DripIcons_Menu", { font = "dripicons-v2", size = 16, @@ -390,6 +391,16 @@ end) hook.Add("PlayerStartVoice", "DRC_SpeakingPoseParam_MarkTrue", function(ply) if game.SinglePlayer() then return end ply.IsUsingVoice = true end) hook.Add("PlayerEndVoice", "DRC_SpeakingPoseParam_MarkFalse", function(ply) if game.SinglePlayer() then return end ply.IsUsingVoice = false end) +hook.Add("CreateClientsideRagdoll", "Draconic_FunnyPlayerCorpses_Client", function(ply, rag) + if GetConVar("sv_drc_funnyplayercorpses"):GetInt() == 1 && ply:IsPlayer() then + local rag2 = ply:GetRagdollEntity() + timer.Simple(0, function() + rag2:SetColor(Color(255, 255, 255, 0)) + rag2:SetRenderMode(RENDERMODE_TRANSCOLOR) + end) + end +end) + @@ -422,9 +433,256 @@ DRC.ThirdPerson.DefaultOffsets = { ["revolver"] = Vector(50, -25, 0), } +DRC.ThirdPerson.Presets = {} + +function DRC:ThirdPersonResetToDefault() + table.CopyFromTo(DRC.ThirdPerson.DefaultSettings, DRC.ThirdPerson.EditorSettings) + table.CopyFromTo(DRC.ThirdPerson.DefaultSettings, DRC.ThirdPerson.LoadedSettings) + RunConsoleCommand("cl_drc_thirdperson_preset", "") + + DRC:UpdateThirdPersonEditorMenu() +end + +function DRC:GetThirdPersonPresets() + local presets = file.Find("draconic/thirdperson/*.json", "DATA") + if table.IsEmpty(presets) then + file.CreateDir("draconic/thirdperson/") + file.Write("draconic/thirdperson/dummyfile.json", "This file exists solely for the Draconic Base to register this directory.") + return {"dummyfile.json"} + else + return presets + end +end + +function DRC:UpdateThirdPersonEditorMenu() + if DRC.ThirdPerson.EditorMenu != nil then + local Derma = DRC.ThirdPerson.EditorMenu + Derma.offsets:SetValue(DRC.ThirdPerson.EditorSettings.UseBaseOffsets) + Derma.freelook:SetValue(DRC.ThirdPerson.EditorSettings.AllowFreeLook) + Derma.cameraz:SetValue(DRC.ThirdPerson.EditorSettings.Height) + Derma.cameray:SetValue(DRC.ThirdPerson.EditorSettings.Length) + Derma.sliderx:SetValue(DRC.ThirdPerson.EditorSettings.Offset.X) + Derma.slidery:SetValue(-DRC.ThirdPerson.EditorSettings.Offset.Y) + Derma.sliderz:SetValue(DRC.ThirdPerson.EditorSettings.Offset.Z) + Derma.sliderfov:SetValue(DRC.ThirdPerson.EditorSettings.BaseFOV) + Derma.sliderlerppos:SetValue(DRC.ThirdPerson.EditorSettings.LerpPos) + Derma.sliderlerpang:SetValue(DRC.ThirdPerson.EditorSettings.LerpAngle) + Derma.ddorigin:SetValue(DRC.ThirdPerson.EditorSettings.BasePoint) + Derma.ddfocal:SetValue(DRC.ThirdPerson.EditorSettings.FocalPoint) + end +end + +function DRC:CreateThirdPersonPresetMenu(parent, iseditor) + if !file.Exists("draconic", "DATA") then file.CreateDir("draconic") end + if !file.Exists("draconic/thirdperson", "DATA") then file.CreateDir("draconic/thirdperson") end + + local panel = vgui.Create("DScrollPanel", parent) + panel:SetSize(parent:GetWide(), parent:GetTall()) + panel.Paint = function(self, w, h) + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end + + local SelectedPreset, SelectedPresetName + + local loadbutton = vgui.Create("DButton", panel) + loadbutton:SetSize(panel:GetWide(), 30) + loadbutton:SetPos(0, 0) + loadbutton:Dock(TOP) + loadbutton:SetText("Load selected preset") + loadbutton:SetEnabled(false) + loadbutton.DoClick = function() + table.CopyFromTo(SelectedPreset, DRC.ThirdPerson.LoadedSettings) + if iseditor == true then table.CopyFromTo(SelectedPreset, DRC.ThirdPerson.EditorSettings) DRC:UpdateThirdPersonEditorMenu() end + RunConsoleCommand("cl_drc_thirdperson_preset", SelectedPresetName) + end + + local function RefreshPresets() + local panel2 = vgui.Create("DPanel", panel) + panel2:SetSize(panel:GetWide(), panel:GetTall()) + panel2:Dock(FILL) + panel2.Paint = function(self, w, h) + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end + for k,v in pairs(DRC:GetThirdPersonPresets()) do + if v != "dummyfile.json" then + local container = vgui.Create("DPanel", panel2) + container:SetSize(panel:GetWide(), 24) + container:SetPos(0, 0) + container:Dock(TOP) + container:DockMargin(0, 0, 0, 1) + container:SetBackgroundColor(Color(0, 0, 0, 0)) + + local loadedpreset = file.Read("draconic/thirdperson/".. v .."", "DATA") + local tbl = util.JSONToTable(loadedpreset) + + local label = vgui.Create("DButton", container) + label:SetText(tbl.Name) + label:SetSize(container:GetWide(), container:GetTall()) + label:Dock(FILL) + if tbl.Name == SelectedPresetName then + label:SetEnabled(false) + end + label.DoClick = function() + SelectedPreset = tbl + SelectedPresetName = tbl.Name + label:SetEnabled(false) + loadbutton:SetEnabled(true) + panel2:Remove() + RefreshPresets() + end + + local delete = vgui.Create("DButton", container) + delete:SetSize(container:GetTall(), container:GetTall()) + delete:SetText("9") + delete:Dock(RIGHT) + delete:SetTooltip("Click to delete this preset.") + delete:SetFont("DripIcons_Menu") + function delete:Paint( w, h ) + draw.RoundedBox( 4, 0, 0, w, h, Color( 200, 50, 50 ) ) + end + + local function DeletePopup() + local Frame = vgui.Create("DFrame") + Frame:SetPos(ScrW() / 3, ScrH() / 2) + Frame:SetTitle("CONFIRMATION") + Frame:SetSize(300, 80) + Frame:MakePopup() + + local label = vgui.Create("DLabel", Frame) + label:Dock(TOP) + label:SetText("Are you sure you want to delete this thirdperson preset?") + label:SetContentAlignment(5) + + local cont = vgui.Create("DPanel", Frame) + cont:Dock(TOP) + cont:SetBackgroundColor(Color(255, 255, 255, 0)) + + local DELET = vgui.Create("DButton", cont) + DELET:Dock(LEFT) + DELET:SetText("Delete") + DELET.DoClick = function() + file.Delete("draconic/thirdperson/".. tbl.Name ..".json") + Frame:Remove() + loadbutton:SetEnabled(false) + + timer.Simple(0.1, function() + RefreshPresets() + end) + end + + local CancelCulture = vgui.Create("DButton", cont) + CancelCulture:Dock(RIGHT) + CancelCulture:SetText("Cancel") + CancelCulture.DoClick = function() + Frame:Remove() + end + end + + delete.DoClick = function() + DeletePopup() + end + + if iseditor == true then + local save = vgui.Create("DButton", container) + save:SetSize(container:GetTall(), container:GetTall()) + save:SetText(":") + save:Dock(LEFT) + save:SetTooltip("Click to overwrite this preset.") + save.name = string.gsub(v, ".json", "") + save:SetFont("DripIcons_Menu") + save:SetPaintBackground(false) + function save:Paint( w, h ) + draw.RoundedBox( 4, 0, 0, w, h, Color( 50, 200, 50 ) ) + end + + save.DoClick = function() + DRC:SaveThirdPersonPrompt(false, save.name) + RunConsoleCommand("cl_drc_thirdperson_preset", save.name) + end + end + end + end + end + RefreshPresets() +end + +function DRC:SaveThirdPersonPreset(tbl, name) + tbl.Name = name + local json = util.TableToJSON(tbl, true) + file.Write("Draconic/Thirdperson/".. name ..".json", json) +end + +function DRC:SaveThirdPersonPrompt(isnew, old) + local Frame = vgui.Create("DFrame") + Frame:SetPos(ScrW() / 2 - 300, ScrH() / 2 - 150) + Frame:SetSize(300, 80) + + if !old then + Frame:SetTitle("Enter a name for your save.") + + local SaveButton, TextBot + SaveButton = vgui.Create("DButton", Frame) + SaveButton:Dock(RIGHT) + SaveButton:SetEnabled(false) + SaveButton:SetText("[ Save ]") + SaveButton.DoClick = function() + DRC:SaveThirdPersonPreset(DRC.ThirdPerson.EditorSettings, TextBox:GetValue()) + Frame:Remove() + table.CopyFromTo(DRC.ThirdPerson.EditorSettings, DRC.ThirdPerson.LoadedSettings) + LocalPlayer():ChatPrint("Preset saved & applied.") + end + + TextBox = vgui.Create("DTextEntry", Frame) + TextBox:Dock(FILL) + TextBox:SetTabbingDisabled(true) + TextBox:SetUpdateOnType(true) + TextBox.OnValueChange = function() + local val = TextBox:GetValue() + + if val == nil then + SaveButton:SetEnabled(false) + elseif file.Exists("Draconic/Thirdperson/".. val ..".json", "DATA") then + Frame:SetTitle("Save name already in use, will override!") + else + SaveButton:SetEnabled(true) + Frame:SetTitle("Enter a name for your preset.") + end + end + else + Frame:SetTitle("OVERWRITING EXISTING PRESET.") + local label = vgui.Create("DLabel", Frame) + label:Dock(TOP) + label:SetText("Are you sure you want to overwrite this thirdperson preset?") + label:SetContentAlignment(5) + + local cont = vgui.Create("DPanel", Frame) + cont:Dock(TOP) + cont:SetBackgroundColor(Color(255, 255, 255, 0)) + + local SAVE = vgui.Create("DButton", cont) + SAVE:Dock(LEFT) + SAVE:SetText("Overwrite") + SAVE.DoClick = function() + DRC:SaveThirdPersonPreset(DRC.ThirdPerson.EditorSettings, old) + Frame:Remove() + table.CopyFromTo(DRC.ThirdPerson.EditorSettings, DRC.ThirdPerson.LoadedSettings) + LocalPlayer():ChatPrint("Preset saved & applied.") + end + + local CancelCulture = vgui.Create("DButton", cont) + CancelCulture:Dock(RIGHT) + CancelCulture:SetText("Cancel") + CancelCulture.DoClick = function() + Frame:Remove() + end + end + + Frame:MakePopup() +end + function ThirdPersonModEnabled(ply) local veh, drctpcheck5 = ply:GetVehicle(), false - if IsValid(veh) then + if IsValid(veh) && veh:GetClass() != "prop_vehicle_choreo_generic" then drctpcheck5 = veh:GetThirdPersonMode() end @@ -465,6 +723,7 @@ function DRC:ThirdPersonEnabled(ply) end function DRC:ShouldDoDRCThirdPerson(ply) + if DRC.CalcView.ThirdPerson.EditorOpen == true && DRC.SV.drc_disable_thirdperson != 1 then return true end if !IsValid(ply) then return end if pac then if pace.IsActive() == true then return false end end local curswep = ply:GetActiveWeapon() @@ -474,6 +733,7 @@ function DRC:ShouldDoDRCThirdPerson(ply) end function DRC:IsDraconicThirdPersonEnabled(ply) + if DRC.CalcView.ThirdPerson.EditorOpen == true && DRC.SV.drc_disable_thirdperson != 1 then return true end if !IsValid(ply) then return end local curswep = ply:GetActiveWeapon() if !IsValid(curswep) then @@ -535,6 +795,15 @@ net.Receive("DRC_WeaponAttachSyncInventory", function() LocalPlayer().DRCAttachmentInventory = net.ReadTable() end) +net.Receive("DRC_WeaponCamoSwitch_Sync", function() + local wpn = net.ReadEntity() + local mat = net:ReadString() + + wpn:SetCamo(mat) + +-- surface.PlaySound(DRC.Inspection.Theme.Sounds.Select) +end) + @@ -548,124 +817,165 @@ hook.Add("PlayerBindPress", "DRC_ClientsideHotkeys", function(ply, bind, pressed return true end end) -hook.Add("CalcView", "!DrcLerp", function(ply, origin, ang, fov, zn, zf) - if !IsValid(ply) then return end - if ThirdPersonModEnabled(ply) then return end - if not !game.IsDedicated() then return end - if DRC.SV.drc_viewdrag != 1 then return end - if ply:GetViewEntity() ~= ply then return end - if ply:InVehicle() then return end - +local function CalcViewChecks(ply) + if !IsValid(ply) then return false end + if ThirdPersonModEnabled(ply) then return false end +-- if game.IsDedicated() then return false end + if DRC.SV.drc_viewdrag != 1 then return false end + if ply:GetViewEntity() ~= ply then return false end + if ply:InVehicle() then return false end + local wpn = ply:GetActiveWeapon() if !IsValid(wpn) then return end - if wpn:GetClass() == "drc_camera" then return end - if wpn.Draconic == nil then return end - if wpn.IsMelee == true then return end - local vm = ply:GetViewModel() - local sights = wpn.SightsDown - - local attachment = vm:LookupAttachment("muzzle") - local pos = Vector(0, drc_vmapos.y, drc_vmapos.z) - local oang = drc_vmaangle - - if GetConVar("cl_drc_lowered_crosshair"):GetFloat() == 1 then - DRC.CrosshairAngMod = Angle(-8, 0, 0) - else - DRC.CrosshairAngMod = Angle(0, 0, 0) - end + if wpn:GetClass() == "drc_camera" then return false end + if wpn.Draconic == nil then return false end + if wpn.IsMelee == true then return false end - if sights == true or (ply:GetCanZoom() == true && ply:KeyDown(IN_ZOOM)) then - drc_vm_sightpow = Lerp(FrameTime() * 25, drc_vm_sightpow or 1, 0) - else - drc_vm_sightpow = Lerp(FrameTime() * 25, drc_vm_sightpow or 0, 1) - end - - if sights == true then - drc_vm_sightpow_inv = Lerp(FrameTime() * 25, drc_vm_sightpow_inv or 0, 1) - else - drc_vm_sightpow_inv = Lerp(FrameTime() * 25, drc_vm_sightpow_inv or 1, 0) - end - - drc_crosshair_pitchmod = Angle(wpn.Secondary.ScopePitch, 0, 0) * drc_vm_sightpow_inv - - if wpn.Loading == false && wpn.Inspecting == false then - drc_vm_lerpang = Angle(oang.x, oang.y, Lerp(FrameTime() * drc_vm_angmedian, drc_vm_lerpang.z or 0, 0)) - else - drc_vm_lerpang = LerpAngle(FrameTime(), oang or Angle(0, 0, 0), oang) - end - - drc_vm_lerppos = Vector(Lerp(FrameTime() * 25, 0 or pos.x, 0), Lerp(FrameTime() * 25, 0 or pos.y, 0), Lerp(FrameTime() * 25, 0 or pos.z, 0)) - if wpn:GetNWBool("Loading") == true then - drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or 30, 30) - elseif wpn:GetNWBool("InspectCamLerp") == true then - drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or 16, 16) - else - drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or 50, 50) - end - - if wpn.SightsDown == true or (wpn.Loading == false && wpn.Inspecting == false && wpn.Idle == 1) then - local fr = math.Round(1 / FrameTime()) + return true +end + +drc_vm_angmul = Vector() +hook.Add("CalcView", "!DrcLerp", function(ply, origin, ang, fov, zn, zf) + if CalcViewChecks(ply) == true then + local vm = ply:GetViewModel() + local wpn = ply:GetActiveWeapon() + local sights = wpn.SightsDown + + local attachment = vm:LookupAttachment("muzzle") + local pos = Vector(0, drc_vmapos.y, drc_vmapos.z) + local oang = drc_vmaangle + + if GetConVar("cl_drc_lowered_crosshair"):GetFloat() == 1 then + DRC.CrosshairAngMod = Angle(-8, 0, 0) + else + DRC.CrosshairAngMod = Angle(0, 0, 0) + end + + if sights == true or (ply:GetCanZoom() == true && ply:KeyDown(IN_ZOOM)) then + drc_vm_sightpow = Lerp(FrameTime() * 25, drc_vm_sightpow or 1, 0) + else + drc_vm_sightpow = Lerp(FrameTime() * 25, drc_vm_sightpow or 0, 1) + end + + if sights == true then + drc_vm_sightpow_inv = Lerp(FrameTime() * 25, drc_vm_sightpow_inv or 0, 1) + else + drc_vm_sightpow_inv = Lerp(FrameTime() * 25, drc_vm_sightpow_inv or 1, 0) + end - if fr > 15 then + drc_crosshair_pitchmod = Angle(wpn.Secondary.ScopePitch, 0, 0) * drc_vm_sightpow_inv + + if wpn.Loading == false && wpn.Inspecting == false then + drc_vm_lerpang = Angle(oang.x, oang.y, Lerp(FrameTime() * drc_vm_angmedian, drc_vm_lerpang.z or 0, 0)) + else + drc_vm_lerpang = LerpAngle(FrameTime(), oang or Angle(0, 0, 0), oang) + end + + local swepmul = 50 + local loading, inspecting, idle, melee, firing = wpn.PlayingLoadAnimation, wpn:GetNWBool("InspectCamLerp"), (wpn.OwnerActivity == "standidle" or wpn.OwnerActivity == "crouchidle"), wpn:GetNWBool("IsDoingMelee"), wpn.PlayingShootAnimation + local swepmuls = { + ["idle"] = math.Clamp(wpn.CameraStabilityIdle, 0.1, 5), + ["move"] = math.Clamp(wpn.CameraStabilityMove, 0.1, 5), + ["reload"] = math.Clamp(wpn.CameraStabilityReload, 0.1, 5), + ["inspect"] = math.Clamp(wpn.CameraStabilityInspect, 0.1, 5), + ["melee"] = math.Clamp(wpn.CameraStabilityMelee, 0.1, 5), + } + local angmuls = { + ["idle"] = wpn.CameraAngleMulIdle, + ["move"] = wpn.CameraAngleMulMove, + ["reload"] = wpn.CameraAngleMulReload, + ["inspect"] = wpn.CameraAngleMulInspect, + ["melee"] = wpn.CameraAngleMulMelee, + ["firing"] = wpn.CameraAngleMulFiring or wpn.CameraAngleMulIdle + } + + drc_vm_lerppos = Vector(Lerp(FrameTime() * 25, 0 or pos.x, 0), Lerp(FrameTime() * 25, 0 or pos.y, 0), Lerp(FrameTime() * 25, 0 or pos.z, 0)) + if loading == true && !firing then + local val = swepmul * swepmuls.reload + drc_vm_angmul = angmuls.reload + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif firing && !loading then + local val = swepmul * swepmuls.idle + drc_vm_angmul = angmuls.firing + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif melee == true then + local val = swepmul * swepmuls.melee + drc_vm_angmul = angmuls.melee + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif inspecting == true then + local val = swepmul * swepmuls.inspect + drc_vm_angmul = angmuls.inspect + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif !loading && !inspecting && idle then + local val = swepmul * swepmuls.idle + drc_vm_angmul = angmuls.idle + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + elseif !loading && !inspecting && !idle then + local val = swepmul * swepmuls.move + drc_vm_angmul = angmuls.move + drc_vm_lerpdivval = Lerp(FrameTime() * 5, drc_vm_lerpdivval or val, val) + end + + if wpn.SightsDown == true or (wpn.Loading == false && wpn.Inspecting == false && wpn.Idle == 1) then + local fr = math.Round(1 / FrameTime()) + if ply:KeyDown(IN_SPEED) or wpn.SightsDown == true then drc_vm_lerpang_final = Angle(0, 0, 0) else drc_vm_lerpang_final = LerpAngle(FrameTime() * drc_vm_angmedian, drc_vm_lerpang_final or Angle(0, 0, 0), drc_vm_lerpang) end else - drc_vm_lerpang_final = Angle(0, 0, 0) + drc_vm_lerpang_final = LerpAngle(FrameTime() * drc_vm_angmedian, drc_vm_lerpang_final or drc_vm_lerpang, drc_vm_lerpang) * 1 end - else - drc_vm_lerpang_final = LerpAngle(FrameTime() * drc_vm_angmedian, drc_vm_lerpang_final or drc_vm_lerpang, drc_vm_lerpang) - end - - drc_vm_lerpdiv = Lerp(FrameTime() * 5, drc_vm_lerpdivval or drc_vm_lerpdiv, drc_vm_lerpdivval) - - if wpn.IsMelee == false && !attachment then return end - - if ply:GetNW2Int("TFALean", 1337) != 1337 then - local tfaleanang = LeanCalcView(ply, origin, ang, fov) - for k, v in pairs(tfaleanang) do - if k == "origin" then - drc_calcview_tfapos = v - elseif k == "angles" then - drc_calcview_tfaang = v + + drc_vm_lerpdiv = Lerp(FrameTime() * 5, drc_vm_lerpdiv or drc_vm_lerpdivval, drc_vm_lerpdivval) + + if wpn.IsMelee == false && !attachment then return end + + if ply:GetNW2Int("TFALean", 1337) != 1337 then + local tfaleanang = LeanCalcView(ply, origin, ang, fov) + for k, v in pairs(tfaleanang) do + if k == "origin" then + drc_calcview_tfapos = v + elseif k == "angles" then + drc_calcview_tfaang = v + end end + else + drc_calcview_tfapos = ply:EyePos() + drc_calcview_tfaang = ply:EyeAngles() + end + + if ply:GetNW2Int("TFALean", 1337) != 1337 then + DRC.CalcView.Pos = drc_vm_lerppos / drc_vm_lerpdiv - ( origin - drc_calcview_tfapos) + DRC.CalcView.Ang = drc_vm_lerpang_final / drc_vm_lerpdiv - ( ang - drc_calcview_tfaang) + DRC.CrosshairAngMod * drc_vm_sightpow + -- if GetConVar("cl_drc_sway"):GetFloat() != 1 then DRC.CalcView.Ang = Angle() end + local view = { + origin = origin - drc_vm_lerppos / drc_vm_lerpdiv - ( origin - drc_calcview_tfapos), + angles = ang - DRC.CalcView.Ang, + fov = fov + } + return view + else + DRC.CalcView.Pos = drc_vm_lerppos / drc_vm_lerpdiv + DRC.CalcView.Ang = drc_crosshair_pitchmod - drc_vm_lerpang_final / drc_vm_lerpdiv + DRC.CrosshairAngMod * drc_vm_sightpow + -- if GetConVar("cl_drc_sway"):GetFloat() != 1 then DRC.CalcView.Ang = Angle() end + local view = { + origin = origin - drc_vm_lerppos / drc_vm_lerpdiv, + angles = ang + DRC.CalcView.Ang, + fov = fov + } + return view end - else - drc_calcview_tfapos = ply:EyePos() - drc_calcview_tfaang = ply:EyeAngles() - end - - if ply:GetNW2Int("TFALean", 1337) != 1337 then - DRC.CalcView.Pos = drc_vm_lerppos / drc_vm_lerpdiv - ( origin - drc_calcview_tfapos) - DRC.CalcView.Ang = drc_vm_lerpang_final / drc_vm_lerpdiv - ( ang - drc_calcview_tfaang) + DRC.CrosshairAngMod * drc_vm_sightpow - -- if GetConVar("cl_drc_sway"):GetFloat() != 1 then DRC.CalcView.Ang = Angle() end - local view = { - origin = origin - drc_vm_lerppos / drc_vm_lerpdiv - ( origin - drc_calcview_tfapos), - angles = ang - DRC.CalcView.Ang, - fov = fov - } - return view - else - DRC.CalcView.Pos = drc_vm_lerppos / drc_vm_lerpdiv - DRC.CalcView.Ang = drc_crosshair_pitchmod - drc_vm_lerpang_final / drc_vm_lerpdiv + DRC.CrosshairAngMod * drc_vm_sightpow - -- if GetConVar("cl_drc_sway"):GetFloat() != 1 then DRC.CalcView.Ang = Angle() end - local view = { - origin = origin - drc_vm_lerppos / drc_vm_lerpdiv, - angles = ang + DRC.CalcView.Ang, - fov = fov - } - return view end end) function DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) - if wpn.Draconic then + if IsValid(wpn) && wpn.Draconic then local ply = wpn:GetOwner() if IsValid(ply) then - if ply:Alive() then + if ply:Alive() && ogpos != nil && ogang != nil then local calcpos, calcang = wpn:GetViewModelPosition(ogpos, ogang) local newpos, newang = calcpos, calcang if calcpos && calcang && newpos && newang then @@ -717,12 +1027,13 @@ function DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) end end - rollval_lerp = Lerp(0.06, rollval_lerp or rollval, rollval) - drc_xval_lerp = Lerp(0.1, drc_xval_lerp or xval, xval) - drc_yval_lerp = Lerp(0.1, drc_yval_lerp or yval, yval) + local rft = RealFrameTime() + rollval_lerp = Lerp(rft*5, rollval_lerp or rollval, rollval) + drc_xval_lerp = Lerp(rft*10, drc_xval_lerp or xval, xval) + drc_yval_lerp = Lerp(rft*10, drc_yval_lerp or yval, yval) rollval_lerp = rollval_lerp * sightkill local vel = math.Clamp(ply:GetVelocity():LengthSqr()*0.00005, 0, 4) - drc_vel_lerp = Lerp(0.1, drc_vel_lerp or vel, vel) + drc_vel_lerp = Lerp(rft*10, drc_vel_lerp or vel, vel) if wpn.ShouldWalkBlend == false then drc_xval_lerp = Lerp(0.5, drc_xval_lerp or 0, 0) @@ -738,7 +1049,7 @@ function DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) local holdang = LocalPlayer():EyeAngles() wpn.dang = LerpAngle((wpn.SS/15), wpn.dang, holdang - wpn.oang) - if RealTime() > wpn.LLTime + (RealFrameTime() * 0.001) then + if RealTime() > wpn.LLTime + (FrameTime() * 0.001) then wpn.LLTime = RealTime() wpn.oang = LocalPlayer():EyeAngles() wpn.dang = wpn.dang * sightkill @@ -748,10 +1059,7 @@ function DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) -- if GetConVar("cl_drc_sway"):GetInt() < 1 then wpn.dang = Angle(0, 0, 0) end local dynang = Angle(wpn.dang.x * -wpn.SS/1.25, wpn.dang.y * wpn.SS/2, wpn.dang.z + rollval_lerp)*2 - - newang:RotateAroundAxis(ang:Right(), dynang.x) - newang:RotateAroundAxis(ang:Up(), dynang.y) - newang:RotateAroundAxis(ang:Forward(), dynang.z) + newpos:Add(ang:Right() * dynang.y*wpn.SS/6) -- newpos:Add(ang:Forward() * dynang.y) newpos:Add(ang:Up() * -dynang.x*wpn.SS/6) @@ -763,8 +1071,192 @@ function DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) end end +local sprpos, sprang, sprposlerp, spranglerp = Vector(), Vector(), Vector(), Vector() +local passpos, passang, passposlerp, passanglerp = Vector(), Vector(), Vector(), Vector() +local inspos, insang, insposlerp, insanglerp = Vector(), Vector(), Vector(), Vector() +local crpos, crang, crposlerp, cranglerp = Vector(), Vector(), Vector(), Vector() +local irpos, irang, irposlerp, iranglerp = Vector(), Vector(), Vector(), Vector() +local lerppower = 7 +local bump, bumpang = Vector(), Vector() + +local function Bump(pos, ang, thyme) + bump = pos + bumpang = ang + timer.Simple(thyme * 0.05, function() bump = pos*0.8 bumpang = ang*0.8 end) + timer.Simple(thyme * 0.075, function() bump = pos*0.6 bumpang = ang*0.6 end) + timer.Simple(thyme * 0.1, function() bump = pos*0.4 bumpang = ang*0.4 end) + timer.Simple(thyme * 0.125, function() bump = pos*0.2 bumpang = ang*0.2 end) + timer.Simple(thyme * 0.15, function() bump = Vector() bumpang = Vector() end) -- I'm lazy and it works, I'll rewrite it into a proper queue later. +end + +local osd = false +local oins = false +local opas = false +local onehand = { "pistol", "slam", "magic" } +local twohand = { "smg", "ar2", "shotgun", "crossbow", "camera", "revolver" } +local dualtypes = { "duel" } +local lowtypes = { "physgun" } +local hightypes = { "rpg" } +local meleetypes = { "melee", "knife", "grenade", "slam" } +local meleetwohand = { "melee2" } +local handguns = { "pistol", "revolver" } + +function DRCSwepOffset(wpn, vm) + if !wpn.Draconic then return end + local ply = LocalPlayer() + local DrcGlobalVMOffset = Vector(GetConVar("cl_drc_vmoffset_x"):GetFloat(), GetConVar("cl_drc_vmoffset_y"):GetFloat(), GetConVar("cl_drc_vmoffset_z"):GetFloat()) + + local offs = { + ["null"] = {Vector(), Vector()}, + ["base"] = {wpn.VMPos, wpn.VMAng}, + ["crouch"] = {wpn.VMPosCrouch or wpn.VMPos, wpn.VMAngCrouch or wpn.VMAng}, + ["iron"] = {wpn.VARSightPos, wpn.VARSightAng}, + ["sprint"] = {wpn.SprintPos or wpn.PassivePos, wpn.SprintAng or wpn.PassiveAng}, + ["passive"] = {wpn.PassivePos, wpn.PassiveAng}, + ["inspect"] = {wpn.InspectPos, wpn.InspectAng}, + } + + local cv = ply:Crouching() + local ea = ply:EyeAngles() + local sd = wpn.SightsDown + local sk = ply:KeyDown(IN_SPEED) + local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) + local sprint = sk && mk && (wpn.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1) + local passive = wpn:GetNWBool("Passive", false) && DRC.SV.drc_passives >= 1 + local inspect = wpn:GetNWBool("Inspecting") && DRC.SV.drc_inspections >= 1 + lerppower = FrameTime() * 7 + if DRC.SV.drc_force_sprint == 2 then sprint = false end + + if sprint then passive = false end + + local mul2 = 1 + if cv && !sd then offs.base = offs.crouch mul2=0.25 end + + if sprint then sprpos = offs.sprint[1] + offs.base[1] sprang = offs.sprint[2] + offs.base[2] + else sprpos = offs.base[1] sprang = offs.base[2] end + if !sprpos or !sprang then return end + sprposlerp = LerpVector(lerppower*mul2, sprposlerp or sprpos, sprpos) + spranglerp = LerpVector(lerppower*0.75*mul2, spranglerp or sprang, sprang) + + if opas != passive then + opas = passive + if passive == true then Bump(Vector(0, 0, 0.5), Vector(-2, 0, 2), 2) end + if passive == false then Bump(Vector(0, 0, 1), Vector(2, 0, 5), 3) end + end + + if passive then passpos = offs.passive[1] + bump passang = offs.passive[2] + bumpang + else passpos = offs.null[1] passang = offs.null[2] end + if !passpos or !passang then return end + passposlerp = LerpVector(lerppower*0.4, passposlerp or passpos, passpos) + passanglerp = LerpVector(lerppower*0.6, passanglerp or passang, passang) + + if oins != inspect then + oins = inspect + if inspect == true then Bump(Vector(0, 0, 0.5), Vector(-2, 0, 2), 2) end + if inspect == false then Bump(Vector(0, 0, 1), Vector(2, 0, 5), 3) end + end + + if inspect then inspos = offs.inspect[1] + bump insang = offs.inspect[2] + bumpang + else inspos = offs.null[1] insang = offs.null[2] end + if !inspos or !insang then return end + insposlerp = LerpVector(lerppower*0.7, insposlerp or inspos, inspos) + insanglerp = LerpVector(lerppower*0.5, insanglerp or insang, insang) + + local POX = (ea.x / 135) + local POY = (ea.x / 100 * 5) + local POZ = (ea.x / -45) + local AOX = (ea.x / 30) + + wpn.VAPos = Vector(POX, POY, POZ) + wpn.VAAng = Vector(AOX, 0, 0) + + wpn.VARPos = LerpVector(wpn.MulI, -wpn.VMPos / 255, wpn.VAPos ) * math.Clamp(wpn.PerspectivePower, 0, 1) + wpn.VARAng = LerpVector(wpn.MulI, Vector(0, 0, 0), wpn.VAAng ) * math.Clamp(wpn.PerspectivePower, 0, 1) + + wpn.DownCorrectionPos = Vector() + wpn.DownCorrectionAng = Vector() + wpn.DownCorrectionAng.z = wpn.DownCorrectionAng.z - (ea.x / 10) * math.Clamp(wpn.PerspectivePower, 0, 1) + wpn.DownCorrectionAng.z = math.Clamp(wpn.DownCorrectionAng.z, -10, 2) * math.Clamp(wpn.PerspectivePower, 0, 1) + wpn.DownCorrectionAng.y = wpn.DownCorrectionAng.y + math.abs(ea.x / 90) * math.Clamp(wpn.PerspectivePower, 0, 1) + + local eyepos = ply:EyePos() + + local walloffset, heft = {}, 10 + if CTFK(handguns, wpn:GetHoldType()) then + heft = 10 + walloffset = { + Vector(-2, -5, 1), + Vector(0, 0, 0), + } + elseif CTFK(meleetwohand, wpn:GetHoldType()) then + heft = 3 + walloffset = { + Vector(2, -5, -3), + Vector(25, -7.5, -15), + } + else + heft = 5 + walloffset = { + Vector(2, -5, -1), + Vector(5, 6, 0), + } + end + if wpn.NearWallPos then walloffset[1] = wpn.NearWallPos end + if wpn.NearWallAng then walloffset[2] = wpn.NearWallAng end + + local aids = ply:GetEyeTrace().HitPos + local hiv = math.Round(ply:EyePos():Distance(aids)) + hiv = math.Clamp(hiv, 0, 50) / 50 + hiv = 1 - hiv + wpn.walllerpval = Lerp((0.008) * heft, wpn.walllerpval or hiv, hiv) * math.Clamp(wpn.NearWallPower, 0, 1) + local wallpos = Lerp(wpn.walllerpval, Vector(), walloffset[1]) + local wallang = Lerp(wpn.walllerpval, Vector(), walloffset[2]) + + wpn.VARPos = wpn.VARPos + wpn.DownCorrectionPos + wallpos + wpn.VARAng = wpn.VARAng + wpn.DownCorrectionAng + wallang + + if osd != sd then + osd = sd + if sd == true then Bump(Vector(-2.5, 0, -1), Vector(0, -5, -15), 1) end + end + + if sd then irpos = offs.iron[1] - offs.base[1] + bump irang = offs.iron[2] - offs.base[2] + bumpang + else irpos = offs.null[1] + bump + DrcGlobalVMOffset + wpn.VARPos irang = offs.null[2] + bumpang + wpn.VARAng end + if !irpos or !irang then return end + irposlerp = LerpVector(lerppower*1.5, irposlerp or irpos, irpos) + iranglerp = LerpVector(lerppower, iranglerp or irang, irang) + + local angpos + if wpn.Sway_IsShouldered == true then + local mul = wpn.Sway_OffsetPowerPos + local x = -wpn.dynmove.Ang.y*0.15 * mul.x + local y = math.abs(wpn.dynmove.Ang.x*0.25) * mul.y + local z = wpn.dynmove.Ang.x*0.25 * mul.z + angpos = Vector(x, y, z) + else + local mul = wpn.Sway_OffsetPowerPos + local x = wpn.dynmove.Ang.y*0.15 * mul.x + local y = math.abs(wpn.dynmove.Ang.x*0.25) * mul.y + local z = -wpn.dynmove.Ang.x*0.25 * mul.z + angpos = Vector(x, y, z) + end + angpos = angpos + + local finalpos = sprposlerp + passposlerp + insposlerp + irposlerp + angpos + local finalang = spranglerp + passanglerp + insanglerp + iranglerp + local dynang = Vector(wpn.dynmove.Ang.x, wpn.dynmove.Ang.y, wpn.dynmove.Ang.z) + dynang.x = dynang.x * wpn.Sway_OffsetPowerAng.x + dynang.y = dynang.y * wpn.Sway_OffsetPowerAng.y + dynang.z = dynang.z * wpn.Sway_OffsetPowerAng.z + finalang = finalang + dynang + + wpn.DynOffsetPos = finalpos + wpn.DynOffsetAng = finalang +end + hook.Add("CalcViewModelView", "DRC_SWEP_Effects", function(wpn, vm, ogpos, ogang, pos, ang) DRCSwepSway(wpn, vm, ogpos, ogang, pos, ang) + DRCSwepOffset(wpn, vm) --[[ if LocalPlayer():GetInfoNum("cl_drc_testvar_0", 0) == 1 then local function Ease(fr, f, t) @@ -844,7 +1336,6 @@ hook.Add("CalcViewModelView", "DRC_SWEP_Effects", function(wpn, vm, ogpos, ogang newpos:Add(ang:Up() * bob.z) end --]] -- return newpos, newang - end) @@ -856,17 +1347,28 @@ concommand.Add("draconic_menu", function() DRCMenu(LocalPlayer()) end) -concommand.Add("draconic_thirdperson_toggle", function() - DRC.CalcView.ThirdPerson.Ang = LocalPlayer():EyeAngles() - DRC.CalcView.ThirdPerson.Ang_Stored = LocalPlayer():EyeAngles() - DRC.CalcView.ThirdPerson.DirectionalAng = LocalPlayer():EyeAngles() - DRC:ThirdPerson_PokeLiveAngle(LocalPlayer()) +local function ToggleThird() + local ply = LocalPlayer() + DRC.CalcView.ThirdPerson.LerpedFinalPos = ply:EyePos() + DRC.CalcView.ThirdPerson.Pos = ply:EyePos() + DRC.CalcView.ThirdPerson.Ang = ply:EyeAngles() + DRC.CalcView.ThirdPerson.Ang_Stored = ply:EyeAngles() + DRC.CalcView.ThirdPerson.DirectionalAng = ply:EyeAngles() + DRC:ThirdPerson_PokeLiveAngle(ply) if GetConVar("cl_drc_thirdperson"):GetFloat() == 0 then RunConsoleCommand("cl_drc_thirdperson", 1) else RunConsoleCommand("cl_drc_thirdperson", 0) end +end + +concommand.Add("draconic_thirdperson", function() + ToggleThird() +end) + +concommand.Add("draconic_thirdperson_toggle", function() + ToggleThird() end) concommand.Add("draconic_thirdperson_swapshoulder", function() @@ -877,6 +1379,11 @@ concommand.Add("draconic_thirdperson_swapshoulder", function() end end) +concommand.Add("draconic_thirdperson_openeditor", function() + local ply = LocalPlayer() + DRC:OpenThirdpersonEditor(ply) +end) + concommand.Add("draconic_firstperson_toggle", function() if GetConVar("cl_drc_experimental_fp"):GetFloat() == 0 then RunConsoleCommand("cl_drc_experimental_fp", 1) @@ -912,7 +1419,9 @@ DRC.Debug = {} local drc_frame = 0 local drc_framesavg = 0 local function drc_DebugUI() - if !LocalPlayer():Alive() then return end + local ply = LocalPlayer() + if !IsValid(ply) then return end + if !ply:Alive() then return end if DRC.SV.drc_allowdebug == 0 then return end if GetConVar("cl_drawhud"):GetFloat() == 0 then return end if GetConVar("cl_drc_debugmode"):GetFloat() == 0 then return end @@ -922,6 +1431,7 @@ local function drc_DebugUI() end local hp, maxhp, ent = DRC:GetShield(LocalPlayer()) + local over = math.Round(DRC:GetOverShield(LocalPlayer()) or 0, 2) local tps = 694201337 if game.SinglePlayer() then @@ -933,7 +1443,7 @@ local function drc_DebugUI() tps = math.floor(tps) drcshieldinterp = Lerp(RealFrameTime() * 25, drcshieldinterp or hp, hp) - draw.DrawText( "Shield: ".. tostring(math.Round(drcshieldinterp)) .."/".. maxhp .."", "TargetID", ScrW() * 0.02, ScrH() * 0.875, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "Shield: ".. tostring(math.Round(drcshieldinterp)) .."/".. maxhp .." +".. over .."", "TargetID", ScrW() * 0.02, ScrH() * 0.875, color_white, TEXT_ALIGN_LEFT ) draw.DrawText( "FPS: ".. drc_framesavg .." | ".. math.Round(1/RealFrameTime()) .."", "TargetID", ScrW() * 0.02, ScrH() * 0.855, color_white, TEXT_ALIGN_LEFT ) draw.DrawText( "TPS: ".. tps .." | ".. math.floor(1/engine.TickInterval()) .."", "TargetID", ScrW() * 0.02, ScrH() * 0.835, color_white, TEXT_ALIGN_LEFT ) @@ -943,11 +1453,29 @@ local function drc_DebugUI() local ammo, maxammo = curswep:Clip1(), curswep:GetMaxClip1() if curswep.Draconic == true then + local vm = draw.DrawText( "".. ammo .."(".. math.Round(curswep:GetNWInt("LoadedAmmo"), 4) ..")/".. maxammo .." | Ammo", "TargetID", ScrW() * 0.975, ScrH() * 0.855, color_white, TEXT_ALIGN_RIGHT ) draw.DrawText( "".. math.Round(curswep:GetHeat(), 4) .."% | Heat", "TargetID", ScrW() * 0.975, ScrH() * 0.855+24, color_white, TEXT_ALIGN_RIGHT ) draw.DrawText( "".. curswep.Category .." - ".. curswep:GetPrintName() .."", "TargetID", ScrW() * 0.975, ScrH() * 0.855-24, color_white, TEXT_ALIGN_RIGHT ) draw.DrawText( "".. curswep.OwnerActivity .."", "TargetID", ScrW() * 0.5, ScrH() * 0.8 + 24, color_white, TEXT_ALIGN_CENTER ) + draw.DrawText( "drc_movement: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_movement"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 48, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_move_x: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_move_x"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 60, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_move_y: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_move_y"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 72, color_white, TEXT_ALIGN_LEFT ) + + draw.DrawText( "drc_ammo: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_ammo"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 94, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_emptymag: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_emptymag"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 106, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_heat: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_heat"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 118, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_battery: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_battery"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 130, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_charge: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_charge"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 142, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "drc_health: ".. math.Round(ply:GetViewModel():GetPoseParameter("drc_health"), 2) .."", "DermaDefault", 32, ScrH() * 0.5 + 166, color_white, TEXT_ALIGN_LEFT ) + + draw.DrawText( "Loading: ".. tostring(curswep.Loading) .."", "DermaDefault", 32, ScrH() * 0.5 + 190, color_white, TEXT_ALIGN_LEFT ) + + draw.DrawText( "Firing Anim: ".. tostring(curswep.PlayingShootAnimation) .."", "DermaDefault", 32, ScrH() * 0.5 + 214, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "Loading Anim: ".. tostring(curswep.PlayingLoadAnimation) .."", "DermaDefault", 32, ScrH() * 0.5 + 226, color_white, TEXT_ALIGN_LEFT ) + draw.DrawText( "Inspect Anim: ".. tostring(curswep:GetNWBool("InspectCamLerp")) .."", "DermaDefault", 32, ScrH() * 0.5 + 238, color_white, TEXT_ALIGN_LEFT ) + local col1 = Color(255, 255, 255, 175) local col2 = Color(255, 255, 255, 75) local posx, posy = ScrW() * 0.94, ScrH() * 0.73 @@ -1047,10 +1575,11 @@ local function drc_TraceInfo() surface.DrawText(tostring("".. hp .." / ".. maxhp .."")) local shp, smhp, sent = DRC:GetShield(ent) + local over = math.Round(DRC:GetOverShield(ent) or 0, 2) if IsValid(sent) then surface.SetTextPos(pos.x - pos.x/2.6, pos.y + 32) surface.SetTextColor(0, 200, 255) - surface.DrawText(tostring("".. math.Round(shp) .." / ".. smhp .."")) + surface.DrawText(tostring("".. math.Round(shp) .." / ".. smhp .." +".. over .."")) end end @@ -1251,6 +1780,16 @@ hook.Add("PostDrawTranslucentRenderables", "drc_DebugStuff", function() end end) +hook.Add("PostDrawTranslucentRenderables", "DRC_LightVolumeRendering", function() + if GetConVar("cl_drc_debugmode"):GetFloat() > 0 && GetConVar("cl_drc_debug_lights"):GetFloat() == 1 && DRC:DebugModeAllowed() then + for k,v in pairs(DRC.VolumeLights) do + local pos, ang, length, width, col, ent, light = v[1], v[2], v[3], v[4]*10, v[5], v[6], v[7] + if light.AddAng then ang = ang + light.AddAng end + render.DrawWireframeBox(pos, ang, Vector(0, width, width), Vector(length, -width, -width), Color(col.r, col.g, col.b, 1), true) + end + end +end) + net.Receive("DRC_RenderTrace", function() local tbl = net.ReadTable() if !tbl then return end @@ -1260,6 +1799,15 @@ net.Receive("DRC_RenderTrace", function() DRC:RenderTrace(tr, colour, thyme) end) +net.Receive("DRC_RenderSphere", function() + local tbl = net.ReadTable() + if !tbl then return end + local origin, radius, colour, thyme = tbl[1], tbl[2], tbl[3], tbl[4] + if isstring(colour) then colour = DRC.Cols[colour] end + + DRC:RenderSphere(origin, radius, colour, thyme) +end) + function DRC:RenderTrace(tr, colour, thyme) if GetConVar("cl_drc_debug_tracelines"):GetFloat() != 1 then return end if !tr then return end @@ -1270,6 +1818,30 @@ function DRC:RenderTrace(tr, colour, thyme) timer.Simple(thyme, function() DRC.Debug.TraceLines[id] = nil end) end +function DRC:RenderSphere(origin, radius, colour, thyme) + if DRC:DebugModeAllowed() && GetConVar("cl_drc_debugmode"):GetFloat() != 1 then return end + if !DRC:DebugModeAllowed() then return end + radius = radius*0.19 + + if !gui.IsGameUIVisible() then + local csent1 = ClientsideModel("models/dav0r/hoverball.mdl") + local csent2 = ClientsideModel("models/dav0r/hoverball.mdl") + csent1:SetMaterial("models/wireframe") + csent2:SetMaterial("models/debug/debugwhite") + csent1:SetPos(origin) + csent2:SetPos(origin) + csent1:SetRenderMode(RENDERMODE_TRANSCOLOR) + csent2:SetRenderMode(RENDERMODE_TRANSCOLOR) + csent1:SetColor(colour) + csent2:SetColor(colour) + csent1:SetModelScale(radius) + csent2:SetModelScale(radius) + csent1:Spawn() + csent2:Spawn() + timer.Simple(thyme, function() csent1:Remove() csent2:Remove() end) + end +end + function DRC:IDLight(pos, colour, size, colmul, thyme) if GetConVar("cl_drc_debug_lights"):GetFloat() != 1 then return end local id = math.Round(math.Rand(1, 999999999)) diff --git a/lua/draconic/cl/menu.lua b/lua/draconic/cl/menu.lua index 4bc84b3..0e008b3 100644 --- a/lua/draconic/cl/menu.lua +++ b/lua/draconic/cl/menu.lua @@ -8,31 +8,27 @@ local function GreyOut(element) element.GreyOut:SetBackgroundColor(Color(127,127,127,127)) end +local ind = { + [1]=32, + [2]=48, + [3]=64, + [4]=72, + [5]=94, + [6]=128, +} function DRCMenu( player ) - local ply = player + local ply = player local VSelection = ply:GetNWString("DRCVoiceSet") local FSelection = ply:GetNWString("DRCFootsteps") - local Customization, TweakMode = DRC:GetCustomizationAllowed() - + local Customization, TweakMode = true, 0 + Customization, TweakMode = DRC:GetCustomizationAllowed() + local usekey = string.upper(ReturnKey("+use")) local m1key = string.upper(ReturnKey("+attack")) local m2key = string.upper(ReturnKey("+attack2")) - local m3key = string.upper(ReturnKey("+attack3")) local sprintkey = string.upper(ReturnKey("+speed")) - local duckkey = string.upper(ReturnKey("+duck")) - local jumpkey = string.upper(ReturnKey("+jump")) local reloadkey = string.upper(ReturnKey("+reload")) local forwkey = string.upper(ReturnKey("+forward")) - local alt1key = string.upper(ReturnKey("+alt1")) - local alt2key = string.upper(ReturnKey("+alt2")) - - local w2 = ScrW()/2 - local leftwide = w2 - local leftwidehalf = leftwide / 2 - - local h2 = ScrH() - local topwide = h2 - local topwidehalf = topwide / 2 local TextCol = Color(220, 220, 220, 255) local SubtextCol = Color(170, 170, 170, 255) @@ -54,58 +50,120 @@ function DRCMenu( player ) draw.RoundedBox(5, 0, 0, 16, 16, Color(157,161,165)) end end - - local Derma = vgui.Create("DFrame") - Derma:SetPos( leftwidehalf/1.25, topwidehalf/4 ) - Derma:SetSize( 1200, 720) - Derma:SetTitle("Draconic Menu") + + local Derma = vgui.Create("DFrame") + Derma:SetSize(1200, 720) + Derma:SetMinWidth(1200) + Derma:SetMinHeight(720) + Derma:SetSizable(false) + Derma:SetTitle("Draconic Menu") Derma:SetIcon("icon16/draconic_base.png") Derma:MakePopup() + Derma:SetDraggable(true) Derma:SetBackgroundBlur(true) Derma:SetScreenLock(false) - Derma.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 200)) - end + Derma:ShowCloseButton(true) + Derma:Center() + Derma:SetVisible(true) + Derma.Paint = function(self, w, h) + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 200)) + end local windowwide = Derma:GetWide() local windowtall = Derma:GetTall() + local windowwidehalf = windowwide * 0.5 + + local function RefreshIcons(isfullscreen, exactoverride) + local size = GetConVar("cl_drc_menu_iconsize"):GetInt() + if isfullscreen then size = GetConVar("cl_drc_menu_iconsize_fullscreen"):GetInt() end + if exactoverride then size = exactoverride end + + for k,v in pairs(Derma.PlayerModels:GetItems()) do + v:SetSize(ind[size],ind[size]) + end + for k,v in pairs(Derma.PlayerModels_Hands:GetItems()) do + v:SetSize(ind[size],ind[size]) + end + Derma.PlayerModels:InvalidateLayout() + Derma.PlayerModels_Hands:InvalidateLayout() + end - local mainframe = vgui.Create("DPanel", Derma) + timer.Simple(0.1, function() + RefreshIcons() + end) + + local maximized = false + Derma.btnMaxim:SetEnabled( true ) + Derma.btnMaxim.DoClick = function() + if maximized == false then + Derma:SetSize(ScrW(), ScrH()) + Derma:Center() + Derma:SetDraggable(false) + maximized = true + + Derma.PlayerFrame1:SetWide(ScrW()*0.5) + Derma.PlayerApplyButton:SetPos(Derma.PlayerFrame1:GetWide()*0.5 - 64,10) + local spraymax = math.Clamp(windowwidehalf, windowwidehalf, 1024) + Derma.SprayPreview:SetSize(spraymax, spraymax) + Derma.SprayPreview:Dock(NODOCK) + + RefreshIcons(true) + elseif maximized == true then + Derma:SetSize(1200,720) + Derma:Center() + Derma:SetDraggable(true) + maximized = false + + Derma.PlayerFrame1:SetWide(windowwide*0.5) + Derma.PlayerApplyButton:SetPos(230,10) + Derma.SprayPreview:SetSize(320, 320) + Derma.SprayPreview:Dock(FILL) + + RefreshIcons(false) + end + end + + Derma.mainframe = vgui.Create("DPanel", Derma) + local mainframe = Derma.mainframe mainframe:Dock(FILL) mainframe:DockMargin(0, 0, 0, 0) mainframe:DockPadding(0, 0, 0, 0) mainframe:SetPaintBackground(false) - local maintabs = vgui.Create( "DPropertySheet", mainframe ) + Derma.maintabs = vgui.Create( "DPropertySheet", mainframe ) + local maintabs = Derma.maintabs maintabs:Dock(FILL) maintabs:DockMargin(0, 0, 0, 0) maintabs:DockPadding(0, 0, 0, 0) maintabs:SetPadding(0) maintabs.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end - local mt1 = vgui.Create( "DPanel", maintabs ) + mainframe.maintabs = vgui.Create( "DPanel", maintabs ) + local mt1 = mainframe.maintabs mt1:DockMargin(0, 0, 0, 0) mt1:DockPadding(0, 0, 0, 0) mt1:SetBackgroundColor(Color(255, 255, 255, 0)) maintabs:AddSheet( "Player Representation", mt1, "icon16/user.png") - - local frame = vgui.Create("DPanel", mt1) - frame:SetSize(590, 658) + + Derma.PlayerFrame1 = vgui.Create("DPanel", mt1) + local frame = Derma.PlayerFrame1 + frame:SetWide(windowwide*0.5) frame:Dock(LEFT) frame:DockPadding(0, 0, 0, 0) --- frame:SetSize(512, topwide/1.5-24) - frame:SetBackgroundColor(Color(255, 255, 255, 5)) - - local frame2 = vgui.Create("DPanel", mt1) - frame2:SetPos(windowwide/2, 0) - frame2:SetWide(windowwide/2) - frame2:Dock(RIGHT) +-- frame:SetSize(512, topwide/1.5-24) + frame:SetBackgroundColor(Color(255, 255, 255, 5)) + + Derma.PlayerFrame2 = vgui.Create("DPanel", mt1) + local frame2 = Derma.PlayerFrame2 + frame2:SetPos(windowwide*0.5, 0) + frame2:SetWide(windowwide*0.5) + frame2:Dock(FILL) frame2:DockPadding(0, 0, 0, 0) -- frame2:SetSize(leftwide*1.25/2, topwide/1.5-54) frame2:SetBackgroundColor(Color(255, 255, 255, 15)) - + local MapAmbient = render.GetAmbientLightColor() * 255 MapAmbient.r = math.Clamp(MapAmbient.r, 35, 255) MapAmbient.g = math.Clamp(MapAmbient.g, 35, 255) @@ -113,14 +171,16 @@ function DRCMenu( player ) local LocalAmbient = render.GetLightColor(LocalPlayer():EyePos()) * 255 local PreviewAmbient = Color((MapAmbient.r + LocalAmbient.r), (MapAmbient.g + LocalAmbient.g), (MapAmbient.b + LocalAmbient.b), 255) - local bg = vgui.Create("DImage", frame) + Derma.PlayerBG = vgui.Create("DImage", frame) + local bg = Derma.PlayerBG bg:SetPos(0, 0) bg:Dock(FILL) bg:SetSize(589, 658) -- bg:SetImage("vgui/drc_playerbg") bg:SetZPos(-10) - local bgloading = vgui.Create("DImage", frame) + Derma.PlayerLoading = vgui.Create("DImage", frame) + local bgloading = Derma.PlayerLoading bgloading:SetPos(0, 0) bgloading:Dock(FILL) bgloading:SetSize(589, 658) @@ -129,6 +189,7 @@ function DRCMenu( player ) bgloading:SetVisible(false) frame.tools = vgui.Create("DPanel", frame) + Derma.PlayerTools = frame.tools frame.tools:SetSize(590,666) frame.tools:Dock(FILL) frame.tools:SetVisible(false) @@ -146,12 +207,13 @@ function DRCMenu( player ) MapAmbient.b = math.Clamp(MapAmbient.b, 127, 255) frame.previewfloor = vgui.Create("DAdjustableModelPanel", frame) - frame.previewfloor:SetSize(590,680) - frame.previewfloor:SetPos(0, 0) - frame.previewfloor:SetFOV(47) +-- frame.previewfloor:SetSize(590,680) + frame.previewfloor:Dock(FILL) + frame.previewfloor:SetPos(0, 0) + frame.previewfloor:SetFOV(47) frame.previewfloor:SetModel("models/props_phx/construct/glass/glass_angle360.mdl") frame.previewfloor:SetAnimated( true ) - frame.previewfloor:SetAnimationEnabled(true) + frame.previewfloor:SetAnimationEnabled(true) frame.previewfloor:SetAmbientLight(MapAmbient) frame.previewfloor:SetDirectionalLight(BOX_TOP, MapAmbient*2) frame.previewfloor:SetDirectionalLight(BOX_FRONT, MapAmbient*1.5) @@ -162,13 +224,14 @@ function DRCMenu( player ) frame.previewfloor:SetLookAng(Angle(10.278, 203.334, 0)) frame.previewfloor:SetCamPos(Vector(80.69, 36.7, 52.02)) - frame.preview = vgui.Create("DAdjustableModelPanel", frame) - frame.preview:SetSize(589,666) - frame.preview:SetPos(0, 0) - frame.preview:SetFOV(47) + frame.preview = vgui.Create("DAdjustableModelPanel", frame) +-- frame.preview:SetSize(589,666) + frame.preview:SetPos(0, 0) + frame.preview:Dock(FILL) + frame.preview:SetFOV(47) frame.preview:SetModel(tostring(pmodelname)) frame.preview:SetAnimated( true ) - frame.preview:SetAnimationEnabled(true) + frame.preview:SetAnimationEnabled(true) frame.preview:SetAmbientLight(MapAmbient) frame.preview:SetDirectionalLight(BOX_TOP, MapAmbient*2) frame.preview:SetDirectionalLight(BOX_FRONT, MapAmbient*1.5) @@ -209,13 +272,13 @@ function DRCMenu( player ) ent.Preview = true DRC.PlayermodelMenuEnt = ent frame.preview:SetFOV(math.Clamp(frame.preview:GetFOV(), 10, 100)) - local idle = ent:SelectWeightedSequence(ACT_HL2MP_IDLE) + if !ent.SelectedIdle then ent.SelectedIdle = ent:SelectWeightedSequence(ACT_HL2MP_IDLE) end if ent:LookupSequence("drc_menu") != -1 then ent:SetSequence("drc_menu") elseif ent:LookupSequence("drc_menu_xdr_default") != -1 then ent:SetSequence("drc_menu_xdr_default") else - ent:SetSequence(idle) + ent:SetSequence(ent.SelectedIdle) end ent.BGNum = 0 @@ -259,7 +322,7 @@ function DRCMenu( player ) frame.previewfloor:SetFOV(frame.preview:GetFOV()) frame.previewfloor:GetEntity():SetParent(frame.preview:GetEntity()) frame.previewfloor:GetEntity():AddEffects(EF_BONEMERGE) - end + end function frame.previewfloor:LayoutEntity(ent) ent:SetLOD(0) @@ -272,8 +335,10 @@ function DRCMenu( player ) bottompanel:SetPos(0,frame.preview:GetTall() - 50) bottompanel:SetSize(frame.preview:GetWide(), 50) bottompanel:SetBackgroundColor(Color(0, 0, 0, 50)) + bottompanel:Dock(BOTTOM) - local applybutton = vgui.Create("DButton", bottompanel) + Derma.PlayerApplyButton = vgui.Create("DButton", bottompanel) + local applybutton = Derma.PlayerApplyButton applybutton:SetText("Apply Changes") applybutton:SetPos(230,10) applybutton:SetSize(128, 32) @@ -288,9 +353,11 @@ function DRCMenu( player ) end end - local hint = vgui.Create("DButton", frame) + local hint = vgui.Create("DButton", bottompanel) hint:SetText("Controls") hint:SetPos(frame.preview:GetWide() - 80,frame.preview:GetTall() - 42) + hint:Dock(RIGHT) + hint:DockMargin(6, 6, 6, 6) hint:SetSize(64, 32) hint:SetTextColor(color_white) hint:SetContentAlignment(5) @@ -610,45 +677,66 @@ function DRCMenu( player ) tabs:SetPadding(0) tabs:DockPadding(0, 0, 0, 0) tabs.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end local tab1 = vgui.Create("DPropertySheet", tabs) tab1:SetPadding(0) tab1:DockPadding(0, 0, 0, 0) - tabs:AddSheet( "Player", tab1, "icon16/user.png") tab1.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end function tab1:OnActiveTabChanged(old, new) local mode = new:GetText() end + if Customization == true then + tabs:AddSheet( "Player", tab1, "icon16/user.png") + else + tab1:SetVisible(false) + end + local tab1PMs = vgui.Create( "DPanel", tab1 ) tab1PMs:DockPadding(0, 0, 0, 0) tab1PMs:SetBackgroundColor( Color(245, 245, 245, 0) ) - tab1:AddSheet( "Playermodels", tab1PMs, "icon16/folder_user.png") + if TweakMode < 1 && Customization == true then + tab1:AddSheet( "Playermodels", tab1PMs, "icon16/folder_user.png") + else + tab1PMs:SetVisible(false) + end tab1.tab1Hands = vgui.Create( "DPanel", tab1 ) tab1.tab1Hands:DockPadding(0, 0, 0, 0) tab1.tab1Hands:SetBackgroundColor( Color(245, 245, 245, 0) ) - tab1:AddSheet( "Hands", tab1.tab1Hands, "icon16/folder_page.png") + if TweakMode < 1 && Customization == true then + tab1:AddSheet( "Hands", tab1.tab1Hands, "icon16/folder_page.png") + else + tab1.tab1Hands:SetVisible(false) + end local tab2 = vgui.Create( "DPanel", tab1 ) tab2:SetBackgroundColor( Color(255, 255, 255, 255) ) - tab1:AddSheet( "Colours", tab2, "icon16/color_wheel.png" ) + if TweakMode != 3 && Customization == true then + tab1:AddSheet( "Colours", tab2, "icon16/color_wheel.png" ) + else + tab2:SetVisible(false) + end + local t3c = vgui.Create( "DPanel", tab1 ) t3c:SetBackgroundColor( Color(0, 0, 0, 0) ) t3c:SetPos(-200, 0) - local t3p = t3c:Add( "DPanelList" ) - t3p:DockPadding( 32, 8, 8, 8 ) - t3p:EnableVerticalScrollbar( true ) - t3p:Dock(FILL) - - local tab3 = tab1:AddSheet( "#smwidget.bodygroups", t3p, "icon16/cog.png" ) + local tab3 = t3c:Add( "DPanelList" ) + tab3:DockPadding( 32, 8, 8, 8 ) + tab3:EnableVerticalScrollbar( true ) + tab3:Dock(FILL) + if TweakMode != 2 && Customization == true then + tab1:AddSheet( "#smwidget.bodygroups", tab3, "icon16/cog.png" ) + else + tab3:SetVisible(false) + end local modelListPnl = tab1PMs:Add( "DPanel" ) modelListPnl:DockPadding( 8, 0, 8, 0 ) @@ -661,12 +749,13 @@ function DRCMenu( player ) SearchBar:SetUpdateOnType( true ) SearchBar:SetPlaceholderText( "#spawnmenu.quick_filter" ) - local PanelSelect = modelListPnl:Add( "DPanelSelect" ) + Derma.PlayerModels = modelListPnl:Add( "DPanelSelect" ) + local PanelSelect = Derma.PlayerModels PanelSelect:Dock(FILL) PanelSelect:SetBackgroundColor(Color(0, 0, 0, 0)) PanelSelect.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end local arms = { ["c_"] = "c_", @@ -742,7 +831,8 @@ function DRCMenu( player ) modelListPnl_Hands:Dock(FILL) modelListPnl_Hands:SetBackgroundColor(Color(0, 0, 0, 0)) - local PanelSelect_Hands = modelListPnl_Hands:Add( "DPanelSelect" ) + Derma.PlayerModels_Hands = modelListPnl_Hands:Add( "DPanelSelect" ) + local PanelSelect_Hands = Derma.PlayerModels_Hands PanelSelect_Hands:Dock(FILL) PanelSelect_Hands:SetBackgroundColor(Color(0, 0, 0, 0)) PanelSelect_Hands.Paint = function(self, w, h) @@ -819,7 +909,7 @@ function DRCMenu( player ) end end - local ScrollPrim = vgui.Create("DPanel", tab2) + local ScrollPrim = vgui.Create("DPanel", tab2) ScrollPrim:SetPos(0, 0) ScrollPrim:Dock(FILL) ScrollPrim:DockMargin(0, 0, 4, 4) @@ -828,19 +918,19 @@ function DRCMenu( player ) local row1 = vgui.Create("DPanel", ScrollPrim) row1:Dock(TOP) row1:DockMargin(4, 4, 0, 0) - row1:SetSize(windowwide/2, windowtall/3.75 ) + row1:SetSize(windowwide*0.5, windowtall/3.75 ) row1:SetBackgroundColor(Color(255, 255, 255, 0)) local row2 = vgui.Create("DPanel", ScrollPrim) row2:Dock(TOP) row2:DockMargin(4, 4, 0, 0) - row2:SetSize(windowwide/2, windowtall/3.75 ) + row2:SetSize(windowwide*0.5, windowtall/3.75 ) row2:SetBackgroundColor(Color(255, 255, 255, 0)) local row3 = vgui.Create("DPanel", ScrollPrim) row3:Dock(TOP) row3:DockMargin(4, 4, 0, 0) - row3:SetSize(windowwide/2, windowtall/3.75 ) + row3:SetSize(windowwide*0.5, windowtall/3.75 ) row3:SetBackgroundColor(Color(255, 255, 255, 0)) @@ -1081,8 +1171,8 @@ function DRCMenu( player ) local tab5 = vgui.Create( "DPropertySheet", tabs ) tab5:DockPadding(0, 0, 0, 0) tab5.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(234, 234, 234, 255)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(234, 234, 234, 255)) + end tabs:AddSheet( "Extra", tab5, "icon16/draconic_base.png" ) tab5.SpraySettings = vgui.Create( "DPanel", tab1 ) @@ -1150,6 +1240,7 @@ function DRCMenu( player ) SpraypreviewText:Dock(TOP) local Spraypreview = vgui.Create("DImage", tab5.SpraySettings) + Derma.SprayPreview = Spraypreview Spraypreview:SetPos(8, 115) Spraypreview:SetSize(320, 320) Spraypreview:SetImageColor(Color(255, 255, 255, 255)) @@ -1432,13 +1523,14 @@ function DRCMenu( player ) end local function RebuildBodygroupTab() - t3p:Clear() + tab3:Clear() + if !IsValid(tab3) then return end -- tab3.Tab:SetVisible( false ) local nskins = frame.preview.Entity:SkinCount() - 1 if ( nskins > 0 ) then - local skins = vgui.Create( "DNumSlider", t3p ) + local skins = vgui.Create( "DNumSlider", tab3 ) skins:Dock( TOP ) skins:SetText( "Skin" ) skins:SetDark( true ) @@ -1449,11 +1541,11 @@ function DRCMenu( player ) skins.type = "skin" skins.OnValueChanged = UpdateBodyGroups - t3p:AddItem( skins ) + tab3:AddItem( skins ) frame.preview.Entity:SetSkin( GetConVarNumber( "cl_playerskin" ) ) - tab3.Tab:SetVisible( true ) + if tab3.Tab then tab3.Tab:SetVisible( true ) end end local groups = string.Explode( " ", GetConVarString( "cl_playerbodygroups" ) ) @@ -1472,11 +1564,11 @@ function DRCMenu( player ) bgroup:SetValue( groups[ k + 1 ] or 0 ) bgroup.OnValueChanged = UpdateBodyGroups - t3p:AddItem( bgroup ) + tab3:AddItem( bgroup ) frame.preview.Entity:SetBodygroup( k, groups[ k + 1 ] or 0 ) - tab3.Tab:SetVisible( true ) + if tab3.Tab then tab3.Tab:SetVisible( true ) end end tabs.tabScroller:InvalidateLayout() @@ -1515,6 +1607,7 @@ function DRCMenu( player ) SetupScene(name) RunConsoleCommand( "cl_playerbodygroups", "0" ) RunConsoleCommand( "cl_playerskin", "0" ) + frame.preview.Entity.SelectedIdle = nil end timer.Simple(0.1, function() if !table.IsEmpty(DRC.CurrentSpecialModelOptions) && table.HasValue(DRC.CurrentSpecialModelOptions, name) then @@ -1862,7 +1955,7 @@ function DRCMenu( player ) -- GreyOut(tab5.VoiceSetSettings) if TweakMode == 1 then - tab1PMs:Remove() + -- tab1PMs:Remove() for k,v in pairs(tab1:GetItems()) do if v.Name == "Playermodels" then tab1:CloseTab(v.Tab) end end @@ -1877,29 +1970,13 @@ function DRCMenu( player ) end tab1:SetActiveTab(tab1:GetItems()[1].Tab) - elseif Customization == false then - for k,v in pairs(tabs:GetItems()) do - if v.Name == "Player" then - tabs:CloseTab(v.Tab) - elseif v.Name == "Saved Avatars" then - tabs:CloseTab(v.Tab) - elseif v.Name == "Colours" then - tabs:CloseTab(v.Tab) - elseif v.Name == "#smwidget.bodygroups" then - tabs:CloseTab(v.Tab) - end - end - tab1:Remove() - tab2:Remove() - tab4:Remove() - tab5.VoiceSetSettings:Remove() end RefreshAvatars() local mt2 = vgui.Create( "DPanel", maintabs ) mt2:SetBackgroundColor(Color(255, 255, 255, 5)) - maintabs:AddSheet( "Settings", mt2, "icon16/wrench.png") + maintabs:AddSheet( "Settings & Tools", mt2, "icon16/wrench.png") local t2frame = vgui.Create("DPanel", mt2) t2frame:SetBackgroundColor(Color(255, 255, 255, 5)) @@ -1909,36 +1986,36 @@ function DRCMenu( player ) t2tabs:Dock(FILL) t2tabs:SetPadding(0) t2tabs.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end local controls = vgui.Create( "DPanel", t2tabs) controls:Dock(RIGHT) controls:SetSize(320) controls.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local CTitle = vgui.Create( "DPanel", controls ) CTitle:Dock(TOP) CTitle:SetSize(320, 50) CTitle.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local controls1 = vgui.Create( "DPanel", controls ) controls1:Dock(LEFT) controls1:SetSize(160) controls1.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local controls2 = vgui.Create( "DPanel", controls ) controls2:Dock(LEFT) controls2:SetSize(160) controls2.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local ControlsTitle = vgui.Create( "DLabel", CTitle) ControlsTitle:SetText("Controls List") @@ -1965,8 +2042,8 @@ function DRCMenu( player ) local t2tab1 = vgui.Create( "DPanel" ) t2tab1:Dock(FILL) t2tab1.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t2tabs:AddSheet( "Client Settings", t2tab1, "icon16/wrench_orange.png") local AccessibilityTitle = vgui.Create( "DLabel", t2tab1) @@ -2112,31 +2189,59 @@ function DRCMenu( player ) MakeHint(t2tab1, 4, 355, "(Default 1) Scales the torso depth down for Experimental First Person, for playermodels with large geoemtry which can get in the way of aiming.") - local DrcThirdperson = vgui.Create( "DCheckBoxLabel", t2tab1 ) - DrcThirdperson:SetPos(25, 75) - DrcThirdperson:SetSize(500, 20) - DrcThirdperson:SetText( "Enable Draconic Thirdperson*" ) - DrcThirdperson:SetConVar( "cl_drc_thirdperson" ) - DrcThirdperson.Label:SetColor(TextCol) - DrcThirdperson:SetEnabled(true) + local PlayermodelSpawnIconSize = vgui.Create( "DLabel", t2tab1) + PlayermodelSpawnIconSize:SetPos(25, 400) + PlayermodelSpawnIconSize:SetSize(200, 20) + PlayermodelSpawnIconSize:SetText("Playermodel Selector Icon Size:") + PlayermodelSpawnIconSize:SetColor(TextCol) + + local PlayermodelSpawnIconSizeCombo = vgui.Create( "DComboBox", t2tab1 ) + PlayermodelSpawnIconSizeCombo:SetSortItems(false) + PlayermodelSpawnIconSizeCombo:SetPos(180, 400) + PlayermodelSpawnIconSizeCombo:SetSize(150, 20) + PlayermodelSpawnIconSizeCombo:SetConVar( "cl_drc_menu_iconsize" ) + PlayermodelSpawnIconSizeCombo:AddChoice("32x32", 1) + PlayermodelSpawnIconSizeCombo:AddChoice("48x48", 2) + PlayermodelSpawnIconSizeCombo:AddChoice("64x64 (default)", 3) + PlayermodelSpawnIconSizeCombo:AddChoice("96x96", 4) + PlayermodelSpawnIconSizeCombo:AddChoice("128x128", 5) + function PlayermodelSpawnIconSizeCombo:OnSelect(index, value, data) + index = math.Round(index) + RunConsoleCommand("cl_drc_menu_iconsize", index) + if !maximized then RefreshIcons(false, index) end + end - local DrcThirdperson_Dyn = vgui.Create( "DCheckBoxLabel", t2tab1 ) - DrcThirdperson_Dyn:SetPos(25, 95) - DrcThirdperson_Dyn:SetSize(500, 20) - DrcThirdperson_Dyn:SetText( "Disable Thirdperson Free-look" ) - DrcThirdperson_Dyn:SetConVar( "cl_drc_thirdperson_disable_freelook" ) - DrcThirdperson_Dyn.Label:SetColor(TextCol) - DrcThirdperson_Dyn:SetEnabled(true) + local PlayermodelSpawnIconSizeFullscreen = vgui.Create( "DLabel", t2tab1) + PlayermodelSpawnIconSizeFullscreen:SetPos(25, 420) + PlayermodelSpawnIconSizeFullscreen:SetSize(200, 20) + PlayermodelSpawnIconSizeFullscreen:SetText("Selector Fullscreen Icon Size:") + PlayermodelSpawnIconSizeFullscreen:SetColor(TextCol) + + local PlayermodelSpawnIconSizeComboFullscreen = vgui.Create( "DComboBox", t2tab1 ) + PlayermodelSpawnIconSizeComboFullscreen:SetSortItems(false) + PlayermodelSpawnIconSizeComboFullscreen:SetPos(180, 420) + PlayermodelSpawnIconSizeComboFullscreen:SetSize(150, 20) + PlayermodelSpawnIconSizeComboFullscreen:SetConVar( "cl_drc_menu_iconsize_fullscreen" ) + PlayermodelSpawnIconSizeComboFullscreen:AddChoice("32x32", 1) + PlayermodelSpawnIconSizeComboFullscreen:AddChoice("48x48", 2) + PlayermodelSpawnIconSizeComboFullscreen:AddChoice("64x64 (default)", 3) + PlayermodelSpawnIconSizeComboFullscreen:AddChoice("96x96", 4) + PlayermodelSpawnIconSizeComboFullscreen:AddChoice("128x128", 5) + function PlayermodelSpawnIconSizeComboFullscreen:OnSelect(index, value, data) + index = math.Round(index) + RunConsoleCommand("cl_drc_menu_iconsize_fullscreen", index) + if maximized then RefreshIcons(true, index) end + end local DrcExperimentalFP = vgui.Create( "DCheckBoxLabel", t2tab1 ) - DrcExperimentalFP:SetPos(25, 115) + DrcExperimentalFP:SetPos(25, 75) DrcExperimentalFP:SetSize(500, 20) DrcExperimentalFP:SetText( "Enable ''Experimental First Person'' mode" ) DrcExperimentalFP:SetConVar( "cl_drc_experimental_fp" ) DrcExperimentalFP.Label:SetColor(TextCol) DrcExperimentalFP:SetEnabled(true) - MakeHint(t2tab1, 4, 115, "<< Work in Progress Feature >>\n\n''Experimental First Person'' is a true full-body first person camera system which still utilizes the player's viewmodel.\n\nEFP Does:\n> Show your body in first person, accurate to how it is seen in third-person.\n> Show your character's arms when in a vehicle\n> Add a small amount of viewbobbing based on your character's head\n> Still uses the player's viewmodel, allowing you to see your weapon properly as intended by its creators.\n\nEFP Does NOT:\n> Change the aiming angle to match the new camera position (yet)\n\nCurrent known issues:\n> Body desyncs when game is paused in singleplayer") + MakeHint(t2tab1, 4, 75, "<< Work in Progress Feature >>\n\n''Experimental First Person'' is a true full-body first person camera system which still utilizes the player's viewmodel.\n\nEFP Does:\n> Show your body in first person, accurate to how it is seen in third-person.\n> Show your character's arms when in a vehicle\n> Add a small amount of viewbobbing based on your character's head\n> Still uses the player's viewmodel, allowing you to see your weapon properly as intended by its creators.\n\nEFP Does NOT:\n> Change the aiming angle to match the new camera position (yet)\n\nCurrent known issues:\n> Body desyncs when game is paused in singleplayer") local VMOX = vgui.Create( "DNumSlider", t2tab1 ) VMOX:SetPos(25, 240) @@ -2174,175 +2279,169 @@ function DRCMenu( player ) local t2tab2 = vgui.Create( "DPanel" ) t2tab2:Dock(FILL) t2tab2.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t2tabs:AddSheet( "Server Settings", t2tab2, "icon16/wrench.png") - local DrcMovement = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcMovement:SetPos(25, 15) - DrcMovement:SetSize(20, 20) - DrcMovement:SetText( "Draconic SWEP movement speed overrides" ) - DrcMovement:SetConVar( "sv_drc_movement" ) - DrcMovement.Label:SetColor(TextCol) - - local DrcMoveSounds = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcMoveSounds:SetPos(25, 35) - DrcMoveSounds:SetSize(20, 20) - DrcMoveSounds:SetText( "Draconic SWEP movement sounds" ) - DrcMoveSounds:SetConVar( "sv_drc_movesounds" ) - DrcMoveSounds.Label:SetColor(TextCol) - - local DrcInspections = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcInspections:SetPos(25, 55) - DrcInspections:SetSize(20, 20) - DrcInspections:SetText( "Draconic SWEP Inspection Menu" ) - DrcInspections:SetConVar( "sv_drc_inspections" ) - DrcInspections.Label:SetColor(TextCol) - - local DrcPassive = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcPassive:SetPos(25, 75) - DrcPassive:SetSize(20, 20) - DrcPassive:SetText( "Draconic SWEP Passives" ) - DrcPassive:SetConVar( "sv_drc_passives" ) - DrcPassive.Label:SetColor(TextCol) - - local DrcSprintOverride = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcSprintOverride:SetPos(25, 95) - DrcSprintOverride:SetSize(20, 20) - DrcSprintOverride:SetText( "All Draconic weapons use passive sprint" ) - DrcSprintOverride:SetConVar( "sv_drc_force_sprint" ) - DrcSprintOverride.Label:SetColor(TextCol) - - local SvThirdperson = vgui.Create( "DCheckBoxLabel", t2tab2 ) - SvThirdperson:SetPos(25, 115) - SvThirdperson:SetSize(20, 20) - SvThirdperson:SetText( "Disable access to Draconic's thirdperson system" ) - SvThirdperson:SetConVar( "sv_drc_disable_thirdperson" ) - SvThirdperson.Label:SetColor(TextCol) - - MakeHint(t2tab2, 4, 115, "Draconic SWEPs which require thirdperson will still use Draconic thirdperson regardless of this setting.") - - local SvFreecam = vgui.Create( "DCheckBoxLabel", t2tab2 ) - SvFreecam:SetPos(25, 135) - SvFreecam:SetSize(20, 20) - SvFreecam:SetText( "Disable Draconic thirdperson's freecam system globally" ) - SvFreecam:SetConVar( "sv_drc_disable_thirdperson_freelook" ) - SvFreecam.Label:SetColor(TextCol) - - t2tab2.SoundStretch = vgui.Create( "DCheckBoxLabel", t2tab2 ) - t2tab2.SoundStretch:SetPos(25, 155) - t2tab2.SoundStretch:SetSize(20, 20) - t2tab2.SoundStretch:SetText( "Disable host_timescale sound alteration" ) - t2tab2.SoundStretch:SetConVar( "sv_drc_soundtime_disabled" ) - t2tab2.SoundStretch.Label:SetColor(TextCol) - - MakeHint(t2tab2.SoundStretch, 300, 0, "Enabling this setting will make it so sounds do not slow down/speed up when host_timescale changes are in effect.") - - local DiffSetting = vgui.Create( "DLabel", t2tab2) - DiffSetting:SetPos(400, 15) - DiffSetting:SetSize(100, 20) - DiffSetting:SetText("HL2 Difficulty:") - DiffSetting:SetColor(TextCol) - - local HL2Diff = vgui.Create( "DComboBox", t2tab2 ) - HL2Diff:SetSortItems(false) - HL2Diff:SetPos(500, 15) - HL2Diff:SetSize(150, 20) - HL2Diff:SetConVar( "skill" ) - HL2Diff:AddChoice("Easy", 1) - HL2Diff:AddChoice("Medium", 2) - HL2Diff:AddChoice("Hard", 3) - function HL2Diff:OnSelect(index, value, data) - LocalPlayer():ConCommand("skill ".. index .."") - end - - local DiffDescE = vgui.Create( "DLabel", t2tab2) - DiffDescE:SetPos(400, 35) - DiffDescE:SetSize(w2, 20) - DiffDescE:SetText("Easy: ".. GetConVarNumber("sk_dmg_inflict_scale1") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale1") * 100 .."% damage taken.") - DiffDescE:SetColor(SubtextCol) - - local DiffDescM = vgui.Create( "DLabel", t2tab2) - DiffDescM:SetPos(400, 55) - DiffDescM:SetSize(w2, 20) - DiffDescM:SetText("Medium: ".. GetConVarNumber("sk_dmg_inflict_scale2") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale2") * 100 .."% damage taken.") - DiffDescM:SetColor(SubtextCol) - - local DiffDescH = vgui.Create( "DLabel", t2tab2) - DiffDescH:SetPos(400, 75) - DiffDescH:SetSize(w2, 20) - DiffDescH:SetText("Hard: ".. GetConVarNumber("sk_dmg_inflict_scale3") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale3") * 100 .."% damage taken.") - DiffDescH:SetColor(SubtextCol) - - t2tab2.AmmoSetting = vgui.Create( "DLabel", t2tab2) - t2tab2.AmmoSetting:SetPos(400, 110) - t2tab2.AmmoSetting:SetSize(100, 20) - t2tab2.AmmoSetting:SetText("DRC Infinite Ammo:") - t2tab2.AmmoSetting:SetColor(TextCol) - - t2tab2.InfiniteAmmo = vgui.Create( "DComboBox", t2tab2 ) - t2tab2.InfiniteAmmo:SetSortItems(false) - t2tab2.InfiniteAmmo:SetPos(500, 110) - t2tab2.InfiniteAmmo:SetSize(150, 20) - t2tab2.InfiniteAmmo:SetConVar( "sv_drc_infiniteammo" ) - t2tab2.InfiniteAmmo:AddChoice("Disabled", 0) - t2tab2.InfiniteAmmo:AddChoice("Enabled", 1) - t2tab2.InfiniteAmmo:AddChoice("Bottomless Mag", 2) - function t2tab2.InfiniteAmmo:OnSelect(index, value, data) - LocalPlayer():ConCommand("sv_drc_infiniteammo ".. index - 1 .."") - end - ---[[ local DrcDistGunfire = vgui.Create( "DCheckBoxLabel", t2tab2 ) - DrcDistGunfire:SetPos(25, 145) - DrcDistGunfire:SetSize(20, 20) - DrcDistGunfire:SetText( "Disable distant gunfire sounds (can alleviate network usage on larger servers)" ) - DrcDistGunfire:SetConVar( "sv_drc_disable_distgunfire" ) - DrcDistGunfire.Label:SetColor(TextCol) - - - local WeaponSway = vgui.Create( "DNumSlider", t2tab2 ) - WeaponSway:SetPos(25, 115) - WeaponSway:SetSize(300, 20) - WeaponSway:SetText( "AI accuracy handicap" ) - WeaponSway.Label:SetColor(TextCol) - WeaponSway:SetMin( 0 ) - WeaponSway:SetMax( 10 ) - WeaponSway:SetDecimals( 2 ) - WeaponSway:SetConVar( "sv_drc_npc_accuracy" ) - - local LGTitle = vgui.Create( "DLabel", t2tab2) - LGTitle:SetPos(25, 135) - LGTitle:SetSize(w2, 60) - LGTitle:SetText("Handicap of how much an NPCs accuracy should be with Draconic guns. \n 0 = Seal Team 6 accuracy (perfect) \n 2 - Half-Life 2 AI Accuracy \n 10 = Can't hit shit.") - LGTitle:SetColor(TextCol) --]] + local DrcMovement = vgui.Create( "DCheckBoxLabel", t2tab2 ) + DrcMovement:SetPos(25, 15) + DrcMovement:SetSize(20, 20) + DrcMovement:SetText( "Draconic SWEP movement speed overrides" ) + DrcMovement:SetConVar( "sv_drc_movement" ) + DrcMovement.Label:SetColor(TextCol) + + local DrcMoveSounds = vgui.Create( "DCheckBoxLabel", t2tab2 ) + DrcMoveSounds:SetPos(25, 35) + DrcMoveSounds:SetSize(20, 20) + DrcMoveSounds:SetText( "Draconic SWEP movement sounds" ) + DrcMoveSounds:SetConVar( "sv_drc_movesounds" ) + DrcMoveSounds.Label:SetColor(TextCol) + + local DrcInspections = vgui.Create( "DCheckBoxLabel", t2tab2 ) + DrcInspections:SetPos(25, 55) + DrcInspections:SetSize(20, 20) + DrcInspections:SetText( "Draconic SWEP Inspection Menu" ) + DrcInspections:SetConVar( "sv_drc_inspections" ) + DrcInspections.Label:SetColor(TextCol) + + local DrcPassive = vgui.Create( "DCheckBoxLabel", t2tab2 ) + DrcPassive:SetPos(25, 75) + DrcPassive:SetSize(20, 20) + DrcPassive:SetText( "Draconic SWEP Passives" ) + DrcPassive:SetConVar( "sv_drc_passives" ) + DrcPassive.Label:SetColor(TextCol) + + local SvThirdperson = vgui.Create( "DCheckBoxLabel", t2tab2 ) + SvThirdperson:SetPos(25, 115) + SvThirdperson:SetSize(20, 20) + SvThirdperson:SetText( "Disable access to Draconic's thirdperson system" ) + SvThirdperson:SetConVar( "sv_drc_disable_thirdperson" ) + SvThirdperson.Label:SetColor(TextCol) + + MakeHint(t2tab2, 4, 115, "Draconic SWEPs which require thirdperson will still use Draconic thirdperson regardless of this setting.") + + local SvFreecam = vgui.Create( "DCheckBoxLabel", t2tab2 ) + SvFreecam:SetPos(25, 135) + SvFreecam:SetSize(20, 20) + SvFreecam:SetText( "Disable Draconic thirdperson's freecam system globally" ) + SvFreecam:SetConVar( "sv_drc_disable_thirdperson_freelook" ) + SvFreecam.Label:SetColor(TextCol) + + t2tab2.SoundStretch = vgui.Create( "DCheckBoxLabel", t2tab2 ) + t2tab2.SoundStretch:SetPos(25, 155) + t2tab2.SoundStretch:SetSize(20, 20) + t2tab2.SoundStretch:SetText( "Disable host_timescale sound alteration" ) + t2tab2.SoundStretch:SetConVar( "sv_drc_soundtime_disabled" ) + t2tab2.SoundStretch.Label:SetColor(TextCol) + + MakeHint(t2tab2, 4, 135, "Enabling this setting will make it so sounds do not slow down/speed up when host_timescale changes are in effect.") + + local DiffSetting = vgui.Create( "DLabel", t2tab2) + DiffSetting:SetPos(400, 15) + DiffSetting:SetSize(100, 20) + DiffSetting:SetText("HL2 Difficulty:") + DiffSetting:SetColor(TextCol) + + local HL2Diff = vgui.Create( "DComboBox", t2tab2 ) + HL2Diff:SetSortItems(false) + HL2Diff:SetPos(500, 15) + HL2Diff:SetSize(150, 20) + HL2Diff:SetConVar( "skill" ) + HL2Diff:AddChoice("Easy", 1) + HL2Diff:AddChoice("Medium", 2) + HL2Diff:AddChoice("Hard", 3) + function HL2Diff:OnSelect(index, value, data) + LocalPlayer():ConCommand("skill ".. index .."") + end ---[[ local t2tab3 = vgui.Create( "DPanel" ) + local textE = "''Easy'': ".. GetConVarNumber("sk_dmg_inflict_scale1") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale1") * 100 .."% damage taken." + local textM = "''Medium'': ".. GetConVarNumber("sk_dmg_inflict_scale2") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale2") * 100 .."% damage taken." + local textH = "''Hard'': ".. GetConVarNumber("sk_dmg_inflict_scale3") * 100 .."% damage dealt, ".. GetConVarNumber("sk_dmg_take_scale3") * 100 .."% damage taken." + + MakeHint(t2tab2, 378, 17, "".. textE .."\n\n".. textM .."\n\n".. textH .."\n\n\nThis is the actual Half-Life 2 difficulty the game/server is currently set to.\nIt will also affect certain NPC's behaviours.\n\nDEFAULT AND RECOMMENDED IS MEDIUM.") + + t2tab2.AmmoSetting = vgui.Create( "DLabel", t2tab2) + t2tab2.AmmoSetting:SetPos(400, 50) + t2tab2.AmmoSetting:SetSize(100, 20) + t2tab2.AmmoSetting:SetText("DRC Infinite Ammo:") + t2tab2.AmmoSetting:SetColor(TextCol) + + t2tab2.InfiniteAmmo = vgui.Create( "DComboBox", t2tab2 ) + t2tab2.InfiniteAmmo:SetSortItems(false) + t2tab2.InfiniteAmmo:SetPos(500, 50) + t2tab2.InfiniteAmmo:SetSize(150, 20) + t2tab2.InfiniteAmmo:SetConVar( "sv_drc_infiniteammo" ) + t2tab2.InfiniteAmmo:AddChoice("Disabled", 0) + t2tab2.InfiniteAmmo:AddChoice("Enabled", 1) + t2tab2.InfiniteAmmo:AddChoice("Bottomless Mag", 2) + function t2tab2.InfiniteAmmo:OnSelect(index, value, data) + LocalPlayer():ConCommand("sv_drc_infiniteammo ".. index - 1 .."") + end + + MakeHint(t2tab2, 378, 52, "''Enabled'': Weapons need to be reloaded, weapons will overheat; but won't take ammo from your pool.\n\n''Bottomless Mag'': Ammo never depletes, weapons will never overheat.") + + t2tab2.SprintSetting = vgui.Create( "DLabel", t2tab2) + t2tab2.SprintSetting:SetPos(400, 85) + t2tab2.SprintSetting:SetSize(100, 20) + t2tab2.SprintSetting:SetText("DRC SWEP Sprint:") + t2tab2.SprintSetting:SetColor(TextCol) + + t2tab2.SprintDropdown = vgui.Create( "DComboBox", t2tab2 ) + t2tab2.SprintDropdown:SetSortItems(false) + t2tab2.SprintDropdown:SetPos(500, 85) + t2tab2.SprintDropdown:SetSize(150, 20) + t2tab2.SprintDropdown:SetConVar( "sv_drc_force_sprint" ) + t2tab2.SprintDropdown:AddChoice("SWEP Default", 0) + t2tab2.SprintDropdown:AddChoice("Force Passives", 1) + t2tab2.SprintDropdown:AddChoice("Disable Passives", 2) + function t2tab2.SprintDropdown:OnSelect(index, value, data) + LocalPlayer():ConCommand("sv_drc_force_sprint ".. index - 1 .."") + end + + MakeHint(t2tab2, 378, 87, "''SWEP Default'': Passive sprinting will be based on the weapon's settings.\n\n''Force Passives'': Passive sprinting will be forced on all DRC SWEPs.\n\n''Disable Passives'': Passive sprinting will be DISABLED on all DRC SWEPs.") + + local t2tab3 = vgui.Create( "DPanel" ) t2tab3:Dock(FILL) t2tab3.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end - t2tabs:AddSheet( "Experimental Settings", t2tab3, "icon16/script_error.png") - - local DisclaimerExperimental = vgui.Create( "DLabel", t2tab3) - DisclaimerExperimental:SetPos(20, -8) - DisclaimerExperimental:SetSize(300, 50) - DisclaimerExperimental:SetText("Experimental Settings") - DisclaimerExperimental:SetFont("DermaLarge") - DisclaimerExperimental:SetColor(Color(255, 255, 255, 255)) - - local DisclaimerExperimental = vgui.Create( "DLabel", t2tab3) - DisclaimerExperimental:SetPos(24, 20) - DisclaimerExperimental:SetSize(w2, 50) - DisclaimerExperimental:SetText("Anything in this tab is either an unstable personal project or a work-in-progress feature in need of testing.") - DisclaimerExperimental:SetColor(TextCol) ]] - --- local t2tab3 = vgui.Create( "DPanel" ) --- t2tab3:Dock(FILL) --- t2tab3.Paint = function(self, w, h) --- draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) --- end --- t2tabs:AddSheet( "Draconic Thirdperson", t2tab3, "icon16/camera.png") + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end + t2tabs:AddSheet( "Thirdperson Settings", t2tab3, "icon16/camera.png") + + local DrcThirdperson = vgui.Create( "DCheckBoxLabel", t2tab3 ) + DrcThirdperson:SetPos(25, 35) + DrcThirdperson:SetSize(500, 20) + DrcThirdperson:SetText( "Enable Draconic Thirdperson*" ) + DrcThirdperson:SetConVar( "cl_drc_thirdperson" ) + DrcThirdperson.Label:SetColor(TextCol) + DrcThirdperson:SetEnabled(true) + + t2tab3.ThirdPersonEditor = vgui.Create("DButton", t2tab3) + t2tab3.ThirdPersonEditor:SetPos(20, 76) + t2tab3.ThirdPersonEditor:SetSize(200, 24) + t2tab3.ThirdPersonEditor:SetEnabled(true) + t2tab3.ThirdPersonEditor:SetText("Open Thirdperson Editor") + t2tab3.ThirdPersonEditor.DoClick = function() + DRC:OpenThirdpersonEditor(ply) + Derma:Remove() + end + t2tab3.TPReset = vgui.Create("DButton", t2tab3) + t2tab3.TPReset:SetPos(20, 106) + t2tab3.TPReset:SetSize(200, 24) + t2tab3.TPReset:SetEnabled(true) + t2tab3.TPReset:SetText("Reset Thirdperson to Default") + t2tab3.TPReset.DoClick = function() + DRC:ThirdPersonResetToDefault() + end + + local ThirdpersonPresets = vgui.Create("DPanel", t2tab3) + ThirdpersonPresets:SetSize(430, 630) + ThirdpersonPresets:SetPos(440, 0) + ThirdpersonPresets.Paint = function(self, w, h) + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end + + DRC:CreateThirdPersonPresetMenu(ThirdpersonPresets, false) local mt3 = vgui.Create( "DPanel", maintabs ) mt3:SetBackgroundColor(Color(255, 255, 255, 5)) @@ -2352,100 +2451,100 @@ function DRCMenu( player ) infopage:Dock(FILL) --infopage:OpenURL("https://www.google.com/") infopage:SetHTML( [[ - - - - - - -
-

Draconic Base

-

Credits

-

Programmming

- -

Bug testing

- -

Sounds

- -

Special Thanks

- - - If this text is scrolling below 30FPS, you are on Awesomium. If it is scrolling at 60fps or more, you are on Chromium. - - - ]] ) + color: lightgrey; + margin: 0; + margin-left: 2em; + margin-bottom: 0.5em; + } + ul{ + font-family: "Lucida Console"; + color: lightgrey; + margin-left: 3em; + margin-top: 0.1em; + margin-bottom: 0.5em; + } + li{ + font-size: 10pt; + margin-top: 0.1em; + margin-bottom: 0.1em; + width: 90vw; + } + marquee{ + font-family: Verdana; + color: lightgrey; + width: 100vw; + + position: fixed; + bottom: 0; + margin-bottom: 0; + margin-top: 10em; + } + body{ + width: 100vw; + height: 100vh; + } + .ultitle{ + font-family: "Lucida Console"; + margin-left: 3em; + margin-top: 0.1em; + margin-bottom: 0.5em; + + color: white; + } + + + + +
+

Draconic Base

+

Credits

+

Programmming

+ +

Bug testing

+ +

Sounds

+ +

Special Thanks

+ + + If this text is scrolling below 30FPS, you are on Awesomium. If it is scrolling at 60fps or more, you are on Chromium. + + + ]] ) local mt4 = vgui.Create( "DPanel", maintabs ) mt4:SetBackgroundColor(Color(255, 255, 255, 10)) @@ -2455,43 +2554,43 @@ function DRCMenu( player ) t4tabs:Dock(FILL) t4tabs:SetPadding(0) t4tabs.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end local t4tab1 = vgui.Create( "DPanel" ) t4tab1:Dock(FILL) t4tab1.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t4tabs:AddSheet( "Debug Information", t4tab1, "icon16/information.png") local debug_gameinfo = vgui.Create( "DPanel", t4tab1) debug_gameinfo:Dock(RIGHT) debug_gameinfo:SetSize(320) debug_gameinfo.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local CTitle = vgui.Create( "DPanel", debug_gameinfo ) CTitle:Dock(TOP) CTitle:SetSize(320, 50) CTitle.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local controls1 = vgui.Create( "DPanel", debug_gameinfo ) controls1:Dock(LEFT) controls1:SetSize(160) controls1.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local controls2 = vgui.Create( "DPanel", debug_gameinfo ) controls2:Dock(LEFT) controls2:SetSize(160) controls2.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 127)) + end local ControlsTitle = vgui.Create( "DLabel", CTitle) ControlsTitle:SetText("Session Information") @@ -2537,7 +2636,7 @@ function DRCMenu( player ) DebugInfo:SetColor(Color(255, 255, 255, 255)) DRC:CubemapCheck() - +--[[ local text = "Unverified" if drc_badlightmaps[cmap] != nil or drc_singlecubemaps[cmap] != nil then text = "Fail" @@ -2549,7 +2648,7 @@ function DRCMenu( player ) text = "Unverified" end ---[[ + local DebugInfo = vgui.Create( "DLabel", debug_gameinfo) DebugInfo:SetPos(15, 140) DebugInfo:SetSize(200, 20) @@ -2610,7 +2709,7 @@ function DRCMenu( player ) ControlsTitle:SetFont("DermaLarge") DebugInfo:SetPos(25, 10) DebugInfo:SetSize(400, 20) - DebugInfo:SetText("HDR Support | Hardware: ".. tostring(render.SupportsHDR()) .." / Map: ".. tostring(render.GetHDREnabled()) .."") + DebugInfo:SetText("HDR Support | Hardware: ".. tostring(render.SupportsHDR()) .." / Map: ".. tostring(render.GetHDREnabled()) .."") DebugInfo:SetColor(TextCol) local gbranch = BRANCH @@ -2632,24 +2731,28 @@ function DRCMenu( player ) ["mat_antialias"] = { 7, "Anti-Aliasing", nil, false, "mat_antialias\n0 to 8\nControls the amount, but not type, of antialising employed. Type must be set in your game's settings menu.\nNewer/modern GPUs only support MSAA in Garry's Mod. You're better off setting a post-AA from your GPU's control panel.\n\nIf you are using ReShade or similar, they will not work if you have antialising enabled in Garry's Mod."}, ["mat_viewportscale"] = { 8, "Render Scale", 1, false, "mat_viewportscale\n0 to 1 (Set to 1)\nThis controls the percentage resolution your game will display at."}, ["r_shadows"] = { 9, "Simple Shadows", 1, false, "r_shadows\n0 or 1 (Set to 1)"}, - ["r_flashlightdepthtexture"] = { 10, "Dynamic Shadows", 1, false, "r_flashlightdepthtexture\n0 or 1 (Recommended: 1)"}, - ["r_flashlightdepthres"] = { 11, "Shadow Resolution", 2048, false, "r_flashlightdepthres\n0 to 16384 (Recommended: 2048 or higher, but not 16384. Must be in values of 2.)\nThe resolution of dynamic shadows."}, + ["r_flashlightdepthtexture"] = { 10, "Projected Shadows", 1, false, "r_flashlightdepthtexture\n0 or 1 (Recommended: 1)\nThe projected textured shadows, like the flashlight and lamp tool."}, + ["r_flashlightdepthres"] = { 11, "Shadow Resolution", 2048, false, "r_flashlightdepthres\n0 to 16384 (Recommended: 2048 or higher, but not 16384. Must be in values of 2.)\nThe resolution of projected shadows."}, ["r_projectedtexture_filter"] = { 12, "Shadow Blur", 0.2, true, "r_projectedtexture_filter\n0 to ??? (Recommended: 0.1)\nHigher values will produce blobby, noisy shadows while extremely low values will produce blocky shadows."}, - ["mat_filtertextures"] = { 13, "Texture Filtering", 1, false, "mat_filtertextures\nWhy would you even have this turned off?"}, - ["mat_forceaniso"] = { 14, "Anisotropic Filtering", 8, false, "mat_forceaniso\n4, 8, or 16.\n16 is recommended, but if your machine cannot handle this or you have a low-resolution monitor, then 8 is just fine."}, - ["mat_filterlightmaps"] = { 15, "Lightmap Filtering", 1, false, "mat_filterlightmaps\nWhy would you even have this turned off?"}, - ["mat_specular"] = { 16, "Cubemap Reflections", 1, false, "mat_specular\n(Recommended: 1)\nSetting this to 0 does not 'fix' anything, and in some cases can actually break some assets from rendering as intended."}, - ["mat_motion_blur_enabled"] = { 17, "Motion Blur", 1, false, "mat_motion_blur_enabled\nSet this to 1.\nIf you want to turn off engine motion blur, set mat_motion_blur_strength to 0.\nTurning it off outright will break a lot of effects for both games & addons which utilize the 4 different types of blur for various effects."}, - ["dsp_enhance_stereo"] = { 18, "Dynamic Sound Processing", 1, false, "dsp_enhance_stereo\nSet this to 1.\nEnables the game to perform digital sound processing effects based on 3d space instead of from a flat filter."}, - ["gmod_mcore_test"] = { 19, "Gmod Multicore", 1, false, "gmod_mcore_test\n0 or 1 (Recommended: 1)\nEnable multicore processing, providing a significant performance increase most of the time."}, - ["cl_threaded_bone_setup"] = { 20, "Threaded Bones", 1, false, "cl_threaded_bone_setup\n0 or 1 (Recommended: 1)\nEnable multithreaded processing of gmod-lua bone transformations."}, - ["cl_threaded_client_leaf_system"] = { 21, "Threaded VisLeafs", 1, false, "cl_threaded_client_leaf_system\n0 or 1 (Recommended: 1)\nEnable multithreaded processing of visleaf-related computations."}, - ["mat_queue_mode"] = { 22, "Threaded Materials", 1, false, "mat_queue_mode\n-1, 0, 1, or 2 (Recommended: 2)\nEnables the following:\n- Multithreaded processing of materials with engine-programming effects such as material proxies.\n- Enables materials being cached for the fist time to be done on multiple threads.\n\n-1: Automatic detection (unreliable)\n0: Synchronus single thread\n1: Single-threaded computation\n2: Multithreaded computation"}, - ["r_threaded_particles"] = { 23, "Threaded Particles", 1, false, "r_threaded_particles\n-1, 0 or 1 (Recommended: 1)\nEnable multithreaded processing of particle computations."}, - ["r_threaded_client_shadow_manager"] = {24, "Threaded Shadows", 1, false, "r_threaded_client_shadow_manager\n-1, 0 or 1 (Recommended: 1)\nNobody seems to know fully what this does, best guesses are that it's a leftover from old-engine,\nas it has nothing tied to it in SDK 2013+. Everyone turns it to 1 just to be safe with no adverse effect."}, - ["r_threaded_renderables"] = { 25, "Threaded Renderables", 1, false, "r_threaded_renderables\n-1, 0 or 1 (Recommended: 1)\nFrom mastercomfig's TF2 configs: ''Asynchronously set up bones on animated entities''."}, - ["r_queued_ropes"] = { 26, "Materialized Ropes", 1, false, "r_queued_ropes\n-1, 0 or 1 (Recommended: 1)\nWhen set to 1, this will make the engine treat ropes as materials, offloading their rendering operations to the GPU instead of the CPU."}, - ["r_occludermincount"] = { 27, "Minimum Occluders", 1, false, "r_occludermincount\n0 to ??? (Recommended: 1)\nForces the game to always have at least one occlusion cull, preventing stuff from being drawn that otherwise shouldn't be when off-screen."}, + ["r_shadow_allowdynamic"] = { 13, "Dynamic Shadows", 1, false, "r_shadow_allowdynamic\n0 or 1 (Recommended: 1)\nAllows standard shadows to change direction based on the nearest/most relevant light source.\nOnly works on maps explicitly compiled with lights set up for this."}, + ["r_shadow_allowbelow"] = { 14, "Dynamic Upward Shadows", 1, false, "r_shadow_allowbelow\n0 or 1 (Recommended: 1)\nAllows standard shadows to be projected above the player, if a light source is below them. (works alongside dynamic shadows)"}, + ["mat_filtertextures"] = { 15, "Texture Filtering", 1, false, "mat_filtertextures\nWhy would you even have this turned off?"}, + ["mat_forceaniso"] = { 16, "Anisotropic Filtering", 8, false, "mat_forceaniso\n4, 8, or 16.\n16 is recommended, but if your machine cannot handle this or you have a low-resolution monitor, then 8 is just fine."}, + ["mat_filterlightmaps"] = { 17, "Lightmap Filtering", 1, false, "mat_filterlightmaps\nWhy would you even have this turned off?"}, + ["mat_specular"] = { 18, "Cubemap Reflections", 1, false, "mat_specular\n(Recommended: 1)\nSetting this to 0 does not 'fix' anything, and in some cases can actually break some assets from rendering as intended."}, + ["mat_motion_blur_enabled"] = { 19, "Motion Blur", 1, false, "mat_motion_blur_enabled\nSet this to 1.\nIf you want to turn off engine motion blur, set mat_motion_blur_strength to 0.\nTurning it off outright will break a lot of effects for both games & addons which utilize the 4 different types of blur for various effects."}, + ["dsp_enhance_stereo"] = { 20, "Dynamic Sound Processing", 1, false, "dsp_enhance_stereo\nSet this to 1.\nEnables the game to perform digital sound processing effects based on 3d space instead of from a flat filter."}, + ["snd_mix_async"] = { 21, "Asynchronous Sounds", 0, false, "snd_mix_async\nSet this to 0.\nBackport from newer engine branches, does not support DSP & breaks it, creating monotone audio output.\nShould not be used."}, +-- ["snd_mixahead"] = { 22, "Asynchronous Mix Time", 0.1, false, "snd_mixahead\nLeave this at its default of 0.1.\nAmount of time (0.1 = 100ms) to dedicate to mixing asynchronous audio.\nSet this too low and audio begins to break, set it too high and audio goes back to synchronous processing."}, + ["gmod_mcore_test"] = { 22, "Gmod Multicore", 1, false, "gmod_mcore_test\n0 or 1 (Recommended: 1)\nEnable multicore processing, providing a significant performance increase most of the time."}, + ["cl_threaded_bone_setup"] = { 23, "Threaded Bones", 1, false, "cl_threaded_bone_setup\n0 or 1 (Recommended: 1)\nEnable multithreaded processing of gmod-lua bone transformations."}, + ["cl_threaded_client_leaf_system"] = { 24, "Threaded VisLeafs", 1, false, "cl_threaded_client_leaf_system\n0 or 1 (Recommended: 1)\nEnable multithreaded processing of visleaf-related computations."}, + ["mat_queue_mode"] = { 25, "Threaded Materials", 1, false, "mat_queue_mode\n-1, 0, 1, or 2 (Recommended: 2)\nEnables the following:\n- Multithreaded processing of materials with engine-programming effects such as material proxies.\n- Enables materials being cached for the fist time to be done on multiple threads.\n\n-1: Automatic detection (unreliable)\n0: Synchronus single thread\n1: Single-threaded computation\n2: Multithreaded computation"}, + ["r_threaded_particles"] = { 26, "Threaded Particles", 1, false, "r_threaded_particles\n-1, 0 or 1 (Recommended: 1)\nEnable multithreaded processing of particle computations."}, + ["r_threaded_client_shadow_manager"] = {27, "Threaded Shadows", 1, false, "r_threaded_client_shadow_manager\n-1, 0 or 1 (Recommended: 1)\nNobody seems to know fully what this does, best guesses are that it's a leftover from old-engine,\nas it has nothing tied to it in SDK 2013+. Everyone turns it to 1 just to be safe with no adverse effect."}, + ["r_threaded_renderables"] = { 28, "Threaded Renderables", 1, false, "r_threaded_renderables\n-1, 0 or 1 (Recommended: 1)\nFrom mastercomfig's TF2 configs: ''Asynchronously set up bones on animated entities''."}, + ["r_queued_ropes"] = { 29, "Materialized Ropes", 1, false, "r_queued_ropes\n-1, 0 or 1 (Recommended: 1)\nWhen set to 1, this will make the engine treat ropes as materials, offloading their rendering operations to the GPU instead of the CPU."}, + ["r_occludermincount"] = { 30, "Minimum Occluders", 1, false, "r_occludermincount\n0 to ??? (Recommended: 1)\nForces the game to always have at least one occlusion cull, preventing stuff from being drawn that otherwise shouldn't be when off-screen."}, } for k,v in pairs(convars) do @@ -2686,13 +2789,21 @@ function DRCMenu( player ) MakeHint(t4tab1, 3, 10 + (15*v[1]), v[5]) end + + t4tab1.copy = vgui.Create("DButton", t4tab1) + t4tab1.copy:SetPos(16, 590) + t4tab1.copy:SetSize(200, 20) + t4tab1.copy:SetText("Copy optimal configs to clipboard") + t4tab1.copy.DoClick = function() + SetClipboardText("r_radiosity 3\nr_ambientmin 0\nr_shadows 1\nr_flashlightdepthres 8192\nr_flashlightdepthtexture 1\nr_projectedtexture_filter 0.1\nr_shadow_allowdynamic 1\nr_shadow_allowbelow 1\nmat_specular 1\nmat_motion_blur_enabled 1\nmat_motion_blur_strength 0\ndsp_enhance_stereo\nsnd_mix_async 0\ngmod_mcore_test 1\ncl_threaded_bone_setup 1\ncl_threaded_client_leaf_system 1\nmat_queue_mode 2\nmat_queue_mode 2\nr_threaded_particles 1\nr_threaded_client_shadow_manager 1\nr_threaded_renderables 1\nr_queued_ropes 1\nr_occludermincount") + end --[[ local col = render.GetLightColor(LocalPlayer():EyePos()) * 255 local DebugInfo = vgui.Create( "DLabel", t4tab1) DebugInfo:SetPos(25, 40) DebugInfo:SetSize(300, 20) - DebugInfo:SetText("Local light level >> ".. tostring(col) .."") + DebugInfo:SetText("Local light level >> ".. tostring(col) .."") DebugInfo:SetColor(TextCol) local DebugInfo = vgui.Create( "DLabel", t4tab1) @@ -2706,15 +2817,15 @@ function DRCMenu( player ) local t4tab2 = vgui.Create( "DPanel" ) t4tab2:Dock(FILL) t4tab2.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t4tabs:AddSheet( "Development Tools", t4tab2, "icon16/bomb.png") local t4tab2panel_left = vgui.Create("DPanel", t4tab2) t4tab2panel_left:Dock(FILL) t4tab2panel_left.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t4tab2panel_left.DRCTitle = vgui.Create( "DLabel", t4tab2panel_left) t4tab2panel_left.DRCTitle:SetText("DRC Debug Tools") @@ -2925,12 +3036,19 @@ function DRCMenu( player ) end local function Yeet() - surface.PlaySound("draconic/oof.ogg") + -- surface.PlaySound("") net.Start("DRC_Nuke") net.WriteEntity(LocalPlayer()) net.SendToServer() end + local function SoftYeet() + -- surface.PlaySound("draconic/NOW.ogg") + net.Start("DRC_KYS") + net.WriteEntity(LocalPlayer()) + net.SendToServer() + end + local nukemap = vgui.Create("DButton", t4tab2panel_right) nukemap:SetText("Nuke Map (Kills NPCs & breaks props)") nukemap:Dock(TOP) @@ -2940,6 +3058,15 @@ function DRCMenu( player ) Derma:Remove() end + local lowtier = vgui.Create("DButton", t4tab2panel_right) + lowtier:SetText("Kill & remove all NPCs & NextBots") + lowtier:Dock(TOP) + lowtier.DoClick = function() + lowtier:SetEnabled(false) + SoftYeet() + Derma:Remove() + end + local function SpawnThatShit() LocalPlayer():ConCommand("drc_debug_spawnweaponmodel") end @@ -2957,14 +3084,19 @@ function DRCMenu( player ) local t4tab3 = vgui.Create( "DPanel" ) t4tab2:Dock(FILL) t4tab2.Paint = function(self, w, h) - draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) - end + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end t4tabs:AddSheet( "Draconic Wiki", t4tab3, "icon16/book_link.png") local wiki = vgui.Create("DHTML", t4tab3) wiki:Dock(FILL) wiki:SetAllowLua(false) wiki:SetScrollbars(true) - wiki:OpenURL("http://vuthakral.com/draconic") + + + function t4tabs:OnActiveTabChanged(old, new) + local mode = new:GetText() + if mode == "Draconic Wiki" then wiki:OpenURL("http://vuthakral.com/draconic") end + end end \ No newline at end of file diff --git a/lua/draconic/cl/render.lua b/lua/draconic/cl/render.lua index 8728021..0e3899d 100644 --- a/lua/draconic/cl/render.lua +++ b/lua/draconic/cl/render.lua @@ -64,8 +64,10 @@ hook.Add("Think", "DRC_Lighting", function() ["DrawShadows"] = true } DRC.CalcView.MuzzleLamp = DRC:ProjectedTexture(vm, "muzzle", lighttable) + DRC.CalcView.MuzzleLamp_Angle = Angle() else - if DRC:ThirdPersonEnabled(ply) then + local thirdperson = DRC:ThirdPersonEnabled(ply) + if thirdperson then if DRC.CalcView.MuzzleLamp:GetParent() != wpn then DRC.CalcView.MuzzleLamp:SetParent(wpn) end else if DRC.CalcView.MuzzleLamp:GetParent() != vm then DRC.CalcView.MuzzleLamp:SetParent(vm) end @@ -82,19 +84,73 @@ hook.Add("Think", "DRC_Lighting", function() ent:SetPos(attinfo.Pos) ent:SetAngles(attinfo.Ang) -- ent.Light:SetColor( Color(255, 150, 25) ) - if DRC.CalcView.MuzzleLamp_Time then if DRC.CalcView.MuzzleLamp_Time < CurTime() then ent.Enabled = false end end + if wpn.Draconic && wpn.IntegratedLight_Enabled == true && wpn:GetNWBool("IntegratedLightState") == true then + local colmain = wpn.IntegratedLight_Colour + local col = Color(colmain.r, colmain.g, colmain.b, 25 * colmain.a) + local bright = (col.a/30) * (1 - math.Clamp(DRC.MapInfo.MapAmbientAvg, 0.15, 1)) + ent.Texture = wpn.IntegratedLight_Texture + ent.Light:SetColor(Color(col.r, col.g, col.b)) + ent.Light:SetBrightness(bright) + local p1, p2 = attinfo.Pos, DRC:TraceDir(attinfo.Pos, attinfo.Ang, wpn.IntegratedLight_MaxDist) + if wpn.IntegratedLight_UseHitPos == true then + local parent = DRC.CalcView.MuzzleLamp:GetParent() == ply + local vm = ply:GetViewModel(0) + local idle = wpn:GetSequenceActivity(wpn:GetSequence(ACT_VM_IDLE)) == ACT_VM_IDLE or wpn:GetSequenceActivity(wpn:GetSequence(ACT_WALK)) == ACT_WALK + local ea = ply:EyeAngles() + local ang1 = ea + (wpn.dang*2) + local ang2 = attinfo.Ang + local atu + + if !parent && !thirdperson then + DRC.CalcView.MuzzleLamp:SetParent(ply) + end + if idle or thirdperson then atu = ang1 else atu = ang2 end + + DRC.CalcView.MuzzleLamp_Angle = LerpAngle(RealFrameTime() * 25, DRC.CalcView.MuzzleLamp_Angle or atu, atu) + + ent:SetPos(ply:EyePos() + ea:Forward() * 15) + ent:SetAngles(DRC.CalcView.MuzzleLamp_Angle) + end + local frac = Lerp(1-p2.Fraction * wpn.IntegratedLight_DistScale, 0, wpn.IntegratedLight_FOV) + ent.FOV = frac + ent.FarZ = wpn.IntegratedLight_MaxDist + ent.Enabled = true + + if wpn.IntegratedLight_DoVolume == true then + local volcol = Color(wpn.IntegratedLight_Colour.r, wpn.IntegratedLight_Colour.g, wpn.IntegratedLight_Colour.b, wpn.IntegratedLight_VolPower) + if !IsValid(wpn.FlashlightVolume) then wpn.FlashlightVolume = DRC:LightVolume(wpn, "muzzle", volcol, wpn.IntegratedLight_VolLength, frac*0.005, 50, nil, wpn.IntegratedLight_VolMaterial) end + end + end + if wpn:GetNWBool("IntegratedLightState") == true then + if DRC.CalcView.MuzzleLamp_Time then if DRC.CalcView.MuzzleLamp_Time < CurTime() && wpn:GetNWBool("IntegratedLightState") == false then ent.Enabled = false end end + else + if DRC.CalcView.MuzzleLamp_Time then if DRC.CalcView.MuzzleLamp_Time < CurTime() then ent.Enabled = false end end + if wpn.IntegratedLight_DoVolume == true then + if IsValid(wpn.FlashlightVolume) then wpn.FlashlightVolume:Remove() end + end + end end end) -function DRC:LightVolume(ent, att, colour, length, width) - if !IsValid(ent) or att == nil then return end - local attnum = ent:LookupAttachment(att) - if attnum == -1 then return end - local attinfo = ent:GetAttachment(attnum) +function DRC:LightVolume(ent, att, colour, length, width, quality, addang, mat) + if !IsValid(ent) then return end + if IsValid(ent.DRCVolumeLight) then return end + if !quality then quality = 25 end + if !mat then mat = "sprites/glow04_noz" end + local attnum, attinfo + if att then + attnum = ent:LookupAttachment(att) + attinfo = ent:GetAttachment(attnum) + end local light = nil light = ents.CreateClientside("draconic_spotlight_base") light:Spawn() light:SetParent(ent, attnum) + light.AddAng = addang or Angle() + light.LightMaterial = mat + + local pos, ang = ent:GetPos(), ent:GetAngles() + if att && attinfo then pos, ang = attinfo.Pos, attinfo.Ang end light.Info = { ["entity"] = ent, @@ -102,60 +158,19 @@ function DRC:LightVolume(ent, att, colour, length, width) ["colour"] = colour, ["length"] = length, ["width"] = width, - ["angles"] = attinfo.Ang, - ["position"] = attinfo.Pos, + ["quality"] = quality, + ["angles"] = ang, + ["position"] = pos, } + ent.DRCVolumeLight = light return light end - ---- ###MapInfos -drc_badlightmaps = { - ["gm_blackmesa_sigma"] = 0.1, - ["gm_bigcity_improved"] = 0.25, - ["gm_bigcity_improved_lite"] = 0.25, - ["gm_emp_chain"] = 0.15, -} --- The only maps that get added to this list are old maps which will not see an update/fix from their authors. --- This is not meant as a mark of shame, it is used in the Draconic menu to inform developers that the map they --- are on has incorrectly compiled lighting, and as a result their content might look a bit scuffed. Values at the --- end are "post fixes" which scales the Draconic Base's Reflection Tint proxies. - -drc_singlecubemaps = { - ["mu_volcano"] = 0.25, - ["gm_cultist_outpost"] = 0.25, - ["gm_reactionsew"] = 0.1, -} --- Maps with no either cubemaps baked into them falling back on the engine default, or only one single cubemap, preventing proper lighting checks from working. - -drc_fullbrightcubemaps = { -} --- Alright, THIS is a mark of shame. Whoever told you to turn on fullbright when compiling cubemaps is an idiot. - -drc_verifiedlightmaps = { - ["gm_construct"] = true, - ["gm_flatgrass"] = true, - ["gm_bigcity"] = true, - ["gm_emp_streetsoffire"] = true, - ["gm_vault"] = true, -} --- Impressive. Very nice. - -drc_authorpassedlightmaps = {} - -DRC.BadLightmapList = {} -table.Merge(DRC.BadLightmapList, drc_badlightmaps) -table.Merge(DRC.BadLightmapList, drc_singlecubemaps) - -DRC.MapInfo.LMCorrection = DRC.BadLightmapList[DRC.MapInfo.Name] -if DRC.MapInfo.LMCorrection == nil then DRC.MapInfo.LMCorrection = 1 end DRC.MapInfo.MapAmbient = render.GetAmbientLightColor() DRC.MapInfo.MapAmbientAvg = (DRC.MapInfo.MapAmbient.x + DRC.MapInfo.MapAmbient.y + DRC.MapInfo.MapAmbient.z) / 3 hook.Add("InitPostEntity", "DRC_LightmapCheck", function() - DRC.MapInfo.LMCorrection = DRC.BadLightmapList[DRC.MapInfo.Name] - if DRC.MapInfo.LMCorrection == nil then DRC.MapInfo.LMCorrection = 1 end DRC.MapInfo.MapAmbient = render.GetAmbientLightColor() DRC.MapInfo.MapAmbientAvg = (DRC.MapInfo.MapAmbient.x + DRC.MapInfo.MapAmbient.y + DRC.MapInfo.MapAmbient.z) / 3 end) @@ -179,7 +194,7 @@ DRC.Accessibility.ColorBlindness = { } -- https://web.archive.org/web/20081014161121/http://www.colorjack.com/labs/colormatrix/ DRC.Accessibility.ColorBlindness_Mul = 0 -hook.Add("DrawOverlay", "DRC_ColourBlindness", function() +hook.Add("HUDPaint", "DRC_ColourBlindness", function() local con = GetConVar("cl_drc_accessibility_colourblind"):GetString() if con == "None" then return end local con2 = GetConVar("cl_drc_accessibility_colourblind_strength"):GetFloat() @@ -230,4 +245,52 @@ hook.Add("RenderScreenspaceEffects", "DRC_Camera_Overlays", function() if IsValid(wpn) && wpn:GetClass() == "drc_camera" then DrawMaterialOverlay(DRC.CameraOverlay or "", DRC.CameraPower) end +end) + +hook.Add("GetMotionBlurValues", "drc_modifiedmotionblur", function(horizontal, vertical, forward, rotational) + local ply = LocalPlayer() + local wpn = ply:GetActiveWeapon() + + if wpn.Draconic then + if !ply.ForwardBlurAdditive then ply.ForwardBlurAdditive = 0 end + if !ply.RotationalBlurAdditive then ply.RotationalBlurAdditive = 0 end + + local kick + local melee = wpn.IsMelee + if melee then kick = 1 else kick = wpn.Primary.Kick end + + kick = kick*0.001 + ply.ForwardBlurAdditive = Lerp(0.01 * wpn.ForwardDecayMul or 1, ply.ForwardBlurAdditive or ply.ForwardBlurAdditive-kick, 0) + ply.RotationalBlurAdditive = Lerp(0.025 * wpn.RotationalDecayMul or 1, ply.RotationalBlurAdditive or ply.RotationalBlurAdditive-kick, 0) + -- ply:ChatPrint(ply.RotationalBlurAdditive) + +-- if wpn:CanUseSights() == false then forward = 0 return forward end + + local w = ScrW() + local h = ScrH() + + local ratio = w/h + + local ss = 4 * wpn.Secondary.ScopeScale + local sw = wpn.Secondary.ScopeWidth + local sh = wpn.Secondary.ScopeHeight + + local wi = w / 10 * ss + local hi = h / 10 * ss + + if wpn.Secondary.Scoped == true && wpn.Secondary.ScopeBlur == true && wpn.SightsDown == true then + if sw != 1 then + forward = forward + (ss * 0.015 / sw) * (wpn.Secondary.IronFOV * ratio * 0.05) + else + forward = forward + (ss * 0.0175) / (wpn.Secondary.IronFOV * ratio * 0.01) + end + -- rotational = rotational + 0.05 * math.sin( CurTime() * 3 ) + end + + if wpn.SightsDown == false or wpn.IsOverheated == true then + forward = 0 + if forward > 0 then forward = 0 end + end + return horizontal, vertical, forward + ply.ForwardBlurAdditive, rotational + ply.RotationalBlurAdditive + end end) \ No newline at end of file diff --git a/lua/draconic/cl/thirdperson.lua b/lua/draconic/cl/thirdperson.lua index 2fe8ac6..bcbf0f1 100644 --- a/lua/draconic/cl/thirdperson.lua +++ b/lua/draconic/cl/thirdperson.lua @@ -4,8 +4,87 @@ DRC.CalcView.ThirdPerson.DirectionalAng = Angle() DRC.CalcView.ThirdPerson.Live = false DRC.CalcView.ThirdPerson.PokeTime = CurTime() DRC.CalcView.ThirdPerson.FreelookForced = false +if !DRC.CalcView.ThirdPerson.EditorOpen then DRC.CalcView.ThirdPerson.EditorOpen = false end +DRC.CalcView.ThirdPerson.LerpedZPos = 0 +DRC.CalcView.ThirdPerson.LerpedFinalAng = Angle() +DRC.CalcView.ThirdPerson.LerpedFinalPos = Vector() +DRC.CalcView.ThirdPerson.LerpedHitPosCorrection = Angle() + +DRC.ThirdPerson.EditorSettings = { + ["Length"] = 100, + ["Height"] = 25, + ["UseBaseOffsets"] = true, + ["AllowFreeLook"] = true, + ["Offset"] = Vector(0, 0, 0), + ["LerpAngle"] = 0, + ["LerpPos"] = 0.1, + ["BaseFOV"] = 75, + ["FocalPoint"] = 0, -- 0 player view, 1 hitpos, 2 head angle + ["BasePoint"] = 0, -- 0 pelvis, 1 eyes, 2 origin + ["ForceFreelook"] = false, + ["FreecamDelay"] = 3, + ["ForceDirectional"] = false, +} + +DRC.ThirdPerson.LoadedSettings = { + ["Length"] = 100, + ["Height"] = 25, + ["UseBaseOffsets"] = true, + ["AllowFreeLook"] = true, + ["Offset"] = Vector(25, 0, 0), + ["LerpAngle"] = 0, + ["LerpPos"] = 0.1, + ["BaseFOV"] = 75, + ["FocalPoint"] = 0, -- 0 player view, 1 hitpos, 2 head angle + ["BasePoint"] = 0, -- 0 pelvis, 1 eyes, 2 origin + ["ForceFreelook"] = false, + ["FreecamDelay"] = 3, + ["ForceDirectional"] = false, +} +DRC.ThirdPerson.LerpedSettings = { + ["Length"] = 100, + ["Height"] = 25, + ["UseBaseOffsets"] = true, + ["AllowFreeLook"] = true, + ["Offset"] = Vector(25, 0, 0), + ["LerpAngle"] = 0, + ["LerpPos"] = 0.1, + ["BaseFOV"] = 75, + ["FocalPoint"] = 0, -- 0 player view, 1 hitpos, 2 head angle + ["BasePoint"] = 0, -- 0 pelvis, 1 eyes, 2 origin + ["ForceFreelook"] = false, + ["FreecamDelay"] = 3, + ["ForceDirectional"] = false, +} + +DRC.ThirdPerson.DefaultSettings = { + ["Length"] = 100, + ["Height"] = 25, + ["UseBaseOffsets"] = true, + ["AllowFreeLook"] = true, + ["Offset"] = Vector(25, 0, 0), + ["LerpAngle"] = 0, + ["LerpPos"] = 0.1, + ["BaseFOV"] = 75, + ["FocalPoint"] = 0, -- 0 player view, 1 hitpos, 2 head angle + ["BasePoint"] = 0, -- 0 pelvis, 1 eyes, 2 origin + ["ForceFreelook"] = false, + ["FreecamDelay"] = 3, + ["ForceDirectional"] = false, +} + +local lastload = GetConVar("cl_drc_thirdperson_preset"):GetString() +if lastload != "" && file.Find("draconic/thirdperson/".. lastload ..".json", "DATA") != nil then + local initialpreset = file.Read("draconic/thirdperson/".. lastload ..".json", "DATA") + local tbl = util.JSONToTable(initialpreset) + table.CopyFromTo(tbl, DRC.ThirdPerson.LoadedSettings) + table.CopyFromTo(tbl, DRC.ThirdPerson.EditorSettings) + DRC:UpdateThirdPersonEditorMenu() +end function DRC:ThirdPerson_PokeLiveAngle(ply) + local wpn = ply:GetActiveWeapon() + local settings = wpn.ThirdPersonProfileOverride or DRC.ThirdPerson.LoadedSettings if !DRC.CalcView.Thirdperson then DRC.CalcView.Thirdperson = {} end if !DRC.CalcView.Ang then DRC.CalcView.Ang = Angle() end if !DRC.CalcView.Ang_Stored then DRC.CalcView.Ang_Stored = Angle() end @@ -13,8 +92,7 @@ function DRC:ThirdPerson_PokeLiveAngle(ply) if !DRC.CalcView.Live then DRC.CalcView.Live = false end if !DRC.CalcView.PokeTime then DRC.CalcView.PokeTime = CurTime() end if DRC.CalcView.ThirdPerson.PokeTime == nil then DRC.CalcView.ThirdPerson.PokeTime = CurTime() end - local wpn = ply:GetActiveWeapon() - if wpn.ThirdpersonForceFreelook == true then + if wpn.ThirdpersonForceFreelook == true or settings.ForceFreelook == true then DRC.CalcView.ThirdPerson.Live = false DRC.CalcView.ThirdPerson.FreelookForced = true DRC.CalcView.ThirdPerson.Poked = true @@ -25,14 +103,15 @@ function DRC:ThirdPerson_PokeLiveAngle(ply) if CurTime() < DRC.CalcView.ThirdPerson.PokeTime then return end DRC.CalcView.ThirdPerson.Live = true DRC.CalcView.ThirdPerson.Poked = true - DRC.CalcView.ThirdPerson.PokeTime = CurTime() + 3 + local delay = DRC.ThirdPerson.LerpedSettings.FreecamDelay or 0 + DRC.CalcView.ThirdPerson.PokeTime = CurTime() + delay timer.Simple(engine.TickInterval() + 0.01, function() - DRC.CalcView.ThirdPerson.Poked = false + if settings.AllowFreeLook == true then DRC.CalcView.ThirdPerson.Poked = false end end) - timer.Simple(3.01, function() + timer.Simple(delay + 0.01, function() if CurTime() > DRC.CalcView.ThirdPerson.PokeTime then - DRC.CalcView.ThirdPerson.Live = false + DRC.CalcView.ThirdPerson.Live = false end end) end @@ -73,9 +152,20 @@ hook.Add("CreateMove", "!drc_thirdpersoncontrol", function(cmd) if !IsValid(ply) then return end local wpn = ply:GetActiveWeapon() if DRC:IsDraconicThirdPersonEnabled(ply) != true then return end - if GetConVar("sv_drc_disable_thirdperson_freelook"):GetFloat() == 1 or GetConVar("cl_drc_thirdperson_disable_freelook"):GetFloat() == 1 then + local settings = wpn.ThirdPersonProfileOverride or DRC.ThirdPerson.LoadedSettings + for k,v in pairs(settings) do -- used to interpolate profile changes for scripted systems that utilize profile overrides. + if !isbool(v) && !isstring(v) then + DRC.ThirdPerson.LerpedSettings[k] = Lerp(RealFrameTime()*5, DRC.ThirdPerson.LerpedSettings[k] or v, v) + else + DRC.ThirdPerson.LerpedSettings[k] = v + end + end + local n, s, e, w = ply:KeyDown(IN_FORWARD), ply:KeyDown(IN_BACK), ply:KeyDown(IN_MOVERIGHT), ply:KeyDown(IN_MOVELEFT) + local moving = n or s or e or w + settings = DRC.ThirdPerson.LerpedSettings + if settings.AllowFreeLook == false or GetConVar("sv_drc_disable_thirdperson_freelook"):GetFloat() == 1 then DRC:ThirdPerson_PokeLiveAngle(ply) - elseif IsValid(wpn) && wpn.ThirdpersonNoFreelook == true then + elseif IsValid(wpn) && (wpn.ThirdpersonNoFreelook == true) then DRC:ThirdPerson_PokeLiveAngle(ply) end DRC.MoveInfo = { @@ -102,8 +192,10 @@ hook.Add("CreateMove", "!drc_thirdpersoncontrol", function(cmd) ply:KeyDown(IN_USE), } - for k,v in pairs(pokers) do - if v == true then DRC:ThirdPerson_PokeLiveAngle(ply) end + if settings.ForceDirectional != true then + for k,v in pairs(pokers) do + if v == true then DRC:ThirdPerson_PokeLiveAngle(ply) end + end end if DRC.MoveInfo.Forward != 0 then DRC:ThirdPerson_PokeLiveAngle(ply) end @@ -112,7 +204,7 @@ hook.Add("CreateMove", "!drc_thirdpersoncontrol", function(cmd) if IsValid(wpn) then local ht = wpn:GetHoldType() - if fullranges[ht] && wpn.ThirdpersonNoFreelook != true then + if fullranges[ht] && wpn.ThirdpersonNoFreelook != true && settings.AllowFreeLook == true then DRC.CalcView.ThirdPerson.Directional = true local Compass = { @@ -136,8 +228,11 @@ hook.Add("CreateMove", "!drc_thirdpersoncontrol", function(cmd) local val = (math.abs(cmd:GetForwardMove()) + math.abs(cmd:GetSideMove())) cmd:SetForwardMove(val * MovementCorrection[input]) cmd:SetSideMove(0) + + if moving then DRC.CalcView.ThirdPerson.DirectionalEyeAngles = ply:EyeAngles() end else DRC.CalcView.ThirdPerson.DirectionalAng = Angle() + DRC.CalcView.ThirdPerson.DirectionalEyeAngles = ply:EyeAngles() end if DRC:SightsDown(wpn) then @@ -156,16 +251,16 @@ end) hook.Add("PrePlayerDraw", "!drc_thirdpersonlook", function(ply) if !IsValid(ply) then return end if ply != LocalPlayer() then return end - if GetConVar("cl_drc_thirdperson"):GetFloat() != 1 then return end - - local angdiff = Angle(DRC.CalcView.ThirdPerson.Ang.x - ply:EyeAngles().x, DRC.CalcView.ThirdPerson.Ang.y - ply:EyeAngles().y, 0) - angdiff:Normalize() - if math.abs(angdiff.y) > 130 then angdiff.x = 0 angdiff.y = 0 end - - DRC.CalcView.ThirdPerson.HeadAngLerp = LerpAngle(0.1, DRC.CalcView.ThirdPerson.HeadAngLerp or angdiff, angdiff) + if GetConVar("cl_drc_thirdperson"):GetInt() == 1 && DRC.CalcView.ThirdPerson.Live == false then + local angdiff = Angle(DRC.CalcView.ThirdPerson.Ang.x - ply:EyeAngles().x, DRC.CalcView.ThirdPerson.Ang.y - ply:EyeAngles().y, 0) + angdiff:Normalize() + if math.abs(angdiff.y) > 130 then angdiff.x = 0 angdiff.y = 0 end + + DRC.CalcView.ThirdPerson.HeadAngLerp = LerpAngle(FrameTime()*5, DRC.CalcView.ThirdPerson.HeadAngLerp or angdiff, angdiff) - ply:SetPoseParameter("head_yaw", DRC.CalcView.ThirdPerson.HeadAngLerp.y) - ply:SetPoseParameter("head_pitch", DRC.CalcView.ThirdPerson.HeadAngLerp.x*3) + ply:SetPoseParameter("head_yaw", DRC.CalcView.ThirdPerson.HeadAngLerp.y) + ply:SetPoseParameter("head_pitch", DRC.CalcView.ThirdPerson.HeadAngLerp.x*3) + end end) hook.Add("CalcView", "!drc_thirdperson", function(ply, pos, angles, fov) @@ -185,14 +280,25 @@ hook.Add("CalcView", "!drc_thirdperson", function(ply, pos, angles, fov) if wpn.ASTWTWO && GetConVar("cl_drc_thirdperson"):GetFloat() == 0 then return end local PSMul = ply:GetModelScale() local root = LocalPlayer():LookupBone("ValveBiped.Bip01_Pelvis") - local bpos = nil + local bpos if root != nil then bpos = LocalPlayer():GetBonePosition(root) end local av = ply:GetAimVector() local ea = DRC.CalcView.ThirdPerson.Ang local ep = ply:EyePos() local pos = ply:GetPos() - if !DRC:ValveBipedCheck(ply) then + local settings = DRC.ThirdPerson.LerpedSettings + local basepoint = math.Round(settings.BasePoint) + if DRC.CalcView.ThirdPerson.EditorOpen == true then settings = DRC.ThirdPerson.EditorSettings end + local attcheck + if basepoint == 1 then + attcheck = ply:LookupAttachment("eyes") + if attcheck != 0 then bpos = ply:GetAttachment(attcheck).Pos else bpos = ply:GetPos() + Vector(0,0,ply:GetCollisionBounds().Z - 10) end + elseif basepoint == 2 then + bpos = Vector(ply:GetPos() + ply:OBBCenter()) + end + + if !DRC:ValveBipedCheck(ply) && basepoint == 0 then local attcheck = ply:LookupAttachment("hips") if attcheck != 0 then local newpos = ply:GetAttachment(attcheck).Pos @@ -220,10 +326,20 @@ hook.Add("CalcView", "!drc_thirdperson", function(ply, pos, angles, fov) if IsValid(wpn) then ht = string.lower(wpn:GetHoldType()) end if !DRC.ThirdPerson.DefaultOffsets[ht] then ht = "duel" end - local offset = (DRC.ThirdPerson.DefaultOffsets[ht] * PSMul) or (DRC.ThirdPerson.DefaultOffsets["duel"] * PSMul) + local offset + local flipshoulder = GetConVar("cl_drc_thirdperson_flipside"):GetFloat() == 1 - if GetConVar("cl_drc_thirdperson_flipside"):GetFloat() == 1 then - offset = (Vector(DRC.ThirdPerson.DefaultOffsets[ht].x, -DRC.ThirdPerson.DefaultOffsets[ht].y, DRC.ThirdPerson.DefaultOffsets[ht].z) * PSMul) or (Vector(DRC.ThirdPerson.DefaultOffsets["duel"].x, -DRC.ThirdPerson.DefaultOffsets["duel"].y, DRC.ThirdPerson.DefaultOffsets["duel"].z) * PSMul) + if settings.UseBaseOffsets == true then + offset = (DRC.ThirdPerson.DefaultOffsets[ht] * PSMul) or (DRC.ThirdPerson.DefaultOffsets["duel"] * PSMul) + + if flipshoulder then + offset = (Vector(DRC.ThirdPerson.DefaultOffsets[ht].x, -DRC.ThirdPerson.DefaultOffsets[ht].y, DRC.ThirdPerson.DefaultOffsets[ht].z) * PSMul) or (Vector(DRC.ThirdPerson.DefaultOffsets["duel"].x, -DRC.ThirdPerson.DefaultOffsets["duel"].y, DRC.ThirdPerson.DefaultOffsets["duel"].z) * PSMul) + end + else + offset = settings.Offset * PSMul + if flipshoulder then + offset = Vector(offset.x, -offset.y, offset.z) + end end if wpn.ThirdpersonOffset && (wpn:GetNWBool("Passive") != true) then offset = wpn.ThirdpersonOffset end @@ -235,13 +351,13 @@ hook.Add("CalcView", "!drc_thirdperson", function(ply, pos, angles, fov) local trZ = util.TraceLine({ start = bonepos, - endpos = bpos + ea:Up() * 25 * PSMul, + endpos = bpos + ea:Up() * settings.Height * PSMul, filter = function(ent) if ent == ply then return false end end }) local tr = util.TraceLine({ start = trZ.HitPos, - endpos = trZ.HitPos + ea:Forward() * -100 * PSMul, + endpos = trZ.HitPos + ea:Forward() * -settings.Length * PSMul, filter = function(ent) if ent == ply then return false end end }) @@ -255,19 +371,52 @@ hook.Add("CalcView", "!drc_thirdperson", function(ply, pos, angles, fov) if DRC.CalcView.ThirdPerson.Poked == true then ply:SetEyeAngles(DRC.CalcView.ThirdPerson.Ang) else - DRC.CalcView.ThirdPerson.Ang = ply:EyeAngles() + if settings.FocalPoint == 0 then DRC.CalcView.ThirdPerson.Ang = ply:EyeAngles() end end end DRC.CalcView.ThirdPerson.StoredAng = DRC.CalcView.ThirdPerson.Ang elseif DRC.CalcView.ThirdPerson.FreelookForced == false then - ply:SetEyeAngles(DRC.CalcView.ThirdPerson.StoredAng) + if settings.ForceDirectional == false then ply:SetEyeAngles(DRC.CalcView.ThirdPerson.StoredAng) + else ply:SetEyeAngles(DRC.CalcView.ThirdPerson.DirectionalEyeAngles) end end + local hitposaim = util.TraceLine({start = DRC.CalcView.ThirdPerson.LerpedFinalPos, endpos = ply:GetEyeTraceNoCursor().HitPos}) + -- DRC:RenderTrace(hitposaim, Color(255, 255, 0, 255), RealFrameTime()) + hitposaim = hitposaim.Normal:Angle() + + local AAAA = math.Clamp(0.5/RealFrameTime(), 1, 100) + local lpos, lang = (RealFrameTime() * AAAA) * settings.LerpPos, (RealFrameTime()*2 * AAAA) * settings.LerpAngle + + if !DRC.CalcView.ThirdPerson.LerpedFinalPos then DRC.CalcView.ThirdPerson.LerpedFinalPos = ply:EyePos() end + DRC.CalcView.ThirdPerson.LerpedZPos = Lerp(lpos*10, DRC.CalcView.ThirdPerson.LerpedZPos or tr.HitPos.z, tr.HitPos.z) + tr.HitPos.z = DRC.CalcView.ThirdPerson.LerpedZPos + DRC.CalcView.ThirdPerson.LerpedFinalPos = LerpVector(lpos, tr.HitPos or DRC.CalcView.ThirdPerson.LerpedFinalPos, DRC.CalcView.ThirdPerson.LerpedFinalPos) + + -- if settings.FocalPoint == 2 then + -- hitposaim = ply:GetAttachment(ply:LookupAttachment("eyes")).Ang + -- end + + if !DRC.CalcView.ThirdPerson.LerpedFinalAng then DRC.CalcView.ThirdPerson.LerpedFinalAng = ply:EyeAngles() end + DRC.CalcView.ThirdPerson.LerpedFinalAng = LerpAngle(lang, DRC.CalcView.ThirdPerson.Ang or DRC.CalcView.ThirdPerson.LerpedFinalAng, DRC.CalcView.ThirdPerson.LerpedFinalAng) + if !DRC.CalcView.ThirdPerson.LerpedHitPosAng then DRC.CalcView.ThirdPerson.LerpedHitPosAng = ply:EyeAngles() end + DRC.CalcView.ThirdPerson.LerpedHitPosAng = LerpAngle(lang, hitposaim or DRC.CalcView.ThirdPerson.LerpedHitPosAng, DRC.CalcView.ThirdPerson.LerpedHitPosAng) + + local ea2 = ply:EyeAngles() + if !DRC.CalcView.ThirdPerson.LerpedHitPosCorrection then DRC.CalcView.ThirdPerson.LerpedHitPosCorrection = ea2 end + DRC.CalcView.ThirdPerson.LerpedHitPosCorrection = LerpAngle(lang, (Angle(ea2.x,ea2.y*2,0)-Angle(hitposaim.x, hitposaim.y*2, 0)) or DRC.CalcView.ThirdPerson.LerpedHitPosCorrection, DRC.CalcView.ThirdPerson.LerpedHitPosCorrection) + if DRC:ThirdPersonEnabled(ply) == true then view = {} - view.origin = tr.HitPos - view.angles = DRC.CalcView.ThirdPerson.Ang - view.fov = 75 * (ply:GetFOV() / 100) + + if settings.FocalPoint == 1 then + view.origin = DRC.CalcView.ThirdPerson.LerpedFinalPos + view.angles = DRC.CalcView.ThirdPerson.LerpedFinalAng + (ea2 - DRC.CalcView.ThirdPerson.LerpedHitPosAng) - DRC.CalcView.ThirdPerson.LerpedHitPosCorrection + -- elseif settings.FocalPoint == 2 then view.angles = DRC.CalcView.ThirdPerson.LerpedHitPosAng + Angle(-20, 0, 0) + else + view.origin = DRC.CalcView.ThirdPerson.LerpedFinalPos + view.angles = DRC.CalcView.ThirdPerson.LerpedFinalAng + end + view.fov = settings.BaseFOV * (ply:GetFOV() / 100) view.drawviewer = true if tr.Hit then view.znear = 0.03 else view.znear = 1 end else diff --git a/lua/draconic/cl/thirdperson_editor.lua b/lua/draconic/cl/thirdperson_editor.lua new file mode 100644 index 0000000..b1708db --- /dev/null +++ b/lua/draconic/cl/thirdperson_editor.lua @@ -0,0 +1,195 @@ +local function GreyOut(element) + element:SetEnabled(false) + element.GreyOut = vgui.Create("DPanel", element) + element.GreyOut:Dock(FILL) + element.GreyOut:DockMargin(0, 0, 0, 0) + element.GreyOut:SetBackgroundColor(Color(127,127,127,127)) +end + +if !DRC.ThirdPerson.EditorSettings then + DRC.ThirdPerson.EditorSettings = { + ["Length"] = 100, + ["Height"] = 25, + ["UseBaseOffsets"] = true, + ["AllowFreeLook"] = true, + ["Offset"] = Vector(0, 0, 0), + ["LerpAngle"] = 0, + ["LerpPos"] = 0, + ["BaseFOV"] = 75, + ["FocalPoint"] = 0, -- 0 player view, 1 hitpos, 2 head angle + ["BasePoint"] = 0, -- 0 pelvis, 1 eyes, 2 origin + } +end + +local function CreateCheckbox(parent, pos, setting, label, tooltip) + local cb = vgui.Create("DCheckBoxLabel", parent) + + cb:SetPos(pos.x, pos.y) + cb:SetSize(300, 20) + cb:SetText(label) + cb:SetValue(setting) + cb:SetToolTip(tooltip) + function cb:OnChange(val) + if val == true then DRC.ThirdPerson.EditorSettings[setting] = true else DRC.ThirdPerson.EditorSettings[setting] = false end + + if parent.SliderAxes != nil then + for k,v in pairs(parent.SliderAxes) do + if setting == "UseBaseOffsets" && val == false then v:SetEnabled(true) else v:SetEnabled(false) end + end + end + end + + return cb +end + +local function UpdateOffset(number, axis) + local vector = DRC.ThirdPerson.EditorSettings.Offset + + if axis == "x" then DRC.ThirdPerson.EditorSettings.Offset = Vector(number, vector.y, vector.z) + elseif axis == "y" then DRC.ThirdPerson.EditorSettings.Offset = Vector(vector.x, number, vector.z) + elseif axis == "z" then DRC.ThirdPerson.EditorSettings.Offset = Vector(vector.x, vector.y, number) + end +end + +local function CreateSlider(parent, pos, axis, label, tooltip) + local slider = vgui.Create("DNumSlider", parent) + local text + local maxi, mini = 100, -100 + local cur + if axis == "x" then cur = DRC.ThirdPerson.EditorSettings.Offset.X + elseif axis == "y" then cur = DRC.ThirdPerson.EditorSettings.Offset.Y + elseif axis == "z" then cur = DRC.ThirdPerson.EditorSettings.Offset.Z + elseif axis == "fov" then cur = DRC.ThirdPerson.EditorSettings.BaseFOV maxi = 120 mini = 20 + elseif axis == "LerpPos" then cur = DRC.ThirdPerson.EditorSettings.LerpPos maxi = 0.999 mini = 0 + elseif axis == "LerpAngle" then cur = DRC.ThirdPerson.EditorSettings.LerpAngle maxi = 0.999 mini = 0 + elseif axis == "Height" then cur = DRC.ThirdPerson.EditorSettings.Height maxi = 100 mini = -100 + elseif axis == "Length" then cur = DRC.ThirdPerson.EditorSettings.Length maxi = 200 mini = 0 end + + + slider:SetPos(pos.x, pos.y) + slider:SetSize(290, 50) + slider:SetMax(maxi) + slider:SetMin(mini) + slider:SetDecimals(2) + slider:SetValue(cur) + slider:SetText(label) + slider:SetToolTip(tooltip) + slider.OnValueChanged = function(self, value) + if axis == "x" then UpdateOffset(value, "x") + elseif axis == "y" then UpdateOffset(-value, "y") + elseif axis == "z" then UpdateOffset(value, "z") + elseif axis == "fov" then DRC.ThirdPerson.EditorSettings.BaseFOV = value + elseif axis == "LerpPos" then DRC.ThirdPerson.EditorSettings.LerpPos = value + elseif axis == "LerpAngle" then DRC.ThirdPerson.EditorSettings.LerpAngle = value + elseif axis == "Height" then DRC.ThirdPerson.EditorSettings.Height = value + elseif axis == "Length" then DRC.ThirdPerson.EditorSettings.Length = value end + end + + if axis == "x" or axis == "y" or axis == "z" then + if !parent.SliderAxes then parent.SliderAxes = {} end + local l2 = "Slider_".. axis + parent["SliderAxes"][l2] = slider + end + + return slider +end + +local function CreateDropDown(parent, pos, setting, labels, tooltip) + local dd = vgui.Create("DComboBox", parent) + + dd:SetPos(pos.x, pos.y) + dd:SetSize(250, 20) + dd:SetValue(labels[1]) + dd:SetToolTip(tooltip) + for i=2,#labels do + dd:AddChoice(labels[i]) + end + dd.OnSelect = function(self, index, value) + DRC.ThirdPerson.EditorSettings[setting] = index-1 + end + + return dd +end + +local function CreateButton(parent, pos, size, text, onclick, tooltip) + local b = vgui.Create("DButton", parent) + + b:SetPos(pos.x, pos.y) + b:SetSize(size.x, size.y) + b:SetText(text) + b:SetToolTip(tooltip) + b.DoClick = onclick + + return b +end + +function DRC:OpenThirdpersonEditor(ply) + DRC.CalcView.ThirdPerson.EditorOpen = true + local width, height = ScrW(), ScrH() + local s = DRC.ThirdPerson.EditorSettings + + local Derma = vgui.Create("DFrame") + Derma:SetSize(300, 720) + Derma:SetMinWidth(1200) + Derma:SetMinHeight(720) + Derma:SetSizable(false) + Derma:SetTitle("Draconic Thirdperson Editor") + Derma:SetIcon("icon16/draconic_base.png") + Derma:MakePopup() + Derma:SetDraggable(true) + Derma:SetBackgroundBlur(false) + Derma:SetScreenLock(false) + Derma:ShowCloseButton(true) + Derma:SetPos(width*0.2, height*0.33) + Derma:SetVisible(true) + Derma.Paint = function(self, w, h) + draw.RoundedBoxEx(8, 0, 0, w, h, Color(0, 0, 0, 200), true, false, true, true) + end + + Derma.btnClose.DoClick = function() + DRC.CalcView.ThirdPerson.EditorOpen = false + DRC.ThirdPerson.EditorMenu = nil + Derma:Remove() + end + + DRC.ThirdPerson.EditorMenu = Derma + + Derma.offsets = CreateCheckbox(Derma, Vector(15, 30), "UseBaseOffsets", "Use holdtype offsets", "When enabled, this prevents the offset settings from\nbeing used, as it uses Draconic's previously-default holdtype offset system.") + Derma.freelook = CreateCheckbox(Derma, Vector(150, 30), "AllowFreeLook", "Enable idle freelook", "When enabled, after three seconds of no movement-related input, the camera\nenters a ''freelook'' state, where you can freely orbit your\ncamera around your player.\n\nThis also enables directional movement functionality on ''passive'' holdtypes.\nIf you are using the ''hit position'' camera focus it is recommended to turn this off.") + + Derma.cameraz = CreateSlider(Derma, Vector(15, 70), "Height", "Camera Height", "The height of the camera pole from the origin.") + Derma.cameray = CreateSlider(Derma, Vector(15, 100), "Length", "Camera Distance", "The distance camera pole from the origin.") + + Derma.sliderx = CreateSlider(Derma, Vector(15, 160), "x", "Offset Forward/Back", "It's here if you need it, but you should really\nuse the camera distance for this one.") + Derma.slidery = CreateSlider(Derma, Vector(15, 190), "y", "Offset Left/Right", "") + Derma.sliderz = CreateSlider(Derma, Vector(15, 220), "z", "Offset Up/Down", "") + + Derma.sliderfov = CreateSlider(Derma, Vector(15, 250), "fov", "Base FOV", "NOT EXACT FOV. This is relative to your fov_desired, and should scale accordingly on its own.") + + Derma.sliderlerppos = CreateSlider(Derma, Vector(15, 280), "LerpPos", "Position interpolation", "(Recommended 0.1 minimum) The ''smoothing'' done to the camera's position.") + Derma.sliderlerpang = CreateSlider(Derma, Vector(15, 310), "LerpAngle", "Angle interpolation", "The ''smoothing'' done to the camera's angles. High values recommended for hitpos focus.") + + Derma.ddorigin = CreateDropDown(Derma, Vector(25, 60), "BasePoint", {"Origin", "Pelvis", "Head", "Center"}, "The originating point for the camera.\n0: Pelvis\n1: Head\n2: Center (This is the center of your player's object space, and won't bob with animations.)") + Derma.ddfocal = CreateDropDown(Derma, Vector(25, 140), "FocalPoint", {"Focus", "Player view", "Hit position", "Head angle (not implemented)"}, "The ''focal point'' of your camera.\n0: Player view (eye angles)\n1: Hit position\n2: Head Angle (not implemented yet)") + + CreateButton(Derma, Vector(25, 350), Vector(100, 20), "Reset to default", function() + DRC:ThirdPersonResetToDefault() + end, "Reset the editor to the default thirdperson settings.") + + CreateButton(Derma, Vector(125, 350), Vector(150, 20), "(Debug) Copy settings", function() + SetClipboardText(util.TableToJSON(DRC.ThirdPerson.EditorSettings, true)) + end, "Copy the editor's settings to your clipboard.") + + CreateButton(Derma, Vector(25, 370), Vector(250, 20), "Save & apply NEW preset", function() + DRC:SaveThirdPersonPrompt(true) + end, "Saves a preset as a NEW FILE, or will overwrite an existing one if you enter a duplicate name.\nIf you want to directly overwrite a previous save, use the green button next to a preset's name.") + + local loader = vgui.Create("DPanel", Derma) + loader:SetPos(0, 400) + loader:SetSize(Derma:GetWide(), 320) + loader.Paint = function(self, w, h) + draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 0)) + end + + DRC:CreateThirdPersonPresetMenu(loader, true) +end \ No newline at end of file diff --git a/lua/draconic/drc_lib.lua b/lua/draconic/drc_lib.lua index af732b9..128cc1a 100644 --- a/lua/draconic/drc_lib.lua +++ b/lua/draconic/drc_lib.lua @@ -1,11 +1,11 @@ Draconic = { ["Version"] = 1.02, - ["Help"] = "https://github.com/Vuthakral/Draconic_Base/wiki", + ["Help"] = "http://vuthakral.com/draconic/", ["Author"] = "Vuthakral", } -if SERVER then AddCSLuaFile("sh/convars.lua") end -include("sh/convars.lua") +if SERVER then AddCSLuaFile("sh/globals.lua") end +include("sh/globals.lua") DRC.MapInfo.Name = game.GetMap() DRC.MapInfo.Versions = { @@ -36,6 +36,7 @@ DRC.MapInfo.Versions = { "SDK 2013-CSGO", -- V25: CSGO, Portal 2 Community Edition "Unknown", -- V26: Not documented "SDK 2009? (Contagion)", -- V27: Contagion + "Unknown", -- V28: Not documented / Never used "How the fuck did you load a Titanfall map?", -- V29: Titanfall 1 } @@ -131,15 +132,14 @@ DRC.RoomDefinitions = { ["Outdoors"] = 900, } -DRC.MaterialCategories = {} - -DRC.MaterialCategories.Metal = { -} -DRC.MaterialCategories.Dust = { +-- Surface properties to ignore because they're used internally +DRC.SurfacePropsEngine = { + ["MAT_DEFAULT_SILENT"] = true, -- Sky brushes + ["MAT_$MATERIAL_INDEX_SHADOW"] = true, -- found on func_brush } -- First entry in table is used for sound references, anything else is for particle systems. --- Sound references: cardboard, computer, dirt, flesh, glass, metal, metalhollow, metaldrum, metalvent, mud, plastic, rubber, rubble, sand, snow, bugshell, tile, wood, stone +-- Sound references: cardboard, computer, dirt, flesh, glass, metal, metalhollow, metaldrum, metalvent, mud, plastic, rubber, rubble, sand, snow, tile, wood, stone -- All existing references: cardboard, computer, bugshell, dirt, dust, flesh, gas, glass, liquid, metal, metaldrum, metalhollow, paint, plastic, rubble, sand, shards, snow, synth, tile, wood, stone DRC.SurfacePropDefinitions = { -- Todo for dynamic particles: flesh, tile, synth, plastic, gas, liquid, computer, cardboard ["MAT_DEFAULT"] = {"stone", "dust"}, -- engine @@ -171,6 +171,8 @@ DRC.SurfacePropDefinitions = { -- Todo for dynamic particles: flesh, tile, synth ["MAT_ITEM"] = {"metal"}, -- engine ["MAT_CROWBAR"] = {"metal"}, -- hl2 ["MAT_METAL"] = {"metal"}, -- engine + ["MAT_METAL_SMALL"] = {"metal"}, -- Vindictus + ["MAT_METAL_MEDIUM"] = {"metal"}, -- Vindictus ["MAT_GRATE"] = {"metal"}, -- engine ["MAT_METALGRATE"] = {"metal"}, -- engine ["MAT_METALVEHICLE"] = {"metal", "metalhollow"}, -- hl2 @@ -198,20 +200,27 @@ DRC.SurfacePropDefinitions = { -- Todo for dynamic particles: flesh, tile, synth ["MAT_DIRT"] = {"dirt", "dust"}, -- engine ["MAT_MUD"] = {"mud", "liquid"}, -- engine ["MAT_SLIME"] = {"mud", "liquid"}, -- hl2 + ["MAT_SLIPPERYSLIME"] = {"mud", "liquid"}, -- hl2 ["MAT_SLOSH"] = {"water", "liquid"}, -- CS:S ["MAT_WADE"] = {"water", "liquid"}, -- engine ["MAT_WATER"] = {"water", "liquid"}, -- engine ["MAT_FOLIAGE"] = {"wood", "dirt"}, -- engine ["MAT_HEDGEROW"] = {"wood", "dirt"}, -- CS:S ["MAT_WOOD"] = {"wood", "dirt"}, -- engine + ["MAT_WOOD_SMALL"] = {"wood", "dirt"}, -- Vindictus + ["MAT_WOOD_MEDIUM"] = {"wood", "dirt"}, -- Vindictus ["MAT_WOOD_FURNITURE"] = {"wood"}, -- hl2 ["MAT_WOOD_SOLID"] = {"wood"}, -- hl2 ["MAT_WOOD_CRATE"] = {"wood"}, -- hl2 ["MAT_WOOD_BOX"] = {"wood"}, -- CS:S ["MAT_WOOD_PLANK"] = {"wood"}, -- hl2 ["MAT_WOOD_PANEL"] = {"wood"}, -- hl2 + ["MAT_WOOD_LOWDENSITY"] = {"wood"}, -- CS:S (?) ["MAT_BOULDER"] = {"stone", "rubble", "dirt"}, -- hl2 ["MAT_ROCK"] = {"stone", "rubble", "dirt"}, -- engine + ["MAT_ROCK_LIGHT"] = {"stone", "rubble", "dirt"}, -- Vindictus + ["MAT_ROCK_SMALL"] = {"stone", "rubble", "dirt"}, -- Vindictus + ["MAT_ROCK_MEDIUM"] = {"stone", "rubble", "dirt"}, -- Vindictus ["MAT_STONE"] = {"stone", "rubble", "dirt"}, -- engine ["MAT_GRAVEL"] = {"rubble", "dirt"}, -- engine ["MAT_GRASS"] = {"grass", "dirt", "dust"}, -- engine @@ -244,7 +253,7 @@ function DRC:GetMaterialSound(pack, mat) if mat == -1 then mat = 0 end local ptu mat = DRC:SurfacePropToEnum(util.GetSurfacePropName(mat)) --- if mat = "MAT_DEFAULT_SILENT" then return "", "" end + if mat == "MAT_DEFAULT_SILENT" then return "", "" end if DRC.MaterialSounds[pack] then ptu = DRC.MaterialSounds[pack] else ptu = DRC.MaterialSounds.default end local snd, snd2 = DRC.SurfacePropDefinitions[mat][1] or "fallback", ptu.overlay or "" if ptu[snd] then snd = ptu[snd] else snd = ptu.fallback end @@ -430,6 +439,7 @@ DRC.HelperEnts = { ["drc_csweaponshadow"] = "drc_csweaponshadow", ["drc_csplayermodel"] = "drc_csplayermodel", ["drc_shieldmodel"] = "drc_shieldmodel", + ["npc_enemyfinder"] = "npc_enemyfinder", } DRC.HoldTypes = { @@ -448,7 +458,11 @@ DRC.HoldTypes = { ["attack"] = ACT_RESET, ["reload"] = ACT_RESET, ["melee"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = true, }, ["pistol"] = { ["deploy"] = ACT_VM_DEPLOY_1, @@ -464,7 +478,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_PISTOL, ["reload"] = ACT_RELOAD_PISTOL, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_pistol", + }, + ["shouldered"] = false, }, ["revolver"] = { ["deploy"] = ACT_VM_DEPLOY_1, @@ -480,7 +498,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RESET, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_pistol", + }, + ["shouldered"] = false, }, ["smg"] = { ["deploy"] = ACT_VM_DEPLOY_2, @@ -496,7 +518,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_SMG1, ["reload"] = ACT_RELOAD_SMG1, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.EmptyGeneric", + }, + ["shouldered"] = false, }, ["ar2"] = { ["deploy"] = ACT_VM_DEPLOY_2, @@ -512,7 +538,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_AR2, ["reload"] = ACT_GESTURE_RELOAD, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.EmptyGeneric", + }, + ["shouldered"] = true, }, ["passive"] = { ["deploy"] = ACT_VM_DEPLOY_2, @@ -527,7 +557,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RESET, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["shotgun"] = { ["deploy"] = ACT_VM_DEPLOY_2, @@ -543,7 +577,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_SHOTGUN, ["reload"] = ACT_RELOAD_SHOTGUN, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_heavy", + }, + ["shouldered"] = true, }, ["crossbow"] = { ["deploy"] = ACT_VM_DEPLOY_2, @@ -559,7 +597,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_SHOTGUN, ["reload"] = ACT_GESTURE_RELOAD, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = true, }, ["duel"] = { ["deploy"] = ACT_VM_DEPLOY_7, @@ -573,7 +615,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_HL2MP_GESTURE_RANGE_ATTACK_DUEL, ["reload"] = ACT_HL2MP_GESTURE_RELOAD_DUEL, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_pistol", + }, + ["shouldered"] = false, }, ["physgun"] = { ["deploy"] = ACT_VM_DEPLOY_4, @@ -589,7 +635,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_SHOTGUN, ["reload"] = ACT_GESTURE_RELOAD, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_heavy", + }, + ["shouldered"] = true, }, ["fist"] = { ["deploy"] = ACT_VM_DEPLOY_7, @@ -605,7 +655,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["normal"] = { ["deploy"] = ACT_RESET, @@ -621,7 +675,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_GMOD_GESTURE_MELEE_SHOVE_1HAND, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["rpg"] = { ["deploy"] = ACT_VM_DEPLOY_3, @@ -637,7 +695,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_RPG, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "draconic.dryfire_heavy", + }, + ["shouldered"] = true, }, ["melee"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -653,7 +715,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_MELEE_ATTACK_SWING, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["knife"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -669,7 +735,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_HL2MP_GESTURE_RANGE_ATTACK_KNIFE, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["grenade"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -685,7 +755,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_COMBINE_THROW_GRENADE, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["slam"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -701,7 +775,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_RANGE_ATTACK_SLAM, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["magic"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -717,7 +795,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_HL2MP_GESTURE_RANGE_ATTACK_MAGIC, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["camera"] = { ["deploy"] = ACT_VM_DEPLOY_5, @@ -733,7 +815,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_HL2MP_GESTURE_RANGE_ATTACK_CAMERA, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, ["melee2"] = { ["deploy"] = ACT_VM_DEPLOY_6, @@ -749,7 +835,11 @@ DRC.HoldTypes = { ["npc"] = { ["attack"] = ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND, ["reload"] = ACT_RESET, - } + }, + ["drcsounds"] = { + ["dryfire"] = "", + }, + ["shouldered"] = false, }, } @@ -791,6 +881,7 @@ DRC.HoldTypes.HardcodedWeapons = { function DRC:GetHoldTypeAnim(ht, anim, npc) if !ht or !anim then return end if !DRC.HoldTypes[ht] then ht = "fallback" end + if !npc then npc = false end if npc == false then return DRC.HoldTypes[ht][anim] @@ -824,7 +915,7 @@ end function DRC:Notify(source, typ, severity, msg, enum, thyme, sound) if source != nil && (severity == "warning" or severity == "error" or severity == "critical") then - MsgC( Color(255, 0, 0), "Error from ".. tostring(source) ..": " ) + MsgC( Color(255, 0, 0), "Error from ".. tostring(source) ..":\n") end local var = GetConVar("cl_drc_disable_errorhints"):GetFloat() @@ -900,7 +991,7 @@ function DRC:SightsDown(ent, irons) elseif base == "arc9" then if ent:IsScoping() == true then return true else return false end elseif base == "mwb" then - if ent:GetIsAiming() == true then return true else return false end + if ent:HasFlag("Aiming") then return true else return false end end else if ent.Draconic then @@ -981,27 +1072,27 @@ end function DRC:GetColours(ent, rgb) if !IsValid(ent) then return end local coltab = {} + if ent:IsPlayer() then --- if !ent:Alive() then return end coltab = { ["Player"] = ent:GetNWVector("PlayerColour_DRC"), ["Weapon"] = ent:GetNWVector("WeaponColour_DRC"), - ["Tint1"] = ent:GetNWVector("ColourTintVec1") / 255, - ["Tint2"] = ent:GetNWVector("ColourTintVec2") / 255, - ["Eye"] = ent:GetNWVector("EyeTintVec") / 255, + ["Tint1"] = ent:GetNWVector("ColourTintVec1") * 0.003921568627451, + ["Tint2"] = ent:GetNWVector("ColourTintVec2") * 0.003921568627451, + ["Eye"] = ent:GetNWVector("EyeTintVec") * 0.003921568627451, ["Energy"] = ent:GetNWVector("EnergyTintVec"), - ["$color2"] = Vector(ent:GetColor().r, ent:GetColor().g, ent:GetColor().b)/255, + ["$color2"] = Vector(ent:GetColor().r, ent:GetColor().g, ent:GetColor().b) * 0.003921568627451, ["Grunge"] = ent:GetNWInt("Grunge_DRC"), } else coltab = { ["Player"] = ent:GetNWVector("PlayerColour_DRC"), ["Weapon"] = ent:GetNWVector("WeaponColour_DRC"), - ["Tint1"] = ent:GetNWVector("ColourTintVec1") / 255, - ["Tint2"] = ent:GetNWVector("ColourTintVec2") / 255, - ["Eye"] = ent:GetNWVector("EyeTintVec") / 255, - ["Energy"] = ent:GetNWVector("EnergyTintVec"), - ["$color2"] = Vector(ent:GetColor().r, ent:GetColor().g, ent:GetColor().b)/255, + ["Tint1"] = ent:GetNWVector("ColourTintVec1") * 0.003921568627451, + ["Tint2"] = ent:GetNWVector("ColourTintVec2") * 0.003921568627451, + ["Eye"] = ent:GetNWVector("EyeTintVec") * 0.003921568627451, + ["Energy"] = ent:GetNWVector("EnergyTintVec") * 0.003921568627451, -- I don't know why but for some reason energy values are pulling as ints on non-players even though the code is the same between the two???? + ["$color2"] = Vector(ent:GetColor().r, ent:GetColor().g, ent:GetColor().b) * 0.003921568627451, ["Grunge"] = ent:GetNWFloat("Grunge_DRC"), } end @@ -1115,15 +1206,51 @@ function DRC:RefreshColours(ply) DRC:UpdatePlayerColours(ply) end -local entmeta = FindMetaTable( "Entity" ) -local varfuncs = { - ["Angle"] = entmeta.SetNWAngle, - ["Bool"] = entmeta.SetNWBool, - ["Entity"] = entmeta.SetNWEnt, - ["string"] = entmeta.SetNWString, - ["Vector"] = entmeta.SetNWVector, - ["number"] = "number", -} +function DRC:CopyCustomization(ent1, ent2, coloursonly) + local cols = DRC:GetColours(ent1) + local skin = ent1:GetSkin() + local bgs = DRC:GetBodyGroups(ent1) + if !coloursonly then coloursonly = false end + + if coloursonly == true then + ent2:SetNWVector("PlayerColour_DRC", cols.Player) + ent2:SetNWVector("WeaponColour_DRC", cols.Weapon) + ent2:SetNWVector("ColourTintVec1", cols.Tint1) + ent2:SetNWVector("ColourTintVec2", cols.Tint2) + ent2:SetNWVector("EyeTintVec", cols.Eye) + ent2:SetNWVector("EnergyTintVec", cols.Energy) + ent2:SetNWInt("Grunge_DRC", cols.Grunge) + ent2:SetColor(ent1:GetColor()) + return end + + ent2:SetSkin(skin) + for k,v in pairs(bgs) do + ent2:SetBodygroup(k-1, v) + end + ent2:SetNWVector("PlayerColour_DRC", cols.Player) + ent2:SetNWVector("WeaponColour_DRC", cols.Weapon) + ent2:SetNWVector("ColourTintVec1", cols.Tint1) + ent2:SetNWVector("ColourTintVec2", cols.Tint2) + ent2:SetNWVector("EyeTintVec", cols.Eye) + ent2:SetNWVector("EnergyTintVec", cols.Energy) + ent2:SetNWInt("Grunge_DRC", cols.Grunge) + ent2:SetColor(ent1:GetColor()) +end + +function DRC:CreateCorpse(ent, lifetime, mass, material) + local corpse = ents.Create("drc_corpse") + corpse:SetModel(ent:GetModel()) + corpse:SetPos(ent:GetPos() + Vector(0, 0, 5)) + corpse:SetAngles(ent:GetAngles()) + corpse:SetNWEntity("Originator", ent) + if mass then corpse.Mass = mass end + if lifetime then corpse.Lifetime = lifetime end + if material then corpse.MaterialType = material end + corpse:Spawn() + DRC:CopyCustomization(ent, corpse) + + return corpse +end function DRC:SetNWVar(ent, key, val) local typ = type(val) @@ -1171,7 +1298,7 @@ function DRC:Interact(ply, ent, movement, mouse) if !IsValid(ply) then return end if !ply:Alive() then return end - if IsValid(ent) then ply:SetNWEnt("Interacted_Entity", ent) end + if IsValid(ent) then ply:SetNWEntity("Interacted_Entity", ent) end if movement == nil then movement = false end if mouse == nil then mouse = false end ply:SetNWBool("Interacting", true) @@ -1181,7 +1308,7 @@ function DRC:Interact(ply, ent, movement, mouse) end function DRC:BreakInteraction(ply, ent) - if IsValid(ent) then ply:SetNWEnt("Interacted_Entity", nil) end + if IsValid(ent) then ply:SetNWEntity("Interacted_Entity", nil) end ply:SetNWBool("Interacting", false) ply:SetNWBool("Interacting_StopMovement", false) ply:SetNWBool("Interacting_StopMouse", false) @@ -1310,13 +1437,32 @@ function DRC:GetSWLightMod() return DRC.SWModVal end -function DRC:EyeCone(ply, dist, degree) - if !ply then return end - if !dist then dist = 1000 end +function DRC:EyeCone(ply, dist, degree, angleoverride) degree = math.cos(math.rad(degree)) + local ang = ply:EyeAngles():Forward() + + return ents.FindInCone(ply:EyePos(), angleoverride or ang, dist or 1000, degree) +end + +function DRC:GetConeTarget(source, distance, degrees, angleoverride) + local coneents = DRC:EyeCone(source, distance, degrees, angleoverride) + local targets = {} + for k,v in pairs(coneents) do + if !DRC.HelperEnts[v] && (v:IsPlayer() && v != source) or v:IsNPC() or v:IsNextBot() or DRC:IsVehicle(v) then table.insert(targets, v) end + end + local closesttarget = nil + for k,v in pairs(targets) do + local dist = v:EyePos():DistToSqr(source:EyePos()) + if k == 1 then + closesttarget = {v, dist} + else + if dist < closesttarget[2] then closesttarget = {v, dist} end + end + end + if !closesttarget then return nil end - local cone = ents.FindInCone( ply:EyePos(), ply:GetAimVector(), dist, degree ) - return cone + local target, dist = closesttarget[1], closesttarget[2] + return target, dist end function DRC:GetRoomSizeDSP(size) -- an experiment @@ -1580,7 +1726,7 @@ hook.Add("PlayerInitialSpawn", "drc_InitialSpawnHook", function(ply) end) end) -hook.Add("PlayerSpawn", "drc_DoPlayerSettings", function(ply) +hook.Add("PlayerSpawn", "drc_DoPlayerSettings", function(ply, transition) DRC:RefreshColours(ply) ply.DRCAttachmentInventory = {} ply:SetNWBool("Interacting", false) @@ -1601,6 +1747,8 @@ hook.Add("PlayerSpawn", "drc_DoPlayerSettings", function(ply) DRC:SetVoiceSet(ply, ply:GetInfo("cl_drc_voiceset") or "None", false) DRC:SetFootsteps(ply, ply:GetInfo("cl_drc_footstepset") or "None", false) + DRC:VoiceSetDelayIdle(ply, math.Rand(15, 200)) + net.Start("DRC_RequestSprayInfo") net.Broadcast() @@ -1622,6 +1770,19 @@ hook.Add("PlayerSpawn", "drc_DoPlayerSettings", function(ply) local convar = GetConVar("cl_playerbodygroups") hands:SetBodyGroups(convar) --]] + + if transition == true then + timer.Simple(1, function() + local weps = ply:GetWeapons() + for k,v in pairs(weps) do + if v.Draconic == true then + v.BurstQueue = {} + v.MeleeQueue = {} + v.AmmoCheck = 0 + end + end + end) + end end) hook.Add("StartCommand", "drc_InteractionBlocks", function(ply, cmd) @@ -2188,16 +2349,10 @@ hook.Add("PlayerTick", "drc_movementhook", function(ply) end) function DRC:GetVelocityPose(ent, length, vel, mspd) - local velang = DRC:GetVelocityAngle(ent, true, false, false) + -- hours wasted here: 11 + local velang = DRC:GetVelocityAngle(ent, false, false, false) if vel == Vector() or length == 0 then velang = Angle() end - local tr = DRC:TraceDir(ent:GetPos() + ent:OBBCenter(), velang, 25) - local tr2 = DRC:TraceDir(ent:GetPos() + ent:OBBCenter(), velang:Right():Angle(), 25) - local tr3 = DRC:TraceDir(ent:GetPos() + ent:OBBCenter(), velang:Up():Angle(), 25) - if tr then DRC:RenderTrace(tr, Color(255, 0, 0, 255), FrameTime()) end - if tr2 then DRC:RenderTrace(tr2, Color(0, 0, 255, 255), FrameTime()) end - if tr3 then DRC:RenderTrace(tr3, Color(0, 255, 0, 255), FrameTime()) end - local speed local walk, duck = false, false if ent:IsPlayer() then @@ -2209,32 +2364,36 @@ function DRC:GetVelocityPose(ent, length, vel, mspd) end speed = Lerp(length * 0.0000064, 0, mspd) * 2.64 -- hammer unit funny moment + local tick = 1/engine.TickInterval() + local tr = DRC:TraceDir(ent:GetPos() + ent:OBBCenter(), velang, 0.64 * tick * speed) + if tr then DRC:RenderTrace(tr, Color(255, 0, 0, 255), FrameTime()) end + local p1, p2 = ent:GetPos() + ent:OBBCenter(), tr.HitPos + local diff = Vector(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z) * 0.064 --- ent:ChatPrint(speed) + local EntY = math.abs(ent:EyeAngles().y)/180 + local diffrotator = Lerp(EntY, -1, 1) local mul = 1.5 if walk then mul = 3 end + ent:ChatPrint(tostring(diffrotator)) - ent:SetPlaybackRate(speed*mul) - - ent.DRCVelocityPoseX = Lerp(0.1, ent.DRCVelocityPoseX or velang:Right(), velang:Right()) - ent.DRCVelocityPoseY = Lerp(0.1, ent.DRCVelocityPoseY or velang:Forward(), velang:Forward()) + ent.DRCVelocityPoseX = Lerp(0.01, ent.DRCVelocityPoseX or diff.x, diff.x) * -diffrotator + ent.DRCVelocityPoseY = Lerp(0.01, ent.DRCVelocityPoseY or diff.y, diff.y) * -diffrotator - local percx = (velang:Right() * ent:GetVelocity()) * 0.033 - local percy = (velang:Forward() * ent:GetVelocity()) * 0.033 + local percx = (diff.x * vel.x) * 0.064 + local percy = (diff.y * vel.y) * 0.064 local lx, ly = ent.DRCVelocityPoseX * percx, ent.DRCVelocityPoseY * percy - return ly, lx + return lx, -ly end hook.Add("UpdateAnimation", "DRC_MoveBlendWithoutRootMotion", function(ply, vel, msgs) if ply:LookupPoseParameter("drc_move_x") != -1 && ply:LookupPoseParameter("drc_move_y") != -1 then - local pose = DRC:GetVelocityPose(ply, vel:Length(), vel) - local x, y = pose.x, pose.y + local x, y = DRC:GetVelocityPose(ply, vel:Length(), vel) - ply:SetPoseParameter("drc_move_x", y) - ply:SetPoseParameter("drc_move_y", x) + ply:SetPoseParameter("drc_move_x", x) + ply:SetPoseParameter("drc_move_y", y) if CLIENT then ply:InvalidateBoneCache() end return true end @@ -2316,6 +2475,7 @@ end hook.Add( "PlayerSwitchWeapon", "drc_weaponswitchanim", function(ply, ow, nw) if !SERVER then return end + if nw.ARC9 && GetConVar("arc9_tpik"):GetFloat() == 1 then return end local neww = nw:GetClass() if ow.PickupOnly == true then @@ -2336,7 +2496,7 @@ hook.Add( "PlayerSwitchWeapon", "drc_weaponswitchanim", function(ply, ow, nw) ply:DropWeapon(ow) ply:PickupWeapon(ow) end - end -- holy shit why can there not just be a select weapon function that is predicted/shared? + end end if nw.NoReadyAnimation != true then @@ -2373,8 +2533,37 @@ net.Receive("DRC_Nuke", function(len, ply) return end if ply:IsAdmin() then for k,v in pairs(ents.GetAll()) do - if v:IsNPC() or v:IsNextBot() or v:GetClass() == "prop_physics" or v:GetClass() == "prop_physics_multiplayer" then v:TakeDamage(999999999, ent) v:Remove() - elseif v:IsPlayer() then v:ScreenFade(SCREENFADE.IN, Color(255, 255, 255), 3, 0) + if v:IsNPC() or v:IsNextBot() or v:GetClass() == "prop_physics" or v:GetClass() == "prop_physics_multiplayer" then + if v:IsNPC() && IsValid(v:GetActiveWeapon()) then + local wpn = v:GetActiveWeapon() + v:DropWeapon(wpn) + wpn:Remove() + end + v:TakeDamage(999999999, ent) + v:Remove() + elseif v:IsPlayer() then v:EmitSound("draconic/oof.ogg") v:ScreenFade(SCREENFADE.IN, Color(100, 100, 100), 2, 0) + end + end + end +end) + +net.Receive("DRC_KYS", function(len, ply) + local ent = net.ReadEntity() + if !IsValid(ent) then return end + if !ent:IsAdmin() then + if SERVER then DRC:CheaterWarning(ply, "This player's client attempted to call the 'DRC_KYS' net message but they aren't an admin!") end + return end + if ply:IsAdmin() then + for k,v in pairs(ents.GetAll()) do + if v:IsNPC() or v:IsNextBot() then + if v:IsNPC() && IsValid(v:GetActiveWeapon()) then + local wpn = v:GetActiveWeapon() + v:DropWeapon(wpn) + wpn:Remove() + end + v:TakeDamage(999999999, ent) + v:Remove() + elseif v:IsPlayer() then v:EmitSound("draconic/NOW.ogg") v:ScreenFade(SCREENFADE.IN, Color(130, 170, 255), 0.33, 0) end end end @@ -2408,10 +2597,6 @@ hook.Add("Tick", "drc_ForceThingsToFunction", function() end end) -hook.Add("UpdateTransmitState", "drc_SpotLightTransmit", function(ent) - print(ent) -end) - DraconicAmmoTypes = {} function DRC:AddAmmoType(tbl) table.insert(DraconicAmmoTypes, tbl) @@ -2431,6 +2616,21 @@ local batteryammo = { } DRC:AddAmmoType(batteryammo) +function DRC:AddAmmoTypeSimple(internalname, stringname) + local tbl = { + Name = internalname, + Text = stringname, + DMG = DMG_BULLET, + DamagePlayer = 0, + DamageNPC = 0, + Tracer = TRACER_LINE_AND_WHIZ, + Force = 500, + SplashMin = 5, + SplashMax = 10, + MaxCarry = 9999, + } +end + function DRC:RefreshAmmoTypes() for k,v in pairs(DraconicAmmoTypes) do if !istable(v) then DRC:Notify(nil, nil, "critical", "Someone put a non-table into the Draconic ammo registry, aborting.", ENUM_ERROR, 10) return end @@ -2477,7 +2677,7 @@ function DRC:GetHGMul(ent, hg, dinfo) local infl = dinfo:GetInflictor() if infl.DraconicProjectile == true then infl = infl:GetCreator() end if dinfo:GetDamageCustom() == 2221208 then return 1 end -- prevents running on melee weapons - local mul, enum = 1, HITGROUP_GENERIC + local mul, enum = 1, "HITGROUP_GENERIC" if hg == HITGROUP_HEAD then enum = "HITGROUP_HEAD" elseif hg == HITGROUP_CHEST then enum = "HITGROUP_CHEST" @@ -2486,7 +2686,7 @@ function DRC:GetHGMul(ent, hg, dinfo) elseif hg == HITGROUP_RIGHTARM then enum = "HITGROUP_RIGHTARM" elseif hg == HITGROUP_LEFTLEG then enum = "HITGROUP_LEFTLEG" elseif hg == HITGROUP_RIGHTLEG then enum = "HITGROUP_RIGHTLEG" - elseif hg == HITGROUP_GEAR then enum = "HITGROUP_GEAR" end + elseif hg == HITGROUP_GEAR then enum = "HITGROUP_GEAR"end local BaseProfile = scripted_ents.GetStored("drc_abp_generic") local BT = infl.ActiveAttachments.AmmunitionTypes.t.BulletTable @@ -2499,7 +2699,14 @@ function DRC:GetHGMul(ent, hg, dinfo) TTP = BDT end - mul = TTP[enum] + local headscale = 1 + if hg == HITGROUP_HEAD && !dinfo:GetAttacker():IsPlayer() then + headscale = BT.EvPHeadshots + if !headscale then headscale = BBT.EvPHeadshots end + if headscale == false then headscale = 0.33 end + end + + mul = TTP[enum] * headscale return mul end @@ -2694,9 +2901,20 @@ function DRC:GetBodyGroups(ent) return tbl end +local vehicleclasses = { + ["gmod_sent_vehicle_fphysics_base"] = "sphys", + ["npc_helicopter"] = "npc", + ["npc_combinegunship"] = "npc", + ["haloveh_base"] = "halo", + ["ma2_mech"] = "ma2", + ["ma2_battlesuit"] = "ma2", +} + function DRC:IsVehicle(ent) if !IsValid(ent) then return false end - if ent:IsVehicle() or ent:GetClass() == "gmod_sent_vehicle_fphysics_base" or ent:GetClass() == "npc_helicopter" or ent:GetClass() == "npc_combinegunship" or ent.LFS or ent.LVS or ent.Base == "haloveh_base" or ent.Base == "ma2_mech" or ent.Base == "ma2_battlesuit" then return true else return false end + if ent:IsVehicle() or vehicleclasses[ent:GetClass()] or vehicleclasses[ent.Base] then return true end + if ent.LFS or ent.LVS or ent.IsAVehicle then return true end + return false end function DRC:IsCharacter(ent) @@ -2729,6 +2947,9 @@ if SERVER then ent:SetNWString("DRC_Shield_DepleteEffect", tbl.Effects.Deplete) ent:SetNWString("DRC_Shield_RechargeEffect", tbl.Effects.Recharge) ent:SetNWString("DRC_Shield_Material", tbl.Material) + ent:SetNWString("DRC_Shield_Model", tbl.Model or ent:GetModel()) + ent:SetNWVector("DRC_Shield_BaseScale", tbl.BaseScale or Vector(1,1,1)) + ent:SetNWVector("DRC_Shield_BaseOffset", tbl.BaseOffset or Vector()) ent:SetNWInt("DRC_Shield_PingScale", tbl.ScaleMin) ent:SetNWInt("DRC_Shield_PingScale_Min", tbl.ScaleMin) ent:SetNWInt("DRC_Shield_PingScale_Max", tbl.ScaleMax) @@ -2796,14 +3017,14 @@ if SERVER then local shieldhp = ent:GetNWInt("DRC_ShieldHealth") local overshieldhp = ent:GetNWInt("DRC_ShieldHealth_Extra") if shieldhp <= 0 then ent:SetNWBool("DRC_ShieldDown", true) end - if ent.DoCustomShieldHit then tgt:DoCustomShieldHit(dmg) end + if ent.DoCustomShieldHit then ent:DoCustomShieldHit(amount) end if overshieldhp <= 0 then ent:SetNWInt("DRC_ShieldHealth", math.Clamp(ent:GetNWInt("DRC_ShieldHealth") - amount, 0, ent:GetNWInt("DRC_ShieldMaxHealth"))) ent:SetNWInt("DRC_Shield_DamageTime", CurTime() + ent:GetNWInt("DRC_ShieldRechargeDelay") - engine.TickInterval()) timer.Simple(ent:GetNWInt("DRC_ShieldRechargeDelay"), function() if !IsValid(ent) then return end - if CurTime() > ent:GetNWInt("DRC_Shield_DamageTime") then + if CurTime() > ent:GetNWInt("DRC_Shield_DamageTime") && ent:GetNWInt("DRC_Shield_Recharges") == true then ent:SetNWBool("DRC_ShieldDown", false) DRC:EmitSound(ent, ent:GetNWString("DRC_Shield_RechargeSound"), nil, 1500) local ed = EffectData() @@ -2926,6 +3147,7 @@ local function ProcessInput(ply, shuffle, key) end local function SelectFootstep(ply, shuffle, fs, jump, wade, landing, overlay) + if IsValid(ply:GetVehicle()) then return "", "", 1, 1 end if !fs or string.lower(fs) == "none" then return "" end if landing then shuffle = true end local input = ProcessInput(ply, shuffle) @@ -3162,6 +3384,10 @@ function DRC:RegisterVoiceSetDSPCopy(vs, dsp, subtitle) DRC.VoiceSets[name] = newtab end +function DRC:VoiceSetDelayIdle(ply, thyme) + ply.NextVSIdleTime = CurTime() + thyme +end + function DRC:VoiceSpot(ply) if !IsValid(ply) then return end local voice = DRC.VoiceSets[DRC:GetVoiceSet(ply)] @@ -3183,23 +3409,23 @@ function DRC:VoiceSpot(ply) local target = closesttarget[1]:GetClass() if closesttarget[1]:IsRagdoll() then - DRC:SpeakSentence(ply, "Spotting", "DeadBody", true) + DRC:SpeakSentence(ply, "Spotting", "DeadBody", true, math.Rand(20, 80)) elseif closesttarget[1]:IsNPC() then local disp = closesttarget[1]:Disposition(ply) if !DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Spotting", target) then if disp < 3 then - DRC:SpeakSentence(ply, "Spotting", "Generic_Enemy", true) + DRC:SpeakSentence(ply, "Spotting", "Generic_Enemy", true, math.Rand(120, 220)) else - DRC:SpeakSentence(ply, "Spotting", "Generic_Friendly", true) + DRC:SpeakSentence(ply, "Spotting", "Generic_Friendly", true, math.Rand(20, 80)) end else - DRC:SpeakSentence(ply, "Spotting", target, true) + DRC:SpeakSentence(ply, "Spotting", target, true, math.Rand(20, 80)) end elseif closesttarget[1]:IsNextBot() then if !voice["Spotting"][target] then - DRC:SpeakSentence(ply, "Spotting", "Generic", true) + DRC:SpeakSentence(ply, "Spotting", "Generic", true, math.Rand(20, 80)) end - elseif closesttarget[1]:IsPlayer() then DRC:SpeakSentence(ply, "Spotting", "Generic", true) + elseif closesttarget[1]:IsPlayer() then DRC:SpeakSentence(ply, "Spotting", "Generic", true, math.Rand(20, 80)) end end @@ -3249,7 +3475,7 @@ function DRC:IsVSentenceValid(vs, call, subcall, response) end end -function DRC:SpeakSentence(ent, call, subcall, important) +function DRC:SpeakSentence(ent, call, subcall, important, idledelay) if important == true or !important && !isstring(subcall) then ent.DRCSpeaking = false end if ent.DRCSpeaking == true then return end local num, rng, sel = nil, nil, nil @@ -3279,7 +3505,12 @@ function DRC:SpeakSentence(ent, call, subcall, important) -- ent:EmitSound(start) end ent.DRCSpeaking = true - timer.Simple(durstart, function() if ent:IsValid() then ent:EmitSound(sel, nil, 100, 1, nil, SND_NOFLAGS, dsp) end end) + timer.Simple(durstart, function() + if ent:IsValid() then + ent:EmitSound(sel, nil, 100, 1, nil, SND_NOFLAGS, dsp) + if idledelay != nil then DRC:VoiceSetDelayIdle(ent, idledelay) end + end + end) timer.Simple(dur, function() if ent:IsValid() then if stop then @@ -3311,16 +3542,16 @@ function DRC:ResponseSentence(ent, trigger, response, delay) end end -function DRC:IsDamageFriendly(dmg) +function DRC:IsDamageFriendly(dmg, victim) if !IsValid(dmg) then return end - local att, infl, vic = dmg:GetAttacker(), dmg:GetAttacker(), dmg:GetVictim() + local att, infl = dmg:GetAttacker(), dmg:GetAttacker() - if att:IsPlayer() && vic:IsPlayer() then - if att:Team() == vic:Team() then return true else return false end + if att:IsPlayer() && victim:IsPlayer() then + if att:Team() == victim:Team() then return true else return false end end - if att:IsNPC() && vic:IsPlayer() then - if att:Disposition(vic) >= 3 then return true else return false end + if att:IsNPC() && victim:IsPlayer() then + if att:Disposition(victim) >= 3 then return true else return false end end end @@ -3329,6 +3560,8 @@ function DRC:DamageSentence(ent, damage, dmg) local hp, mhp = ent:Health(), ent:GetMaxHealth() local percentage, newhp = damage/mhp, hp - damage local attacker = dmg:GetAttacker() + local infl = dmg:GetInflictor() + local victim = ent local function PostComplaint(dam, condition, attackerisnpc) local str, thyme = "Minor_Post", math.Rand(1, 3) @@ -3360,21 +3593,23 @@ function DRC:DamageSentence(ent, damage, dmg) str = "Rad_".. str .."" elseif condition == "plasma" then str = "Plasma_".. str .."" + elseif condition == "poison" then + str = "Poison_".. str .."" elseif attackerisnpc == true && DRC:IsVSentenceValid(DRC:GetVoiceSet(ent), "Pain", attacker:GetClass()) then str = attacker:GetClass() end - if DRC:IsDamageFriendly(dmg) then + if DRC:IsDamageFriendly(dmg, victim) then timer.Simple(thyme, function() if IsValid(ent) && ent:Health() > 0.01 then - DRC:SpeakSentence(ent, "Reactions", "FriendlyFire", important) + DRC:SpeakSentence(ent, "Reactions", "FriendlyFire", important, math.Rand(20, 60)) end end) else if DRC:IsVSentenceValid(DRC:GetVoiceSet(ent), "Pain", str) then timer.Simple(thyme, function() if IsValid(ent) && ent:Health() > 0.01 then - DRC:SpeakSentence(ent, "Pain", str, important) + DRC:SpeakSentence(ent, "Pain", str, important, math.Rand(90, 120)) end end) else @@ -3382,40 +3617,54 @@ function DRC:DamageSentence(ent, damage, dmg) thyme = math.Rand(1, 3) timer.Simple(thyme, function() if IsValid(ent) && ent:Health() > 0.01 then - DRC:SpeakSentence(ent, "Pain", str) + DRC:SpeakSentence(ent, "Pain", str, important, math.Rand(90, 120)) end end) end end end - local enum, conditionstring, npc = dmg:GetDamageType(), false, false - if enum == DMG_FALL then conditionstring = "fall" end - if enum == DMG_SHOCK then conditionstring = "shock" end - if enum == DMG_SLOWBURN then conditionstring = "fire" end - if enum == DMG_BURN then conditionstring = "fire" end - if enum == DMG_DIRECT then conditionstring = "fire" end - if enum == DMG_ACID then conditionstring = "acid" end - if enum == DMG_RADIATION then conditionstring = "radiation" end - if enum == DMG_PLASMA then conditionstring = "plasma" end - if attacker then npc = true end - - if conditionstring == "fall" && DRC:IsVSentenceValid(DRC:GetVoiceSet(ent), "Pain", "Fall") && newhp > 0.0001 then - if IsValid(ent) && ent:Health() > 0.01 then - DRC:SpeakSentence(ent, "Pain", "Fall", true) - PostComplaint(percentage, conditionstring) + if DRC:IsVehicle(infl) && (attacker.GetVehicle && attacker:GetVehicle() == infl) then + if percentage >= 0.2 then + DRC:SpeakSentence(ent, "Pain", "Vehicle_Collide_Hard", true, math.Rand(60, 120)) + PostComplaint(percentage, "fall", false) + elseif percentage < 0.2 && percentage >= 0.1 then + DRC:SpeakSentence(ent, "Pain", "Vehicle_Collide", true, math.Rand(60, 120)) + PostComplaint(percentage, "fall", false) + elseif percentage < 0.1 then + DRC:SpeakSentence(ent, "Pain", "Vehicle_Collide", true, math.Rand(60, 120)) + PostComplaint(percentage, "fall", false) + end + else + local enum, conditionstring, npc = dmg:GetDamageType(), false, false + if enum == DMG_FALL then conditionstring = "fall" end + if enum == DMG_SHOCK then conditionstring = "shock" end + if enum == DMG_SLOWBURN then conditionstring = "fire" end + if enum == DMG_BURN then conditionstring = "fire" end + if enum == DMG_DIRECT then conditionstring = "fire" end + if enum == DMG_ACID then conditionstring = "acid" end + if enum == DMG_RADIATION then conditionstring = "radiation" end + if enum == DMG_PLASMA then conditionstring = "plasma" end + if enum == DMG_POISON then conditionstring = "poison" end + if attacker then npc = true end + + if conditionstring == "fall" && DRC:IsVSentenceValid(DRC:GetVoiceSet(ent), "Pain", "Fall") && newhp > 0.0001 then + if IsValid(ent) && ent:Health() > 0.01 then + DRC:SpeakSentence(ent, "Pain", "Fall", true, math.Rand(60, 120)) + PostComplaint(percentage, conditionstring) + end + return end + + if percentage >= 0.2 then + DRC:SpeakSentence(ent, "Pain", "Major", true, math.Rand(60, 120)) + PostComplaint(percentage, conditionstring, npc) + elseif percentage < 0.2 && percentage >= 0.1 then + DRC:SpeakSentence(ent, "Pain", "Medium", true, math.Rand(60, 120)) + PostComplaint(percentage, conditionstring, npc) + elseif percentage < 0.1 then + DRC:SpeakSentence(ent, "Pain", "Minor", true, math.Rand(60, 120)) + PostComplaint(percentage, conditionstring, npc) end - return end - - if percentage >= 0.2 then - DRC:SpeakSentence(ent, "Pain", "Major", true) - PostComplaint(percentage, conditionstring, npc) - elseif percentage < 0.2 && percentage >= 0.1 then - DRC:SpeakSentence(ent, "Pain", "Medium", true) - PostComplaint(percentage, conditionstring, npc) - elseif percentage < 0.1 then - DRC:SpeakSentence(ent, "Pain", "Minor", true) - PostComplaint(percentage, conditionstring, npc) end end @@ -3434,49 +3683,49 @@ function DRC:DeathSentence(vic, att, dmg) if enum == DMG_FALL && newhp > 0.0001 then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_FallDamage") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_FallDamage") + DRC:SpeakSentence(vic, "Pain", "Death_FallDamage", true, 9999) end return end if DRC:IsVehicle(infl) then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Splatter") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_Splatter") + DRC:SpeakSentence(vic, "Pain", "Death_Splatter", true, 9999) end return end if velocity > 650 && (att:IsWorld() or att == vic) then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Falling") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_Falling") + DRC:SpeakSentence(vic, "Pain", "Death_Falling", true, 9999) end return end if damage < microlife then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Light") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_Light") + DRC:SpeakSentence(vic, "Pain", "Death_Light", true, 9999) end elseif damage > microlife && damage < quarterlife then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Medium") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_Medium") + DRC:SpeakSentence(vic, "Pain", "Death_Medium", true, 9999) end elseif damage >= quarterlife then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Major") then - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) else - DRC:SpeakSentence(vic, "Pain", "Death_Major") + DRC:SpeakSentence(vic, "Pain", "Death_Major", true, 9999) end return end - DRC:SpeakSentence(vic, "Pain", "Death") + DRC:SpeakSentence(vic, "Pain", "Death", true, 9999) end function DRC:GetFootsteps(ent) @@ -3490,7 +3739,7 @@ function DRC:GetFootsteps(ent) if ent:GetInfoNum("cl_drc_footstepset_automatic", 0) == 1 then local mdl = player_manager.TranslateToPlayerModelName(ent:GetModel()) local val = DRC:GetPlayerModelValue(mdl, "Footsteps") - if val then vs = val end + if val && val != "" then vs = val end end end @@ -3612,7 +3861,7 @@ function DRC:GetBaseName(ent) if ent.ArcCW then return "arccw" end if ent.ASTWTWO then return "astw2" end if ent.ARC9 then return "arc9" end - if ent.mg_IsPlayerReverbOutside && ent.SprintBehaviourModule then return "mwb" end + if ent.mg_IsPlayerReverbOutside then return "mwb" end if ent.IsSimfphyscar or IsValid(ent:GetOwner()) && ent:GetOwner():GetClass() == "gmod_sent_vehicle_fphysics_base" then return "sphys" end if ent.States && ent.WeaponTypes then return "ma2" end if ent:GetClass() == "decal" then return "decal" end @@ -3807,6 +4056,7 @@ function DRC:CreateProjectile(class, pos, ang, force, owner, inherit) if !SERVER then return end local proj = ents.Create(class) if owner then proj:SetOwner(owner) end + proj.InitialSpeed = force proj:SetPos(pos) proj:SetAngles(ang) proj:Spawn() @@ -3907,6 +4157,22 @@ function DRC:RegisterPlayerExtension(model, val1, val2, val3) end end +if !DRC.WeaponSkins then DRC.WeaponSkins = {} end +function DRC:RegisterWeaponSkin(name, desc, mat, icon, isproxy) + if !isproxy then isproxy = false end + local str + if !isproxy then str = "materials/".. mat ..".vmt" end + if !isproxy && !file.Exists(str, "GAME") then return end + + local ntu + if isproxy == false then ntu = mat else ntu = mat.UniqueName end + + DRC.WeaponSkins[ntu] = {["name"] = name, ["desc"] = desc, ["icon"] = icon or nil, ["proxy"] = isproxy} + if isproxy then DRC.WeaponSkins[ntu]["ProxyMat"] = mat end + + table.SortByMember(DRC.WeaponSkins, "name") +end + hook.Add( "PlayerCanPickupWeapon", "drc_PreventBatteryAmmoPickup", function( ply, weapon ) if !IsValid(ply) or !IsValid(weapon) then return end if weapon.IsBatteryBased == true then @@ -4076,9 +4342,9 @@ end) hook.Add("WeaponEquip", "VoiceSets_WeaponEquip", function(wpn, ply) local vs = DRC:GetVoiceSet(ply) if DRC:IsVSentenceValid(vs, "Actions", "pickup_".. wpn:GetClass() .."") then - DRC:SpeakSentence(ply, "Actions", "pickup_".. wpn:GetClass() .."") + DRC:SpeakSentence(ply, "Actions", "pickup_".. wpn:GetClass() .."", false, math.Rand(20, 80)) elseif DRC:IsVSentenceValid(vs, "Actions", "pickup_generic") then - DRC:SpeakSentence(ply, "Actions", "pickup_generic") + DRC:SpeakSentence(ply, "Actions", "pickup_generic", false, math.Rand(20, 80)) end end) @@ -4242,14 +4508,14 @@ hook.Add("CalcMainActivity", "DRC_BarnacleGrab", function(ply, vel) local wpn = ply:GetActiveWeapon() if !IsValid(wpn) then local seq = ply:LookupSequence("barnacle_unarmed") - if seq != 0 then return ACT_GMOD_NOCLIP_LAYER, seq end + if seq != -1 then return ACT_GMOD_NOCLIP_LAYER, seq end else if wpn:GetHoldType() != "normal" then local seq = ply:LookupSequence("barnacle_armed") - if seq != 0 then return ACT_GMOD_NOCLIP_LAYER, seq end + if seq != -1 then return ACT_GMOD_NOCLIP_LAYER, seq end else local seq = ply:LookupSequence("barnacle_unarmed") - if seq != 0 then return ACT_GMOD_NOCLIP_LAYER, seq end + if seq != -1 then return ACT_GMOD_NOCLIP_LAYER, seq end end end end diff --git a/lua/draconic/sh/convars.lua b/lua/draconic/sh/globals.lua similarity index 88% rename from lua/draconic/sh/convars.lua rename to lua/draconic/sh/globals.lua index 5ab630a..5cafb7e 100644 --- a/lua/draconic/sh/convars.lua +++ b/lua/draconic/sh/globals.lua @@ -1,197 +1,257 @@ -DRC.Convars_CL = {} -DRC.Convars_SV = {} - -function DRC:DebugModeAllowed() - if DRC.SV.drc_allowdebug != 0 then return true else return false end -end - -DRC.SV = {} -function DRC:ServerVar(name, desc, default, mini, maxi, flagoverride) - if !name then return end - if !desc then return end - if !default then default = 1 end - if !mini then mini = 0 end - if !maxi then maxi = 1 end - if !flagoverride then flagoverride = {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO} end - local str2 = "sv_".. name .."" - - CreateConVar(str2, default, flagoverride, desc, mini, maxi) - DRC.SV[name] = GetConVar(str2):GetFloat() - cvars.RemoveChangeCallback(str2, "remove") - cvars.AddChangeCallback(str2, function(vname, old, new) - DRC.SV[name] = tonumber(new) - if SERVER then - net.Start("DRC_SyncServerVar") - net.WriteString(name) - net.WriteFloat(new) - net.Broadcast() - end - end, "remove") -end - -DRC:ServerVar("drc_allowdebug", "Allows all players to access the debug menu of the Draconic Base.", 0, 0, 1) -DRC:ServerVar("drc_soundtime_disabled", "Pitch of audio changing with host_timescale", 0, 0, 1) - -DRC:ServerVar("drc_disable_thirdperson", "Disables Draconic thirdperson access server-wide. (Unless a weapon relies on it)", 0, 0, 1) -DRC:ServerVar("drc_disable_thirdperson_freelook", "Disables Draconic thirdperson's freelook functionality.", 0, 0, 1) - -DRC:ServerVar("drc_playerrep_disallow", "Disables players from accessing playermodel customization from the Draconic Menu.", 0, 0, 1) -DRC:ServerVar("drc_playerrep_tweakonly", "Limits players to only changing their colours/bodygroup/skin in the Draconic Menu. Set to 2 to limit it to colours only, or 3 for bodygroups & skin only.", 0, 0, 3) -DRC:ServerVar("drc_voicesets_noanimations", "Whether or not to disable animations from playing for the 'Help!' and 'Let's go!' voicesets.", 0, 0, 1) - -DRC:ServerVar("drc_movement", "Enables or disables the custom movement modifiers of ALL weapons made on the Draconic SWEP Base.", 1, 0, 1) -DRC:ServerVar("drc_movesounds", "Enables or disables the custom sprint/jump sounds of ALL weapons made on the Draconic SWEP Base.", 1, 0, 1) -DRC:ServerVar("drc_force_sprint", "Forces all Draconic weapons to use the passive-sprint system, regardless of SWEP author intention.", 0, 0, 1) -DRC:ServerVar("drc_passives", "Enables or disables the ability to put weapons in a passive stance.", 1, 0, 1) -DRC:ServerVar("drc_attachments_disallowmodification", "Disallow players from modifying weapon attachments.", 0, 0, 1) -DRC:ServerVar("drc_attachments_autounlock", "When enabled, weapons will spawn with all attachments unlocked. When disabled, only the default (first) attachment in each slot will be unlocked and others will need to be manually picked up or granted to the player by the server.", 1, 0, 1) -DRC:ServerVar("drc_inspections", "Enables or disables the ability to access the inspection mode, which shows weapon stats & allows weapon customization.", 1, 0, 1) -DRC:ServerVar("drc_inspect_hideHUD", "Enables or disables the ability to see the inspection menu.", 1, 0, 1) -DRC:ServerVar("drc_forcebasegameammo", "Force Draconic weaapons to use standard base-game ammunition. (Requires weapon respawn on toggle)", 0, 0, 1) -DRC:ServerVar("drc_infiniteammo", "0 Off | 1 Infinite | 2 Bottomless Mag", 0, 0, 2) -DRC:ServerVar("drc_disable_crosshairs", "Enable/Disable SWEP base crosshairs for all clients. Clients can still disable them on their own, but this can prevent them from using them.", 0, 0, 1) -DRC:ServerVar("drc_viewdrag", "Enables or disables first person camera drag effects with animations.", 0, 0, 1) - ---if GetConVar("sv_drc_movement") == nil then DRC.Convars_SV.Movement = CreateConVar("sv_drc_movement", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the custom movement modifiers of ALL weapons made on the Draconic SWEP Base.", 0, 1) end ---if GetConVar("sv_drc_movesounds") == nil then DRC.Convars_SV.MoveSounds = CreateConVar("sv_drc_movesounds", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the custom sprint/jump sounds of ALL weapons made on the Draconic SWEP Base.", 0, 1) end ---if GetConVar("sv_drc_force_sprint") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_force_sprint", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Forces all DSB weapons to use the passive-sprint system, regardless of SWEP author intention.", 0, 1) end ---if GetConVar("sv_drc_maxrmour") == nil then CreateConVar("sv_drc_maxrmour", 250, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_DEMO}, "Maximum armour a DSB weapon can reapply to.") end -if GetConVar("sv_drc_disable_distgunfire") == nil then DRC.Convars_SV.DistGunfire = CreateConVar("sv_drc_disable_distgunfire", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "If true, disables distant gunfire for weapons. Alleviates network traffic on huge (100+ player) servers.", 0, 1) end ---if GetConVar("sv_drc_inspections") == nil then DRC.Convars_SV.Inspection = CreateConVar("sv_drc_inspections", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to access the inspection mode, which shows weapon stats & puts the viewmodel in an alternate view.", 0, 1) end ---if GetConVar("sv_drc_inspect_hideHUD") == nil then DRC.Convars_SV.Inspection_HideHUD = CreateConVar("sv_drc_inspect_hideHUD", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to see the inspection menu which shows weapon stats.", 0, 1) end ---if GetConVar("sv_drc_passives") == nil then DRC.Convars_SV.Passives = CreateConVar("sv_drc_passives", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to put weapons in a passive stance.", 0, 1) end ---if GetConVar("sv_drc_viewdrag") == nil then DRC.Convars_SV.ViewDrag = CreateConVar("sv_drc_viewdrag", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables first person camera drag effects with animations.", 0, 1) end ---if GetConVar("sv_drc_allowdebug") == nil then DRC.Convars_SV.AllowDebug = CreateConVar("sv_drc_allowdebug", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_DEMO}, "Allows all players to access the debug menu of the Draconic Base.", 0, 1) end ---if GetConVar("sv_drc_disable_thirdperson") == nil then DRC.Convars_SV.DisableTP = CreateConVar("sv_drc_disable_thirdperson", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Disables Draconic thirdperson when not using a weapon which requires it.", 0, 1) end ---if GetConVar("sv_drc_disable_thirdperson_freelook") == nil then DRC.Convars_SV.DisableTP_Freelook = CreateConVar("sv_drc_disable_thirdperson_freelook", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Disables Draconic thirdperson's freelook functionality.", 0, 1) end ---if GetConVar("sv_drc_disable_crosshairs") == nil then DRC.Convars_SV.DisableCrosshairs = CreateConVar("sv_drc_disable_crosshairs", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enable/Disable SWEP base crosshairs for all clients. Clients can still disable them on their own, but this can prevent them from using them.", 0, 1) end ---if GetConVar("sv_drc_forcebasegameammo") == nil then DRC.Convars_SV.BaseGameAmmo = CreateConVar("sv_drc_forcebasegameammo", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Force Draconic weaapons to use standard base-game ammunition. (Requires weapon respawn on toggle)", 0, 1) end ---if GetConVar("sv_drc_infiniteammo") == nil then DRC.Convars_SV.InfiniteAmmo = CreateConVar("sv_drc_infiniteammo", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "0 off | 1 Infinite | 2 Bottomless Mag", 0, 2) end -if GetConVar("cl_drc_disable_errorhints") == nil then DRC.Convars_SV.ErrorHitns = CreateConVar("cl_drc_disable_errorhints", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disables error hints from displaying.", 0, 1) end ---if GetConVar("sv_drc_playerrep_disallow") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_playerrep_disallow", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Disables players from accessing playermodel customization from the Draconic Menu.", 0, 1) end ---if GetConVar("sv_drc_playerrep_tweakonly") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_playerrep_tweakonly", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Limits players to only changing their colours/bodygroup/skin in the Draconic Menu. Set to 2 to limit it to colours only, or 3 for bodygroups only.", 0, 3) end ---if GetConVar("sv_drc_soundtime_disabled") == nil then DRC.Convars_SV.DisableTP = CreateConVar("sv_drc_soundtime_disabled", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Pitch of audio changing with host_timescale", 0, 1) end ---if GetConVar("sv_drc_voicesets_noanimations") == nil then CreateConVar("sv_drc_voicesets_noanimations", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Whether or not to disable animations from playing for the 'Help!' and 'Let's go!' voicesets.", 0, 1) end ---if GetConVar("sv_drc_attachments_disallowmodification") == nil then DRC.Convars_SV.SWEPAttachments = CreateConVar("sv_drc_attachments_disallowmodification", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disallow players from modifying weapon attachments.", 0, 1) end ---if GetConVar("sv_drc_attachments_autounlock") == nil then DRC.Convars_SV.SWEPAttachments = CreateConVar("sv_drc_attachments_autounlock", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "When enabled, weapons will spawn with all attachments unlocked. When disabled, only the default (first) attachment in each slot will be unlocked and others will need to be manually picked up or granted to the player by the server.", 0, 1) end - -local CheeseGrater = {} -- this isn't a perfect solution by a longshot but it will stop most skids at least. - -if CLIENT then - net.Receive("DRC_SyncServerVar", function() - local str, flt = net.ReadString(), net.ReadFloat() - CheeseGrater[str] = flt - DRC.SV[str] = flt - end) - - local hn = "CheeseGrater".. tostring(math.Rand(0, 999999999)) .."" - hook.Add("Think", hn, function() - for k,v in pairs(CheeseGrater) do - if DRC.SV[k] != CheeseGrater[k] then DRC.SV[k] = CheeseGrater[k] end - end - end) - - function DRC:DebugModeEnabled() - if DRC:DebugModeAllowed() == true && GetConVar("cl_drc_debugmode"):GetFloat() != 0 then return true else return false end - end - - if GetConVar("cl_playerhands") == nil then CreateConVar("cl_playerhands", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end - if GetConVar("cl_playerhands_bodygroups") == nil then CreateConVar("cl_playerhands_bodygroups", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end - if GetConVar("cl_playerhands_skin") == nil then CreateConVar("cl_playerhands_skin", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end - if GetConVar("cl_drc_debugmode") == nil then CreateConVar("cl_drc_debugmode", 0, {FCVAR_USERINFO}, "Enables / Disables debug mode of the Draconic Base. (Requires sv_drc_allowdebug.)", 0, 2) end - if GetConVar("cl_drc_debug_invertnearfar") == nil then CreateConVar("cl_drc_debug_invertnearfar", 0, {FCVAR_USERINFO}, "Inverts the near/far sound effect code.", 0, 1) end - if GetConVar("cl_drc_debug_vmattachments") == nil then CreateConVar("cl_drc_debug_vmattachments", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Show/hide the viewmodel attachment visualizations.", 0, 1) end - if GetConVar("cl_drc_debug_legacyassistant") == nil then CreateConVar("cl_drc_debug_legacyassistant", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Show/hide the old legacy debug window 'DSB Debug Assisstant'.", 0, 1) end - if GetConVar("cl_drc_debug_crosshairmode") == nil then DRC.Convars_CL.Debug_Crosshair = CreateConVar("cl_drc_debug_crosshairmode", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "0: No debug crosshair \n 1: Standard debug crosshair /n 2: Melee travel path only /n 3: Full debug crosshair", 0, 3) end - if GetConVar("cl_drc_debug_hitboxes") == nil then DRC.Convars_CL.Debug_Hitboxes = CreateConVar("cl_drc_debug_hitboxes", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable hitbox rendering. Continuously draws the local player's hitboxes, and draws the hitboxes of whatever you are looking at.", 0, 1) end - if GetConVar("cl_drc_debug_bounds") == nil then DRC.Convars_CL.Debug_Hitboxes = CreateConVar("cl_drc_debug_bounds", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable collision bounds rendering. Continuously draws the local player's bounds, and draws the bounds of whatever you are looking at.", 0, 1) end - if GetConVar("cl_drc_debug_tracelines") == nil then DRC.Convars_CL.Debug_Tracelines = CreateConVar("cl_drc_debug_tracelines", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable rendering traces used by the Draconic Base. Detailed information about what each colour means can be found on the wiki.", 0, 1) end - if GetConVar("cl_drc_debug_lights") == nil then DRC.Convars_CL.Debug_Lights = CreateConVar("cl_drc_debug_lights", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable visualizing lights created by the Draconic Base.", 0, 1) end - if GetConVar("cl_drc_debug_sounds") == nil then DRC.Convars_CL.Debug_Sounds = CreateConVar("cl_drc_debug_sounds", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable visualizing lights created by the Draconic Base.", 0, 1) end - if GetConVar("cl_drc_debug_cubemaps") == nil then DRC.Convars_CL.Debug_Cubemaps = CreateConVar("cl_drc_debug_cubemaps", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable rendering the locations of env_cubemap entities.", 0, 1) end - if GetConVar("cl_drc_debug_cubefallbacks") == nil then DRC.Convars_CL.Debug_Cubemaps = CreateConVar("cl_drc_debug_cubefallbacks", 0, {FCVAR_USERINFO}, "Enable/Disable forcing the Draconic Base to think that the current map does not have any envmaps.", 0, 1) end - if GetConVar("cl_drc_debug_alwaysshowshields") == nil then DRC.Convars_CL.Debug_Shields = CreateConVar("cl_drc_debug_alwaysshowshields", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "When set to 1 all DRC shields will constantly render.", 0, 1) end - if GetConVar("cl_drc_debug_hideshaderfixes") == nil then DRC.Convars_CL.Debug_ShaderFixes = CreateConVar("cl_drc_debug_hideshaderfixes", 0, {FCVAR_USERINFO}, "Hides ReflectionTint & ScalingRimLight proxy effects for the sake of showing with vs without.", 0, 1) end - if GetConVar("cl_drc_lowered_crosshair") == nil then CreateConVar("cl_drc_lowered_crosshair", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable Halo-styled lowered crosshair, providing more vertical viewing space.", 0, 1) end - if GetConVar("cl_drc_experimental_fp") == nil then CreateConVar("cl_drc_experimental_fp", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable experimental first person. (Compatibility with other addons not guaranteed.)", 0, 1) end - if GetConVar("cl_drc_experimental_fp_chestscale") == nil then CreateConVar("cl_drc_experimental_fp_chestscale", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Scale inward your playermodel's chest region in first person if your playermodel is blocking your view.", 0, 1) end - if GetConVar("cl_drc_testvar_0") == nil then CreateConVar("cl_drc_testvar_0", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_1") == nil then CreateConVar("cl_drc_testvar_1", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_2") == nil then CreateConVar("cl_drc_testvar_2", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_3") == nil then CreateConVar("cl_drc_testvar_3", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_4") == nil then CreateConVar("cl_drc_testvar_4", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_5") == nil then CreateConVar("cl_drc_testvar_5", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_6") == nil then CreateConVar("cl_drc_testvar_6", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_7") == nil then CreateConVar("cl_drc_testvar_7", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_8") == nil then CreateConVar("cl_drc_testvar_8", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_testvar_9") == nil then CreateConVar("cl_drc_testvar_9", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end - if GetConVar("cl_drc_thirdperson") == nil then CreateConVar("cl_drc_thirdperson", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable Draconic Thirdperson.", 0, 1) end - if GetConVar("cl_drc_thirdperson_flipside") == nil then CreateConVar("cl_drc_thirdperson_flipside", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Flip the thirdperson side the view is on.", 0, 1) end - if GetConVar("cl_drc_thirdperson_disable_freelook") == nil then CreateConVar("cl_drc_thirdperson_disable_freelook", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disable freelook movement in third person.", 0, 1) end - DRC.Convars_CL.ForceEFP = false - --- if GetConVar("cl_drc_sway") == nil then CreateConVar("cl_drc_sway", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable predictive-aim weapon swaying", 0, 1)end - if GetConVar("cl_drc_voiceset") == nil then CreateConVar("cl_drc_voiceset", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE}, "VoiceSet to use. (Can be overriden by servers.)") end - if GetConVar("cl_drc_voiceset_automatic") == nil then CreateConVar("cl_drc_voiceset_automatic", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Automatatically update your VoiceSet to what playermodel authors assign.", 0, 1) end - - if GetConVar("cl_drc_footstepset") == nil then CreateConVar("cl_drc_footstepset", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Footstep set to use. (Can be overriden by servers.)") end - if GetConVar("cl_drc_footstepset_automatic") == nil then CreateConVar("cl_drc_footstepset_automatic", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Automatatically update your footstep sounds to what playermodel authors assign.", 0, 1) end - - if GetConVar("drc_colour_r_player") == nil then - CreateConVar("drc_colour_r_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_r_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_r_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_r_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_r_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_r_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_g_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_b_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - CreateConVar("drc_colour_grunge", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) - end - - if GetConVar("cl_drc_sell_soul") == nil then CreateClientConVar("cl_drc_sell_soul", "1", true, false, "Give unto the dragon.", 0, 1) end - if GetConVar("cl_drc_disable_crosshairs") == nil then CreateClientConVar("cl_drc_disable_crosshairs", "0", true, true, "Hides all DRC related crosshairs (except for debug mode)", 0, 1) end - if GetConVar("cl_drc_eyecolour_r") == nil then CreateConVar("cl_drc_eyecolour_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_eyecolour_g") == nil then CreateConVar("cl_drc_eyecolour_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_eyecolour_b") == nil then CreateConVar("cl_drc_eyecolour_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_energycolour_r") == nil then CreateConVar("cl_drc_energycolour_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_energycolour_g") == nil then CreateConVar("cl_drc_energycolour_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_energycolour_b") == nil then CreateConVar("cl_drc_energycolour_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint1_r") == nil then CreateConVar("cl_drc_tint1_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint1_g") == nil then CreateConVar("cl_drc_tint1_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint1_b") == nil then CreateConVar("cl_drc_tint1_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint2_r") == nil then CreateConVar("cl_drc_tint2_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint2_g") == nil then CreateConVar("cl_drc_tint2_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_tint2_b") == nil then CreateConVar("cl_drc_tint2_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_vmoffset_x") == nil then CreateConVar("cl_drc_vmoffset_x", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_vmoffset_y") == nil then CreateConVar("cl_drc_vmoffset_y", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_vmoffset_z") == nil then CreateConVar("cl_drc_vmoffset_z", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - if GetConVar("cl_drc_playergrunge") == nil then CreateConVar("cl_drc_playergrunge", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) end - - if GetConVar("cl_drc_showspray") == nil then CreateConVar("cl_drc_showspray", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on content that supports it.", 0, 1) end - if GetConVar("cl_drc_showspray_weapons") == nil then CreateConVar("cl_drc_showspray_weapons", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on weapons that support it.", 0, 1) end - if GetConVar("cl_drc_showspray_vehicles") == nil then CreateConVar("cl_drc_showspray_vehicles", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on vehicles that support it.", 0, 1) end - if GetConVar("cl_drc_showspray_player") == nil then CreateConVar("cl_drc_showspray_player", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on your player if the model support it.", 0, 1) end - - if GetConVar("cl_drc_accessibility_photosensitivity_muzzle") == nil then CreateConVar("cl_drc_accessibility_photosensitivity_muzzle", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Dim the effects of the dynamic-light muzzle flashes on Draconic weapons", 0, 1) end - if GetConVar("cl_drc_accessibility_colourblind") == nil then CreateConVar("cl_drc_accessibility_colourblind", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Probably a bad attempt at making game-wide colour correction for those who need it.") end - if GetConVar("cl_drc_accessibility_colourblind_strength") == nil then CreateConVar("cl_drc_accessibility_colourblind_strength", 50, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Colour blindness strength amount.", 0, 100) end - if GetConVar("cl_drc_accessibility_amduser") == nil then CreateConVar("cl_drc_accessibility_amduser", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Changes how certain stuff in the Draconic Base renders to be AMD compatible.", 0, 1) end - - if GetConVar("drc_lightcolour") == nil then CreateConVar("drc_lightcolour", 50, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar used to easily pull your light level for serverside use.", 0, 100) end - - if GetConVar("r_fogcolour") == nil then CreateConVar("r_fogcolour", "127 127 127", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end - if GetConVar("r_fogstart") == nil then CreateConVar("r_fogstart", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end - if GetConVar("r_fogend") == nil then CreateConVar("r_fogend", 10000, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end - if GetConVar("r_fogdensity") == nil then CreateConVar("r_fogdensity", 0.9, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end +-- ### Definitions +DRCD = {} +DRCD.Weapons = { + ["chargeresponses"] = { -- fallback, overcharge, holds + ["dualheld"] = {"primary", "overcharge", true}, + ["dualaction"] = {"primary", "overcharge", false}, + ["discharge"] = {nil, "overcharge", false}, + ["held"] = {nil, "overcharge", true} + }, + ["ironsounds"] = { + ["ar2"] = {"draconic.IronInRifle", "draconic.IronOutRifle"}, + ["smg"] = {"draconic.IronInSMG", "draconic.IronOutSMG"}, + ["duel"] = {"draconic.IronInSMG", "draconic.IronOutSMG"}, + ["pistol"] = {"draconic.IronInPistol", "draconic.IronOutPistol"}, + ["revolver"] = {"draconic.IronInPistol", "draconic.IronOutPistol"}, + ["shotgun"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, + ["crossbow"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, + ["rpg"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, + ["physgun"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, + ["grenade"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["slam"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["melee"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["melee2"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["passive"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["normal"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["knife"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["camera"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + ["magic"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, + }, + ["bloom_updates"] = { + ["standidle"] = 0, + ["crouchidle"] = 0, + ["running"] = 0.1, + ["crouchrunning"] = 0.1, + ["sprinting"] = 0.3, + ["crouchingsprinting"] = 0.3, + ["swimidle"] = 0, + ["swimming"] = 0.1, + }, + ["bloom_maximums"] = { + ["standidle"] = 1, + ["crouchidle"] = 1, + ["running"] = 1.3, + ["crouchrunning"] = 1.3, + ["sprinting"] = 1.7, + ["crouchingsprinting"] = 1.7, + ["swimidle"] = 0.9, + ["swimming"] = 1.1, + } +} + + + +-- ### Convars +DRC.Convars_CL = {} +DRC.Convars_SV = {} + +function DRC:DebugModeAllowed() + if DRC.SV.drc_allowdebug != 0 then return true else return false end +end + +DRC.SV = {} +function DRC:ServerVar(name, desc, default, mini, maxi, flagoverride) + if !name then return end + if !desc then return end + if !default then default = 1 end + if !mini then mini = 0 end + if !maxi then maxi = 1 end + if !flagoverride then flagoverride = {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_DEMO} end + local str2 = "sv_".. name .."" + + CreateConVar(str2, default, flagoverride, desc, mini, maxi) + DRC.SV[name] = GetConVar(str2):GetFloat() + cvars.RemoveChangeCallback(str2, "remove") + cvars.AddChangeCallback(str2, function(vname, old, new) + DRC.SV[name] = tonumber(new) + if SERVER then + net.Start("DRC_SyncServerVar") + net.WriteString(name) + net.WriteFloat(new) + net.Broadcast() + end + end, "remove") +end + +DRC:ServerVar("drc_allowdebug", "Allows all players to access the debug menu of the Draconic Base.", 0, 0, 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}) +DRC:ServerVar("drc_soundtime_disabled", "Pitch of audio changing with host_timescale", 0, 0, 1) + +DRC:ServerVar("drc_disable_thirdperson", "Disables Draconic thirdperson access server-wide. (Unless a weapon relies on it)", 0, 0, 1) +DRC:ServerVar("drc_disable_thirdperson_freelook", "Disables Draconic thirdperson's freelook functionality.", 0, 0, 1) + +DRC:ServerVar("drc_playerrep_disallow", "Disables players from accessing playermodel customization from the Draconic Menu.", 0, 0, 1) +DRC:ServerVar("drc_playerrep_tweakonly", "Limits players to only changing their colours/bodygroup/skin in the Draconic Menu. Set to 2 to limit it to colours only, or 3 for bodygroups & skin only.", 0, 0, 3) +DRC:ServerVar("drc_voicesets_noanimations", "Whether or not to disable animations from playing for the 'Help!' and 'Let's go!' voicesets.", 0, 0, 1) + +DRC:ServerVar("drc_movement", "Enables or disables the custom movement modifiers of ALL weapons made on the Draconic SWEP Base.", 1, 0, 1) +DRC:ServerVar("drc_movesounds", "Enables or disables the custom sprint/jump sounds of ALL weapons made on the Draconic SWEP Base.", 1, 0, 1) +DRC:ServerVar("drc_force_sprint", "0: off | 1: Forces all Draconic weapons to use a passive-sprint, 2: Forces all Draconic weapons to NOT use a passive-sprint.", 0, 0, 2) +DRC:ServerVar("drc_passives", "Enables or disables the ability to put weapons in a passive stance.", 1, 0, 1) +DRC:ServerVar("drc_attachments_disallowmodification", "Disallow players from modifying weapon attachments.", 0, 0, 1) +DRC:ServerVar("drc_attachments_autounlock", "When enabled, weapons will spawn with all attachments unlocked. When disabled, only the default (first) attachment in each slot will be unlocked and others will need to be manually picked up or granted to the player by the server.", 1, 0, 1) +DRC:ServerVar("drc_inspections", "Enables or disables the ability to access the inspection mode, which shows weapon stats & allows weapon customization.", 1, 0, 1) +DRC:ServerVar("drc_inspect_hideHUD", "Enables or disables the ability to see the inspection menu.", 0, 0, 1) +DRC:ServerVar("drc_forcebasegameammo", "Force Draconic weaapons to use standard base-game ammunition. (Requires weapon respawn on toggle)", 0, 0, 1) +DRC:ServerVar("drc_infiniteammo", "0 Off | 1 Infinite | 2 Bottomless Mag", 0, 0, 2) +DRC:ServerVar("drc_disable_crosshairs", "Enable/Disable SWEP base crosshairs for all clients. Clients can still disable them on their own, but this can prevent them from using them.", 0, 0, 1) +DRC:ServerVar("drc_viewdrag", "Enables or disables first person camera drag effects with animations.", 1, 0, 1) + +DRC:ServerVar("drc_funnyplayercorpses", "I added this just to force players to spawn drc_corpse on death as a means of testing.", 0, 0, 1) + +--if GetConVar("sv_drc_movement") == nil then DRC.Convars_SV.Movement = CreateConVar("sv_drc_movement", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the custom movement modifiers of ALL weapons made on the Draconic SWEP Base.", 0, 1) end +--if GetConVar("sv_drc_movesounds") == nil then DRC.Convars_SV.MoveSounds = CreateConVar("sv_drc_movesounds", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the custom sprint/jump sounds of ALL weapons made on the Draconic SWEP Base.", 0, 1) end +--if GetConVar("sv_drc_force_sprint") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_force_sprint", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Forces all DSB weapons to use the passive-sprint system, regardless of SWEP author intention.", 0, 1) end +--if GetConVar("sv_drc_maxrmour") == nil then CreateConVar("sv_drc_maxrmour", 250, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_DEMO}, "Maximum armour a DSB weapon can reapply to.") end +if GetConVar("sv_drc_disable_distgunfire") == nil then DRC.Convars_SV.DistGunfire = CreateConVar("sv_drc_disable_distgunfire", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_DEMO}, "If true, disables distant gunfire for weapons. Alleviates network traffic on huge (100+ player) servers.", 0, 1) end +--if GetConVar("sv_drc_inspections") == nil then DRC.Convars_SV.Inspection = CreateConVar("sv_drc_inspections", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to access the inspection mode, which shows weapon stats & puts the viewmodel in an alternate view.", 0, 1) end +--if GetConVar("sv_drc_inspect_hideHUD") == nil then DRC.Convars_SV.Inspection_HideHUD = CreateConVar("sv_drc_inspect_hideHUD", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to see the inspection menu which shows weapon stats.", 0, 1) end +--if GetConVar("sv_drc_passives") == nil then DRC.Convars_SV.Passives = CreateConVar("sv_drc_passives", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables the ability to put weapons in a passive stance.", 0, 1) end +--if GetConVar("sv_drc_viewdrag") == nil then DRC.Convars_SV.ViewDrag = CreateConVar("sv_drc_viewdrag", 1, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enables or disables first person camera drag effects with animations.", 0, 1) end +--if GetConVar("sv_drc_allowdebug") == nil then DRC.Convars_SV.AllowDebug = CreateConVar("sv_drc_allowdebug", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_DEMO}, "Allows all players to access the debug menu of the Draconic Base.", 0, 1) end +--if GetConVar("sv_drc_disable_thirdperson") == nil then DRC.Convars_SV.DisableTP = CreateConVar("sv_drc_disable_thirdperson", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Disables Draconic thirdperson when not using a weapon which requires it.", 0, 1) end +--if GetConVar("sv_drc_disable_thirdperson_freelook") == nil then DRC.Convars_SV.DisableTP_Freelook = CreateConVar("sv_drc_disable_thirdperson_freelook", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Disables Draconic thirdperson's freelook functionality.", 0, 1) end +--if GetConVar("sv_drc_disable_crosshairs") == nil then DRC.Convars_SV.DisableCrosshairs = CreateConVar("sv_drc_disable_crosshairs", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Enable/Disable SWEP base crosshairs for all clients. Clients can still disable them on their own, but this can prevent them from using them.", 0, 1) end +--if GetConVar("sv_drc_forcebasegameammo") == nil then DRC.Convars_SV.BaseGameAmmo = CreateConVar("sv_drc_forcebasegameammo", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Force Draconic weaapons to use standard base-game ammunition. (Requires weapon respawn on toggle)", 0, 1) end +--if GetConVar("sv_drc_infiniteammo") == nil then DRC.Convars_SV.InfiniteAmmo = CreateConVar("sv_drc_infiniteammo", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "0 off | 1 Infinite | 2 Bottomless Mag", 0, 2) end +if GetConVar("cl_drc_disable_errorhints") == nil then DRC.Convars_SV.ErrorHitns = CreateConVar("cl_drc_disable_errorhints", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disables error hints from displaying.", 0, 1) end +--if GetConVar("sv_drc_playerrep_disallow") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_playerrep_disallow", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Disables players from accessing playermodel customization from the Draconic Menu.", 0, 1) end +--if GetConVar("sv_drc_playerrep_tweakonly") == nil then DRC.Convars_SV.SprintOverride = CreateConVar("sv_drc_playerrep_tweakonly", 0, {FCVAR_REPLICATED, FCVAR_NOTIFY, FCVAR_ARCHIVE, FCVAR_DEMO}, "Limits players to only changing their colours/bodygroup/skin in the Draconic Menu. Set to 2 to limit it to colours only, or 3 for bodygroups only.", 0, 3) end +--if GetConVar("sv_drc_soundtime_disabled") == nil then DRC.Convars_SV.DisableTP = CreateConVar("sv_drc_soundtime_disabled", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Pitch of audio changing with host_timescale", 0, 1) end +--if GetConVar("sv_drc_voicesets_noanimations") == nil then CreateConVar("sv_drc_voicesets_noanimations", 0, {FCVAR_REPLICATED, FCVAR_ARCHIVE, FCVAR_NOTIFY, FCVAR_DEMO}, "Whether or not to disable animations from playing for the 'Help!' and 'Let's go!' voicesets.", 0, 1) end +--if GetConVar("sv_drc_attachments_disallowmodification") == nil then DRC.Convars_SV.SWEPAttachments = CreateConVar("sv_drc_attachments_disallowmodification", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disallow players from modifying weapon attachments.", 0, 1) end +--if GetConVar("sv_drc_attachments_autounlock") == nil then DRC.Convars_SV.SWEPAttachments = CreateConVar("sv_drc_attachments_autounlock", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "When enabled, weapons will spawn with all attachments unlocked. When disabled, only the default (first) attachment in each slot will be unlocked and others will need to be manually picked up or granted to the player by the server.", 0, 1) end + +local CheeseGrater = {} -- this isn't a perfect solution by a longshot but it will stop most skids at least. + +if CLIENT then + net.Receive("DRC_SyncServerVar", function() + local str, flt = net.ReadString(), net.ReadFloat() + CheeseGrater[str] = flt + DRC.SV[str] = flt + end) + + local hn = "CheeseGrater".. tostring(math.Rand(0, 999999999)) .."" + hook.Add("Think", hn, function() + for k,v in pairs(CheeseGrater) do + if DRC.SV[k] != CheeseGrater[k] then DRC.SV[k] = CheeseGrater[k] end + end + end) + + function DRC:DebugModeEnabled() + if DRC:DebugModeAllowed() == true && GetConVar("cl_drc_debugmode"):GetFloat() != 0 then return true else return false end + end + + if GetConVar("cl_playerhands") == nil then CreateConVar("cl_playerhands", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end + if GetConVar("cl_playerhands_bodygroups") == nil then CreateConVar("cl_playerhands_bodygroups", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end + if GetConVar("cl_playerhands_skin") == nil then CreateConVar("cl_playerhands_skin", "", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "c_arms for the player to use, if the server allows for customization of this.") end + if GetConVar("cl_drc_debugmode") == nil then CreateConVar("cl_drc_debugmode", 0, {FCVAR_USERINFO}, "Enables / Disables debug mode of the Draconic Base. (Requires sv_drc_allowdebug.)", 0, 2) end + if GetConVar("cl_drc_debug_invertnearfar") == nil then CreateConVar("cl_drc_debug_invertnearfar", 0, {FCVAR_USERINFO}, "Inverts the near/far sound effect code.", 0, 1) end + if GetConVar("cl_drc_debug_vmattachments") == nil then CreateConVar("cl_drc_debug_vmattachments", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Show/hide the viewmodel attachment visualizations.", 0, 1) end + if GetConVar("cl_drc_debug_legacyassistant") == nil then CreateConVar("cl_drc_debug_legacyassistant", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Show/hide the old legacy debug window 'DSB Debug Assisstant'.", 0, 1) end + if GetConVar("cl_drc_debug_crosshairmode") == nil then DRC.Convars_CL.Debug_Crosshair = CreateConVar("cl_drc_debug_crosshairmode", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "0: No debug crosshair \n 1: Standard debug crosshair /n 2: Melee travel path only /n 3: Full debug crosshair", 0, 3) end + if GetConVar("cl_drc_debug_hitboxes") == nil then DRC.Convars_CL.Debug_Hitboxes = CreateConVar("cl_drc_debug_hitboxes", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable hitbox rendering. Continuously draws the local player's hitboxes, and draws the hitboxes of whatever you are looking at.", 0, 1) end + if GetConVar("cl_drc_debug_bounds") == nil then DRC.Convars_CL.Debug_Hitboxes = CreateConVar("cl_drc_debug_bounds", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable collision bounds rendering. Continuously draws the local player's bounds, and draws the bounds of whatever you are looking at.", 0, 1) end + if GetConVar("cl_drc_debug_tracelines") == nil then DRC.Convars_CL.Debug_Tracelines = CreateConVar("cl_drc_debug_tracelines", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable rendering traces used by the Draconic Base. Detailed information about what each colour means can be found on the wiki.", 0, 1) end + if GetConVar("cl_drc_debug_lights") == nil then DRC.Convars_CL.Debug_Lights = CreateConVar("cl_drc_debug_lights", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable visualizing lights created by the Draconic Base.", 0, 1) end + if GetConVar("cl_drc_debug_sounds") == nil then DRC.Convars_CL.Debug_Sounds = CreateConVar("cl_drc_debug_sounds", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable visualizing lights created by the Draconic Base.", 0, 1) end + if GetConVar("cl_drc_debug_cubemaps") == nil then DRC.Convars_CL.Debug_Cubemaps = CreateConVar("cl_drc_debug_cubemaps", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable rendering the locations of env_cubemap entities.", 0, 1) end + if GetConVar("cl_drc_debug_cubefallbacks") == nil then DRC.Convars_CL.Debug_Cubemaps = CreateConVar("cl_drc_debug_cubefallbacks", 0, {FCVAR_USERINFO}, "Enable/Disable forcing the Draconic Base to think that the current map does not have any envmaps.", 0, 1) end + if GetConVar("cl_drc_debug_alwaysshowshields") == nil then DRC.Convars_CL.Debug_Shields = CreateConVar("cl_drc_debug_alwaysshowshields", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "When set to 1 all DRC shields will constantly render.", 0, 1) end + if GetConVar("cl_drc_debug_hideshaderfixes") == nil then DRC.Convars_CL.Debug_ShaderFixes = CreateConVar("cl_drc_debug_hideshaderfixes", 0, {FCVAR_USERINFO}, "Hides ReflectionTint & ScalingRimLight proxy effects for the sake of showing with vs without.", 0, 1) end + if GetConVar("cl_drc_lowered_crosshair") == nil then CreateConVar("cl_drc_lowered_crosshair", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable Halo-styled lowered crosshair, providing more vertical viewing space.", 0, 1) end + if GetConVar("cl_drc_experimental_fp") == nil then CreateConVar("cl_drc_experimental_fp", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable experimental first person. (Compatibility with other addons not guaranteed.)", 0, 1) end + if GetConVar("cl_drc_experimental_fp_chestscale") == nil then CreateConVar("cl_drc_experimental_fp_chestscale", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Scale inward your playermodel's chest region in first person if your playermodel is blocking your view.", 0, 1) end + if GetConVar("cl_drc_testvar_0") == nil then CreateConVar("cl_drc_testvar_0", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_1") == nil then CreateConVar("cl_drc_testvar_1", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_2") == nil then CreateConVar("cl_drc_testvar_2", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_3") == nil then CreateConVar("cl_drc_testvar_3", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_4") == nil then CreateConVar("cl_drc_testvar_4", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_5") == nil then CreateConVar("cl_drc_testvar_5", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_6") == nil then CreateConVar("cl_drc_testvar_6", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_7") == nil then CreateConVar("cl_drc_testvar_7", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_8") == nil then CreateConVar("cl_drc_testvar_8", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_testvar_9") == nil then CreateConVar("cl_drc_testvar_9", 0, {FCVAR_USERINFO}, "This variable is used to toggle experimental features, please use the menu to change these settings.", 0, 1) end + if GetConVar("cl_drc_thirdperson") == nil then CreateConVar("cl_drc_thirdperson", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/Disable Draconic Thirdperson.", 0, 1) end + if GetConVar("cl_drc_thirdperson_flipside") == nil then CreateConVar("cl_drc_thirdperson_flipside", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Flip the thirdperson side the view is on.", 0, 1) end + if GetConVar("cl_drc_thirdperson_disable_freelook") == nil then CreateConVar("cl_drc_thirdperson_disable_freelook", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Disable freelook movement in third person.", 0, 1) end + if GetConVar("cl_drc_thirdperson_preset") == nil then CreateConVar("cl_drc_thirdperson_preset", "", {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Last loaded preset. Used to automatically select this at session start.") end + DRC.Convars_CL.ForceEFP = false + +-- if GetConVar("cl_drc_sway") == nil then CreateConVar("cl_drc_sway", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable predictive-aim weapon swaying", 0, 1)end + if GetConVar("cl_drc_voiceset") == nil then CreateConVar("cl_drc_voiceset", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE}, "VoiceSet to use. (Can be overriden by servers.)") end + if GetConVar("cl_drc_voiceset_automatic") == nil then CreateConVar("cl_drc_voiceset_automatic", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Automatatically update your VoiceSet to what playermodel authors assign.", 0, 1) end + + if GetConVar("cl_drc_footstepset") == nil then CreateConVar("cl_drc_footstepset", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Footstep set to use. (Can be overriden by servers.)") end + if GetConVar("cl_drc_footstepset_automatic") == nil then CreateConVar("cl_drc_footstepset_automatic", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Automatatically update your footstep sounds to what playermodel authors assign.", 0, 1) end + + if GetConVar("drc_colour_r_player") == nil then + CreateConVar("drc_colour_r_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_player", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_r_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_weapon", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_r_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_eye", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_r_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_energy", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_r_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_acc1", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_r_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_g_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_b_acc2", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + CreateConVar("drc_colour_grunge", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) + end + + if GetConVar("cl_drc_sell_soul") == nil then CreateClientConVar("cl_drc_sell_soul", "1", true, false, "Give unto the dragon.", 0, 1) end + if GetConVar("cl_drc_disable_crosshairs") == nil then CreateClientConVar("cl_drc_disable_crosshairs", "0", true, true, "Hides all DRC related crosshairs (except for debug mode)", 0, 1) end + if GetConVar("cl_drc_eyecolour_r") == nil then CreateConVar("cl_drc_eyecolour_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_eyecolour_g") == nil then CreateConVar("cl_drc_eyecolour_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_eyecolour_b") == nil then CreateConVar("cl_drc_eyecolour_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_energycolour_r") == nil then CreateConVar("cl_drc_energycolour_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_energycolour_g") == nil then CreateConVar("cl_drc_energycolour_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_energycolour_b") == nil then CreateConVar("cl_drc_energycolour_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint1_r") == nil then CreateConVar("cl_drc_tint1_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint1_g") == nil then CreateConVar("cl_drc_tint1_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint1_b") == nil then CreateConVar("cl_drc_tint1_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint2_r") == nil then CreateConVar("cl_drc_tint2_r", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint2_g") == nil then CreateConVar("cl_drc_tint2_g", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_tint2_b") == nil then CreateConVar("cl_drc_tint2_b", "127", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_vmoffset_x") == nil then CreateConVar("cl_drc_vmoffset_x", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_vmoffset_y") == nil then CreateConVar("cl_drc_vmoffset_y", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_vmoffset_z") == nil then CreateConVar("cl_drc_vmoffset_z", "0", {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + if GetConVar("cl_drc_playergrunge") == nil then CreateConVar("cl_drc_playergrunge", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE}) end + + if GetConVar("cl_drc_menu_iconsize") == nil then CreateConVar("cl_drc_menu_iconsize", 3, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "") end + if GetConVar("cl_drc_menu_iconsize_fullscreen") == nil then CreateConVar("cl_drc_menu_iconsize_fullscreen", 3, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "") end + + if GetConVar("cl_drc_showspray") == nil then CreateConVar("cl_drc_showspray", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on content that supports it.", 0, 1) end + if GetConVar("cl_drc_showspray_weapons") == nil then CreateConVar("cl_drc_showspray_weapons", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on weapons that support it.", 0, 1) end + if GetConVar("cl_drc_showspray_vehicles") == nil then CreateConVar("cl_drc_showspray_vehicles", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on vehicles that support it.", 0, 1) end + if GetConVar("cl_drc_showspray_player") == nil then CreateConVar("cl_drc_showspray_player", 1, {FCVAR_USERINFO, FCVAR_ARCHIVE}, "Enable/disable showing your spray on your player if the model support it.", 0, 1) end + + if GetConVar("cl_drc_accessibility_photosensitivity_muzzle") == nil then CreateConVar("cl_drc_accessibility_photosensitivity_muzzle", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Dim the effects of the dynamic-light muzzle flashes on Draconic weapons", 0, 1) end + if GetConVar("cl_drc_accessibility_colourblind") == nil then CreateConVar("cl_drc_accessibility_colourblind", "None", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Probably a bad attempt at making game-wide colour correction for those who need it.") end + if GetConVar("cl_drc_accessibility_colourblind_strength") == nil then CreateConVar("cl_drc_accessibility_colourblind_strength", 50, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Colour blindness strength amount.", 0, 100) end + if GetConVar("cl_drc_accessibility_amduser") == nil then CreateConVar("cl_drc_accessibility_amduser", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Changes how certain stuff in the Draconic Base renders to be AMD compatible.", 0, 1) end + + if GetConVar("drc_lightcolour") == nil then CreateConVar("drc_lightcolour", 50, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar used to easily pull your light level for serverside use.", 0, 100) end + + if GetConVar("r_fogcolour") == nil then CreateConVar("r_fogcolour", "127 127 127", {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end + if GetConVar("r_fogstart") == nil then CreateConVar("r_fogstart", 0, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end + if GetConVar("r_fogend") == nil then CreateConVar("r_fogend", 10000, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end + if GetConVar("r_fogdensity") == nil then CreateConVar("r_fogdensity", 0.9, {FCVAR_USERINFO, FCVAR_ARCHIVE, FCVAR_DEMO}, "Convar added by the Draconic Base for serverside to be able to get fog information about the current map.") end end \ No newline at end of file diff --git a/lua/draconic/sh/spawnmenu.lua b/lua/draconic/sh/spawnmenu.lua index 1f36c0c..9ddbdda 100644 --- a/lua/draconic/sh/spawnmenu.lua +++ b/lua/draconic/sh/spawnmenu.lua @@ -16,29 +16,41 @@ local ignorecats = { ["Half-Life 2"] = true, ["Half-Life: Source"] = true, ["Other"] = true, + ["Fun + Games"] = true, + ["Editors"] = true, + ["Animals"] = true, + ["Combine"] = true, + ["Humans + Resistance"] = true, + ["Nextbot"] = true, + ["Portal"] = true, + ["Zombies + Enemy Aliens"] = true, + ["VJ Base"] = true, + ["Default"] = true, + ["Tools"] = true, + ["Entities"] = true, + ["LVS"] = true, + ["[LVS]"] = true, + ["LFS"] = true, + ["[LFS]"] = true, + ["TFA"] = true, + ["Modern Warfare"] = true, } -local function IconCheck() +local ignoresweps = {"drc_camera", "drc_cubemap"} + +function DRC:AddCategoryIgnore(cat) + ignorecats[cat] = true end hook.Add("PreRegisterSWEP", "DRC_SWEPPreRegister", function(swep, cl) if !string.find(cl, "drc_") then return end - local ignore = {"drc_camera", "drc_cubemap" } - if ignore[cl] then return end + if ignoresweps[cl] then return end if swep.Category && !ignorecats[swep.Category] then DRC.Categories[swep.Category] = swep.Category end if DRC.Categories[swep.Category] then DRC:RegisterCategoryIcon(swep.Category, "icon16/draconic_base.png") end --- if KMA then --- local data = { --- ["PrintName"] = swep.PrintName, --- ["Primary.Damage"] = swep.Primary.Damage, --- } --- KMA.WeaponSpawner:AddTemplate(data, cl) --- end - if swep.CanStore != false then if RE2_INV && swep.WorldModel && swep.WorldModel != "" then -- Support for "Resident Evil 2 Inventory" addon. RE2_INV.AddItem({ @@ -54,4 +66,68 @@ hook.Add("PreRegisterSWEP", "DRC_SWEPPreRegister", function(swep, cl) if !swep.PrintName then swep.PrintName = cl end list.Add("NPCUsableWeapons", {class = cl, title = "[DRC] ".. swep.PrintName .."", category = Category}) -end) \ No newline at end of file +end) + +-- based on garrysmod/gamemodes/sandbox/gamemode/spawnmenu/creationmenu/content/contenttypes/weapons.lua +-- because I know someone is gonna wanna copy this, compare with that file to understand how this works. +-- lol just fucking kidding I can't get it to work properly and broke this trying to fix a minor issue +--[[ +drcwpnslist = {} +hook.Add("PopulateWeapons", "DraconicSWEPSpawnmenuCustom", function(pnl, tree, node) + timer.Simple(0, function() -- I blame garry + for k,v in pairs(list.Get("Weapon")) do + if weapons.IsBasedOn(v.ClassName, "draconic_base") && v.Spawnable == true then + local subcat = weapons.GetStored(v.ClassName).Subcategory or "NONE111" + if subcat != "NONE111" && (drcwpnslist[v.Category] == nil) then + drcwpnslist[v.Category] = {} + table.insert(drcwpnslist[v.Category], v) + end + end + end + + for k,v in pairs(tree:Root():GetChildNodes()) do + if (drcwpnslist[v:GetText()] != nil) then + local cats = { ["Uncategorized"] = {} } + + for kay, vee in pairs(drcwpnslist[v:GetText()]) do + local fuckme = weapons.Get(vee.ClassName) + + if (fuckme.Subcategory == nil) then table.insert(cats.Uncategorized, vee) + else + if cats[fuckme.Subcategory] == nil then cats[fuckme.Subcategory] = {} end + table.insert(cats[fuckme.Subcategory], vee) + end + end + + v.DoPopulate = function(self) + -- if (self.PropPanel) then return end + + self.PropPanel = vgui.Create("ContentContainer", pnl) + self.PropPanel:SetVisible(false) + self.PropPanel:SetTriggerSpawnlistChange(false) + + for catname,weps in SortedPairs(cats) do + if (#weps <= 0) then continue end + + local cattext = vgui.Create("ContentHeader", container) + cattext:SetText(catname) + cattext:SetFont("DraconicSpawnMenuCategory") + cattext:SetTextColor(Color(255, 255, 255)) + + self.PropPanel:Add(cattext) + + for kay,vee in SortedPairsByMemberValue(weps, "PrintName") do + local spawnicon = spawnmenu.CreateContentIcon(vee.ScriptedEntityType or "weapon", self.PropPanel, { + nicename = vee.PrintName, + spawnname = vee.ClassName, + material = "entities/" .. vee.ClassName .. ".png", + admin = vee.AdminOnly, + }) + end -- holy + end -- shit + end -- look + end -- at + end -- this + end) -- fucking +end) -- waterfall +]] \ No newline at end of file diff --git a/lua/draconic/sv/library.lua b/lua/draconic/sv/library.lua index aa885ac..acf4654 100644 --- a/lua/draconic/sv/library.lua +++ b/lua/draconic/sv/library.lua @@ -85,6 +85,11 @@ function DRC:EMP(src, tgt, thyme, sound, effect) tgt:SetActive( false ) timer.Simple(thyme, function() if IsValid(tgt) then tgt:StartEngine() tgt:SetActive(true) tgt:SetNWBool("EMPed", false) end end) end + elseif tgt.Draconic && tgt.IsVehicle == true then + if tgt:EngineStatus() == 1 then + Effects() + timer.Simple(thyme, function() if IsValid(tgt) then tgt:SetNWBool("EMPed", false) end end) + end elseif tgt:GetClass() == "prop_vehicle_jeep" or tgt:GetClass() == "prop_vehicle_airboat" then if tgt:IsEngineStarted() == true then Effects() @@ -226,6 +231,7 @@ util.AddNetworkString("DRCNetworkedAddText") util.AddNetworkString("DRC_SyncSpray") util.AddNetworkString("DRC_RequestSprayInfo") util.AddNetworkString("DRC_Nuke") -- "Nuke Map" dev tool +util.AddNetworkString("DRC_KYS") util.AddNetworkString("DRC_MapVersion") util.AddNetworkString("DRC_MakeShieldEnt") util.AddNetworkString("DRC_WeaponDropped") @@ -243,6 +249,8 @@ util.AddNetworkString("DRC_PlayerSquadMove") util.AddNetworkString("DRC_NetworkScreenShake") util.AddNetworkString("DRC_WeaponAttachSwitch") util.AddNetworkString("DRC_WeaponAttachSwitch_Sync") +util.AddNetworkString("DRC_WeaponCamoSwitch") +util.AddNetworkString("DRC_WeaponCamoSwitch_Sync") util.AddNetworkString("DRC_WeaponAttachClose") util.AddNetworkString("DRC_WeaponAttachForceOpen") util.AddNetworkString("DRC_WeaponAttachSyncInventory") @@ -257,6 +265,10 @@ hook.Add("EntityRemoved", "drc_KillShieldTimer", function(ent) end end) +local function IsMeleeDamage(d) + if d:GetDamageCustom() == 2221208 then return true else return false end +end + local fuckedupmodels = { ["models/combine_dropship.mdl"] = "NoMat", } @@ -266,10 +278,6 @@ hook.Add("EntityTakeDamage", "DRC_EntityTakeDamageHook", function(tgt, dmg) local attacker = dmg:GetAttacker() local vehicle = false - local function IsMeleeDamage(d) - if d:GetDamageCustom() == 2221208 then return true else return false end - end - if !IsMeleeDamage(dmg) && inflictor.Draconic && DRC:IsCharacter(attacker) then dmg:ScaleDamage(attacker:GetNWInt("DRC_GunDamageMod", 1)) elseif IsMeleeDamage(dmg) && inflictor.Draconic && DRC:IsCharacter(attacker) then @@ -294,7 +302,7 @@ hook.Add("EntityTakeDamage", "DRC_EntityTakeDamageHook", function(tgt, dmg) timer.Create("DRCShield_".. tgt.DRCShield_UID .."", 0.1, 0, function() local hp, maxhp = DRC:GetShield(tgt) if hp >= maxhp && tgt:GetNWBool("DRC_ShieldDown") == true then tgt:SetNWBool("DRC_ShieldDown", false) end - if tgt:GetNWBool("DRC_ShieldDown") == false && CurTime() > tgt:GetNWInt("DRC_Shield_DamageTime") && tgt:GetNWInt("DRC_ShieldHealth") != tgt:GetNWInt("DRC_ShieldMaxHealth") then + if tgt:GetNWBool("DRC_ShieldDown") == false && CurTime() > tgt:GetNWInt("DRC_Shield_DamageTime") && tgt:GetNWInt("DRC_ShieldHealth") != tgt:GetNWInt("DRC_ShieldMaxHealth") && tgt:GetNWInt("DRC_Shield_Recharges") == true then DRC:AddShield(tgt, amount/10) end end) @@ -325,7 +333,7 @@ hook.Add("EntityTakeDamage", "DRC_EntityTakeDamageHook", function(tgt, dmg) DRC:PopShield(tgt) DRC:ShieldEffects(tgt, dmg) end - return end + end if DRC:IsVehicle(tgt) then vehicle = true end @@ -397,9 +405,8 @@ hook.Add("EntityTakeDamage", "DRC_EntityTakeDamageHook", function(tgt, dmg) end if inflictor:GetAttachmentValue("Ammunition", "EvPUseHL2Scale") == true && (!attacker:IsPlayer() && tgt:IsPlayer()) then - damagevalue = (damagevalue * 0.3) * hl2diff_take + damagevalue = damagevalue * hl2diff_take end - if inflictor:GetAttachmentValue("Ammunition", "PvEUseHL2Scale") == true && (attacker:IsPlayer() && (tgt:IsNPC() or tgt:IsNextBot())) then damagevalue = damagevalue * hl2diff_inflict end @@ -415,7 +422,7 @@ hook.Add("EntityTakeDamage", "DRC_EntityTakeDamageHook", function(tgt, dmg) end if vehicle == true then damagevalue = damagevalue * inflictor:GetAttachmentValue("Ammunition", "VehicleDamageMul") end - elseif (inflictor.BProfile == true or inflictor.OverrideBProfile != nil) && !IsMeleeDamage(dmg) then + elseif (inflictor.BProfile == true or inflictor.OverrideBProfile != nil) && !IsMeleeDamage(dmg) then if !inflictor:GetCreator().ActiveAttachments then return end BT = inflictor:GetCreator().ActiveAttachments.AmmunitionTypes.t.BulletTable DT = inflictor:GetCreator().ActiveAttachments.AmmunitionTypes.t.BulletTable.MaterialDamageMuls @@ -503,7 +510,8 @@ hook.Add("DoPlayerDeath", "VoiceSets_Death", function(vic, att, dmg) return end if IsValid(infl) then - if DRC:IsVehicle(infl) or att:GetClass() == "npc_antlionguard" or infl:GetClass() == "npc_antlionguard" then + local veh = DRC:IsVehicle(infl) + if veh or att:GetClass() == "npc_antlionguard" or infl:GetClass() == "npc_antlionguard" then if !DRC:IsVSentenceValid(DRC:GetVoiceSet(vic), "Pain", "Death_Splatter") then DRC:SpeakSentence(vic, "Pain", "Death") else @@ -543,6 +551,12 @@ hook.Add("DoPlayerDeath", "VoiceSets_Death", function(vic, att, dmg) DRC:SpeakSentence(vic, "Pain", "Death") end) +hook.Add("PlayerDeath", "Draconic_FunnyPlayerCorpses", function(ply, infl, att) + if GetConVar("sv_drc_funnyplayercorpses"):GetInt() == 1 then + DRC:CreateCorpse(ply, 30) + end +end) + hook.Add("PlayerSpawn", "VoiceSets_Spawn", function(vic, trans) local vs = DRC:GetVoiceSet(vic) if vs == nil then return end @@ -588,6 +602,38 @@ hook.Add("EntityEmitSound", "VoiceSets_Responses", function(tab) end end) +hook.Add("EntityTakeDamage", "VoiceSets_VehicleChecks", function(tgt, dmg) + local att, infl = dmg:GetAttacker(), dmg:GetInflictor() + if att:IsPlayer() then + if DRC:IsVehicle(att) then att = att:GetDriver() end + if att.GetVehicle && att:GetVehicle() == infl && tgt:Health() - dmg:GetDamage() <= 0 then + if DRC:IsVSentenceValid(DRC:GetVoiceSet(att), "Reactions", "Splatter") then + DRC:SpeakSentence(att, "Reactions", "Splatter") + end + end + end +end) + +local function VoiceSetVehicleLine(ply, veh, inout) + if inout == true then + if DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Actions", "Vehicle_Enter") then + DRC:SpeakSentence(ply, "Actions", "Vehicle_Enter") + end + else + if DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Actions", "Vehicle_Exit") then + DRC:SpeakSentence(ply, "Actions", "Vehicle_Exit") + end + end +end + +hook.Add("PlayerEnteredVehicle", "VoiceSets_EnterVehicle", function(ply, vehicle, role) + VoiceSetVehicleLine(ply, vehicle, true) +end) + +hook.Add("PlayerLeaveVehicle", "VoiceSets_ExitVehicle", function(ply, vehicle, role) + VoiceSetVehicleLine(ply, vehicle, false) +end) + hook.Add("PostEntityTakeDamage", "VoiceSets_PostKill", function(tgt, dmg, b) if DRC:IsCharacter(tgt) && DRC:IsCharacter(dmg:GetAttacker()) then local class = tgt:GetClass() @@ -624,6 +670,78 @@ hook.Add("PlayerTick", "DRC_BarnacleGrabDetection", function(ply, cmd) end -- This engine flag always returns false on client, so I make it usable for client players here. end) +hook.Add("PlayerTick", "DRC_VoiceSetsBreathing", function(ply) + if DRC:GetVoiceSet(ply) != nil && DRC.VoiceSets[DRC:GetVoiceSet(ply)].Breathing != nil then + local ct = CurTime() + if !ply.NextVSBreathTime then ply.NextVSBreathTime = 0 end + if !ply.NextVSBreath then ply.NextVSBreath = 0 end -- 0 in 1 out + if ct > ply.NextVSBreathTime then + local n,s,e,w,cv,ju,sprinting = ply:KeyDown(IN_FORWARD), ply:KeyDown(IN_BACK), ply:KeyDown(IN_MOVERIGHT), ply:KeyDown(IN_MOVELEFT), ply:Crouching(), ply:KeyDown(IN_JUMP), ply:KeyDown(IN_SPEED) + local swimming = ply:WaterLevel() == 3 + local settings = DRC.VoiceSets[DRC:GetVoiceSet(ply)].Breathing + local moving = n or s or e or w + + local delay + if !moving && !swimming && !sprinting && !cv then + delay = settings.Delay_Idle or 1 + if ply.NextVSBreath == 0 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "In_Idle") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 1 DRC:SpeakSentence(ply, "Breathing", "In_Idle") + elseif ply.NextVSBreath == 1 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "Out_Idle") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 0 DRC:SpeakSentence(ply, "Breathing", "Out_Idle") + end + elseif !moving && !swimming && !sprinting && cv then + delay = settings.Delay_Crouch or delay + if ply.NextVSBreath == 0 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "In_Crouch") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 1 DRC:SpeakSentence(ply, "Breathing", "In_Crouch") + elseif ply.NextVSBreath == 1 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "Out_Crouch") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 0 DRC:SpeakSentence(ply, "Breathing", "Out_Crouch") + end + elseif moving && !swimming && !sprinting then + delay = settings.Delay_Run or delay + if ply.NextVSBreath == 0 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "In_Run") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 1 DRC:SpeakSentence(ply, "Breathing", "In_Run") + elseif ply.NextVSBreath == 1 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "Out_Run") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 0 DRC:SpeakSentence(ply, "Breathing", "Out_Run") + end + elseif moving && !swimming && sprinting then + delay = settings.Delay_Sprint or delay + if ply.NextVSBreath == 0 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "In_Sprint") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 1 DRC:SpeakSentence(ply, "Breathing", "In_Sprint") + elseif ply.NextVSBreath == 1 && DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Breathing", "Out_Sprint") then + ply.NextVSBreathTime = ct + delay ply.NextVSBreath = 0 DRC:SpeakSentence(ply, "Breathing", "Out_Sprint") + end + end + end + end +end) + +hook.Add("PlayerTick", "DRC_VoiceSetsIdling", function(ply) + if DRC:GetVoiceSet(ply) != nil && DRC.VoiceSets[DRC:GetVoiceSet(ply)].Idle != nil then + local ct = CurTime() + if !ply.NextVSIdleTime then ply.NextVSIdleTime = 0 end + if ct > ply.NextVSIdleTime then + local swimming = ply:WaterLevel() == 3 + local settings = DRC.VoiceSets[DRC:GetVoiceSet(ply)].Idle + local delay = math.random(settings.Delay_Min or 30, settings.Delay_Max or 120) + if !swimming then + local hp, mhp = DRC:Health(ply) + local chp = hp/mhp + if chp < (settings.InjureThreshold or 0.75) && settings.Injured != nil then + if DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Idle", "Generic") then + DRC:SpeakSentence(ply, "Idle", "Injured", false, delay) + end + else + if DRC:IsVSentenceValid(DRC:GetVoiceSet(ply), "Idle", "Generic") then + DRC:SpeakSentence(ply, "Idle", "Generic", false, delay) + end + end + else + DRC:VoiceSetDelayIdle(ply, delay) + end + end + end +end) + -- haha I wrote this whole thing before being told there's an engine flag for this, kms -- keeping it here in case I need it for reference for anything similar in the future. --[[ @@ -672,6 +790,19 @@ hook.Add("Tick", "DRC_BarnacleGrabDetection_Barnacles", function() end end) ]] +hook.Add("PlayerSwitchFlashlight", "drc_IntegratedLights", function(ply, b) + if !IsValid(ply) then return end + if IsValid(ply:GetActiveWeapon()) && ply:KeyDown(IN_USE) then + local wpn = ply:GetActiveWeapon() + if wpn.Draconic && wpn.IntegratedLight_Enabled == true then + if wpn:GetActivity() == ACT_VM_IDLE or wpn:GetActivity() == ACT_WALK then + wpn:ToggleIntegratedLight() + return false + else return false end + end + end +end) + net.Receive("DRCVoiceSet_CL", function(len, ply) local tbl = net.ReadTable() local value = tbl[2] @@ -783,6 +914,22 @@ net.Receive("DRC_WeaponAttachSwitch", function(l,ply) return end end) +net.Receive("DRC_WeaponCamoSwitch", function(l,ply) + local wpn = net:ReadEntity() + local lply = net:ReadEntity() + local mat = net:ReadString() + + if ply != lply then + DRC:CheaterWarning(ply, "This player's client attempted to change the weapon camo of another player.") + else + wpn:SetCamo(mat) + net.Start("DRC_WeaponCamoSwitch_Sync") + net.WriteEntity(wpn) + net.WriteString(mat) + net.Broadcast() + return end +end) + net.Receive("DRC_WeaponAttachClose", function(l,ply) local wpn = net:ReadEntity() local lply = net:ReadEntity() @@ -798,6 +945,7 @@ end) -- ###Debug util.AddNetworkString("DRC_RenderTrace") +util.AddNetworkString("DRC_RenderSphere") function DRC:RenderTrace(tr, colour, thyme) if !game.SinglePlayer() then return end @@ -806,4 +954,13 @@ function DRC:RenderTrace(tr, colour, thyme) net.Start("DRC_RenderTrace") net.WriteTable(tbl) net.Broadcast() +end + +function DRC:RenderSphere(origin, radius, colour, thyme) + if !game.SinglePlayer() then return end + + local tbl = {origin, radius, colour, thyme} + net.Start("DRC_RenderSphere") + net.WriteTable(tbl) + net.Broadcast() end \ No newline at end of file diff --git a/lua/effects/drc_lightvolume.lua b/lua/effects/drc_lightvolume.lua index 893d98b..a9dbc02 100644 --- a/lua/effects/drc_lightvolume.lua +++ b/lua/effects/drc_lightvolume.lua @@ -4,50 +4,85 @@ function EFFECT:Init( data ) local pos, ang, att = data:GetOrigin(), data:GetAngles(), data:GetAttachment() local ent = data:GetEntity() local col, width, length = data:GetStart(), data:GetRadius(), data:GetScale() - data:SetStart(data:GetOrigin()) + data:SetStart(data:GetOrigin()) ang = ent:GetAngles() - + + local mat = ent.DRCVolumeLight.LightMaterial local normal = data:GetNormal() + local emitter = ParticleEmitter(pos) + + local quality = data:GetFlags()*0.01 + local totalnum = length * quality + local noskip = {} + for i=1,totalnum do + local calc = i*(quality/totalnum) + local lerp = Lerp(calc, 0, length)/totalnum + local skip = Lerp(lerp, 0, length) + noskip[skip] = true + end - local emitter = ParticleEmitter( pos ) for i=1,length do - local particle = emitter:Add( "sprites/glow04_noz", pos) - if particle then - local size = Lerp(math.ease.OutSine(i/length), 1, length) * width - local fade = Lerp(math.ease.InSine(i/length), length, 1) - particle:SetMaterial("sprites/glow04_noz") - particle:SetLighting(false) - particle:SetPos(pos + ang:Forward() * i) - particle:SetVelocity(Vector(0, 0, 0)) - particle:SetLifeTime(0) - particle:SetDieTime(1+RealFrameTime()) - particle:SetStartAlpha(fade) - particle:SetEndAlpha(fade) - particle:SetStartSize(size) - particle:SetEndSize(size) - particle:SetStartLength(0) - particle:SetEndLength(0) - particle:SetAngleVelocity(Angle(0, 0, 0)) - particle:SetRoll(0) - particle:SetColor(col.x, col.y, col.z) - particle:SetGravity( Vector(0,0,0) ) - particle:SetAirResistance(0) - particle:SetCollide(true) - particle:SetBounce(0) - - particle:SetCollideCallback(function(part, hitpos, normal) - part:Remove() - end) - - particle:SetNextThink(CurTime()) - particle:SetThinkFunction(function(part) - if !IsValid(ent) then return end - pos = ent:GetAttachment(att).Pos - ang = ent:GetAngles() - part:SetPos(pos + ang:Forward() * i * 0.5) - part:SetNextThink(CurTime() + RealFrameTime()) - end) + if noskip[i] then + local particle = emitter:Add(mat, pos) + if particle then + local size = Lerp(math.ease.OutSine(i/length), 1, length) * width + local fade = Lerp(math.ease.InSine(i/length), length, 1) + local spacing = quality + i*length*0.033 + particle:SetMaterial(mat) + particle:SetLighting(false) + particle:SetPos(pos + ang:Forward() * spacing) + particle:SetVelocity(Vector(0, 0, 0)) + particle:SetLifeTime(0) + particle:SetDieTime(math.huge) + particle:SetStartAlpha(fade) + particle:SetEndAlpha(fade) + particle:SetStartSize(size) + particle:SetEndSize(size) + particle:SetStartLength(0) + particle:SetEndLength(0) + particle:SetAngleVelocity(Angle(0, 0, 0)) + particle:SetRoll(0) + particle:SetColor(col.x, col.y, col.z) + particle:SetGravity( Vector(0,0,0) ) + particle:SetAirResistance(0) + particle:SetCollide(true) + particle:SetBounce(0) + + particle:SetCollideCallback(function(part, hitpos, normal) + part:Remove() + end) + + particle:SetNextThink(CurTime()) + particle:SetThinkFunction(function(part) + local newent = ent + local ply = LocalPlayer() + local thirdperson = DRC:ThirdPersonEnabled(ply) + local light = ent.DRCVolumeLight + if IsValid(ply) then + local vm = ent == LocalPlayer():GetActiveWeapon() && thirdperson == false + if vm then newent = ply:GetViewModel() end + if !IsValid(ent) then part:SetDieTime(0) return end + if !IsValid(newent) then part:SetDieTime(0) return end + if !IsValid(light) then part:SetDieTime(0) return end + if newent:IsWeapon() && newent:GetNWBool("IntegratedLightState") == false then part:SetDieTime(0) end + if newent:LookupAttachment("flashlight") != 0 then att = newent:LookupAttachment("flashlight") end + local atta = newent:GetAttachment(att) + pos = atta.Pos + ang = light:GetAngles() + if light.AddAng then ang = ang + light.AddAng end + part:SetPos(pos + ang:Forward() * spacing * 0.5) + + if light.IsDynamic != false then + local ncol = light.col + if newent == ply && !thirdperson then ncol = Color(0, 0, 0, 0) end + if ent:IsWeapon() && ent.Draconic && ent.IntegratedLight_DoVolume == false then ncol = Color(0, 0, 0, 0) end + part:SetColor(ncol.r, ncol.g, ncol.b) + end + part:SetNextThink(CurTime() + 0) + end + end) + end end end diff --git a/lua/effects/drc_snow.lua b/lua/effects/drc_snow.lua new file mode 100644 index 0000000..d44c774 --- /dev/null +++ b/lua/effects/drc_snow.lua @@ -0,0 +1,84 @@ +function EFFECT:Init( data ) + local Pos = data:GetOrigin() + + self.Position = data:GetStart() + self.Magnitude = data:GetMagnitude()*0.6 + self.Normal = data:GetNormal() + + local emitter = ParticleEmitter( Pos ) + for i = 0,math.Rand(5,math.Clamp(self.Magnitude*4, 150, 350)) do + local particle = emitter:Add( "particle/smokesprites_0001", Pos) + if (particle) then + local chance = math.Round(math.Rand(1,3)) + if chance == 1 then + particle:SetMaterial("particle/smokesprites_0001") + elseif chance == 2 then + particle:SetMaterial("particle/snow") + elseif chance == 3 then + particle:SetMaterial("particle/smokesprites_0014") + end + + local LighCol = render.GetLightColor(Pos) + local OGCol = Vector(255, 255, 255) + OGCol.x = math.Clamp(OGCol.x + (LighCol.r * 255), 0, 255) + OGCol.y = math.Clamp(OGCol.y + (LighCol.g * 255), 0, 255) + OGCol.z = math.Clamp(OGCol.z + (LighCol.b * 255), 0, 255) + + local dir = Vector(math.Rand(-self.Magnitude*2, self.Magnitude*2), math.Rand(-self.Magnitude*2, self.Magnitude*2), 1) + + particle:SetLighting(false) + particle:SetPos(Pos + dir) + particle:SetVelocity((self.Normal * 0.5) * math.Rand(-2, 2) * self.Magnitude + Vector(0, 0, (math.Rand(2, 39)*self.Magnitude)) + dir:Angle():Forward() * (math.Rand(2, 6)*self.Magnitude)) + particle:SetLifeTime(math.Rand(0.1, 0.15)) + particle:SetDieTime(math.Rand(0.3,7)) + particle:SetStartAlpha(math.Rand(100,255)) + particle:SetEndAlpha(0) + particle:SetStartSize(0.004 * self.Magnitude) + particle:SetEndSize(9 * self.Magnitude) + particle:SetStartLength(0) + particle:SetEndLength(0) + particle:SetAngleVelocity( Angle(0,3,0) ) + particle:SetRoll(math.Rand( 0, 30 )) + particle:SetColor(OGCol.x, OGCol.y, OGCol.z) + particle:SetGravity( Vector(0,0,math.Rand(-200, -100)) ) + particle:SetAirResistance(200) + particle:SetCollide(false) + particle:SetBounce(math.Rand(0.1,0.2)) + + if chance == 2 then + particle:SetVelocity((self.Normal * 0.5) * math.Rand(-2, 2) * self.Magnitude + Vector(0, 0, (math.Rand(2, 29)*self.Magnitude)) + dir:Angle():Forward() * (math.Rand(2, 16)*self.Magnitude)) + particle:SetStartAlpha(255) + particle:SetEndAlpha(255) + particle:SetDieTime(math.Rand(3,7)) + particle:SetStartSize(math.Rand(0.01, 0.05)*self.Magnitude) + particle:SetEndSize(0) + particle:SetAirResistance(0) + particle:SetGravity(Vector(0, 0, -600)) + particle:SetCollide(true) + particle:SetColor(255, 255, 255) + end + + particle:SetNextThink(CurTime()) + particle:SetThinkFunction(function(part) + local ll = render.GetLightColor(part:GetPos()) + local lla = ll.x + ll.y + ll.z / 3 + local mini = 1 + local smoketint = Vector(math.Clamp((200 * ll.x), mini, 255), math.Clamp((200 * ll.y), mini, 255), math.Clamp((200 * ll.z), mini, 255)) + local boost = 100 + smoketint.x = smoketint.x + (boost * lla) + smoketint.y = smoketint.y + (boost * lla) + smoketint.z = smoketint.z + (boost * lla) + part:SetColor(smoketint.x,smoketint.y,smoketint.z) + part:SetNextThink(CurTime() + math.Rand(0.2, 1)) + end) + end + end + + emitter:Finish() +end + +function EFFECT:Think() +end + +function EFFECT:Render() +end \ No newline at end of file diff --git a/lua/entities/draconic_ammo_station.lua b/lua/entities/draconic_ammo_station.lua index b6f385e..a7e07ab 100644 --- a/lua/entities/draconic_ammo_station.lua +++ b/lua/entities/draconic_ammo_station.lua @@ -23,7 +23,7 @@ ENT.AdminOnly = false ENT.Model = "models/items/ammocrate_smg1.mdl" ENT.UseDelay = 0 -ENT.ATR = 0 +ENT.ATR = nil ENT.HidePopup = false ENT.RemoveOnUse = false ENT.PickupType = "ammostation" @@ -31,6 +31,8 @@ ENT.UseType = "simple" ENT.UseSound = "" ENT.DenySound = "" +ENT.SpecificAmmoType = nil + ENT.Whitelist = nil ENT.WhitelistIsBlack = false @@ -56,11 +58,11 @@ ENT.DamageType = DMG_GENERIC ENT.AffectRadius = 150 -- The "DO NOT TOUCH" zone. -ENT.CD = false ENT.Draconic = true ENT.Dead = false ENT.LastInflictor = nil ENT.Powered = true +ENT.NextUseTime = 0 function ENT:Initialize() self:DoCustomInitialize() @@ -91,23 +93,18 @@ function ENT:OnTakeDamage(dmginfo) timer.Simple(self.DamageDelay, function(dg) if not self:IsValid() then return end self:SetHealth(self:Health() - self.DamageTaken) - -- self.LastInflictor:ChatPrint("".. dmginfo:GetDamage() .." - ".. self:Health() .." left") end) end ENT.PhysDamageCD = 0 function ENT:PhysicsCollide(data, col) - if self.Destroyable == true then if CurTime() > self.PhysDamageCD then - -- print("Speed: ", data.Speed) self.PhysDamageCD = CurTime() + 0.5 local damage = data.Speed / 20 damage = math.Round(math.pow(damage, data.Speed / 1000)) if damage < 3 then damage = 0 end - -- print("Damage:", damage) - -- print("Health Remain:", self:Health()) if damage > 25 or (self:Health() - damage <= 0) then self:EmitSound("MetalGrate.ImpactHard") elseif damage < 25 && damage > 2 then @@ -129,7 +126,7 @@ function ENT:LuaExplode(effe, damage, dt, ep, radius, shake, shakedist, shaketim local phys = self:GetPhysicsObject() local owner = self:GetOwner() - DRCSound(self, self.BreakSound, nil, 1500) + DRC:EmitSound(self, self.BreakSound, nil, 1500) if self.LastInflictor == nil then self.Killer = self @@ -168,13 +165,10 @@ function ENT:LuaExplode(effe, damage, dt, ep, radius, shake, shakedist, shaketim }) local ang = tr.Normal:Angle() v:SetVelocity(ang:Forward() * dist * 3) - -- v:SetVelocity((v:OBBCenter()-pos)*ep/(v:OBBCenter()):Distance(pos) * 50) end if SERVER then v:TakeDamageInfo(dmg2) end end end - --- util.ScreenShake( Vector( self:GetPos() ), (shake / 2), shake, shaketime, shakedist ) if self:IsValid() then if effe != nil then @@ -194,6 +188,10 @@ function ENT:LuaExplode(effe, damage, dt, ep, radius, shake, shakedist, shaketim self:DoCustomBreak() end +function ENT:CanUse() + if CurTime() > self.NextUseTime then return true else return false end +end + function ENT:Think() if self.Destroyable == true then if self.Dead == false && self:Health() <= 0 then @@ -220,7 +218,8 @@ end function ENT:GetRequiredEnt() local EntsInRange = ents.FindByClass( self.RequiredEnt ) - if table.IsEmpty(EntsInRange) then return false end + if table.IsEmpty(EntsInRange) then return false end + for k,v in ipairs(EntsInRange) do local pos = self:GetPos() local epos = v:GetPos() @@ -238,73 +237,71 @@ function ENT:GetRequiredEnt() end function ENT:Use(_, ply) + if !self:CanUse() then self:EmitSound(self.DenySound) return end local curswep = ply:GetActiveWeapon() - if not IsValid(curswep) then return end + if !IsValid(curswep) then return end self:DoCustomUse(ply, curswep) if self.RequiredEnt != nil && self.PickupType != "stationrequirement" then - self.Powered = false - if self:GetRequiredEnt() == true then - self.Powered = true - else - self.Powered = false - end + self.Powered = false + if self:GetRequiredEnt() == true then self.Powered = true else self.Powered = false end end if self.Powered == false then return end -if self.CD == true then - self:EmitSound(self.DenySound) -else + if self.Whitelist != nil then if self.WhitelistIsBlack == false then if table.HasValue(self.Whitelist, curswep:GetClass()) then self:GiveAmmo(ply) - else self:EmitSound(self.DenySound) end + else + if self.SpecificAmmoType != nil then self:GiveAmmo(ply, true) else self:EmitSound(self.DenySound) end + end else if table.HasValue(self.Whitelist, curswep:GetClass()) then self:EmitSound(self.DenySound) - else self:GiveAmmo(ply) end + else + if self.SpecificAmmoType != nil then self:GiveAmmo(ply, true) else self:EmitSound(self.DenySound) end + end end else self:GiveAmmo(ply) end end + + +function ENT:DoGiveAmmo(ply, atr, wpn, hide) + self:EmitSound(self.UseSound) + local ct = CurTime() + local retur = self.ATR or wpn:GetMaxClip1() + local typ = self.SpecificAmmoType or wpn:GetPrimaryAmmoType() + + ply:GiveAmmo(retur, typ, hide) + if self.UseDelay > 0 then self.NextUseTime = ct + self.UseDelay end + + if self.RemoveOnUse == true then self:Remove() end end -function ENT:GiveAmmo(ply) +function ENT:DoBatteryReset(ply, wpn, hide) + self:EmitSound(self.UseSound) + local ct = CurTime() + wpn:SetLoadedAmmo(100) + if self.UseDelay > 0 then self.NextUseTime = ct + self.UseDelay end + if self.RemoveOnUse == true then self:Remove() end +end + +function ENT:GiveAmmo(ply, override) local curswep = ply:GetActiveWeapon() - if not IsValid(curswep) then return end + if !IsValid(curswep) then return end + local ct = CurTime() + local atr = self.ATR + local pop = self.HidePopup + if override == true then pop = false end if self.PickupType == "universalstation" then if curswep.Base == "draconic_gun_base" then - self:EmitSound(self.UseSound) - if self.ATR == 0 then - ply:GiveAmmo(curswep:GetMaxClip1(), curswep:GetPrimaryAmmoType(), self.HidePopup) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - else - ply:GiveAmmo(self.ATR, curswep:GetPrimaryAmmoType(), self.HidePopup) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - end - if self.RemoveOnUse == true then - self:Remove() - end + self:DoGiveAmmo(ply, atr, curswep, pop) elseif curswep.Base == "draconic_battery_base" then - self:EmitSound(self.UseSound) - curswep.Weapon:SetNWInt("LoadedAmmo", 100) - curswep:SetClip1(100) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - if self.RemoveOnUse == true then - self:Remove() - end + self:DoBatteryReset(ply, curswep, pop) elseif curswep.Base == "draconic_melee_base" then if curswep.InfoName == nil then ply:ChatPrint("I don't think my ".. curswep.PrintName .." uses bullets...") @@ -312,27 +309,11 @@ function ENT:GiveAmmo(ply) ply:ChatPrint("I don't think my ".. curswep.InfoName .." uses bullets...") end else - ply:ChatPrint("This ammo station only works with Draconic SWEPs!") + self:DoGiveAmmo(ply, atr, curswep, pop) end elseif self.PickupType == "ammostation" then if curswep.Base == "draconic_gun_base" then - self:EmitSound(self.UseSound) - if self.ATR == 0 then - ply:GiveAmmo(curswep:GetMaxClip1(), curswep:GetPrimaryAmmoType(), self.HidePopup) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - else - ply:GiveAmmo(self.ATR, curswep:GetPrimaryAmmoType(), self.HidePopup) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - end - if self.RemoveOnUse == true then - self:Remove() - end + self:DoGiveAmmo(ply, atr, curswep, pop) elseif curswep.Base == "draconic_battery_base" then self:EmitSound(self.DenySound) elseif curswep.Base == "draconic_melee_base" then @@ -342,23 +323,14 @@ function ENT:GiveAmmo(ply) ply:ChatPrint("I don't think my ".. curswep.InfoName .." uses bullets...") end else - ply:ChatPrint("This ammo station only works with Draconic SWEPs!") + self:DoGiveAmmo(ply, atr, curswep, pop) end elseif self.PickupType == "batterystation" then if curswep.Base == "draconic_gun_base" then self:EmitSound(self.DenySound) elseif curswep.Base == "draconic_battery_base" then - if curswep.Weapon:GetNWInt("LoadedAmmo") < 100 then - self:EmitSound(self.UseSound) - curswep.Weapon:SetNWInt("LoadedAmmo", 100) - curswep:SetClip1(100) - if self.UseDelay > 0 then - self.CD = true - timer.Simple(self.UseDelay, function() self.CD = false end) - end - if self.RemoveOnUse == true then - self:Remove() - end + if curswep:GetLoadedAmmo() < 100 then + self:DoBatteryReset(ply, curswep, pop) else self:EmitSound(self.DenySound) end @@ -369,9 +341,8 @@ function ENT:GiveAmmo(ply) ply:ChatPrint("I don't think I should shove my ".. curswep.InfoName .." into this...") end else - ply:ChatPrint("This ammo station only works with Draconic SWEPs!") + ply:ChatPrint("This ammo station only works with Draconic SWEPs (for now)!") end - elseif self.PickupType == "stationrequirement" then end end diff --git a/lua/entities/draconic_projectile_base.lua b/lua/entities/draconic_projectile_base.lua index 5758972..9123783 100644 --- a/lua/entities/draconic_projectile_base.lua +++ b/lua/entities/draconic_projectile_base.lua @@ -40,9 +40,42 @@ ENT.ExplosionType = "hl2" ENT.ExplosiveIgnoresCover = false ENT.RemoveInWater = false +ENT.StickSound = nil + +ENT.MaxBounces = 0 +ENT.BounceChance = 100 +ENT.BounceMaxAngle = 30 +ENT.BouncePreservesSpeed = true +ENT.BounceCharacters = false +ENT.BounceVehicles = false +ENT.BounceDestructibles = false +ENT.BounceSound = nil +ENT.BounceSurfaces = { + ["cardboard"] = false, + ["computer"] = true, + ["bugshell"] = true, + ["dirt"] = false, + ["flesh"] = false, + ["glass"] = true, + ["metal"] = true, + ["metalhollow"] = true, + ["metaldrum"] = true, + ["metalvent"] = true, + ["mud"] = false, + ["plastic"] = true, + ["rubber"] = false, + ["rubble"] = true, + ["stone"] = true, + ["sand"] = false, + ["snow"] = false, + ["tile"] = true, + ["wood"] = true, +} + ENT.Tracking = false ENT.TrackType = "Tracking" ENT.TrackFraction = 0.5 +ENT.TrackingSpeed = nil ENT.SuperCombineRequirement = 0 ENT.SuperDamage = 100 @@ -79,6 +112,13 @@ ENT.Effect = nil ENT.SpawnEffect = nil ENT.LuaExplEffect = nil ENT.SuperLuaExplEffect = nil +ENT.RemoveEffect = nil + +ENT.PCFEffect = nil +ENT.PCFSpawnEffect = nil +ENT.PCFLuaExplEffect = nil +ENT.PCFSuperLuaExplEffect = nil +ENT.PCFRemoveEffect = nil ENT.ImpactEffect = nil ENT.ImpactSound = nil @@ -143,6 +183,8 @@ ENT.ManualDetect = { "npc_hunter", "npc_combinedropship" } +ENT.BounceCount = 0 +ENT.BounceDoolDown = 0 function ENT:GetCreator() return self.Creator @@ -163,15 +205,19 @@ end ENT.EffectTick = 0 ENT.ThinkTimer = 0 +ENT.UpdateLastInfo = 0 function ENT:Think() if !IsValid(self) then return end local ct = CurTime() - if CLIENT && self.Effect != nil && RealTime() > self.EffectTick then - local ed = EffectData() - ed:SetOrigin(self:GetPos()) - ed:SetEntity(self) - util.Effect(self.Effect, ed) + if CLIENT && (self.Effect != nil or self.PCFEffect != nil) && RealTime() > self.EffectTick then + if self.Effect != nil then + local ed = EffectData() + ed:SetOrigin(self:GetPos()) + ed:SetEntity(self) + util.Effect(self.Effect, ed) + end + if self.PCFEffect != nil then ParticleEffect(self.PCFEffect, self:GetPos(), self:GetAngles(), self) end self.EffectTick = (RealTime() + 1/self.EffectTickRate) end @@ -202,7 +248,11 @@ function ENT:Think() end end - self.LastPos = pos + if self.UpdateLastInfo < ct then + self.UpdateLastInfo = ct + engine.TickInterval() + self.LastPos = pos + self.LastAng = phys:GetAngles() + end -- if !timer.Exists(self.TimerName) && tipe != "sticky" && tipe != "playersticky" && tipe != "supercombine" && tipe != "magazine" then -- timer.Create(self.TimerName, self.TimerFrequency, 0, function() @@ -246,12 +296,15 @@ function ENT:Think() if !IsValid(self) or !IsValid(self:GetPhysicsObject()) then return end - local tr = util.TraceLine({ + self.FrontTrace = util.TraceLine({ start = self:GetPos(), endpos = self:GetPos() + vel:GetNormal() * 100, filter = function(ent) if ent == self or ent == self:GetOwner() or ent == self:GetCreator() then return false else return true end end, mask = MASK_SHOT_HULL }) + local tr = self.FrontTrace + self.LastHitNormal = tr.HitNormal + if tr then DRC:RenderTrace(tr, Color(255, 255, 255, 255), FrameTime(), true) end if tr.Entity == nil then return end if self.Triggered == true then return end @@ -305,7 +358,13 @@ function ENT:PhysicsUpdate() local tgt = self.TrackTarget if IsValid(tgt) && IsValid(Entity(tgt:EntIndex())) then local endp = tgt:GetPos() + tgt:OBBCenter() - if DRC:IsVehicle(tgt) then endp = tgt:GetPos() + Vector(0, 0, 2) end + if DRC:IsVehicle(tgt) then + if tgt:LookupAttachment("tracking_goal") != 0 then + endp = tgt:GetAttachment(tgt:LookupAttachment("tracking_goal")).Pos + else + endp = tgt:GetPos() + Vector(0, 0, 2) + end + end local tr = util.TraceLine({ start = phys:GetPos(), endpos = endp, @@ -321,7 +380,11 @@ function ENT:PhysicsUpdate() ang = Angle(angx, angy, angz) phys:SetAngles(ang) - phys:SetVelocity(phys:GetAngles():Forward() * self:GetCreator().Primary.ProjSpeed) + if self.TrackingSpeed != nil then + phys:SetVelocity(phys:GetAngles():Forward() * self.TrackingSpeed) + else + phys:SetVelocity(phys:GetAngles():Forward() * self:GetCreator().Primary.ProjSpeed) + end elseif isvector(tgt) then local tr = util.TraceLine({ start = phys:GetPos(), @@ -370,18 +433,20 @@ function ENT:Initialize() end end - if self.InheritDamageFromCreatorPrimary == true then self.Damage = self:GetCreator().Primary.Damage end - if self.InheritDamageFromCreatorSecondary == true then self.Damage = self:GetCreator().Secondary.Damage end + local creator = self:GetCreator() + + if self.InheritDamageFromCreatorPrimary == true then self.Damage = creator.Primary.Damage end + if self.InheritDamageFromCreatorSecondary == true then self.Damage = creator.Secondary.Damage end self:DoCustomInitialize() - if IsValid(self:GetCreator()) && self:GetCreator():IsWeapon() then + if IsValid(creator) && creator:IsWeapon() then self.BProfile = true - if self.Tracking == true then + if self.Tracking == true && creator.Draconic then if self.TrackType == "Tracking" then - self.TrackTarget = self:GetCreator():GetTraceTarget() - if IsValid(self:GetCreator():GetConeTarget()) then self.TrackTarget = self:GetCreator():GetConeTarget() end + self.TrackTarget = creator:GetTraceTarget() + if IsValid(creator:GetConeTarget()) then self.TrackTarget = creator:GetConeTarget() end end end end @@ -394,6 +459,7 @@ function ENT:Initialize() timer.Simple(0.0000000001, function() if self:IsValid() then self.SpawnVelocity = self:GetVelocity() end end) local phys = self:GetPhysicsObject() + self.LastAng = phys:GetAngles() phys:SetBuoyancyRatio(self.Buoyancy) if self.Mass == 0 then self.Mass = 1 phys:SetMass(self.Mass) end if self.Mass != nil then phys:SetMass(self.Mass) end @@ -451,11 +517,14 @@ function ENT:Initialize() timer.Simple(self.FuseTime, function() if self:IsValid() then self:TriggerExplosion() end end) else end - if self.SpawnEffect != nil then - local ed2 = EffectData() - ed2:SetOrigin(self:GetPos()) - ed2:SetEntity(self) - util.Effect(self.SpawnEffect, ed2) + if self.SpawnEffect != nil or self.PCFSpawnEffect != nil then + if self.SpawnEffect != nil then + local ed2 = EffectData() + ed2:SetOrigin(self:GetPos()) + ed2:SetEntity(self) + util.Effect(self.SpawnEffect, ed2) + end + if self.PCFSpawnEffect != nil then ParticleEffect(self.PCFSpawnEffect, self:GetPos(), self:GetAngles(), self) end end if self.LoopingSound != nil then @@ -525,8 +594,6 @@ end function ENT:DoCustomDraw() end -local cooldown = 0 - function ENT:Touch(ent) local ty = self.ProjectileType @@ -546,6 +613,9 @@ function ENT:Touch(ent) end end +function ENT:DoCustomStick(data, ent) +end + function ENT:Stick(data, tgt) self:SetSolid(SOLID_NONE) self:SetMoveType(MOVETYPE_NONE) @@ -553,127 +623,184 @@ function ENT:Stick(data, tgt) self:DoImpactEffect() self:SetVelocity(Vector()) self:SetPos(data.HitPos) + if self.StickSound != nil then self:EmitSound(self.StickSound) end self:SetNWBool("Stuck", true) + + self:DoCustomStick(data, tgt) +end + +function ENT:CheckBounceValidity(data) + if self.BounceMaxAngle == 0 then return true end + local ang1 = DRC:GetVelocityAngle(data.OurOldVelocity) + local ang2 = DRC:GetVelocityAngle(data.OurNewVelocity) + + local dx, dy = math.AngleDifference(ang1.x, ang2.x), math.AngleDifference(ang1.y, ang2.y) + dx, dy = math.abs(dx), math.abs(dy) + + local xg, yg = dx > self.BounceMaxAngle, dy > self.BounceMaxAngle + + if xg == true or yg == true then return false else return true end + return true end +function ENT:CheckBounceIgnorance(ent) + if self.BounceCharacters == false && DRC:IsCharacter(ent) then return true end + if self.BounceVehicles == false && DRC:IsVehicle(ent) then return true end + if self.BounceDestructibles == false && ent.GetMaxHealth && ent:Health() > 0 then return true end + return false +end + +function ENT:CheckBounceMaterial(sprop) + local matstring = DRC:SurfacePropToEnum(util.GetSurfacePropName(sprop)) + if DRC.SurfacePropsEngine[matstring] then return false end + local str = DRC.SurfacePropDefinitions[matstring][1] + local retr = self.BounceSurfaces[str] + if retr == nil then retr = true end + return retr +end + +ENT.burncooldown = 0 +ENT.bouncecooldown = 0 function ENT:PhysicsCollide( data, phys ) if !IsValid(self) or !IsValid(self:GetPhysicsObject()) then return end local typ = self.ProjectileType local tgt = data.HitEntity local cl = self:GetClass() local SCC = "sc_".. self:GetClass() .."" + local sprop = data.TheirSurfaceProps + local ct = CurTime() + + if ct > self.bouncecooldown && self.MaxBounces > 0 && self.BounceCount < self.MaxBounces && (math.Rand(0, 100) <= self.BounceChance) && self:CheckBounceValidity(data) && self:CheckBounceIgnorance(tgt) == false && self:CheckBounceMaterial(sprop) then + timer.Simple(0, function() if IsValid(self) then + self.BounceCount = self.BounceCount + 1 + end end) + self.BounceDoolDown = ct + 0.05 + if self.BouncePreservesSpeed == true then timer.Simple(0.1, function() if IsValid(self) then + phys:SetAngleVelocity(Vector()) + phys:SetVelocity(DRC:GetVelocityAngle(self):Forward() * self.InitialSpeed) + end end) end + if self.BounceSound != nil then self:EmitSound(self.BounceSound) end + return end + + if ct < self.BounceDoolDown then return end if self.Triggered == true then return end self.Triggered = true - if self:GetCreator():IsWeapon() && self:GetCreator().Draconic == true && typ == "point" then - if self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal") != nil && !tgt:IsNPC() then - util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal"), self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) - end - - if self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal") != nil && !tgt:IsNPC() then - util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal"), self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) + if ((self:GetCreator():IsWeapon() && self:GetCreator().Draconic == true) or self.OverrideBProfile != nil) && typ == "point" then + if self.OverrideBProfile != nil then + local tbl = scripted_ents.GetStored(self.OverrideBProfile).t.BulletTable + local impact, burn = tbl.ImpactDecal, tbl.BurnDecal + if impact != nil then util.Decal( impact, self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) end + if burn != nil then util.Decal( burn, self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) end + else + if self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal") != nil && !tgt:IsNPC() then + util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal"), self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) + end + + if self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal") != nil && !tgt:IsNPC() then + util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal"), self:GetPos(), self:GetPos() + self:GetAngles():Forward() * 100, self) + end end end timer.Simple(0, function() - if tgt:IsWorld() == false then - if !IsValid(tgt) then SafeRemoveEntity(self) return end - local NI = tgt:GetNWInt(SCC) - if typ == "point" then - local tr = util.TraceLine({start=self:GetPos(), endpos=tgt:LocalToWorld(tgt:OBBCenter()), filter={self, self:GetOwner()}, mask=MASK_SHOT_HULL}) - self:SetPos(data.HitPos) - self:DamageTarget(tgt, tr) - self:DoImpactEffect() - - SafeRemoveEntity(self) - if self.EMP == true then self:DoEMP(tgt) end - elseif typ == "explosive" then - self:TriggerExplosion() - self:DoImpactEffect() - if self.EMP == true then self:DoEMP(tgt) end - elseif typ == "lua_explosive" then - self.ExplosionType = "lua" - self:TriggerExplosion() - self:DoImpactEffect() - if self.EMP == true then self:DoEMP(tgt) end - elseif typ == "playersticky" then - if tgt:IsNPC() or tgt:IsNextBot() or (tgt:IsPlayer() and tgt ~= self:GetOwner()) or (tgt == self:GetOwner() and tgt:IsVehicle()) then - self:Stick(data, tgt) + if !IsValid(self) then return end + if tgt:IsWorld() == false then + if !IsValid(tgt) then SafeRemoveEntity(self) return end + local NI = tgt:GetNWInt(SCC) + if typ == "point" then + local tr = util.TraceLine({start=self:GetPos(), endpos=tgt:LocalToWorld(tgt:OBBCenter()), filter={self, self:GetOwner()}, mask=MASK_SHOT_HULL}) + self:SetPos(data.HitPos) + self:DamageTarget(tgt, tr) self:DoImpactEffect() - if self.Explosive == false then self:DamageTarget(tgt, tr) end + + SafeRemoveEntity(self) if self.EMP == true then self:DoEMP(tgt) end - end - elseif typ == "sticky" then - if tgt != self:GetOwner() then + elseif typ == "explosive" then + self:TriggerExplosion() + self:DoImpactEffect() + if self.EMP == true then self:DoEMP(tgt) end + elseif typ == "lua_explosive" then + self.ExplosionType = "lua" + self:TriggerExplosion() + self:DoImpactEffect() + if self.EMP == true then self:DoEMP(tgt) end + elseif typ == "playersticky" then + if tgt:IsNPC() or tgt:IsNextBot() or (tgt:IsPlayer() and tgt ~= self:GetOwner()) or (tgt == self:GetOwner() and tgt:IsVehicle()) then + self:Stick(data, tgt) + self:DoImpactEffect() + if self.Explosive == false then self:DamageTarget(tgt, tr) end + if self.EMP == true then self:DoEMP(tgt) end + end + elseif typ == "sticky" then + if tgt != self:GetOwner() then + self:Stick(data, tgt) + if self.Explosive == false then self:DamageTarget(tgt, tr) end + timer.Simple(15, function() if self.Explosive == false && self:IsValid() then self:Remove() end end) + if self.EMP == true then self:DoEMP(tgt) end + end + elseif typ == "FuseAfterFirstBounce" then + if self.FirstBounce == false then self.FirstBounce = true end + if self.FirstBounce == true then timer.Simple(self.FuseTime, function() if self:IsValid() then self:TriggerExplosion() end end) end + elseif typ == "supercombine" then self:Stick(data, tgt) - if self.Explosive == false then self:DamageTarget(tgt, tr) end - timer.Simple(15, function() if self.Explosive == false && self:IsValid() then self:Remove() end end) + self:DoImpactEffect() if self.EMP == true then self:DoEMP(tgt) end - end - elseif typ == "FuseAfterFirstBounce" then - if self.FirstBounce == false then self.FirstBounce = true end - if self.FirstBounce == true then timer.Simple(self.FuseTime, function() if self:IsValid() then self:TriggerExplosion() end end) end - elseif typ == "supercombine" then - self:Stick(data, tgt) - self:DoImpactEffect() - if self.EMP == true then self:DoEMP(tgt) end - if self:GetParent() != nil && self:GetParent():IsNPC() or self:GetParent():IsPlayer() or self:GetParent():IsNextBot() then - if NI >= self.SuperCombineRequirement - 1 then - for f, v in pairs(tgt:GetChildren()) do - if v:GetClass() == self:GetClass() then - v:Remove() + if self:GetParent() != nil && self:GetParent():IsNPC() or self:GetParent():IsPlayer() or self:GetParent():IsNextBot() then + if NI >= self.SuperCombineRequirement - 1 then + for f, v in pairs(tgt:GetChildren()) do + if v:GetClass() == self:GetClass() then + v:Remove() + end end + self:TriggerSC() + tgt:SetNWInt(SCC, 0) + else + tgt:SetNWInt(SCC, NI + 1) end - self:TriggerSC() - tgt:SetNWInt(SCC, 0) - else - tgt:SetNWInt(SCC, NI + 1) + timer.Simple(self.FuseTime, function() + if IsValid(tgt) then + local CNI = tgt:GetNWInt(SCC) + tgt:SetNWInt(SCC, math.Clamp(CNI - 1, 0, 99)) + NI = math.Clamp(NI, 0, 99) + end + end) end - -- print(NI) - timer.Simple(self.FuseTime, function() + end + elseif tgt:IsWorld() == true then + if typ == "point" then + timer.Simple(0.01, function() if IsValid(self) then self:Remove() end end) + self:SetPos(data.HitPos) + self:DoImpactEffect() + elseif typ == "explosive" then + self:TriggerExplosion() + self:DoImpactEffect() + elseif typ == "lua_explosive" then + self.ExplosionType = "lua" + self:TriggerExplosion() + self:DoImpactEffect() + elseif typ == "sticky" or typ == "supercombine" then + self:Stick(data, tgt) + self:DoImpactEffect() + elseif typ == "FuseAfterFirstBounce" then + if self.FirstBounce == false then self.FirstBounce = true end + if self.FirstBounce == true then timer.Simple(self.FuseTime, function() if self:IsValid() then self:TriggerExplosion() end end) end + elseif typ == "fire" then - local CNI = tgt:GetNWInt(SCC) - tgt:SetNWInt(SCC, math.Clamp(CNI - 1, 0, 99)) - NI = math.Clamp(NI, 0, 99) - -- print("Supercombine entity removed. | SC Score: ".. NI .."") - - end) + if ct > self.burncooldown then + local startpos = self:GetPos() + local endpos = self:GetVelocity():Angle():Forward() * 25 + util.Decal("Scorch", startpos, endpos, {self}) + self.burncooldown = ct + 0.05 + end end end - elseif tgt:IsWorld() == true then - if typ == "point" then - timer.Simple(0.01, function() if IsValid(self) then self:Remove() end end) - self:SetPos(data.HitPos) - self:DoImpactEffect() - elseif typ == "explosive" then - self:TriggerExplosion() - self:DoImpactEffect() - elseif typ == "lua_explosive" then - self.ExplosionType = "lua" + + if self.ProjectileType == "custom_explosive" then + self.ExplosionType = "custom" self:TriggerExplosion() - self:DoImpactEffect() - elseif typ == "sticky" or typ == "supercombine" then - self:Stick(data, tgt) - self:DoImpactEffect() - elseif typ == "FuseAfterFirstBounce" then - if self.FirstBounce == false then self.FirstBounce = true end - if self.FirstBounce == true then timer.Simple(self.FuseTime, function() if self:IsValid() then self:TriggerExplosion() end end) end - elseif typ == "fire" then - - if CurTime() > cooldown then - local startpos = self:GetPos() - local endpos = self:GetVelocity():Angle():Forward() * 25 - util.Decal("Scorch", startpos, endpos, {self}) - cooldown = CurTime() + 0.05 - end end - end - - if self.ProjectileType == "custom_explosive" then - self.ExplosionType = "custom" - self:TriggerExplosion() - end end) self:DoCustomPhysicsCollide(data, phys) @@ -776,18 +903,27 @@ function ENT:TriggerExplosion(nodecal) local U = DRC:TraceDir(pos, Angle(-90, 0, 0), dist) local D = DRC:TraceDir(pos, Angle(90, 0, 0), dist) local TraceTable = {N, S, E, W, U, D} + + local impact, burn + if (self:GetCreator():IsWeapon() && self:GetCreator().Draconic == true) or self.OverrideBProfile != nil && typ == "point" then + if self.OverrideBProfile != nil then + local tbl = scripted_ents.GetStored(self.OverrideBProfile).t.BulletTable + impact, burn = tbl.ImpactDecal, tbl.BurnDecal + else + impact = self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal") + burn = self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal") + end + end - if self:GetCreator():IsWeapon() && self:GetCreator().Draconic == true && nodecal == false then - for k,v in pairs(TraceTable) do - if v.Hit then - if v.HitSky then return end - if self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal") != nil && !v.Entity:IsNPC() then - util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "ImpactDecal"), self:GetPos(), v.HitPos + v.Normal:Angle():Forward() * 100, self) - end - - if self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal") != nil && !v.Entity:IsNPC() then - util.Decal( self:GetCreator():GetAttachmentValue("Ammunition", "BurnDecal"), self:GetPos(), v.HitPos + v.Normal:Angle():Forward() * 100, self) - end + for k,v in pairs(TraceTable) do + if v.Hit then + if v.HitSky then return end + if impact != nil && !v.Entity:IsNPC() then + util.Decal( impact, self:GetPos(), v.HitPos + v.Normal:Angle():Forward() * 100, self) + end + + if burn != nil && !v.Entity:IsNPC() then + util.Decal( burn, self:GetPos(), v.HitPos + v.Normal:Angle():Forward() * 100, self) end end end @@ -848,6 +984,7 @@ function ENT:LuaExplode(mode) self.MSExplShakeDist = self.ExplodeShakeDistance self.MSExplShakeTime = self.ExplodeShakeTime self.MSLuaEffect = self.LuaExplEffect + self.MSPCFExplode = self.PCFLuaExplEffect elseif mode == "super" then self.MSDamage = self.SuperDamage self.MSDamageType = self.SuperDamageType @@ -857,8 +994,11 @@ function ENT:LuaExplode(mode) self.MSExplShakeDist = self.SuperExplodeShakeDistance self.MSExplShakeTime = self.SuperExplodeShakeTime self.MSLuaEffect = self.SuperLuaExplEffect + self.MSPCFExplode = self.PCFSuperLuaExplEffect end + DRC:RenderSphere(pos, self.MSRadius, Color(255, 0, 0, 100), 2) + DRC:DynamicParticle(self, self.MSPressure * 30, self.MSPressure * 20, "blast") local entities = ents.FindInSphere(pos, self.MSRadius) @@ -910,12 +1050,18 @@ function ENT:LuaExplode(mode) util.ScreenShake( Vector( self:GetPos() ), (self.MSExplShakePower / 2), self.MSExplShakePower, self.MSExplShakeTime, self.MSExplShakeDist ) if self:IsValid() then - if self.LuaExplEffect != nil then - local ed3 = EffectData() - ed3:SetOrigin(pos) - ed3:SetEntity(self) - util.Effect(self.MSLuaEffect, ed3) - -- print(self:GetPos()) + if self.LuaExplEffect != nil or self.MSPCFExplode != nil then + if self.LuaExplEffect != nil then + local ed3 = EffectData() + ed3:SetOrigin(pos) + ed3:SetEntity(self) + util.Effect(self.MSLuaEffect, ed3) + end + if mode == "super" then + if self.MSPCFExplode != nil then ParticleEffect(self.MSPCFExplode, self:GetPos(), Angle(), nil) end + else + if self.MSPCFExplode != nil then ParticleEffect(self.MSPCFExplode, self:GetPos(), (self:GetAngles():Forward() * -50):Angle(), nil) end + end end end @@ -954,7 +1100,8 @@ function ENT:Explode(mode) self.explosion = self end - local explo = ents.Create("env_explosion") + if SERVER then + local explo = ents.Create("env_explosion") explo:SetOwner(self.explosion) explo:SetPos(self:GetPos()) explo:SetKeyValue("iMagnitude", "25") @@ -962,6 +1109,7 @@ function ENT:Explode(mode) explo:Spawn() explo:Activate() explo:Fire("Explode", "", 0) + end util.BlastDamage(self, self.explosion, self:GetPos(), self.MSRadius, self.MSDamage) util.ScreenShake( Vector( self:GetPos() ), (self.MSExplShakePower / 2), self.MSExplShakePower, self.MSExplShakeTime, self.MSExplShakeDist ) @@ -988,13 +1136,27 @@ function ENT:Explode(mode) SafeRemoveEntity(self) end +function ENT:DoCustomRemove() +end + function ENT:OnRemove() + self:DoCustomRemove() if self.LoopingSound != nil then if self:IsValid() then self:StopSound(self.LoopingSound) end end + if CLIENT && (self.RemoveEffect != nil or self.PCFRemoveEffect != nil) then + if self.Effect != nil then + local ed = EffectData() + ed:SetOrigin(self:GetPos()) + ed:SetEntity(self) + util.Effect(self.RemoveEffect, ed) + end + if self.PCFRemoveEffect != nil then ParticleEffect(self.PCFRemoveEffect, self:GetPos(), self:GetAngles(), self) end + end + if !SERVER then return end local ct = self:GetCreator() if ct then diff --git a/lua/entities/draconic_spotlight_base.lua b/lua/entities/draconic_spotlight_base.lua index 97b3ef6..8a3d419 100644 --- a/lua/entities/draconic_spotlight_base.lua +++ b/lua/entities/draconic_spotlight_base.lua @@ -2,8 +2,8 @@ AddCSLuaFile() --[[ I M P O R T A N T -Please, go to the GitHub wiki for this, and not just rip settings from the base as reference. -https://github.com/Vuthakral/Draconic_Base/wiki +Please, go to the wiki for this, and not just rip settings from the base as reference. +http://vuthakral.com/draconic/ It contains all of the settings, explanations on how to use them, tutorials, helpful links, etc. @@ -25,15 +25,15 @@ ENT.AdminOnly = false ENT.Draconic = true ENT.Model = "models/hunter/blocks/cube025x025x025.mdl" ENT.IsLight = true -ENT.Enabled = true -ENT.Brightness = 1 -ENT.Texture = "effects/flashlight_gel" -ENT.FarZ = 1 -ENT.NearZ = 25 -ENT.FOV = 70 -ENT.DrawShadows = false +ENT.Enabled = false ENT.Dummy = true -- compatibility with other addons +local function getrng() + local rng = math.Round(math.Rand(0, 999999999)) + if DRC.VolumeLights[rng] then rng = math.Round(math.Rand(0, 999999999)) end + return rng +end + function ENT:Initialize() self:DoCustomInitialize() @@ -46,9 +46,14 @@ function ENT:Initialize() self:SetSolid(SOLID_VPHYSICS) self:PhysWake() else end + + self:Toggle(true) + + self.VolumeID = getrng() end -ENT.ParticleTick = 0 +ENT.ParticleMade = false +ENT.TargetEntity = nil function ENT:Think() -- self:Remove() if !self.Info then return end @@ -60,43 +65,69 @@ function ENT:Think() local info = self.Info local ent = info.entity if !IsValid(ent) then self:Remove() return end - local attinfo = ent:GetAttachment(ent:LookupAttachment(info.attachment)) + if ent:GetClass() == "phys_bone_follower" then self:Remove() return end + self.TargetEntity = ent + local tgt = self.TargetEntity + local attinfo + if info.attachment then + attinfo = ent:GetAttachment(ent:LookupAttachment(info.attachment)) + else + attinfo = {["Pos"] = self:GetPos(), ["Ang"] = self:GetAngles()} + end - if self:GetParent() != info.entity then - self:SetParent(info.entity) + local ply = LocalPlayer() + + local etu = self.TargetEntity + if tgt:IsWeapon() && tgt == ply:GetActiveWeapon() && !DRC:ThirdPersonEnabled(ply) then + attinfo = ply:GetViewModel():GetAttachment(ply:GetViewModel():LookupAttachment(info.attachment)) + attinfo.Pos = ply:GetActiveWeapon():FormatViewModelAttachment(ply:GetActiveWeapon().ViewModelFOV, attinfo.Pos, false) + etu = ply:GetViewModel() + end + + if self:GetParent() != etu then + self:SetParent(etu) end - if self:GetPos() != attinfo.Pos then - self:SetPos(attinfo.Pos) + if etu:IsPlayer() or etu:IsNPC() && info.attachment == "eyes" then + attinfo.Ang = Angle(etu:EyeAngles().x*0.8, attinfo.Ang.y, attinfo.Ang.z) end --- self:SetAngles(attinfo.Ang) + self:SetPos(attinfo.Pos) + self:SetAngles(attinfo.Ang) --- LocalPlayer():ChatPrint(tostring(attinfo.Ang)) + local lcol = render.GetLightColor(self:GetPos()) + local ambient = math.Clamp(1 - ((lcol.r + lcol.g + lcol.b) * 0.333)*2, 0 , 1) + if self:WaterLevel() == 3 then ambient = ambient*2 end + local newcol = Vector(info.colour.r, info.colour.g, info.colour.b)*info.colour.a*ambient + self.col = LerpVector(FrameTime()*5, self.col or newcol, newcol) - if self.ParticleTick < RealTime() then + if self.ParticleMade == false && self:GetEnabled() == true then local ed = EffectData() - ed:SetEntity(info.entity) - ed:SetAttachment(info.entity:LookupAttachment(info.attachment)) + ed:SetEntity(self.TargetEntity) + if info.attachment then ed:SetAttachment(info.entity:LookupAttachment(info.attachment)) end ed:SetOrigin(info.position) ed:SetStart(Vector(info.colour.r, info.colour.g, info.colour.b)) ed:SetAngles(attinfo.Ang) ed:SetRadius(info.width) ed:SetScale(info.length) + ed:SetFlags(info.quality) util.Effect("drc_lightvolume", ed) - self.ParticleTick = RealTime() + 1 + self.ParticleMade = true end + + DRC.VolumeLights[self.VolumeID] = {self:GetPos(), attinfo.Ang, info.length, info.width, self.col, self.TargetEntity, self} end function ENT:Toggle(b) if b == nil then if self.Enabled == true then + self.Enabled = false else self.Enabled = true end else - self.Enabled = true + self.Enabled = b end end @@ -108,6 +139,10 @@ function ENT:Use(_, ply) self:DoCustomUse(ply) end +function ENT:OnRemove() + DRC.VolumeLights[self.VolumeID] = nil +end + function ENT:DoCustomUse(ply) end diff --git a/lua/entities/drc_abp_buckshot.lua b/lua/entities/drc_abp_buckshot.lua index 9d4011a..98afe0f 100644 --- a/lua/entities/drc_abp_buckshot.lua +++ b/lua/entities/drc_abp_buckshot.lua @@ -32,6 +32,7 @@ ENT.BulletTable = { EvPDamageMul = 1, EvEDamageMul = 1, DamageType = DMG_BUCKSHOT, + HullSize = 5, AmmoType = "Buckshot", FallbackBaseAmmoType = "Buckshot", NumShots = 7, diff --git a/lua/entities/drc_abp_generic.lua b/lua/entities/drc_abp_generic.lua index 1d088b4..cfb511a 100644 --- a/lua/entities/drc_abp_generic.lua +++ b/lua/entities/drc_abp_generic.lua @@ -36,9 +36,10 @@ ENT.BulletTable = { VehicleDamageMul = 1, PvEUseHL2Scale = true, EvPUseHL2Scale = true, + EvPHeadshots = false, DamageType = DMG_BULLET, HullSize = 1, - HullDamage = 0.25, + HullDamage = 0.5, HitboxDamageMuls = { ["HITGROUP_GENERIC"] = 1, ["HITGROUP_HEAD"] = 1, diff --git a/lua/entities/drc_corpse.lua b/lua/entities/drc_corpse.lua new file mode 100644 index 0000000..12c373c --- /dev/null +++ b/lua/entities/drc_corpse.lua @@ -0,0 +1,104 @@ +AddCSLuaFile() + +ENT.Type = "anim" +ENT.PrintName = "Corpse" +ENT.Author = "Vuthakral" +ENT.Information = "Halo-esque dead body that plays funny animations when blown away." +ENT.Category = "Draconic" +ENT.Draconic = true + +ENT.Spawnable = false +ENT.AdminSpawnable = false + +ENT.DrawMirror = true +ENT.AutomaticFrameAdvance = true + +ENT.Lifetime = 30 +ENT.Mass = 200 + +ENT.animations = { + ["idle"] = ACT_HL2MP_ZOMBIE_SLUMP_IDLE, + ["fall"] = ACT_ZOMBIE_LEAPING, + ["death"] = ACT_GMOD_DEATH, +} + +ENT.DeathAnimPlayed = false +ENT.HasBeenMoved = false +ENT.LaunchVelocity = Vector() + +function ENT:Initialize() + self.CreationTime = CurTime() + self:SetHealth(0) + self:SetAutomaticFrameAdvance(true) + self:SetPlaybackRate(1) + self:SetCollisionGroup(COLLISION_GROUP_WORLD) + self:PhysicsInitBox(Vector(-16, -16, 0), Vector(16, 16, 8)) + self:PhysWake() + + self:SetNWInt("anim_idle", self.animations.idle) + self:SetNWInt("anim_fall", self.animations.fall) + self:SetNWInt("anim_death", self.animations.death) + + if SERVER then + constraint.Keepupright(self, self:GetAngles(), 0, 180) + self:GetPhysicsObject():SetMass(self.Mass) + if self.MaterialType then self:GetPhysicsObject():SetMaterial(self.MaterialType) end + + timer.Simple(0.1, function() if IsValid(self) then + local ent = self:GetNWEntity("Originator") + local vel = ent:GetVelocity() + self:SetVelocity(vel) + self:GetPhysicsObject():ApplyForceCenter(vel*self.Mass) + end end) + end + + if self.Lifetime != 0 then + timer.Simple(self.Lifetime, function() + if SERVER && IsValid(self) then self:Remove() end + end) + end +end + +function ENT:Think() + local ground = DRC:FloorDist(self) < 15 + local vel = self:GetVelocity() + local speed = vel.x + vel.y + vel.z * 0.333 + + local idle = self:GetNWInt("anim_idle") + local fall = self:GetNWInt("anim_fall") + local death = self:GetNWInt("anim_death") + + if self.DeathAnimPlayed == false then idle = death end + + if self.animations.idle != idle then self.animations.idle = idle end + if self.animations.fall != fall then self.animations.fall = fall end + + if ground then + if speed > 5 then + local seq = self:GetSequenceName(self:SelectWeightedSequence(self.animations.idle)) + self:SetSequence(seq) + self:SetCycle(0) + -- self:ResetSequence(seq) + if self.HasBeenMoved == false then self.DeathAnimPlayed = true end + else + if CurTime() > self.CreationTime + 5 then self.HasBeenMoved = true end + end + else + local seq = self:GetSequenceName(self:SelectWeightedSequence(self.animations.fall)) + self:SetSequence(seq) + self:SetCycle(self:GetCycle() + FrameTime() * (1/FrameTime()*0.0033)) + if self:GetCycle() > 1 then self:SetCycle(0) end + -- self:ResetSequence(seq) + end + + self:NextThink(CurTime()) + return true +end + +function ENT:Draw() + local rt = render.GetRenderTarget() + if rt != nil && self.DrawMirror == false then + if rt:GetName():lower() == "_rt_waterreflection" or rt:GetName():lower() == "_rt_shadowdummy" or rt:GetName():lower() == "_rt_camera" then return end + end + self:DrawModel() +end \ No newline at end of file diff --git a/lua/entities/drc_csshadowmodel.lua b/lua/entities/drc_csshadowmodel.lua index aa3f301..5105e1d 100644 --- a/lua/entities/drc_csshadowmodel.lua +++ b/lua/entities/drc_csshadowmodel.lua @@ -22,7 +22,7 @@ function ENT:Draw() self:SetMaterial("models/vuthakral/nodraw") if !IsValid(ply) or !ply:Alive() then return end if DRC:ThirdPersonEnabled(ply) == true then return end - if DRC:SightsDown(ply:GetActiveWeapon()) then return end +-- if DRC:SightsDown(ply:GetActiveWeapon()) then return end if GetConVar("cl_drc_experimental_fp"):GetFloat() == 0 then return end if ply:FlashlightIsOn() then return end diff --git a/lua/entities/drc_dummy.lua b/lua/entities/drc_dummy.lua index 02ba784..f35a760 100644 --- a/lua/entities/drc_dummy.lua +++ b/lua/entities/drc_dummy.lua @@ -11,13 +11,24 @@ ENT.AdminSpawnable = false ENT.DrawMirror = true +ENT.AutomaticFrameAdvance = true +ENT.Animating = false + function ENT:Initialize() self:DrawShadow(false) self:SetMaterial("models/vuthakral/nodraw") self:SetAutomaticFrameAdvance(true) + self:SetPlaybackRate(1) +end + +function ENT:Think() + if self.Animating == true then self:SetCycle(self:GetCycle() + RealFrameTime() * (1/RealFrameTime()*0.0033)) end + self:NextThink(CurTime()) + return true end function ENT:Draw() + self:Think() -- why is it not thinking natively wtf local rt = render.GetRenderTarget() if rt != nil && self.DrawMirror == false then if rt:GetName():lower() == "_rt_waterreflection" or rt:GetName():lower() == "_rt_shadowdummy" or rt:GetName():lower() == "_rt_camera" then return end diff --git a/lua/entities/drc_plate_battery.lua b/lua/entities/drc_plate_battery.lua new file mode 100644 index 0000000..09bd825 --- /dev/null +++ b/lua/entities/drc_plate_battery.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Battery Plate" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/squad/sf_plates/sf_plate1x1.mdl" + +ENT.UseDelay = 0 +ENT.ATR = 0 +ENT.HidePopup = false +ENT.RemoveOnUse = false +ENT.PickupType = "batterystation" +ENT.UseSound = "draconic.MenuPosGeneric" +ENT.DenySound = "draconic.MenuNegGeneric" \ No newline at end of file diff --git a/lua/entities/drc_plate_boolet.lua b/lua/entities/drc_plate_boolet.lua new file mode 100644 index 0000000..a6a0e55 --- /dev/null +++ b/lua/entities/drc_plate_boolet.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Bullet Plate" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/squad/sf_plates/sf_plate1x1.mdl" + +ENT.UseDelay = 0.62 +ENT.ATR = 0 +ENT.HidePopup = false +ENT.RemoveOnUse = false +ENT.PickupType = "ammostation" +ENT.UseSound = "items/ammocrate_open.wav" +ENT.DenySound = "doors/handle_pushbar_locked1.wav" \ No newline at end of file diff --git a/lua/entities/drc_plate_universal.lua b/lua/entities/drc_plate_universal.lua new file mode 100644 index 0000000..f105ec9 --- /dev/null +++ b/lua/entities/drc_plate_universal.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Universal Plate" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/squad/sf_plates/sf_plate1x1.mdl" + +ENT.UseDelay = 0.62 +ENT.ATR = 0 +ENT.HidePopup = true +ENT.RemoveOnUse = false +ENT.PickupType = "universalstation" +ENT.UseSound = "draconic.MenuPosGeneric" +ENT.DenySound = "draconic.MenuNegGeneric" \ No newline at end of file diff --git a/lua/entities/drc_shieldmodel.lua b/lua/entities/drc_shieldmodel.lua index b75820b..144b662 100644 --- a/lua/entities/drc_shieldmodel.lua +++ b/lua/entities/drc_shieldmodel.lua @@ -64,26 +64,49 @@ function ENT:Draw() if hp < 0.01 then scale = scale * 2 end self.ShieldScale = Lerp(RealFrameTime() * 10, self.ShieldScale or scale, scale) - if self:GetModel() != parent:GetModel() then - self:SetModel(parent:GetModel()) + local model = parent:GetNWString("DRC_Shield_Model") + if self:GetModel() != model then + self:SetModel(model) self.Bones = DRC:GetBones(self) end self:DrawShadow(false) self:DestroyShadow() self:SetLOD(0) - for k,v in pairs(self.Bones) do - local id = self:LookupBone(k) - if id != nil then - local matr = parent:GetBoneMatrix(id) - if matr then - local newmatr = Matrix() - newmatr:SetTranslation(matr:GetTranslation()) - newmatr:SetAngles(matr:GetAngles()) - newmatr:SetScale(Vector(self.ShieldScale, self.ShieldScale, self.ShieldScale)) - self:SetBoneMatrix(id, newmatr) + local customscale = parent:GetNWVector("DRC_Shield_BaseScale") + customscale = Vector(self.ShieldScale * customscale.x, self.ShieldScale * customscale.y, self.ShieldScale * customscale.z) + if model == parent:GetModel() then + for k,v in pairs(self.Bones) do + local id = self:LookupBone(k) + if id != nil then + local matr = parent:GetBoneMatrix(id) + if matr then + local newmatr = Matrix() + newmatr:SetTranslation(matr:GetTranslation()) + newmatr:SetAngles(matr:GetAngles()) + newmatr:SetScale(customscale) + self:SetBoneMatrix(id, newmatr) + end end end + else + local matr = self:GetBoneMatrix(0) + if matr then + local newmatr = Matrix() + local ang = parent:GetRenderAngles() or parent:GetAngles() + local offset = parent:GetNWVector("DRC_Shield_BaseOffset") + local off = Vector() + + + off = ang:Right() * offset.x + off = ang:Forward() * offset.y + off = ang:Up() * offset.z + + newmatr:SetTranslation(parent:WorldSpaceCenter() + off) + newmatr:SetAngles(ang) + newmatr:SetScale(customscale) + self:SetBoneMatrix(0, newmatr) + end end local function CopyPoseParams(pEntityFrom, pEntityTo) diff --git a/lua/entities/drc_station_battery.lua b/lua/entities/drc_station_battery.lua new file mode 100644 index 0000000..38b0e31 --- /dev/null +++ b/lua/entities/drc_station_battery.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Weapon Battery Recharge Station" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/props_combine/combine_light001b.mdl" + +ENT.UseDelay = 0 +ENT.ATR = 0 +ENT.HidePopup = false +ENT.RemoveOnUse = false +ENT.PickupType = "batterystation" +ENT.UseSound = "draconic.MenuPosGeneric" +ENT.DenySound = "draconic.MenuNegGeneric" \ No newline at end of file diff --git a/lua/entities/drc_station_boolet.lua b/lua/entities/drc_station_boolet.lua new file mode 100644 index 0000000..e37e075 --- /dev/null +++ b/lua/entities/drc_station_boolet.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Generic Ammo Station" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/items/ammocrate_smg1.mdl" + +ENT.UseDelay = 0.62 +ENT.ATR = 0 +ENT.HidePopup = false +ENT.RemoveOnUse = false +ENT.PickupType = "ammostation" +ENT.UseSound = "items/ammocrate_open.wav" +ENT.DenySound = "doors/handle_pushbar_locked1.wav" \ No newline at end of file diff --git a/lua/entities/drc_station_universal.lua b/lua/entities/drc_station_universal.lua new file mode 100644 index 0000000..22c2382 --- /dev/null +++ b/lua/entities/drc_station_universal.lua @@ -0,0 +1,22 @@ +AddCSLuaFile() + +ENT.Base = "draconic_ammo_station" +ENT.Entity = "drc_station_battery" + +ENT.PrintName = "Universal Ammo Station" +ENT.Author = "Vuthakral" +ENT.Information = "" +ENT.Category = "Draconic" + +ENT.Spawnable = true +ENT.AdminOnly = false + +ENT.Model = "models/items/item_item_crate.mdl" + +ENT.UseDelay = 0.62 +ENT.ATR = 0 +ENT.HidePopup = true +ENT.RemoveOnUse = false +ENT.PickupType = "universalstation" +ENT.UseSound = "physics/wood/wood_crate_impact_hard3.wav" +ENT.DenySound = "physics/wood/wood_box_impact_soft3.wav" \ No newline at end of file diff --git a/lua/matproxy/drc_matproxy.lua b/lua/matproxy/drc_matproxy.lua index 853c363..9da1900 100644 --- a/lua/matproxy/drc_matproxy.lua +++ b/lua/matproxy/drc_matproxy.lua @@ -1,7 +1,7 @@ --[[ I M P O R T A N T -Please, go to the GitHub wiki for this, and not just rip settings from the base as reference. -https://github.com/Vuthakral/Draconic_Base/wiki +Please, go to the wiki for this, and not just rip settings from the base as reference. +http://vuthakral.com/draconic It contains all of the settings, explanations on how to use them, tutorials, helpful links, etc. @@ -10,14 +10,13 @@ It contains all of the settings, explanations on how to use them, tutorials, hel local cmap = game.GetMap() local lply = LocalPlayer() local HDR = render.GetHDREnabled() -local LMCor = DRC.MapInfo.LMCorrection DRC.WeathermodScalar = Vector(1,1,1) DRC.MatProxy = {} DRC.ReflectionModifier = 1 function DRC:CubemapCheck() if (DRC:DebugModeEnabled() && GetConVar("cl_drc_debug_cubefallbacks"):GetFloat() == 1) or (GetConVar("cl_drc_accessibility_amduser"):GetFloat() == 1) then return false end - if #drc_cubesamples != 0 then return true else return false end + if #drc_cubesamples > 1 then return true else return false end end local addict = achievements.GetCount(5) >= achievements.GetGoal(5) @@ -41,22 +40,24 @@ hook.Add("InitPostEntity", "DRC_MatProxy_InitPost", function() if lply != LocalPlayer() then lply = LocalPlayer() end end) +local translation = { + ["PlayerColour_DRC"] = "Player", + ["WeaponColour_DRC"] = "Weapon", + ["EyeTintVec"] = "Eye", + ["EnergyTintVec"] = "Energy", + ["ColourTintVec1"] = "Tint1", + ["ColourTintVec2"] = "Tint2", + ["Entity"] = "$color2", + ["Grunge"] = "Grunge", + ["None"] = Vector(1, 1, 1) +} local function GetPlayerColour(src, channel) if !IsValid(src) then src = LocalPlayer() end + if src:GetClass() == "drc_csplayermodel" then src = LocalPlayer() end if !lply then lply = LocalPlayer() end if !lply or !IsValid(lply) then return Vector() end local col = Vector(0.5, 0.5, 0.5) - local translation = { - ["PlayerColour_DRC"] = "Player", - ["WeaponColour_DRC"] = "Weapon", - ["EyeTintVec"] = "Eye", - ["EnergyTintVec"] = "Energy", - ["ColourTintVec1"] = "Tint1", - ["ColourTintVec2"] = "Tint2", - ["Entity"] = "$color2", - ["Grunge"] = "Grunge", - ["None"] = Vector(1, 1, 1) - } + if channel == "Entity" then local vals = DRC:GetColours(src, true) local pull = translation[channel] @@ -74,7 +75,7 @@ local function GetPlayerColour(src, channel) end return col elseif channel && channel != "Entity" && channel != "None" then - if (src.Preview == true or src.preview == true) or (src:EntIndex() == lply:GetHands():EntIndex()) or (src:GetNWVector(channel, Vector(0,0,0)) == Vector(0,0,0)) then + if (src == lply or src.Preview == true or src.preview == true) or (src:EntIndex() == lply:GetHands():EntIndex()) or (src:GetNWVector(channel, Vector(0,0,0)) == Vector(0,0,0)) then local vals = DRC:GetColours(lply, true) local pull = translation[channel] if vals then col = vals[pull] end @@ -82,7 +83,9 @@ local function GetPlayerColour(src, channel) local vals = DRC:GetColours(src, true) local pull = translation[channel] if vals then col = vals[pull] end + -- print(src, channel, col, pull, vals.Energy) end + -- print(src, channel, col) elseif channel == "None" then return Vector(1,1,1) end @@ -108,7 +111,7 @@ local function CalcPoll(ent) end local lightlevel = render.GetLightColor(pos) - local lla = (lightlevel.x + lightlevel.y + lightlevel.z) / 3 + local lla = (lightlevel.x + lightlevel.y + lightlevel.z) / 3 ent.DRCLightPolling["LightTint"] = lightlevel return lightlevel, lla end @@ -140,25 +143,48 @@ table.Inherit(adjustedmaps, drc_fullbrightcubemaps) local function GetAdjustedCubeStrength() end ]] +local function GetColour(e, c, mat) + local colnew = GetPlayerColour(e, c) + if colnew then + colnew.x = math.Clamp(colnew.x, mat.MinFloat, mat.MaxFloat) + colnew.y = math.Clamp(colnew.y, mat.MinFloat, mat.MaxFloat) + colnew.z = math.Clamp(colnew.z, mat.MinFloat, mat.MaxFloat) + return colnew + end +end + +local function ReturnValue(ent, col, mat, channel) + local ll, lla = LightPollEntity(ent) + ll = ll or ent.DRCLightPolling["LightTint"] + if !ll then return Vector() end + ll.r = math.Clamp(ll.r, mat.MinFloat, mat.MaxFloat) + ll.g = math.Clamp(ll.g, mat.MinFloat, mat.MaxFloat) + ll.b = math.Clamp(ll.b, mat.MinFloat, mat.MaxFloat) + if ent:EntIndex() == lply:GetHands():EntIndex() then + ent.DRCLightPolling["Realtime"] = true + col = GetColour(lply, channel, mat) + else + col = GetColour(ent, channel, mat) + end + col = col * Vector(ll.r, ll.g, ll.b) + if HDR then col = col * mat.HDRCorrectionLevel else col = col * mat.LDRCorrectionLevel end +-- col = col * (Vector(DRC.MapInfo.MapAmbient.r + 1, DRC.MapInfo.MapAmbient.g + 1, DRC.MapInfo.MapAmbient.b +1)) + return col * 2 +end + +local blacklist = { + ["drc_csshadowmodel"] = true, + ["drc_shieldmodel"] = true, +} local function GetCubemapStrength(mat, ent, channel, imat, realtime) if GetConVar("cl_drc_debugmode"):GetFloat() != 0 && GetConVar("cl_drc_debug_hideshaderfixes"):GetFloat() == 1 then return(Vector(1,1,1)) end - if CurTime() < ent:GetCreationTime() + 0.03 then return Vector() end if !IsValid(ent) then return Vector() end + if CurTime() < ent:GetCreationTime() + 0.03 then return Vector() end local envmaps = DRC:CubemapCheck() - local blacklist = { - ["drc_csshadowmodel"] = true, - } if blacklist[ent:GetClass()] then return Vector() end - if imat:GetFloat("$cubemaplightingsaturation") then mat.Saturation = imat:GetFloat("$cubemaplightingsaturation") mat.Saturation = 1 end - if imat:GetFloat("$cmlightsat") then mat.Saturation = imat:GetFloat("$cmlightsat") else mat.Saturation = 1 end + if !mat.ResultTo then return end - mat.TintVector = imat:GetVector("$cmtint") or imat:GetVector("$cubemaptint") - mat.PowerFloat = imat:GetFloat("$cmpower") or imat:GetFloat("$cubemappower") - mat.MinFloat = imat:GetFloat("$cmmin") or imat:GetFloat("$cubemapmin") - mat.MaxFloat = imat:GetFloat("$cmmax") or imat:GetFloat("$cubemapmax") - mat.HDRCorrectionLevel = imat:GetFloat("$cmhdr") or imat:GetFloat("$cubemapHDRMul") - mat.LDRCorrectionLevel = imat:GetFloat("$cmldr") or imat:GetFloat("$cubemapLDRMul") if envmaps == false then mat.TintVector = imat:GetVector("$cmtint_fb") or imat:GetVector("$cubemaptintfallback") or mat.TintVector mat.PowerFloat = imat:GetFloat("$cmpower_fb") or imat:GetFloat("$cubemappowerfallback") or mat.PowerFloat @@ -168,44 +194,57 @@ local function GetCubemapStrength(mat, ent, channel, imat, realtime) mat.LDRCorrectionLevel = imat:GetFloat("$cmldr_fb") or imat:GetFloat("$cubemapLDRMulfallback") or mat.LDRCorrectionLevel end - if mat.LerpPower == nil then mat.LerpPower = 1 end - if mat.TintVector == nil then mat.TintVector = Vector(1,1,1) end - if mat.PowerFloat == nil then mat.PowerFloat = 1 end - if mat.MinFloat == nil then mat.MinFloat = 0 end - if mat.MaxFloat == nil then mat.MaxFloat = 1 end - if mat.HDRCorrectionLevel == nil then mat.HDRCorrectionLevel = 1 end - if mat.LDRCorrectionLevel == nil then mat.LDRCorrectionLevel = 1 end - if mat.Saturation == nil then mat.Saturation = 1 end - if mat.LerpPower == nil then mat.LerpPower = 1 end - if !ent.DRCLightPolling then ent.DRCLightPolling = {} end + if !ent.DRCLightPolling then + ent.DRCLightPolling = { + ["LightPollTime"] = 0 + } + end if !ent.DRCLightPolling["LightPollTime"] then ent.DRCLightPolling["LightPollTime"] = 0 end - if !ent.DRCReflectionTints then ent.DRCReflectionTints = {} end - if !ent.DRCReflectionTints.Stored then ent.DRCReflectionTints.Stored = {} end - + local name = imat:GetName() - if ent:EntIndex() == lply:GetViewModel():EntIndex() then ent = lply:GetActiveWeapon() end - if !IsValid(ent) then return end - if !ent.DRCReflectionTints then ent.DRCReflectionTints = {} end - if !ent.DRCReflectionTints[name] then ent.DRCReflectionTints[name] = {} end - if !ent.DRCReflectionTints[name]["UpdateTime"] then ent.DRCReflectionTints[name]["UpdateTime"] = 0 end - if !ent.DRCReflectionTints[name]["EnvmapUpdateTime"] then ent.DRCReflectionTints[name]["EnvmapUpdateTime"] = 0 end - if !ent.DRCReflectionTints[name]["Envmap"] then ent.DRCReflectionTints[name]["Envmap"] = "" end + if ent:EntIndex() == lply:GetActiveWeapon() then ent = lply:GetViewModel():EntIndex() end + if !IsValid(ent) then return end + + if !ent.DRCReflectionTints then + ent.DRCReflectionTints = { + ["Stored"] = { + [name] = {}, + [channel] = Vector() + }, + [name] = { + ["UpdateTime"] = 0, + ["EnvmapUpdateTime"] = 0, + ["Envmap"] = "", + [channel] = Vector(), + }, + } + end + if !ent.DRCReflectionTints[name] then + ent.DRCReflectionTints[name] = { + ["UpdateTime"] = 0, + ["EnvmapUpdateTime"] = 0, + ["Envmap"] = "", + [channel] = Vector(), + } + end + if !ent.DRCReflectionTints.Stored[name] then + ent.DRCReflectionTints.Stored[name] = { + [name] = {}, + [channel] = Vector(), + } + end + if !ent.DRCReflectionTints[name][channel] then ent.DRCReflectionTints[name][channel] = Vector() end - if !ent.DRCReflectionTints.Stored then ent.DRCReflectionTints.Stored = {} end - if !ent.DRCReflectionTints.Stored[name] then ent.DRCReflectionTints.Stored[name] = {} end if !ent.DRCReflectionTints.Stored[name][channel] then ent.DRCReflectionTints.Stored[name][channel] = Vector() end - local col = Vector() - local function GetColour(e, c) - local colnew = GetPlayerColour(e, c) - if colnew then - colnew.x = math.Clamp(colnew.x, mat.MinFloat, mat.MaxFloat) - colnew.y = math.Clamp(colnew.y, mat.MinFloat, mat.MaxFloat) - colnew.z = math.Clamp(colnew.z, mat.MinFloat, mat.MaxFloat) - return colnew - end - end + local col, m2 = Vector(), 1 + if ent.Preview == true or ent.preview == true then + local mul = Vector(1, 1, 1) + if !HDR then mul = (10 * mat.LDRCorrectionLevel) end + col = (mat.TintVector * mat.PowerFloat * (GetColour(lply, channel, mat)*mat.ShiftFloat) * mul) * DRC.WeathermodScalar * DRC.MapInfo.MapAmbient + return col end + local function ReturnEnvmap() if envmaps == false then ent.DRCReflectionTints[name]["Envmap"] = imat:GetString("$envmapstatic") or imat:GetString("$envmapfallback") or "models/vuthakral/defaultcubemap" @@ -219,59 +258,35 @@ local function GetCubemapStrength(mat, ent, channel, imat, realtime) local nexttick = RealTime() + (0.5 + (math.Rand(-0.25, 0.5))) if fps < 40 && fps > 21 then nexttick = RealTime() + (1 + (math.Rand(-0.3, 0.5))) end if fps < 20 then nexttick = RealTime() + (2 + (math.Rand(0, 3))) end - ent.DRCReflectionTints["EnvmapUpdateTime"] = nexttick + ent.DRCReflectionTints[name]["EnvmapUpdateTime"] = nexttick if envmaps == false then ReturnEnvmap() end end --- local cubemap = ent.DRCReflectionTints[name]["Envmap"] or "" if envmaps == false && imat:GetTexture("$envmap") != ent.DRCReflectionTints[name]["Envmap"] then imat:SetTexture("$envmap", ent.DRCReflectionTints[name]["Envmap"]) end - local m2 = 1 if ent.DRCReflectionTints[name]["Envmap"] == "models/vuthakral/defaultcubemap" then m2 = 0.05 end - if ent.Preview == true or ent.preview == true then - local mul = Vector(1, 1, 1) - if !HDR then mul = (10 * mat.LDRCorrectionLevel) end - col = (mat.TintVector * mat.PowerFloat * GetColour(lply, channel) * mul) * DRC.WeathermodScalar * DRC.MapInfo.MapAmbient - return col end - - local function ReturnValue() - local ll, lla = LightPollEntity(ent) - ll = ll or ent.DRCLightPolling["LightTint"] - if !ll then return Vector() end - ll.r = math.Clamp(ll.r, mat.MinFloat, mat.MaxFloat) - ll.g = math.Clamp(ll.g, mat.MinFloat, mat.MaxFloat) - ll.b = math.Clamp(ll.b, mat.MinFloat, mat.MaxFloat) - if ent:EntIndex() == lply:GetHands():EntIndex() then - ent.DRCLightPolling["Realtime"] = true - col = GetColour(lply, channel) - elseif ent:EntIndex() == lply:GetViewModel():EntIndex() then - local newent = lply:GetActiveWeapon() - ent.DRCLightPolling["Realtime"] = true - newent.DRCLightPolling["Realtime"] = true - if !IsValid(newent) then return Vector() end - if !newent.DRCReflectionTints then newent.DRCReflectionTints = {} end - col = GetColour(newent, channel) - else - col = GetColour(ent, channel) - end - col = col * Vector(ll.r, ll.g, ll.b) * mat.HDRCorrectionLevel - col = col * (Vector(DRC.MapInfo.MapAmbient.r + 1, DRC.MapInfo.MapAmbient.g + 1, DRC.MapInfo.MapAmbient.b +1)) - return col - end - if (RealTime() > ent.DRCReflectionTints[name]["UpdateTime"]) then local fps = 1/RealFrameTime() local nexttick = RealTime() + (0.2 + (math.Rand(-0.1, 0.1))) if fps < 40 && fps > 21 then nexttick = RealTime() + (1 + (math.Rand(-0.5, 0.25))) end if fps < 20 then nexttick = RealTime() + (2 + (math.Rand(-1, 2))) end - ent.DRCReflectionTints.Stored[name][channel] = (ReturnValue() * LMCor * DRC.WeathermodScalar) * (DRC.WeathermodScalar * mat.TintVector) * mat.PowerFloat + for k,v in pairs(ent.DRCReflectionTints.Stored[name]) do + if translation[k] then + local col = ReturnValue(ent, col, mat, k) + ent.DRCReflectionTints.Stored[name][k] = (col * DRC.WeathermodScalar) * (DRC.WeathermodScalar * mat.TintVector) * mat.PowerFloat + end + end + -- ent.DRCReflectionTints.Stored[name][channel] = (ReturnValue(ent, col, mat, channel) * DRC.WeathermodScalar) * (DRC.WeathermodScalar * mat.TintVector) * mat.PowerFloat ent.DRCReflectionTints[name]["UpdateTime"] = nexttick end ent.DRCReflectionTints[name][channel] = Lerp(RealFrameTime() * (mat.LerpPower * 2.5), ent.DRCReflectionTints[name][channel] or ent.DRCReflectionTints.Stored[name][channel], ent.DRCReflectionTints.Stored[name][channel]) local avg = (ent.DRCReflectionTints[name][channel].x + ent.DRCReflectionTints[name][channel].y + ent.DRCReflectionTints[name][channel].z) / 3 avg = avg * m2 - local final = (LerpVector(mat.Saturation, Vector(avg, avg, avg), ent.DRCReflectionTints[name][channel]) * mat.TintVector) + local cccorrection = Lerp(avg, 0, mat.Saturation) + avg = Vector(avg, avg, avg) + local fuckme = LerpVector(mat.ShiftFloat, Vector(0,0,0), ent.DRCReflectionTints[name][channel]) + local final = LerpVector(cccorrection, avg, fuckme) * mat.TintVector return final * DRC.ReflectionModifier * m2 end @@ -279,22 +294,8 @@ end matproxy.Add( { name = "drc_EnvmapFallback", init = function( self, mat, values ) - self.Envmap = mat:GetString("$envmapfallback") end, - - bind = function( self, mat, ent ) - if !IsValid(ent) then return end - if !IsValid(lply) then return end - - -- if self.OGEnvmap == nil then self.OGEnvmap = mat:GetTexture("$envmap") end - -- if self.Envmap == nil then self.Envmap = "env_cubemap" end - - -- if DRC:CubemapCheck() == false then - -- mat:SetTexture( "$envmap", self.Envmap ) - -- else - -- mat:SetTexture( "$envmap", self.OGEnvmap ) - -- end - end + bind = function( self, mat, ent ) return end } ) matproxy.Add( { @@ -322,97 +323,128 @@ matproxy.Add( { end } ) +local function ClampVector(vec, mins, maxes) + local newvec = Vector() + + newvec.x = math.Clamp(vec.x, mins.x, maxes.x) + newvec.y = math.Clamp(vec.y, mins.y, maxes.y) + newvec.z = math.Clamp(vec.z, mins.z, maxes.z) + + return newvec +end + +local function InitColours(s,m,v) + s.ResultTo = v.resultvar or "$color2" + s.ResultTo2 = v.resultvar2 + s.ResultTo3 = v.resultvar3 + s.Mul = m:GetVector("$drc_colourmul") or v.mul or Vector(1, 1, 1) + s.Mul2 = m:GetVector("$drc_colourmul2") or v.mul2 or Vector(1, 1, 1) + s.Mul3 = m:GetVector("$drc_colourmul3") or v.mul3 or Vector(1, 1, 1) + s.Min = m:GetVector("$drc_colourmin") or Vector(0, 0, 0) + s.Min2 = m:GetVector("$drc_colourmin2") or Vector(0, 0, 0) + s.Min3 = m:GetVector("$drc_colourmin3") or Vector(0, 0, 0) + s.Max = m:GetVector("$drc_colourmax") or Vector(2, 2, 2) + s.Max2 = m:GetVector("$drc_colourmax2") or Vector(2, 2, 2) + s.Max3 = m:GetVector("$drc_colourmax3") or Vector(2, 2, 2) +end + matproxy.Add( { name = "drc_PlayerColours", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end - if !IsValid(lply) then return end - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end + if !IsValid(ent) then return end local col = GetPlayerColour(ent, "PlayerColour_DRC") - mat:SetVector(self.ResultTo, col * self.MulInt) + if self.ResultTo == nil then self.ResultTo = "$color2" end + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) matproxy.Add( { - name = "drc_PlayerColours_ForPlayer", -- This exists solely for compatibility with old content made using this proxy. + name = "drc_PlayerColours_ForPlayer", -- This exists solely for compatibility with old content made using this proxy. Just use drc_PlayerColours. init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then return end - if !IsValid(lply) then return end - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end local col = GetPlayerColour(ent, "PlayerColour_DRC") - mat:SetVector(self.ResultTo, col * self.MulInt) + if self.ResultTo == nil then self.ResultTo = "$color2" end + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) matproxy.Add( { name = "drc_PlayerWeaponColours", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then ent = LocalPlayer() end - if !IsValid(lply) then return end - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end local col = GetPlayerColour(ent, "WeaponColour_DRC") - mat:SetVector(self.ResultTo, col * self.MulInt) + if self.ResultTo == nil then self.ResultTo = "$color2" end + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) matproxy.Add( { - name = "drc_WeaponColours_ForPlayer", + name = "drc_WeaponColours_ForPlayer", -- This exists solely for compatibility with old content made using this proxy. Just use drc_WeaponColours. init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then return end - if !IsValid(lply) then return end - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end local col = GetPlayerColour(ent, "WeaponColour_DRC") - mat:SetVector(self.ResultTo, col * self.MulInt) + if self.ResultTo == nil then self.ResultTo = "$color2" end + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) matproxy.Add( { name = "drc_EyeColour", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then return end - if !IsValid(lply) then return end - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end - -- if addict then - -- mat:SetVector(self.ResultTo, Vector(TimedSin(2.75, 0.5, 1, 0), TimedSin(1.83, 0.5, 1, 0), TimedSin(0.916, 0.5, 1, 0))) - -- return end local col = GetPlayerColour(ent, "EyeTintVec") - mat:SetVector(self.ResultTo, col * self.MulInt) - ---[[ local shader = string.lower(mat:GetShader()) + if self.ResultTo == nil then self.ResultTo = "$color2" end + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end - if shader == "eyes_dx9" then - -- render.SetColorModulation(col.x, col.y, col.z) - end ]] + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) @@ -422,8 +454,8 @@ matproxy.Add( { self.ResultTo = values.resultvar self.ResultTo2 = values.resultvar2 self.ResultTo3 = values.resultvar3 - self.PowerFloat = mat:GetFloat("$energy_Mul") - self.MinFloat = mat:GetVector("$energy_Min") + self.PowerFloat = mat:GetFloat("$energy_Mul") or 1 + self.MinFloat = mat:GetVector("$energy_Min") or Vector() end, bind = function( self, mat, ent ) @@ -433,8 +465,6 @@ matproxy.Add( { -- if addict then -- mat:SetVector(self.ResultTo, Vector(TimedSin(2.75, 0.5, 1, 0), TimedSin(1.83, 0.5, 1, 0), TimedSin(0.916, 0.5, 1, 0))) -- return end - if !self.PowerFloat then self.PowerFloat = 1 end - if !self.MinFloat then self.MinFloat = Vector(0,0,0) end if self.ResultTo == nil then self.ResultTo = "$color2" end if ent:GetClass() == "drc_shieldmodel" then @@ -443,51 +473,55 @@ matproxy.Add( { mat:SetVector(self.ResultTo, col * self.PowerFloat) return end - local flickerflicker = TimedSin(2, 0.6, 1, 0) - local deathflicker = TimedSin(4, 0.7, flickerflicker, 0) - if ent:Health() > 0.01 then deathflicker = 1 end + ent.flickerflicker = TimedSin(2, 0.6, 1, 0) + ent.deathflicker = TimedSin(4, 0.7, ent.flickerflicker, 0) + if DRC:Health(ent) > 0.01 then ent.deathflicker = 1 end if ent:EntIndex() == lply:GetHands():EntIndex() or ent.preview == true then - deathflicker = 1 + ent.deathflicker = 1 end local col = GetPlayerColour(ent, "EnergyTintVec") col = Vector(math.Clamp(col.x, self.MinFloat.x, 1), math.Clamp(col.y, self.MinFloat.y, 1), math.Clamp(col.z, self.MinFloat.z, 1)) - mat:SetVector( self.ResultTo, col * deathflicker ) - if self.ResultTo2 then mat:SetVector( self.ResultTo2, col * deathflicker ) end - if self.ResultTo3 then mat:SetVector( self.ResultTo3, col * deathflicker ) end + mat:SetVector( self.ResultTo, (col * self.PowerFloat) * ent.deathflicker ) + if self.ResultTo2 then mat:SetVector( self.ResultTo2, (col * self.PowerFloat) * ent.deathflicker ) end + if self.ResultTo3 then mat:SetVector( self.ResultTo3, (col * self.PowerFloat) * ent.deathflicker ) end end } ) matproxy.Add( { name = "drc_PlayerColour1", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then return end local col = GetPlayerColour(ent, "ColourTintVec1") if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end - mat:SetVector(self.ResultTo, col * self.MulInt) + if self.Mul == nil then self.Mul = 1 end + if self.Mul2 == nil then self.Mul2 = 1 end + if self.Mul3 == nil then self.Mul3 = 1 end + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) matproxy.Add( { name = "drc_PlayerColour2", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.MulInt = mat:GetFloat("$colourmul") + InitColours(self, mat, values) end, bind = function( self, mat, ent ) if !IsValid(ent) then return end local col = GetPlayerColour(ent, "ColourTintVec2") - if self.ResultTo == nil then self.ResultTo = "$color2" end - if self.MulInt == nil then self.MulInt = 1 end - mat:SetVector(self.ResultTo, col * self.MulInt) + + mat:SetVector(self.ResultTo, ClampVector(col*self.Mul, self.Min, self.Max)) + if self.ResultTo2 then mat:SetVector(self.ResultTo2, ClampVector(col*self.Mul2, self.Min2, self.Max2)) end + if self.ResultTo3 then mat:SetVector(self.ResultTo3, ClampVector(col*self.Mul3, self.Min3, self.Max3)) end end } ) @@ -743,6 +777,7 @@ matproxy.Add( { init = function( self, mat, values ) self.ResultTo = values.resultvar self.PowerFloat = mat:GetFloat("$rimlightpower") + self.TweakFloat = mat:GetFloat("$rimlightmul") self.TintBool = mat:GetFloat("$rimlightdotint") self.LerpPower = mat:GetFloat("$rimlight_ls") end, @@ -754,13 +789,14 @@ matproxy.Add( { if !IsValid( owner ) then return end if self.PowerFloat == nil then self.PowerFloat = 1 end + if self.TweakFloat == nil then self.TweakFloat = 1 end if self.LerpPower == nil then self.LerpPower = 1 end if self.TintBool == nil then self.TintBool = 0 end if ent.Preview == true or ent.preview == true then local col = mat:GetVector("$color2") local calc = (col.x + col.y + col.z) / 3 - mat:SetFloat("$rimlightboost", self.PowerFloat/10 * calc) + mat:SetFloat("$rimlightboost", ((self.PowerFloat*0.1) * self.TweakFloat) * calc) else local name = mat:GetName() if ent:EntIndex() == lply:GetViewModel():EntIndex() then ent = lply:GetActiveWeapon() end @@ -814,9 +850,9 @@ matproxy.Add( { if GetConVar("cl_drc_debugmode"):GetFloat() != 0 && GetConVar("cl_drc_debug_hideshaderfixes"):GetFloat() == 1 then ent.DRCScalingRimLightParams[name]["Value"] = 1 end if HDR then - mat:SetFloat( "$rimlightboost", ent.DRCScalingRimLightParams[name]["Value"] ) + mat:SetFloat( "$rimlightboost", ent.DRCScalingRimLightParams[name]["Value"] * self.TweakFloat ) else - mat:SetFloat( "$rimlightboost", ent.DRCScalingRimLightParams[name]["Value"] ) + mat:SetFloat( "$rimlightboost", ent.DRCScalingRimLightParams[name]["Value"] * self.TweakFloat ) end end end @@ -882,32 +918,36 @@ matproxy.Add( { end } ) +local function InitReflectionTint(self, mat, values) + if !self or !mat or !values then return end + self.ResultTo = values.resultvar or "$envmaptint" + self.ResultTo2 = values.resultvar2 + self.ResultTo3 = values.resultvar3 + self.TintVector = mat:GetVector("$cmtint") or mat:GetVector("$cubemaptint") or Vector(1, 1, 1) + self.PowerFloat = mat:GetFloat("$cmpower") or mat:GetFloat("$cubemappower") or 1 + self.ShiftFloat = values.shiftpower or 1 + self.MinFloat = mat:GetFloat("$cmmin") or mat:GetFloat("$cubemapmin") or 0 + self.MaxFloat = mat:GetFloat("$cmmax") or mat:GetFloat("$cubemapmax") or 1 + self.HDRCorrectionLevel = mat:GetFloat("$cmhdr") or mat:GetFloat("$cubemapHDRMul") or 1 + self.LDRCorrectionLevel = mat:GetFloat("$cmldr") or mat:GetFloat("$cubemapLDRMul") or 1 + self.LerpPower = mat:GetFloat("$cubemap_ls") or 1 + self.Saturation = mat:GetFloat("$cmlightsat") or mat:GetFloat("$cubemaplightingsaturation") or 1 + self.Envmap = mat:GetString("$envmapfallback") +end + matproxy.Add( { name = "drc_ReflectionTint", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") - self.Envmap = mat:GetString("$envmapfallback") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - local owner = ent - if !IsValid( owner ) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end local val = GetCubemapStrength(self, ent, "None", mat) if val then - mat:SetVector(self.ResultTo, val) + mat:SetVector(self.ResultTo or "$envmaptint", val) if self.ResultTo2 then mat:SetVector(self.ResultTo2, val) end if self.ResultTo3 then mat:SetVector(self.ResultTo3, val) end end @@ -917,25 +957,12 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_EntityColour", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - local owner = ent - if !IsValid( owner ) then return end - - if !self.ResultTo then self.ResultTo = "$envmaptint" end local val = GetCubemapStrength(self, ent, "Entity", mat) if val then @@ -949,24 +976,13 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_PlayerColour", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end - local val = GetCubemapStrength(self, ent, "PlayerColour_DRC", mat) if val then mat:SetVector(self.ResultTo, val) @@ -979,24 +995,13 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_EyeColour", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end - local val = GetCubemapStrength(self, ent, "EyeTintVec", mat) if val then mat:SetVector(self.ResultTo, val) @@ -1009,24 +1014,13 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_PlayerTint1", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end - local val = GetCubemapStrength(self, ent, "ColourTintVec1", mat) if val then mat:SetVector(self.ResultTo, val) @@ -1039,24 +1033,13 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_PlayerTint2", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.LerpPower = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end - local val = GetCubemapStrength(self, ent, "ColourTintVec2", mat) if val then mat:SetVector(self.ResultTo, val) @@ -1069,24 +1052,13 @@ matproxy.Add( { matproxy.Add( { name = "drc_ReflectionTint_WeaponColour", init = function( self, mat, values ) - self.ResultTo = values.resultvar - self.ResultTo2 = values.resultvar2 - self.ResultTo3 = values.resultvar3 - self.TintVector = mat:GetVector("$cubemaptint") - self.PowerFloat = mat:GetFloat("$cubemappower") - self.MinFloat = mat:GetFloat("$cubemapmin") - self.MaxFloat = mat:GetFloat("$cubemapmax") - self.HDRCorrectionLevel = mat:GetFloat("$cubemapHDRMul") - self.LDRCorrectionLevel = mat:GetFloat("$cubemapLDRMul") - self.PowerFloat = mat:GetFloat("$cubemap_ls") + InitReflectionTint(self, mat, values) end, bind = function( self, mat, ent ) - if ( !IsValid( ent )) then return end + if (!IsValid(ent)) then return end if !IsValid(lply) then return end - if !self.ResultTo then self.ResultTo = "$envmaptint" end - local val = GetCubemapStrength(self, ent, "WeaponColour_DRC", mat) if val then mat:SetVector(self.ResultTo, val) @@ -1592,6 +1564,7 @@ matproxy.Add( { ent.DRCBlinkTimed = true ent.DRCBlinkFrame = 0 timer.Simple(math.Rand(3, 16), function() + if !IsValid(ent) then return end ent.DRCBlinkStatus = false ent.DRCBlinkTimed = false @@ -1725,7 +1698,8 @@ matproxy.Add( { self.ResultTo = values.resultvar self.Power = mat:GetFloat("$psx_mul") self.Speed = mat:GetFloat("$psx_speed") - self.World = mat:GetFloat("$psx_world") + self.World = mat:GetFloat("$psx_world") or 0 + self.Menu = mat:GetFloat("$psx_menu") or 0 self.Framerate = mat:GetFloat("$psx_fps") end, @@ -1733,18 +1707,27 @@ matproxy.Add( { if !IsValid(ent) then ent = Entity(0) end if !IsValid(ent) then return end if !IsValid(lply) then return end + local cspm = ent:GetClass() == "drc_csplayermodel" or ent:GetClass() == "drc_csshadowmodel" + if ent == lply && (GetConVar("cl_drc_experimental_fp"):GetFloat() > 0 && DRC:ThirdPersonEnabled(lply) == false) then return end if !self.Power then self.Power = 1 end if !self.Speed then self.Speed = 1 end if !self.World then self.World = 0 end - if !self.Framerate then self.Framerate = 24 end + local localvel = lply:GetVelocity() local localspeed = localvel:Length() + local hands = ent == lply:GetHands() + local vm = ent == lply:GetViewModel(0) + + if !self.Framerate then self.Framerate = 24 end + ent.PSXFramerate = self.Framerate local c1, c2 = ent:GetPos() + ent:OBBCenter(), lply:EyePos() local m1, m2 = (self.Power or 1)*0.1, 1 + if ent == lply then c2 = lply:EyePos() + (lply:EyeAngles():Forward() * -DRC.ThirdPerson.LoadedSettings.Length*0.666) end + ent.PSXDistance = (math.Distance(c1.x, c1.y, c2.x, c2.y) / 50) if !ent.PSXDistance then ent.PSXDistance = 0 end ent.DesiredPower = m1 * m2 @@ -1762,35 +1745,47 @@ matproxy.Add( { if !ent.PSXCycle then ent.PSXCycle = 0 end if !ent.PSXTick then ent.PSXTick = 0 end - if CurTime() > ent.psxcd then - local fps = 1/self.Framerate - ent.psxcd = CurTime() + fps + if RealTime() > ent.psxcd then + local fps = 1/ent.PSXFramerate + ent.psxcd = RealTime() + fps if ent.psxbool == 0 then ent.psxbool = 1 else ent.psxbool = 0 end local mspd, mul, amount + if !ent.psxspeedmul then ent.psxspeedmul = 0 end + if !ent.psxamount then ent.psxamount = 0 end if ent.preview == true or ent.Preview == true then - amount = 0.0052 - elseif ent:IsPlayer() then - mspd = ent:GetRunSpeed() - (ent:GetRunSpeed() * 0.25) - if ent:KeyDown(IN_WALK) then mspd = ent:GetSlowWalkSpeed() * 3.75 end - if ent:KeyDown(IN_DUCK) then mspd = mspd * 1.5 end - mul = Lerp(localspeed/64000, 0, mspd) * 2.5 - amount = (fps * mul) + ent.psxamount = 0.0052 + ent.psxspeedmul = Lerp(1, 0, 0.0416) * 2 + ent.psxamount = (fps * ent.psxspeedmul) + elseif ent:IsPlayer() or cspm then + local etu = ent + if cspm then etu = lply end + if etu:KeyDown(IN_JUMP) then etu.PSXCycle = 0 end + mspd = etu:GetRunSpeed() - (etu:GetRunSpeed() * 0.25) + if etu:KeyDown(IN_WALK) then mspd = etu:GetSlowWalkSpeed() * 3.75 end + if etu:KeyDown(IN_DUCK) then mspd = mspd * 1.5 end + if cspm then mspsd = mspd * 0.01 end + if ent:GetVelocity() == Vector() then ent.psxspeedmul = Lerp(1, 0, 0.0416) * 3.333 + else ent.psxspeedmul = Lerp(localspeed/64000, 0, mspd) * 2.5 end + ent.psxamount = (fps * ent.psxspeedmul) else - amount = fps + ent.psxamount = fps end - ent.PSXCycle = ent.PSXCycle + amount or 0 + amount - ent.PSXTick = ent.PSXTick + amount or 0 + amount + ent.PSXCycle = ent.PSXCycle + ent.psxamount or 0 + ent.psxamount + ent.PSXTick = ent.PSXTick + ent.psxamount or 0 + ent.psxamount end if DRC:FloorDist(ent) < 10 or (ent.preview == true or ent.Preview == true) then ent:SetCycle(ent.PSXCycle) end if self.World < 1 then local str = ent.DesiredPower * self.Power + local height = 0 + if vm or hands && self.Menu < 1 then str = 0.05 height = 100 end + if self.Menu > 0 then height = 100 end mat:SetInt("$treesway", ent.psxbool) - mat:SetFloat("$treeswayheight", 0) - mat:SetFloat("$treeswaystartheight", 0) + mat:SetFloat("$treeswayheight", -height) + mat:SetFloat("$treeswaystartheight", height) mat:SetFloat("$treeswayradius", 1) mat:SetFloat("$treeswaystartradius", 1) mat:SetFloat("$treeswayspeed", 1) @@ -1820,9 +1815,6 @@ matproxy.Add( { end } ) ------------------------------------------------------------------------------------------------------------------------ --- Nothing below is on the wiki yet because it's very unfinished & unstable. - local matlerps = { ["Linear"] = "L", ["InBack"] = math.ease.InBack, @@ -1879,7 +1871,7 @@ local function Read(mat, ent) if ent:IsWeapon() then if input == "clip1" then val = calc(math.Clamp(ent:Clip1()/ent:GetMaxClip1(), 0, 1)) - elseif input == "heat" then val = calc(math.Clamp(ent:GetHeat()/ent:GetMaxHeat(), 0, 1)) + elseif input == "heat" && ent.GetMaxHeat then val = calc(math.Clamp(ent:GetHeat()/ent:GetMaxHeat(), 0, 1)) elseif input == "charge" then val = calc(math.Clamp(ent:GetCharge()/ent:GetMaxCharge(), 0, 1)) elseif input == "velocity" then local own = ent:GetOwner() @@ -1887,7 +1879,6 @@ local function Read(mat, ent) else val = calc(math.Clamp(ent:GetOwner():GetVelocity():Length(), 1, 999999)/funcmax, 0, 1) -- weapon is held by an entity end end - return val end if DRC:IsVehicle(ent) then @@ -1911,7 +1902,13 @@ local function Read(mat, ent) b = TimedSin(1/mod, maxi.z, mini.z, 0) val = Vector(r,g,b) elseif input == "health" then local hp, mhp = DRC:Health(ent) val = calc(math.Clamp(hp/mhp, 0, 1)) - elseif input == "armour" then print(ent) local ap = ent:Armor() map = ent:GetMaxArmor() val = calc(math.Clamp(ap/map, 0, 1)) + elseif input == "armour" then + local ap, map = 1, 100 + if ent.Armor != nil && ent.GetMaxArmor != nil then + ap = ent:Armor() + map = ent:GetMaxArmor() + end + val = calc(math.Clamp(ap/map, 0, 1)) elseif input == "shield" then local sp, msp = DRC:GetShield(ent) val = calc(math.Clamp(sp/msp, 0, 1)) elseif input == "lightlevel" then val = LightPollEntity(ent) elseif input == "velocity" then @@ -1930,8 +1927,8 @@ local function Read(mat, ent) local b = ent:GetNWBool(mod) if b == true then val = Vector(1) else val = Vector(0) end elseif input == "nwvector" then val = ent:GetNWVector(mod) - elseif input == "nwfloat" then val = ent:GetNWFloat(mod) - elseif input == "nwint" then val = ent:GetNWInt(mod) + elseif input == "nwfloat" then val = calc(ent:GetNWFloat(mod)) + elseif input == "nwint" then val = calc(ent:GetNWInt(mod)) elseif input == "nwangle" then val = ent:GetNWAngle(mod) elseif input == "nwstring" then val = ent:GetNWString(mod) end @@ -1943,10 +1940,15 @@ local matfuncs = { ["read"] = Read, } -local matreturns = { -- 0 vector, 1 string, 2 bool, 3 number - ["$basetexture"] = 1, - ["$bumpmap"] = 1, - ["$normalmap"] = 1, +local matreturns = { -- 0 vector, 1 string, 2 bool, 3 number, 4 texture + ["$basetexture"] = 4, + ["$bumpmap"] = 4, + ["$normalmap"] = 4, + ["$lightwarptexture"] = 4, + ["$detail"] = 4, + ["$detailscale"] = 3, + ["$detailblendmode"] = 3, + ["$detailblendfactor"] = 3, ["$color"] = 0, ["$color2"] = 0, ["$phong"] = 2, @@ -1954,15 +1956,19 @@ local matreturns = { -- 0 vector, 1 string, 2 bool, 3 number ["$phongboost"] = 3, ["$phongtint"] = 0, ["$phongfresnelranges"] = 0, - ["$phongexponenttexture"] = 1, + ["$phongexponenttexture"] = 4, ["$phongexponentfactor"] = 3, ["$phongdisablehalflambert"] = 2, ["$phongalbedotint"] = 2, ["$phongalbedoboost"] = 3, + ["$basemapalphaphongmask"] = 2, ["$basemapalphaenvmapmask"] = 2, ["$normalmapalphaenvmapmask"] = 2, ["$envmap"] = 1, ["$envmaptint"] = 0, + ["$selfillum"] = 2, + ["$selfillumtint"] = 0, + ["$emissiveblendtint"] = 0, ["$rimlight"] = 2, ["$rimlightexponent"] = 3, ["$rimlightboost"] = 3, @@ -1970,14 +1976,17 @@ local matreturns = { -- 0 vector, 1 string, 2 bool, 3 number ["$cloakfactor"] = 3, ["$cloakcolortint"] = 0, ["$refractamount"] = 3, + ["$basetexturetransform"] = 1, -- These few below technically don't exist, but are the most common used for translations ["$angle"] = 3, ["$translate"] = 0, ["$center"] = 0, ["$offset"] = 3, -- Draconic parameters beyond this point - ["$cmpower"] = 0, + ["$cmpower"] = 3, ["$cmtint"] = 0, + ["$cmshiftpower"] = 3, + ["$cmshift"] = 0, ["$rimlightpower"] = 3, } @@ -1986,6 +1995,7 @@ local function ReturnVal(info, val, mat) if numb == 0 then mat:SetVector(info.ResultTo, Vector(val * info.Mul1)) elseif numb == 1 then mat:SetString(info.ResultTo, val * info.Mul1) elseif numb == 2 or numb == 3 then mat:SetFloat(info.ResultTo, val.x * info.Mul1) + elseif numb == 4 then mat:SetTexture(info.ResultTo, val) end if matreturns[info.ResultTo2] then @@ -1993,6 +2003,7 @@ local function ReturnVal(info, val, mat) if numb == 0 then mat:SetVector(info.ResultTo2, Vector(val * info.Mul2)) elseif numb == 1 then mat:SetString(info.ResultTo2, val * info.Mul2) elseif numb == 2 or numb == 3 then mat:SetFloat(info.ResultTo2, val.x * info.Mul2) + elseif numb == 4 then mat:SetTexture(info.ResultTo, val) end end @@ -2001,10 +2012,68 @@ local function ReturnVal(info, val, mat) if numb == 0 then mat:SetVector(info.ResultTo3, Vector(val * info.Mul3)) elseif numb == 1 then mat:SetString(info.ResultTo3, val * info.Mul3) elseif numb == 2 or numb == 3 then mat:SetFloat(info.ResultTo3, val.x * info.Mul3) + elseif numb == 4 then mat:SetTexture(info.ResultTo, val) end end end +local function SetVal(key, val, mat) +-- print(key, val) + local numb = matreturns[key] + if numb == 0 then mat:SetVector(key, val) + elseif numb == 1 then mat:SetString(key, val) + elseif numb == 2 or numb == 3 then mat:SetFloat(key, val) + elseif numb == 4 then mat:SetTexture(key, val) + end +end + +local function CopyBaseVals(mat, ent) + if ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")] != nil then + mat:SetTexture("$basetexture", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetTexture("$basetexture") or "") + mat:SetTexture("$bumpmap", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetTexture("$bumpmap") or "") + mat:SetTexture("$phongexponenttexture", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetTexture("$phongexponenttexture") or "") + mat:SetVector("$color2", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetVector("$color2") or Vector(1,1,1)) + mat:SetVector("$phongtint", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetVector("$phongtint") or Vector(1,1,1)) + mat:SetVector("$phongfresnelranges", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetVector("$phongfresnelranges") or Vector(1,1,1)) + mat:SetVector("$cmtint", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetVector("$cmtint") or Vector(1,1,1)) + mat:SetFloat("$cmpower", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetFloat("$cmpower") or 1) + mat:SetFloat("$rimlightpower", ent.WeaponSkinProxyMaterials[mat:GetFloat("$slotnum")]:GetFloat("$rimlightpower") or 1) + end +end + +matproxy.Add({ + name = "drc_WeaponCamo", + init = function( self, mat, values ) + end, + + bind = function( self, mat, ent ) + if !IsValid(ent) then return end + if !IsValid(lply) then return end + if ent == lply:GetViewModel() then ent = lply:GetActiveWeapon() end + local skin = ent.WeaponSkinApplied + if skin != nil && DRC.WeaponSkins[skin].ProxyMat then + CopyBaseVals(mat, ent) + for k,v in pairs(DRC.WeaponSkins[skin].ProxyMat) do + if matreturns[k] then SetVal(k, v, mat) end + + if k == "$detailscale" then + for ke,va in pairs(ent.WeaponSkinProxyMaterials) do + local camoscale = ent.WeaponSkinProxyMaterials[ke]:GetFloat("$drc_camoscale") or 1 + if mat:GetString("$detail") != "" then mat:SetFloat("$detailscale", v * camoscale) end + end + --[[ if camoscale != 1 then + local matr = mat:GetMatrix("$basetexturetransform") + matr:SetScale(Vector(camoscale, camoscale, 0)) + mat:SetMatrix("$basetexturetransform", matr) + end ]] -- This ended up being unusable because the normal scales with it and can often become stuck. + end + end + + + end + end +}) + local function DRCFunctionInit(self, mat, values) self.ResultTo = values.resultvar self.ResultTo2 = values.resultvar2 @@ -2033,7 +2102,7 @@ local function DRCFunctionBind(self, mat, ent) local ent2 if ent == lply:GetHands() or ent == lply:GetViewModel(0) then ent2 = lply else ent2 = ent end if !IsValid(ent2) then return end - if self.Target == "weapon" && !ent2:IsWeapon() then ent2 = ent2:GetActiveWeapon() end + if self.Target == "weapon" && !ent2:IsWeapon() then if DRC:IsCharacter(ent2) then ent2 = ent2:GetActiveWeapon() else ent2 = ent end end if self.Target == "vehicle" && !DRC:IsVehicle(ent2) && !ent:IsRagdoll() then ent2 = ent2:GetVehicle() end if !IsValid(ent2) then return end @@ -2121,17 +2190,17 @@ matproxy.Add( { if self.ResultTo then -- "Grunge" layer, intended for detail textures to be tied to detailblendfactor. Increase power from 0-1. if !self.Mul1 then self.Mul1 = 1 end - mat:SetInt(self.ResultTo, val * self.Mul1) + mat:SetFloat(self.ResultTo, val * self.Mul1) end if self.ResultTo2 then -- "Reflection" pass, intended to be tied to cmpower. Decreases power from 1-0. if !self.Mul2 then self.Mul2 = 1 end - mat:SetInt(self.ResultTo2, self.Mul2 - (val * self.Mul2)) + mat:SetFloat(self.ResultTo2, self.Mul2 - (val * self.Mul2)) end if self.ResultTo3 then -- "Specular" pass, intended to be tied to either phongboost or phongalbedoboost. Decreases power from 1-0. if !self.Mul3 then self.Mul3 = 1 end - mat:SetInt(self.ResultTo3, self.Mul3 - (val * self.Mul3)) + mat:SetFloat(self.ResultTo3, self.Mul3 - (val * self.Mul3)) end end } ) \ No newline at end of file diff --git a/lua/weapons/draconic_base/cl_init.lua b/lua/weapons/draconic_base/cl_init.lua index bc2c16c..21be2b5 100644 --- a/lua/weapons/draconic_base/cl_init.lua +++ b/lua/weapons/draconic_base/cl_init.lua @@ -51,15 +51,27 @@ function SWEP:FormatViewModelAttachment(nFOV, vOrigin, bFrom --[[= false]]) end function SWEP:GetWeaponAttachment(att) + if !self.VMA then + local attinfo = {} + attinfo.Pos = Vector() + attinfo.Ang = Angle() + attinfo.ID = 0 + attinfo.ent = self + return attinfo end local ply = self:GetOwner() local ent = self - if ply == LocalPlayer() && !DRC:ThirdPersonEnabled(ply) then ent = ply:GetViewModel() end + + if ply:IsPlayer() then + local tp = DRC:ThirdPersonEnabled(ply) + if ply == LocalPlayer() && !tp then ent = ply:GetViewModel() end + end local attinfo = ent:GetAttachment(ent:LookupAttachment(att)) local newpos, newang = attinfo.Pos, attinfo.Ang if ply:IsPlayer() && ent == ply:GetViewModel() then newpos = self.VMA[att].pos newang = self.VMA[att].ang end + attinfo.Pos = newpos attinfo.ID = ent:LookupAttachment(att) attinfo.ent = ent diff --git a/lua/weapons/draconic_base/init.lua b/lua/weapons/draconic_base/init.lua index c7a0c91..0f87002 100644 --- a/lua/weapons/draconic_base/init.lua +++ b/lua/weapons/draconic_base/init.lua @@ -1,7 +1,17 @@ -if CLIENT or SERVER then - AddCSLuaFile("cl_init.lua") - AddCSLuaFile("shared.lua") +AddCSLuaFile("cl_init.lua") +AddCSLuaFile("shared.lua") - include("shared.lua") - include("sh_funcs.lua") +include("shared.lua") +include("sh_funcs.lua") + +function SWEP:SoundChain(tbl) + local ply = self:GetOwner() + if !tbl then return end + for k,v in pairs(tbl) do + local sound, thyme = v[1], v[2] + timer.Simple(thyme, function() if IsValid(self) then + if ply:GetActiveWeapon() != self then return end + self:EmitSound(sound) + end end) + end end \ No newline at end of file diff --git a/lua/weapons/draconic_base/sh_funcs.lua b/lua/weapons/draconic_base/sh_funcs.lua index bb61dba..e21c988 100644 --- a/lua/weapons/draconic_base/sh_funcs.lua +++ b/lua/weapons/draconic_base/sh_funcs.lua @@ -79,6 +79,7 @@ function SWEP:CanCustomize(bypassinspect) if #v <= 1 then cando = false end end end + if self.WeaponSkinDefaultMat != nil then cando = true end return cando end @@ -137,28 +138,6 @@ function SWEP:RegeneratingHealth(ply) end) end ---[[ -function SWEP:RegeneratingAmmo(self) - local ply = self:GetOwner() - if not ply:IsPlayer() then return end - local ammo, maxammo - if self.RegenAmmo == false or self.RegenAmmo == nil then return end - - self.AmmoRegen = "AmmoRegen_".. ply:Name() - - timer.Create(self.AmmoRegen, self.AmmoInterval, 0, function() - if !SERVER or !self:IsValid() or !timer.Exists( self.AmmoRegen ) then return end - - ammo = self:Clip1() - maxammo = (self.Primary.ClipSize * self:GetAttachmentValue("Ammunition", "ClipSizeMul")) - if maxammo < ammo then return end - if self.Loading == false then - self:SetLoadedAmmo(math.Clamp( ammo + self.AmmoRegenAmount, 0, maxammo )) - self:SetClip1(self:GetLoadedAmmo()) - end - end) -end ]] - function SWEP:RegeneratingAmmo(wpn, delay, amount) if !wpn.AmmoCheck then wpn.AmmoCheck = 0 end if CurTime() > wpn.AmmoCheck then @@ -174,9 +153,10 @@ function SWEP:RegeneratingAmmo(wpn, delay, amount) end end +--[[ function SWEP:DisperseHeat() local ply = self:GetOwner() - if not ply:IsPlayer() then return end + if !ply:IsPlayer() then return end local CurHeat = self:GetHeat() self.HeatDisperseTimer = "HeatDisperseTimer_".. ply:Name() @@ -199,10 +179,10 @@ function SWEP:DisperseHeat() end if ply:GetAmmoCount( "ammo_drc_battery" ) >= 100 then - if self.CanOverheat == true then + if self.CanOverheat == true && self.IsBatteryBased == true then self:Overheat() - else end - else end + end + end if ply:GetAmmoCount( "ammo_drc_battery" ) >= (100 - (100 * self.OverHeatFinishPercent)) then else @@ -216,6 +196,27 @@ function SWEP:DisperseHeat() else end end +]] + +function SWEP:DisperseHeat() + local ply = self:GetOwner() + if !ply:IsPlayer() then return end + if !self.HeatCheck then self.HeatCheck = 0 end + local ct = CurTime() + if ct > self.HeatCheck then + self.HeatCheck = ct + self.HeatLossInterval + local heat = self:GetHeat() + if heat >= 100 then + if self.CanOverheat == true && self.IsBatteryBased == true && self.IsOverheated != true then + self:Overheat() + end + end + -- if ct > self:GetNextPrimaryFire() then + self:SetHeat(math.Clamp( (self:GetHeat() - (self.HeatLossPerInterval * self:GetNWFloat("HeatDispersePower"))), 0, 100), "ammo_drc_battery" ) + ply:SetAmmo(self:GetHeat(), "ammo_drc_battery" ) + -- end + end +end function SWEP:BloomScore() if self.Base != "draconic_melee_base" then @@ -226,6 +227,7 @@ function SWEP:BloomScore() local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) local plidle = (!mk && !sk && !cv) local issprinting = sk && mk + local sd = self.SightsDown self.BloomScoreName = "BloomScore_".. ply:Name() @@ -233,36 +235,27 @@ function SWEP:BloomScore() if !self:IsValid() then return end if self.BloomValue == 0 then return end + local div, maxi, mul, bonus = 1, 1.7, 1, 0 + if !sd then + if plidle then maxi = 1 mul = 1.5 + elseif cv then maxi = 1 mul = 1.75 + elseif mk then maxi = 1.3 mul = 2 bonus = 0.1 + elseif issprinting then maxi = 1.7 mul = 2 bonus = 0.3 end + else + if plidle then maxi = 1 mul = 2 div = 1.5 + elseif cv then maxi = 1 mul = 2 div = 3 + elseif mk then maxi = 1 mul = 1 bonus = 0.1 div = 2 + elseif issprinting then maxi = 1 mul = 1 bonus = 0.3 div = 2 end + end + local bs = self.BloomValue local pbs = self.PrevBS if self.SightsDown == false then - if plidle then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - (self.Primary.Kick * 1.5), 0, 1) - elseif cv then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - (self.Primary.Kick * 1.75), 0, 1) - elseif mk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - self.Primary.Kick * 2 +0.1, 0, 1.3) - elseif issprinting then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - self.Primary.Kick * 2 +0.3, 0, 1.7) - end + self.PrevBS = math.Clamp( bs, 0, 1.7) + self.BloomValue = math.Clamp( bs - (self.Primary.Kick * mul + bonus), 0, maxi) else - if plidle then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - ((self.Primary.Kick * 2) / 1.5), 0, 1) - elseif cv then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - ((self.Primary.Kick * 2) / 3), 0, 1) - elseif mk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - (self.Primary.Kick +0.1) /2, 0, 1) - elseif issprinting then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( bs - (self.Primary.Kick +0.3) /2, 0, 1) - end + self.PrevBS = math.Clamp( bs, 0, 1.7) + self.BloomValue = math.Clamp( bs - (self.Primary.Kick * mul + bonus / div), 0, maxi) end end) @@ -313,96 +306,43 @@ function SWEP:CanOvercharge() if self:GetCharge() > 99 then return true else return false end end ---[[ function SWEP:UpdateBloom(mode) local ply = self:GetOwner() - if !ply:IsPlayer() then return end - local cv = ply:Crouching() - local sk = ply:KeyDown(IN_SPEED) - local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) - local plidle = (!mk && !sk && !cv) - local issprinting = sk && mk + local oa, cv, bs, pbs, mul, sd = self.OwnerActivity, ply:Crouching(), self:GetBS(), self:GetPBS(), 1, self.SightsDown - if mode == "primary" then - self.Kick = self.Primary.Kick - elseif mode == "secondary" then - self.Kick = self.Secondary.Kick - elseif mode == "overcharge" then - self.Kick = self.OCKick - end + local kickmodes = { + ["primary"] = self.PrimaryStats.Kick, + ["secondary"] = self.SecondaryStats.Kick, + ["overcharge"] = self.OCStats.Kick + } - local bs = self.BloomValue - local pbs = self.PrevBS - if bs == nil then bs = 0 end - if pbs == nil then pbs = 0 end - if self.SightsDown == false then - if plidle or sk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + self.Kick, 0, 1) - elseif cv then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + self.Kick / 1.25, 0, 1) - elseif mk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + self.Kick +0.1, 0, 1.3) - elseif issprinting then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + self.Kick +0.3, 0, 1.7) - end - else - if plidle or sk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + self.Primary.Kick /2, 0, 1) - elseif cv then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + (self.Primary.Kick /1.25) /2, 0, 1) - elseif mk then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + (self.Primary.Kick +0.1) /2, 0, 1) - elseif issprinting then - self.PrevBS = math.Clamp( bs, 0, 1.7) - self.BloomValue = math.Clamp( self.BloomValue + (self.Primary.Kick +0.3) /2, 0, 1) - end - end + local blooms = { + ["primary"] = self.PrimaryStats.BloomMul, + ["secondary"] = self.SecondaryStats.BloomMul, + ["overcharge"] = self.OCStats.BloomMul + } --- ply:SetNWInt("PrevBS", self.BloomValue * 10) -end ]] - -local bloom_updates = { - ["standidle"] = 0, - ["crouchidle"] = 0, - ["running"] = 0.1, - ["crouchrunning"] = 0.1, - ["sprinting"] = 0.3, - ["crouchingsprinting"] = 0.3, - ["swimidle"] = 0, - ["swimming"] = 0.1, -} -local bloom_maximums = { - ["standidle"] = 1, - ["crouchidle"] = 1, - ["running"] = 1.3, - ["crouchrunning"] = 1.3, - ["sprinting"] = 1.7, - ["crouchingsprinting"] = 1.7, - ["swimidle"] = 0.9, - ["swimming"] = 1.1, -} - -function SWEP:UpdateBloom(mode) - local ply = self:GetOwner() - local oa, cv, bs, pbs, mul = self.OwnerActivity, ply:Crouching(), self:GetBS(), self:GetPBS(), 1 - if cv then mul = 0.5 end + local bloomscrouch = { + ["primary"] = self.PrimaryStats.BloomMulCrouch, + ["secondary"] = self.SecondaryStats.BloomMulCrouch, + ["overcharge"] = self.OCStats.BloomMulCrouch + } - local kickmodes = { -- defined in here in case anyone codes custom kick modifiers; though don't rely on these as this'll need to be changed later for attachment base integration. - ["primary"] = self.Primary.Kick, - ["secondary"] = self.Secondary.Kick, - ["overcharge"] = self.OCKick + local bloomsads = { + ["primary"] = self.PrimaryStats.BloomMulADS, + ["secondary"] = self.SecondaryStats.BloomMulADS, + ["overcharge"] = self.OCStats.BloomMulADS } + self.Kick = kickmodes[mode] - self.PrevBS = math.Clamp(bs, 0, bloom_maximums[oa]) - self.BloomValue = math.Clamp((self.BloomValue + bloom_updates[oa] + self.Kick) * mul, 0, bloom_maximums[oa]) + if !cv && !sd then mul = blooms[mode] + elseif !cv && sd then mul = blooms[mode] * bloomsads[mode] + elseif cv && !sd then mul = bloomscrouch[mode] + elseif cv && sd then mul = bloomscrouch[mode] * bloomsads[mode] end + + self.PrevBS = math.Clamp(bs, 0, DRCD.Weapons.bloom_maximums[oa]) + self.BloomValue = math.Clamp((self.BloomValue + DRCD.Weapons.bloom_updates[oa] + self.Kick) * mul, 0, DRCD.Weapons.bloom_maximums[oa]) end function SWEP:GetBS() @@ -413,173 +353,6 @@ function SWEP:GetPBS() return self.PrevBS end ---[[ -function SWEP:DoMeleeSwing(mode, flipx, flipy, preventanim) - local ply = self:GetOwner() - local settings = {} - if self.IsMelee then - settings = { - ["primary"] = { - ["range"] = self.Primary.Range, - ["x1m"] = math.Rand(self.Primary.StartX * 0.9, self.Primary.StartX * 1.1), - ["x2m"] = math.Rand(self.Primary.EndX * 0.9, self.Primary.EndX * 1.1), - ["y1m"] = math.Rand(self.Primary.StartY * 0.9, self.Primary.StartY * 1.1), - ["y2m"] = math.Rand(self.Primary.EndY * 0.9, self.Primary.EndY * 1.1), - ["delayhit"] = self.Primary.DelayHit, - ["delaymiss"] = self.Primary.DelayMiss, - ["delayinitial"] = self.Primary.HitDelay, - ["sound"] = self.Primary.SwingSound, - ["shake"] = self.Primary.ShakeMul, - ["anim"] = self.Primary.MeleeAct, - ["anim_crouch"] = self.Primary.MeleeActCrouch, - ["fp_hit"] = self.Primary.HitActivity, - ["fp_hit_crouch"] = self.Primary.CrouchHitActivity, - ["fp_miss"] = self.Primary.MissActivity, - ["fp_miss_crouch"] = self.Primary.CrouchMissActivity, - }, - ["secondary"] = { - ["range"] = self.Secondary.Range, - ["x1m"] = math.Rand(self.Secondary.StartX * 0.9, self.Secondary.StartX * 1.1), - ["x2m"] = math.Rand(self.Secondary.EndX * 0.9, self.Secondary.EndX * 1.1), - ["y1m"] = math.Rand(self.Secondary.StartY * 0.9, self.Secondary.StartY * 1.1), - ["y2m"] = math.Rand(self.Secondary.EndY * 0.9, self.Secondary.EndY * 1.1), - ["delayhit"] = self.Secondary.DelayHit, - ["delaymiss"] = self.Secondary.DelayMiss, - ["delayinitial"] = self.Secondary.HitDelay, - ["sound"] = self.Secondary.SwingSound, - ["shake"] = self.Secondary.ShakeMul, - ["anim"] = self.Secondary.MeleeAct, - ["anim_crouch"] = self.Secondary.MeleeActCrouch, - ["fp_hit"] = self.Secondary.HitActivity, - ["fp_hit_crouch"] = self.Secondary.CrouchHitActivity, - ["fp_miss"] = self.Secondary.MissActivity, - ["fp_miss_crouch"] = self.Secondary.CrouchMissActivity, - }, - ["lungeprimary"] = { - ["range"] = self.Primary.LungeRange, - ["x1m"] = math.Rand(self.Primary.LungeStartX * 0.9, self.Primary.LungeStartX * 1.1), - ["x2m"] = math.Rand(self.Primary.LungeEndX * 0.9, self.Primary.LungeEndX * 1.1), - ["y1m"] = math.Rand(self.Primary.LungeStartY * 0.9, self.Primary.LungeStartY * 1.1), - ["y2m"] = math.Rand(self.Primary.LungeEndY * 0.9, self.Primary.LungeEndY * 1.1), - ["delayhit"] = self.Primary.LungeDelayHit, - ["delaymiss"] = self.Primary.LungeDelayMiss, - ["delayinitial"] = self.Primary.LungeHitDelay, - ["sound"] = self.Primary.LungeSwingSound, - ["shake"] = self.Primary.LungeShakeMul, - ["anim"] = self.Primary.LungeMeleeAct, - ["anim_crouch"] = self.Primary.LungeMeleeActCrouch, - ["fp_hit"] = self.Primary.LungeHitAct, - ["fp_hit_crouch"] = self.Primary.LungeHitActCrouch, - ["fp_miss"] = self.Primary.LungeMissAct, - ["fp_miss_crouch"] = self.Primary.LungeMissActCrouch, - }, - } - else - settings = { - ["gunmelee"] = { - ["range"] = self.Primary.MeleeRange, - ["x1m"] = math.Rand(self.Primary.MeleeStartX * 0.9, self.Primary.MeleeStartX * 1.1), - ["x2m"] = math.Rand(self.Primary.MeleeEndX * 0.9, self.Primary.MeleeEndX * 1.1), - ["y1m"] = math.Rand(self.Primary.MeleeStartY * 0.9, self.Primary.MeleeStartY * 1.1), - ["y2m"] = math.Rand(self.Primary.MeleeEndY * 0.9, self.Primary.MeleeEndY * 1.1), - ["delayhit"] = self.Primary.MeleeDelayHit, - ["delaymiss"] = self.Primary.MeleeDelayMiss, - ["delayinitial"] = self.Primary.MeleeHitDelay, - ["sound"] = self.Primary.SwingSound, - ["shake"] = self.Primary.MeleeShakeMul, - ["anim"] = nil, - ["anim_crouch"] = nil, - ["fp_hit"] = self.Primary.MeleeHitActivity, - ["fp_hit_crouch"] = self.Primary.MeleeHitActivity, - ["fp_miss"] = self.Primary.MeleeMissActivity, - ["fp_miss_crouch"] = self.Primary.MeleeMissActivity, - }, - } - end - - local x1m, x2m, y1m, y2m = settings[mode]["x1m"], settings[mode]["x2m"], settings[mode]["y1m"], settings[mode]["y2m"] - if flipx == true then - x1m = -x1m - x2m = -x2m - end - if flipy == true then - y1m = -y1m - y2m = -y2m - end - - if mode == "gunmelee" then - local ht = string.lower(self:GetHoldType()) - if ht == "ar2" or ht == "smg" or ht == "crossbow" or ht == "shotgun" or ht == "rpg" or ht == "melee2" or ht == "physgun" then - settings.gunmelee.anim = ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND - settings.gunmelee.anim_crouch = ACT_GMOD_GESTURE_MELEE_SHOVE_2HAND - elseif ht == "crowbar" or ht == "pistol" or ht == "revolver" or ht == "grenade" or ht == "slam" or ht == "normal" or ht == "fist" or ht == "knife" or ht == "passive" or ht == "duel" or ht == "magic" or ht == "camera" then - settings.gunmelee.anim = ACT_GMOD_GESTURE_MELEE_SHOVE_1HAND - settings.gunmelee.anim_crouch = ACT_GMOD_GESTURE_MELEE_SHOVE_1HAND - end - end - - if mode == "lungeprimary" then - local target = self:GetConeTarget() - if target then - if ply:GetPos():Distance(target:GetPos()) < self.Primary.LungeMaxDist then - ply:SetVelocity(ply:GetForward() * 8 * ply:GetPos():Distance(target:GetPos())) - end - end - end - - DRC:SpeakSentence(ply, "Actions", "Melee") - if settings[mode]["sound"] != nil then self:EmitSound(Sound(settings[mode]["sound"])) end - - if ply:IsPlayer() && preventanim != true then - local cv = ply:Crouching() - if cv == false then - if SERVER then DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, settings[mode]["anim"]) end - elseif cv == true then - if SERVER then DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, settings[mode]["anim_crouch"]) end - end - end - - if ply:IsPlayer() then - local vm = ply:GetViewModel() - ply:ViewPunch(Angle(y1m, x1m, nil) * -0.1 * settings[mode]["shake"]) - ply:SetViewPunchVelocity(Angle(-x1m * (1 + settings[mode]["delayhit"]) * settings[mode]["shake"], -y1m * (5 + settings[mode]["delayhit"]) * settings[mode]["shake"], 0)) - timer.Simple(.1, function() - if !IsValid(self) then return end - if !IsValid(self:GetOwner()) then return end - ply:ViewPunch(Angle(y1m, x1m, nil) * 0.1 * settings[mode]["shake"]) - end) - - local anim = self:SelectWeightedSequence( settings[mode]["fp_miss"] ) - if ply:IsPlayer() then local cv = ply:Crouching() if cv == true then anim = self:SelectWeightedSequence( settings[mode]["fp_miss_crouch"] ) end end - local animdur = self:SequenceDuration( anim ) - self.IsDoingMelee = true - timer.Simple(animdur, function() if !IsValid(self) then return end self.IsDoingMelee = false end) - if anim != -1 && self:HasViewModel() && preventanim != true then - self:SendWeaponAnim(settings[mode]["fp_miss"]) - self:SendViewModelMatchingSequence(anim) - end - self:SetNextPrimaryFire(CurTime() + settings[mode]["delayhit"] ) - self:SetNextSecondaryFire(CurTime() + settings[mode]["delayhit"] ) - self.IdleTimer = CurTime() + vm:SequenceDuration() - else - self:SetNextPrimaryFire(CurTime() + settings[mode]["delayhit"] ) - self:SetNextSecondaryFire(CurTime() + settings[mode]["delayhit"] ) - self.IsDoingMelee = true - timer.Simple(1, function() if !IsValid(self) then return end self.IsDoingMelee = false end) - end - - for i=1,(math.Round(1/ engine.TickInterval() - 1 , 0)) do - if !IsValid(self) then return end - if !IsValid(ply) then return end - timer.Create( "".. tostring(self) .."_SwingImpact_".. i .."", math.Round((settings[mode]["delayinitial"] * 100) / 60 * i / 60, 3), 1, function() - if !IsValid(self) then return end - if !IsValid(self:GetOwner()) then return end - self:MeleeImpact(settings[mode]["range"], Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), x1m, x2m), Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), y1m, y2m), i, mode) - end) - end -end -]] - function SWEP:DoMeleeSwing(swinginfo, preventanim) if !self:CanMelee() then return false end if !swinginfo or !istable(swinginfo) then return end @@ -588,21 +361,25 @@ function SWEP:DoMeleeSwing(swinginfo, preventanim) if !self.MeleeQueue then self.MeleeQueue = {} end self.IsDoingMelee = true - if swinginfo.anim_fp_miss != nil then - -- self.Loading = true - --self:SendWeaponAnim(swinginfo.anim_fp_miss) - self:PlayAnim(swinginfo.anim_fp_miss, false, true) - -- local anim = self:SelectWeightedSequence(swinginfo.anim_fp_miss) - -- local dur = self:SequenceDuration(anim) - -- self.IdleTimer = CurTime() + dur + self:SetNWBool("IsDoingMelee", true) + if swinginfo.anim_fp_miss != nil then self:PlayAnim(swinginfo.anim_fp_miss, false, true) end + + if CLIENT && self.DoRotationalBlur == true then + local rx, ry = swinginfo.x[1] + swinginfo.x[2], swinginfo.y[1] + swinginfo.y[2] + if rx == 0 then rx = 5 end + if ry == 0 then ry = 5 end + local ra = ((rx+ry)*0.5) * 0.0025 + if swinginfo.x[1] < 0 then ra = -ra end + ply.RotationalBlurAdditive = ply.RotationalBlurAdditive + (ra * self.RotationalGainMul) end if swinginfo.anim_tp != nil && preventanim != true then - DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, swinginfo.anim_tp, true) + local fallback = DRC:GetHoldTypeAnim(string.lower(self:GetHoldType()), "melee", false) + DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, swinginfo.anim_tp, true, fallback) end local delay = swinginfo.delay - if CLIENT or (SERVER && !game.IsDedicated()) && swinginfo.screenshake[1] == true then + if ply:IsPlayer() && swinginfo.screenshake[1] == true then ply:ViewPunch(Angle(swinginfo.y[1], swinginfo.x[1], nil) * -0.1 * swinginfo.screenshake[2]) ply:SetViewPunchVelocity(Angle(-swinginfo.x[1] * (1 + delay[1]) * swinginfo.screenshake[2], -swinginfo.y[1] * (5 + delay[1]) * swinginfo.screenshake[2], 0)) timer.Simple(.1, function() @@ -631,164 +408,14 @@ function SWEP:DoMeleeSwing(swinginfo, preventanim) end end end -end - ---[[ -function SWEP:MeleeImpact(range, x, y, i, att) - if !SERVER then return end - local ply = self:GetOwner() - local vm = nil - local eyeang = ply:EyeAngles() - local eyepos = ply:EyePos() - local centerpos = ply:GetPos() + ply:OBBCenter() - local aimpos = ply:GetPos() + Vector(ply:OBBCenter().x, ply:OBBCenter().y, ply:OBBCenter().z * 1.4) - local rangemul = 1 - local velang = DRC:GetVelocityAngle(ply, true, true) - if ply:IsPlayer() then - vm = ply:GetViewModel() - rangemul = math.Clamp((ply:GetWalkSpeed()/100 * (ply:GetWalkSpeed()/100) / 2) * velang.y / 180, 1, 2.5) - else - rangemul = 2 - end - - local rhm = math.Round(1 / engine.TickInterval() - 1, 0) / 2 - - if !IsValid(self) or !IsValid(ply) then return end - - if i < rhm then - self.dist = eyepos + ( ply:GetAimVector() * range * ( i / 10) ) * rangemul - elseif i == rhm then - self.dist = eyepos + ( ply:GetAimVector() * range * 3.4 ) * rangemul - elseif i > rhm then - self.dist = eyepos + ( ply:GetAimVector() * range / (i / 100) ) * rangemul - end - - local WhyDoesVJAimUpwards = Vector() - if ply.IsVJBaseSNPC then WhyDoesVJAimUpwards = Vector(0 ,0, -40) end - - local tl = { - ["start"] = aimpos, - ["endpos"] = ( self.dist ) + ((eyeang:Up()*y) + (eyeang:Right()*x) + WhyDoesVJAimUpwards), - ["filter"] = {self, ply}, - ["mask"] = MASK_SHOT - } - if ply:IsPlayer() then ply:LagCompensation(true) end - local swingtrace = util.TraceLine( tl ) - if ply:IsPlayer() then ply:LagCompensation(false) end - - att = string.lower(att) - if att == "primary" then - self.Force = self.Primary.Force - self.Damage = self.Primary.Damage - self.ID = self.Primary.ImpactDecal - self.BD = self.Primary.BurnDecal - self.DT = self.Primary.DamageType - self.DH = self.Primary.DelayHit - self.HA = self.Primary.MeleeHitActivity - self.HSF = self.Primary.HitSoundFlesh - self.HSE = self.Primary.HitSoundEnt - self.HSW = self.Primary.HitSoundWorld - elseif att == "secondary" then - self.Force = self.Secondary.Force - self.Damage = self.Secondary.Damage - self.ID = self.Secondary.ImpactDecal - self.BD = self.Secondary.BurnDecal - self.DT = self.Secondary.DamageType - self.DH = self.Secondary.DelayHit - self.HA = self.Secondary.MeleeHitActivity - self.HSF = self.Secondary.HitSoundFlesh - self.HSE = self.Secondary.HitSoundEnt - self.HSW = self.Secondary.HitSoundWorld - elseif att == "lungeprimary" then - self.Force = self.Primary.LungeForce - self.Damage = self.Primary.LungeDamage - self.ID = self.Primary.LungeImpactDecal - self.BD = self.Primary.LungeBurnDecal - self.DT = self.Primary.LungeDamageType - self.DH = self.Primary.LungeDelayHit - self.HA = self.Primary.LungeHitAct - self.HSF = self.Primary.LungeHitSoundFlesh - self.HSE = self.Primary.LungeHitSoundEnt - self.HSW = self.Primary.LungeHitSoundWorld - elseif att == "gunmelee" then - self.Force = self.Primary.MeleeForce - self.Damage = self.Primary.MeleeDamage - self.ID = self.Primary.MeleeImpactDecal - self.BD = self.Primary.MeleeBurnDecal - self.DT = self.Primary.MeleeDamageType - self.DH = self.Primary.MeleeDelayHit - self.HA = self.Primary.MeleeHitActivity - self.HSF = self.Primary.MeleeHitSoundFlesh - self.HSE = self.Primary.MeleeHitSoundEnt - self.HSW = self.Primary.MeleeHitSoundWorld - end - - local damageinfo = DamageInfo() - damageinfo:SetAttacker(ply) - damageinfo:SetInflictor(self) - damageinfo:SetDamageType(self.DT) - damageinfo:SetDamageForce((self.Owner:GetRight() * math.random(3568,4235)) + (self.Owner:GetForward() * math.random(6875,7523))) - damageinfo:SetDamage(self.Damage) - damageinfo:SetBaseDamage(2221208) - - if ( swingtrace.Hit ) then - self:SetNextPrimaryFire( CurTime() + self.DH ) - self:SetNextSecondaryFire( CurTime() + self.DH ) - - if self.HA != nil then self:SendWeaponAnim( self.HA ) end - - for i=-1, (math.Round(1/ engine.TickInterval() - 1 , 0)) do - if timer.Exists("".. tostring(self) .."_SwingImpact".. i .."") then timer.Destroy("".. tostring(self) .."_SwingImpact".. i .."") end - end - - - - if IsValid(swingtrace.Entity) && DRC:IsCharacter(swingtrace.Entity) then - elseif swingtrace.Entity:IsValid() and ( !swingtrace.Entity:IsNPC() or !swingtrace.Entity:IsPlayer() ) && !swingtrace.Entity:IsNextBot() && IsValid(swingtrace.Entity:GetPhysicsObject()) then - if i < rhm then - swingtrace.Entity:GetPhysicsObject():ApplyForceOffset( self.Owner:GetForward() * self.Force * 15 * i, swingtrace.HitPos ) - elseif i == rhm then - swingtrace.Entity:GetPhysicsObject():ApplyForceOffset( self.Owner:GetForward() * self.Force * 15 * i, swingtrace.HitPos ) - elseif i > rhm then - swingtrace.Entity:GetPhysicsObject():ApplyForceOffset( self.Owner:GetForward() * self.Force * 15 * ( i / 10 ), swingtrace.HitPos ) - end - damageinfo:SetDamageForce(Vector()) - - if swingtrace.Entity:Health() > 0 then - swingtrace.Entity:TakeDamage( self.Damage, self.Owner, self.Owner:GetActiveWeapon() ) - end - elseif swingtrace.Entity:IsWorld() then - util.Decal(self.ID, swingtrace.HitPos + swingtrace.HitNormal, swingtrace.HitPos - swingtrace.HitNormal) - util.Decal(self.BD, swingtrace.HitPos + swingtrace.HitNormal, swingtrace.HitPos - swingtrace.HitNormal) - end - end - if IsValid(swingtrace.Entity) then swingtrace.Entity:TakeDamageInfo( damageinfo ) end - - if ( swingtrace.Hit ) then - self:DoCustomMeleeImpact(att, swingtrace) - if swingtrace.Entity:IsPlayer() or string.find(swingtrace.Entity:GetClass(),"npc") or string.find(swingtrace.Entity:GetClass(),"prop_ragdoll") or string.find(swingtrace.Entity:GetClass(),"prop_physics") then - if string.find(swingtrace.Entity:GetClass(),"prop_physics") then - self:EmitSound(Sound(self.HSE)) - else - self:EmitSound(Sound(self.HSF)) - end - else - self:EmitSound(Sound(self.HSW)) - end - end - - if swingtrace.Hit && !swingtrace.Entity:IsWorld() then - DRC:RenderTrace(swingtrace, Color(255, 0, 0, 255), 1) - elseif !swingtrace.Hit then - DRC:RenderTrace(swingtrace, Color(255, 255, 255, 255), 1) - end + self:DoCustomMeleeSwing(swinginfo) end -]] function SWEP:ClearMeleeQueue() self.MeleeQueue = {} self.IsDoingMelee = false + self:SetNWBool("IsDoingMelee", false) -- self.Loading = false end @@ -902,7 +529,6 @@ function SWEP:MeleeImpact(swinginfo, x, y, i) if swinginfo.anim_fp != nil then self:PlayAnim(swinginfo.anim_fp, false, true) end - --self:MeleeImpactSound(swinginfo.hitsound, swingtrace.SurfaceProps, swingtrace.HitPos) self:TriggerCustomImpact(swinginfo, tr) @@ -915,12 +541,8 @@ function SWEP:MeleeImpact(swinginfo, x, y, i) local forceval = forceangle * swinginfo.damage[3] * 15 if i < rhm then forceval = forceval * i - --tr.Entity:GetPhysicsObject():ApplyForceOffset( forceangle * swinginfo.damage[3] * 15 * i, tr.HitPos ) - --elseif i == rhm then - --tr.Entity:GetPhysicsObject():ApplyForceOffset( forceangle * swinginfo.damage[3] * 15 * i, tr.HitPos ) elseif i > rhm then forceval = forceval * (i*0.1) - --tr.Entity:GetPhysicsObject():ApplyForceOffset( forceangle * swinginfo.damage[3] * 15 * ( i / 10 ), tr.HitPos ) end if IsValid(tr.Entity) && DRC:IsCharacter(tr.Entity) then @@ -928,7 +550,6 @@ function SWEP:MeleeImpact(swinginfo, x, y, i) tr.Entity:GetPhysicsObject():ApplyForceOffset( forceval, tr.HitPos ) if SERVER && DRC:Health(tr.Entity) > 0 then tr.Entity:TakeDamage(swinginfo.damage[1], ply, ply:GetActiveWeapon()) end - -- elseif tr.Entity:IsWorld() then end DRC:RenderTrace(tr, Color(255, 0, 0, 255), 1) @@ -936,11 +557,7 @@ function SWEP:MeleeImpact(swinginfo, x, y, i) return true end - if !game.IsDedicated() && SERVER then -- In singleplayer we don't have to rely on lag compensation, plus it breaks impact effects. - if swingtrace.Hit then self:FireBullets(btrace) end - else - self:FireBullets(btrace) - end + if swingtrace.Hit then self:FireBullets(btrace) end if ply:IsPlayer() then ply:LagCompensation(false) end if !swingtrace.Hit && ((game.SinglePlayer() && SERVER) or CLIENT) then @@ -977,23 +594,7 @@ end function SWEP:GetConeTarget() local ply = self:GetOwner() if !ply or !ply:IsPlayer() then return end - local coneents = DRC:EyeCone(ply, self.Primary.AimAssistDist, self.SpreadCone * self.Primary.AimAssist_Mul) - local targets = {} - for k,v in pairs(coneents) do - if (v:IsPlayer() && v != ply) or v:IsNPC() or v:IsNextBot() or DRC:IsVehicle(v) then table.insert(targets, v) end - end - local closesttarget = nil - for k,v in pairs(targets) do - local dist = v:EyePos():DistToSqr(ply:EyePos()) - if k == 1 then - closesttarget = {v, dist} - else - if dist < closesttarget[2] then closesttarget = {v, dist} end - end - end - if !closesttarget then return nil end - - local target, dist = closesttarget[1], closesttarget[2] + target, dist = DRC:GetConeTarget(ply, self.Primary.AimAssistDist, self.SpreadCone * self.Primary.AimAssist_Mul) return target, dist end @@ -1090,7 +691,7 @@ function SWEP:ShootBullet(damage, num, cone, ammo, force, tracer) end self:RunAttachmentFunction("Ammunition", "Callback", nil, {ent, tr, takedamageinfo}) - self:DoCustomBulletImpact(tr.HitPos, tr.Normal, takedamageinfo) + self:DoCustomBulletImpact(tr.HitPos, tr.Normal, takedamageinfo, tr.Entity) if tr.Hit && !tr.Entity:IsPlayer() && self.Primary.Tracer == 0 then local tr2 = util.TraceHull({ @@ -1157,21 +758,29 @@ function SWEP:DoShoot(mode) local batstats = self.BatteryStats local eyeang = ply:EyeAngles() local sd = DRC:SightsDown(self) + local fm = self:GetFireMode() local tr - if ply:IsNPC() && ply.Draconic == true then - tr = ply:GetEyeTrace() + if !ply:IsPlayer() then + tr = util.QuickTrace(ply:EyePos(), ply:EyeAngles():Forward() * 1000000, {self, self:GetOwner()}) + -- tr = ply:GetEyeTrace() else + if CLIENT && self.DoForwardBlur == true then ply.ForwardBlurAdditive = ply.ForwardBlurAdditive + ((stats.Kick*0.0025) * self.ForwardGainMul) end tr = util.GetPlayerTrace(ply) end local trace = util.TraceLine( tr ) local LeftHand = ply:LookupBone(DRC.Skel.LeftHand.Name) - local RightHand = ply:LookupBone(DRC.Skel.RightHand.Name) + local RightHand = ply:GetAttachment(ply:LookupAttachment("righthand")) + if RightHand == nil then + RightHand = ply:GetAttachment(ply:LookupAttachment("anim_attach_RH")) + if RightHand != nil then RightHand = RightHand.Bone + else RightHand = ply:LookupBone("ValveBiped.Bip01_R_Hand") end + else RightHand = RightHand.Bone end local pmag = self:Clip1() local nmag = self:Clip1() - stats.APS - if nmag <= 0 then + if nmag <= -1 then self.PistolSlide = 0 end @@ -1236,7 +845,11 @@ function SWEP:DoShoot(mode) -- if game.SinglePlayer() then self:CallOnClient( "UpdateBloom", "secondary") end end - self:TakeSecondaryAmmo( stats.APS ) + if self.Secondary.UsesPrimaryMag == false then + self:TakeSecondaryAmmo( stats.APS ) + else + self:TakePrimaryAmmo( stats.APS ) + end elseif mode == "overcharge" then if ply:IsPlayer() then self:UpdateBloom("overcharge") @@ -1298,7 +911,10 @@ function SWEP:DoShoot(mode) end end end - ply:SetAnimation( PLAYER_ATTACK1 ) + if SERVER && mode == "primary" && self.Primary.ActOverride != nil then DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, self.Primary.ActOverride) + elseif SERVER && mode == "secondary" && self.Secondary.ActOverride != nil then DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, self.Secondary.ActOverride) + elseif SERVER && mode == "overcharge" && self.Primary.OCActOverride != nil then DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, self.Primary.OCActOverride) + else ply:SetAnimation(PLAYER_ATTACK1) end else end if ply.DraconicNPC && ply:DraconicNPC() == true then @@ -1307,12 +923,12 @@ function SWEP:DoShoot(mode) DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, act, true) end - if self.Base == "draconic_battery_base" then + if self.EnableHeat == true then local heat = self:GetHeat() if stats != self.OCStats then - self:SetHeat((self:GetHeat() + batstats.HPS)) + self:AddHeat(batstats.HPS) else - self:SetHeat((self:GetHeat() + batstats.OCHPS)) + self:AddHeat(batstats.OCHPS) end if self.LowerRPMWithHeat == true then @@ -1325,10 +941,14 @@ function SWEP:DoShoot(mode) self:SetNextPrimaryFire( CurTime() + 60 / stats.RPM) end else - self:SetNextPrimaryFire ( CurTime() + (60 / stats.RPM) ) + self:SetNextPrimaryFire (CurTime() + (60 / stats.RPM)) end else - self:SetNextPrimaryFire( CurTime() + stats.PreCalcRPM ) + if fm != 3 then + self:SetNextPrimaryFire(CurTime() + stats.PreCalcRPM) + else + self:SetNextPrimaryFire(CurTime() + (self.FireModes_BurstDelay or stats.PreCalcRPM * self.FireModes_BurstShots)) + end end if self.Primary.isvFire == true then @@ -1339,7 +959,9 @@ function SWEP:DoShoot(mode) local spr = self:CalculateSpread(false) if self.PreventAllBullets == true then return end if ply:IsPlayer() then ply:LagCompensation(true) end - if self.PreventAllBullets == false then self:ShootBullet(stats.Damage, shotnum, spr, stats.Ammo, stats.Force, stats.Tracer) end + local damnval = stats.Damage + if stats.DamageNPC && !ply:IsPlayer() then damnval = stats.DamageNPC end + if self.PreventAllBullets == false then self:ShootBullet(damnval, shotnum, spr, stats.Ammo, stats.Force, stats.Tracer) end if ply:IsPlayer() then ply:LagCompensation(false) end elseif mode == "secondary" && self.Projectile == "scripted" then timer.Simple(self.Secondary.ProjectileSpawnDelay, function() @@ -1380,7 +1002,7 @@ function SWEP:DoShoot(mode) end if ply.IsVJBaseSNPC then projpos = ply:EyePos() - Vector(0, 0, 15) + ply:GetAimVector() * Vector(25, 25, 25) - projang = projang - Angle(-10, 0 ,0) -- wtf + -- projang = projang - Angle(-10, 0 ,0) -- wtf end end @@ -1393,6 +1015,16 @@ function SWEP:DoShoot(mode) filter = function(ent) if ent != tr2.Entity or tr2.Entity:GetClass() == class then return false else return true end end, }) dir = tr3.Normal:Angle() + elseif ply.IsVJBaseSNPC then -- bruh + if IsValid( ply:GetEnemy()) then + local enemy = ply:GetEnemy() + local tr3 = util.TraceLine({ + start = ptu, + endpos = enemy:GetPos() + enemy:OBBCenter(), + filter = function(ent) if ent != enemy then return false else return true end end, + }) + dir = tr3.Normal:Angle() + end end projang = projang + dir @@ -1419,10 +1051,13 @@ function SWEP:DoShoot(mode) end local mini, maxi, delay, length = self:GetNPCBurstSettings() - if ply:IsNPC() or ply:IsNextBot() then -- NPC Looping Firing sounds + if ply:IsNPC() or ply:IsNextBot() then if mode != "primary" then return end - if self.NPCBursting == true then return end + if self.NPCBursting == true or #self.BurstQueue > 0 then return end + local ct = CurTime() local burst = math.Round(math.Rand(mini, maxi)) + length = burst * delay + math.Rand(0.3,3) + self.NPCBurstTime = ct + length -- print("Min: ".. mini .." | Max: ".. maxi .." | Delay: ".. delay .." | Burst: ".. burst .."") @@ -1439,35 +1074,17 @@ function SWEP:DoShoot(mode) end) self.NPCBursting = true - timer.Simple( burst * delay + math.Rand(0.3,3), function() if !IsValid(ply) or !IsValid(self) then return end self.NPCBursting = false end) - - for i=1,length do - if !IsValid(self) then return end - timer.Simple( delay*i, function() - if !IsValid(ply) or !IsValid(self) then return end - local fm = self:GetNWString("FireMode") - if fm != "Burst" && ply:IsNPC() then - local enemy = ply:GetEnemy() - - if enemy == nil then return end - if IsValid(enemy) && CTFK(self.ignorepcs, enemy:GetClass()) then ply:SetEnemy(nil, true) end - if IsValid(enemy) && ply:GetEnemyLastTimeSeen(enemy) > CurTime() then return end - - if IsValid(enemy) && !ply:IsLineOfSightClear(enemy:GetPos()) then return end - - if IsValid(enemy) then - self:PrimaryAttack() - end - end - self:CallShoot("primary") - end) - end + timer.Simple( length, function() if !IsValid(ply) or !IsValid(self) then return end self.NPCBursting = false end) + length = math.Round(length) + if SERVER then for i=0,burst do + self.BurstQueue[i] = ct + (delay*i) + end end end if ply:IsNPC() or ply:IsNextBot() then timer.Simple( 0.5, function() -- holy fUCK LET ME DETECT WHEN AN NPC RELOADS IN LUA NATIVELY PLEASE - if !IsValid(self) or !IsValid(ply) then return end - if ply:GetActivity() == ACT_RELOAD then + if !SERVER or !IsValid(self) or !IsValid(ply) then return end + if self:GetLoadedAmmo() <= 0 or ply:GetActivity() == ACT_RELOAD then self:DoCustomReloadStartEvents() self:SetLoadedAmmo((self.Primary.ClipSize * self:GetAttachmentValue("Ammunition", "ClipSizeMul"))) end @@ -1489,7 +1106,7 @@ function SWEP:DoEffects(mode, nosound, multishot) if !IsValid(ply) then return end local muzzleattachment = self:LookupAttachment("muzzle") local muzzle = self:GetAttachment(muzzleattachment) - local fm = self:GetNWString("FireMode") + local fm = self:GetFireMode() local ttu = nil if mode == "primary" then @@ -1499,7 +1116,7 @@ function SWEP:DoEffects(mode, nosound, multishot) self:CallOnClient("MuzzleFlash") - if fm == "Semi" or fm == "Auto" then + if fm != 3 then self.Sound = self.Primary.SoundTable.Semiauto.Near self.DistSound = self.Primary.SoundTable.Semiauto.Far self.SoundDistance = self.Primary.SoundTable.Semiauto.FarDistance @@ -1525,7 +1142,7 @@ function SWEP:DoEffects(mode, nosound, multishot) self.DistSound = self.OCDistSound self.Projectile = self.Primary.OCProjectile self.TracerEffect = self.Primary.TracerEffect - if fm == "Semi" or fm == "Auto" then + if fm != 3 then self.Sound = self.OCSound self.DistSound = self.OCDistSound self.SoundDistance = self.Primary.SoundTable.Semiauto.FarDistance @@ -1575,8 +1192,8 @@ function SWEP:DoEffects(mode, nosound, multishot) end if !IsFirstTimePredicted() or nosound == true or self.BurstSound == true then return end - if mode == "primary" && fm == "Burst" && ttu.Single == false then - local thyme = self.PrimaryStats.PreCalcRPM*self.FireModes_BurstShots + 0.01 + if mode == "primary" && fm == 3 && ttu.Single == false then + local thyme = self.PrimaryStats.PreCalcRPM*self.FireModes_BurstShots +0.25 self.BurstSound = true timer.Simple(CurTime() - self:GetNextPrimaryFire() + thyme, function() self.BurstSound = false end) end @@ -1590,7 +1207,7 @@ function SWEP:DoEffects(mode, nosound, multishot) if RoomType == "Vent" && !self.Primary.SoundTable.Envs["Vent"] then RoomType = "Small" end if mode == "primary" && self.Primary.SoundTable.Envs[RoomType] then - if fm == "Semi" or fm == "Auto" then + if fm != 3 then self.Sound = self.Primary.SoundTable.Envs[RoomType].Semiauto.Near self.DistSound = self.Primary.SoundTable.Envs[RoomType].Semiauto.Far else @@ -1633,62 +1250,33 @@ function SWEP:DoRecoil(mode) if !ply:IsPlayer() then return end local eyeang = ply:EyeAngles() local cv = ply:Crouching() - local sk = ply:KeyDown(IN_SPEED) - local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) - local plidle = (!mk && !sk && !cv) - local issprinting = sk && mk - - if mode == "primary" then - self.RecoilDown = (self.Primary.RecoilDown * self:GetAttachmentValue("Ammunition", "RecoilDown")) - self.RecoilUp = (self.Primary.RecoilUp * self:GetAttachmentValue("Ammunition", "RecoilUp")) - self.RecoilHoriz = (self.Primary.RecoilHoriz * self:GetAttachmentValue("Ammunition", "RecoilHoriz")) - self.Kick = (self.Primary.Kick * self:GetAttachmentValue("Ammunition", "Kick")) - self.KickHoriz = (self.Primary.KickHoriz * self:GetAttachmentValue("Ammunition", "KickHoriz")) - self.IronRecoilMul = (self.Primary.IronRecoilMul * self:GetAttachmentValue("Ammunition", "IronRecoilMul")) - elseif mode == "secondary" then - self.RecoilDown = (self.Secondary.RecoilDown * self:GetAttachmentValue("Ammunition", "RecoilDown")) - self.RecoilUp = (self.Secondary.RecoilUp * self:GetAttachmentValue("Ammunition", "RecoilUp")) - self.RecoilHoriz = (self.Secondary.RecoilHoriz * self:GetAttachmentValue("Ammunition", "RecoilHoriz")) - self.Kick = (self.Secondary.Kick * self:GetAttachmentValue("Ammunition", "Kick")) - self.KickHoriz = (self.Secondary.KickHoriz * self:GetAttachmentValue("Ammunition", "KickHoriz")) - self.IronRecoilMul = (self.Secondary.IronRecoilMul * self:GetAttachmentValue("Ammunition", "IronRecoilMul")) - elseif mode == "overcharge" then - self.RecoilDown = (self.OCRecoilDown * self:GetAttachmentValue("Ammunition", "RecoilDown")) - self.RecoilUp = (self.OCRecoilUp * self:GetAttachmentValue("Ammunition", "RecoilUp")) - self.RecoilHoriz = (self.OCRecoilHoriz * self:GetAttachmentValue("Ammunition", "RecoilHoriz")) - self.Kick = (self.OCKick * self:GetAttachmentValue("Ammunition", "Kick")) - self.KickHoriz = (self.OCKickHoriz * self:GetAttachmentValue("Ammunition", "KickHoriz")) - self.IronRecoilMul = (self.OCIronRecoilMul * self:GetAttachmentValue("Ammunition", "IronRecoilMul")) - end - - --if self:GetNWBool("ironsights") == false && cv == false then - if self.SightsDown == false && cv == false then + local stats = self.RecoilStats[mode] + local sd, ru, rd, rh, k, kh = self.SightsDown, stats.RecoilUp, stats.RecoilDown, stats.RecoilHoriz, stats.Kick, stats.KickHoriz + + if sd == false && cv == false then if CLIENT then - eyeang.pitch = eyeang.pitch - ((math.Rand(self.RecoilUp / 1.85, self.RecoilUp * 1.62)) - (math.Rand(self.RecoilDown / 1.85, self.RecoilDown * 1.85) * 0.01)) - eyeang.yaw = eyeang.yaw - (math.Rand( self.RecoilHoriz, (self.RecoilHoriz * -0.81) ) * 0.01) + eyeang.pitch = eyeang.pitch - ((math.Rand(ru / 1.85, ru * 1.62)) - (math.Rand(rd / 1.85, rd * 1.85) * 0.01)) + eyeang.yaw = eyeang.yaw - (math.Rand( rh, (rh * -0.81) ) * 0.01) end - self.Owner:ViewPunch(Angle( -self.Kick, math.Rand(-self.KickHoriz, self.KickHoriz), math.Rand(-self.KickHoriz, self.KickHoriz) / 200 )) - --elseif self:GetNWBool("ironsights") == true && cv == false then - elseif self.SightsDown == true && cv == false then + self.Owner:ViewPunch(Angle( -k, math.Rand(-kh, kh), math.Rand(-kh, kh) / 200 )) + elseif sd == true && cv == false then if CLIENT then - eyeang.pitch = eyeang.pitch - (((math.Rand(self.RecoilUp / 1.5, self.RecoilUp * 1.5)) - (math.Rand(self.RecoilDown / 1.5, self.RecoilDown * 1.5) * 0.01)) * self.IronRecoilMul) - eyeang.yaw = eyeang.yaw - (math.Rand( self.RecoilHoriz, (self.RecoilHoriz * -1) ) * 0.01) + eyeang.pitch = eyeang.pitch - (((math.Rand(ru / 1.5, ru * 1.5)) - (math.Rand(rd / 1.5, rd * 1.5) * 0.01)) * stats.IronRecoilMul) + eyeang.yaw = eyeang.yaw - (math.Rand( rh, (rh * -1) ) * 0.01) end - self.Owner:ViewPunch(Angle( (-self.Kick * 0.69) * self.IronRecoilMul, math.Rand(-self.KickHoriz, self.KickHoriz) / 100, math.Rand(-self.KickHoriz, self.KickHoriz) / 250 ) * self.Secondary.SightsKickMul) - --elseif self:GetNWBool("ironsights") == false && cv == true then - elseif self.SightsDown == false && cv == true then + self.Owner:ViewPunch(Angle( (-k * 0.69) * stats.IronRecoilMul, math.Rand(-kh, kh) / 100, math.Rand(-kh, kh) / 250 ) * self.Secondary.SightsKickMul) + elseif sd == false && cv == true then if CLIENT then - eyeang.pitch = eyeang.pitch - ((math.Rand(self.RecoilUp / 1.5, self.RecoilUp * 1.5)) - (math.Rand(self.RecoilDown / 1.5, self.RecoilDown * 1.5) * 0.01)) - eyeang.yaw = eyeang.yaw - (math.Rand( self.RecoilHoriz, (self.RecoilHoriz * -1) ) * 0.01) + eyeang.pitch = eyeang.pitch - ((math.Rand(ru / 1.5, ru * 1.5)) - (math.Rand(rd / 1.5, rd * 1.5) * 0.01)) + eyeang.yaw = eyeang.yaw - (math.Rand( rh, (rh * -1) ) * 0.01) end - self.Owner:ViewPunch(Angle( -self.Kick * 0.75, math.Rand(-self.KickHoriz, self.KickHoriz) / 100, math.Rand(-self.KickHoriz, self.KickHoriz) / 250 )) - --elseif self:GetNWBool("ironsights") == true && cv == true then - elseif self.SightsDown == true && cv == true then + self.Owner:ViewPunch(Angle( -k * 0.75, math.Rand(-kh, kh) / 100, math.Rand(-kh, kh) / 250 )) + elseif sd == true && cv == true then if CLIENT then - eyeang.pitch = eyeang.pitch - (((math.Rand(self.RecoilUp / 1.5, self.RecoilUp * 0.9)) - (math.Rand(self.RecoilDown / 1.9, self.RecoilDown * 0.9) * 0.01)) * self.IronRecoilMul) - eyeang.yaw = eyeang.yaw - (math.Rand( self.RecoilHoriz, (self.RecoilHoriz * -1) ) * 0.01) + eyeang.pitch = eyeang.pitch - (((math.Rand(ru / 1.5, ru * 0.9)) - (math.Rand(rd / 1.9, rd * 0.9) * 0.01)) * stats.IronRecoilMul) + eyeang.yaw = eyeang.yaw - (math.Rand( rh, (rh * -1) ) * 0.01) end - self.Owner:ViewPunch(Angle( (-self.Kick * 0.42) * self.IronRecoilMul, math.Rand(-self.KickHoriz, self.KickHoriz) / 200, math.Rand(-self.KickHoriz, self.KickHoriz) / 500 )) + self.Owner:ViewPunch(Angle( (-k * 0.42) * stats.IronRecoilMul, math.Rand(-kh, kh) / 200, math.Rand(-kh, kh) / 500 )) end if CLIENT then ply:SetEyeAngles(Angle(0, 0, 0) + Angle(eyeang.pitch, eyeang.yaw, nil)) end @@ -1705,7 +1293,8 @@ function SWEP:MuzzleFlash() DRC.CalcView.MuzzleLamp_Time = CurTime() + math.Rand(0.005, 0.01) local bright = (col.a/30) * (1 - math.Clamp(DRC.MapInfo.MapAmbientAvg, 0.15, 1)) * mul local ent = DRC.CalcView.MuzzleLamp - ent.Texture = self:GetAttachmentValue("Ammunition", "MuzzleFlash", "Mask") + local mask = self:GetAttachmentValue("Ammunition", "MuzzleFlash", "Mask") + if mask != "" then ent.Texture = mask end ent.Light:SetColor(Color(col.r, col.g, col.b)) ent.Light:SetBrightness(bright) ent.FOV = self:GetAttachmentValue("Ammunition", "MuzzleFlash", "FOV") @@ -1738,7 +1327,7 @@ function SWEP:CallShoot(mode, ignoreimpossibility, endburst) if ply:IsPlayer() && (self.DoesPassiveSprint == true or forcesprint) && (ply:KeyDown(IN_SPEED) && (ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK) or ply:KeyDown(IN_LEFT) or ply:KeyDown(IN_RIGHT))) then return end if self:GetLoadedAmmo() <= 0 then if CurTime() > self:GetNextPrimaryFire() then self:EmitSound (self.Primary.EmptySound) end - self:SetNextPrimaryFire(CurTime() + self.PrimaryStats.PreCalcRPM * 2) return + return elseif self:GetNWBool("Passive") == true or self:GetNWBool("Inspecting") == true then return end end @@ -1834,6 +1423,9 @@ function SWEP:RunAttachmentFunction(att, val, subval, args) end end +function SWEP:DoCustomMeleeSwing(swinginfo) +end + function SWEP:DoCustomMeleeImpact(att, tr) end diff --git a/lua/weapons/draconic_base/shared.lua b/lua/weapons/draconic_base/shared.lua index a8bd736..07f83c5 100644 --- a/lua/weapons/draconic_base/shared.lua +++ b/lua/weapons/draconic_base/shared.lua @@ -1,8 +1,8 @@ AddCSLuaFile() --[[ I M P O R T A N T -Please go to the GitHub wiki for this, and don't just rip settings from the base. -https://github.com/Vuthakral/Draconic_Base/wiki +Please go to the wiki for this, and don't just rip settings from the base. +http://vuthakral.com/draconic/ It contains all of the settings, explanations on how to use them, tutorials, helpful links, etc. @@ -16,26 +16,33 @@ SWEP.Instructions = "" SWEP.WepSelectIcon = "vgui/entities/drc_default" SWEP.IgnoreVersioning = false +-- SPAWNMENU SWEP.Category = "Draconic" +SWEP.Subcategory = nil SWEP.PrintName = "Draconic Base" SWEP.Author = "Vuthakral" -SWEP.InfoName = nil -SWEP.Manufacturer = nil -SWEP.InfoDescription = nil SWEP.Spawnable = false SWEP.AdminSpawnable = false SWEP.NPCSpawnable = true -SWEP.AutoSwitchTo = false -SWEP.AutoSwitchFrom = false -SWEP.KeepUpright = false -SWEP.CanStore = true -SWEP.DeploySpeed = 1 -SWEP.Weight = 1 +-- INSPECT MENU +SWEP.InfoName = nil +SWEP.Manufacturer = nil +SWEP.InfoDescription = nil + +-- INVENTORY BEHAVIOUR SWEP.Slot = 0 SWEP.SlotPos = 1 +SWEP.CanBeSwapped = true +SWEP.PickupOnly = false +SWEP.DoNotDrop = false + +SWEP.AutoSwitchTo = false +SWEP.AutoSwitchFrom = false + +-- VM/HUD STUFF SWEP.CrosshairColor = Color(255, 255, 255, 255) SWEP.CrosshairShadow = false SWEP.CrosshairStatic = nil @@ -48,17 +55,20 @@ SWEP.CrosshairFOVPower = 1 SWEP.Crosshair = nil SWEP.ViewModelFOV = 54 -SWEP.ViewModelFlip = true +SWEP.ViewModelFlip = false SWEP.DrawAmmo = true SWEP.UseHands = true SWEP.DoesPassiveSprint = false SWEP.ViewModel = "" SWEP.WorldModel = "" +SWEP.InspectDelay = 0.5 + +-- OFFSETS SWEP.VMPos = Vector(0, 0, 0) SWEP.VMAng = Vector(0, 0, 0) -SWEP.VMPosCrouch = Vector(0, 0, 0) -SWEP.VMAngCrouch = Vector(0, 0, 0) +SWEP.VMPosCrouch = nil +SWEP.VMAngCrouch = nil SWEP.LoweredVMPos = Vector(0, 0, 0) SWEP.LoweredVMAng = Vector(0, 0, 0) SWEP.IronSightsPos = Vector(0, 0, 0) @@ -69,27 +79,46 @@ SWEP.PassivePos = Vector(5, 0, 3) SWEP.PassiveAng = Vector(-15, 25, 0) SWEP.InspectPos = Vector(3, 2, -2.5) SWEP.InspectAng = Vector(15, 15, 0) -SWEP.SprintPos = Vector(5, 0, 3) -SWEP.SprintAng = Vector(-15, 25, 0) +--SWEP.SprintPos = Vector(5, 0, 3) +--SWEP.SprintAng = Vector(-15, 25, 0) + +-- VIEWMODEL SWAY SWEP.SS = 1 SWEP.BS = 1 SWEP.NearWallPower = 1 SWEP.RollingPower = 1 SWEP.PerspectivePower = 1 -SWEP.InspectDelay = 0.5 +SWEP.Sway_IsShouldered = nil +SWEP.Sway_OffsetPowerPos= nil +SWEP.Sway_OffsetPowerAng= Vector(1,1,1) + +-- CAMERA EFFECTS +SWEP.CameraStabilityIdle = 1 +SWEP.CameraStabilityMove = 1 +SWEP.CameraStabilityReload = 0.5 +SWEP.CameraStabilityInspect = 0.25 +SWEP.CameraStabilityMelee = 0.5 + +SWEP.CameraAngleMulIdle = Vector(0, 0, 0) +SWEP.CameraAngleMulMove = Vector(0, 0, 0) +SWEP.CameraAngleMulReload = Vector(1, 1, 1) +SWEP.CameraAngleMulInspect = Vector(1, 1, 1) +SWEP.CameraAngleMulMelee = Vector(1, 1, 1) +SWEP.CameraAngleMulFiring = nil -- inherits from Idle unless overridden + +SWEP.DoForwardBlur = false +SWEP.DoRotationalBlur = false +SWEP.ForwardGainMul = 1 +SWEP.ForwardDecayMul = 1 +SWEP.RotationalGainMul = 1 +SWEP.RotationalDecayMul = 1 SWEP.Thirdperson = false SWEP.ThirdpersonForceFreelook = false -SWEP.CanBeSwapped = true -SWEP.PickupOnly = false -SWEP.DoNotDrop = false - -SWEP.IdleActivity = ACT_VM_IDLE -SWEP.CrouchIdleActivity = ACT_VM_IDLE - -SWEP.FireModes_SwitchSound = Sound("Weapon_AR2.Empty") +SWEP.FireModes_SwitchSound = "Weapon_AR2.Empty" +-- AIM ASSIST (wip, only used for scripted projectiles currently) SWEP.Primary.AimAssist = true SWEP.Primary.AimAssistDist = 1000 SWEP.Primary.AimAssist_Mul = 1 @@ -128,7 +157,6 @@ SWEP.OCProjectile = nil SWEP.OCProjSpeed = 500 -- MOVEMENT MODIFIERS - SWEP.SpeedSprintStand = { nil, nil, nil, nil, nil, nil, @@ -189,67 +217,6 @@ SWEP.JumpHeightsCrouchSprint = { nil, nil, nil } --- MOVEMENT MODIFIERS [OLD AND NO LONGER USED, DEPRECATED. DO NOT USE IN YOUR WEAPONS.] ---[[ -SWEP.SprintSoundStand = Sound( "" ) -SWEP.DoSSStandFwd = false -SWEP.DoSSStandBack = false -SWEP.DoSSStandLeft = false -SWEP.DoSSStandRight = false - -SWEP.SprintSoundCrouch = Sound( "" ) -SWEP.DoSSCrouchFwd = false -SWEP.DoSSCrouchBack = false -SWEP.DoSSCrouchLeft = false -SWEP.DoSSCrouchRight = false - -SWEP.SJumpCrouchSound = Sound( "" ) -SWEP.DoSJCrouchSFwd = false -SWEP.DoSJCrouchSBack = false -SWEP.DoSJCrouchLeft = false -SWEP.DoSJCrouchhRight = false - -SWEP.SpeedStandForward = nil -SWEP.SpeedStandBack = nil -SWEP.SpeedStandLeft = nil -SWEP.SpeedStandRight = nil - -SWEP.SpeedCrouchForward = nil -SWEP.SpeedCrouchBack = nil -SWEP.SpeedCrouchLeft = nil -SWEP.SpeedCrouchRight = nil - -SWEP.SpeedSprintStandForward = nil -SWEP.SpeedSprintStandBack = nil -SWEP.SpeedSprintStandLeft = nil -SWEP.SpeedSprintStandRight = nil - -SWEP.SpeedSprintCrouchForward = nil -SWEP.SpeedSprintCrouchBack = nil -SWEP.SpeedSprintCrouchLeft = nil -SWEP.SpeedSprintCrouchRight = nil - -SWEP.StandingJumpHeightFront = nil -SWEP.StandingJumpHeightBack = nil -SWEP.StandingJumpHeightLeft = nil -SWEP.StandingJumpHeightRight = nil - -SWEP.CrouchingJumpHeightFront = nil -SWEP.CrouchingJumpHeightBack = nil -SWEP.CrouchingJumpHeightLeft = nil -SWEP.CrouchingJumpHeightRight = nil - -SWEP.StandingSprintJumpHeightFront = nil -SWEP.StandingSprintJumpHeightBack = nil -SWEP.StandingSprintJumpHeightLeft = nil -SWEP.StandingSprintJumpHeightRight = nil - -SWEP.CrouchingSprintJumpHeightFront = nil -SWEP.CrouchingSprintJumpHeightBack = nil -SWEP.CrouchingSprintJumpHeightLeft = nil -SWEP.CrouchingSprintJumpHeightRight = nil ---]] - -- MISC SWEP.TauntCooldown = 1 SWEP.HealthRegen = false @@ -258,6 +225,25 @@ SWEP.HealInterval = 1 SWEP.WeaponIdleLoopSound = nil SWEP.IdleLoopSoundConstant = false +SWEP.IntegratedLight_Enabled = false +SWEP.IntegratedLight_FOV = 60 +SWEP.IntegratedLight_MaxDist = 800 +SWEP.IntegratedLight_DistScale = 0 +SWEP.IntegratedLight_Texture = "effects/flashlight001" +SWEP.IntegratedLight_Colour = Color(255, 255, 255, 1) +SWEP.IntegratedLight_OnSound = "Player.FlashlightOn" +SWEP.IntegratedLight_OffSound = "Player.FlashlightOff" +SWEP.IntegratedLight_ToggleFrac = 0.5 +SWEP.IntegratedLight_UseHitPos = false +SWEP.IntegratedLight_DoVolume = false +SWEP.IntegratedLight_VolLength = 60 +SWEP.IntegratedLight_VolPower = 0.333 +SWEP.IntegratedLight_VolMaterial= "sprites/glow04_noz" + +SWEP.KeepUpright = false +SWEP.DeploySpeed = 1 +SWEP.Weight = 1 + SWEP.Glow = false SWEP.GlowColor = Color(255, 255, 255) SWEP.GlowBrightness = 1 @@ -278,10 +264,24 @@ SWEP.Secondary.ScopeHeight = 1 SWEP.Secondary.Disabled = false +SWEP.WeaponSkinDefaultMat = nil +SWEP.WeaponSkinSpecialMats = nil +SWEP.WeaponSkinDisallowUniversals = false + SWEP.VElements = {} SWEP.WElements = {} -- ADDON COMPATIBILITY +SWEP.CanStore = true +SWEP.CanTFALean = true +SWEP.DManip_AllowFL = true +SWEP.vFireLife = 2 +SWEP.vFireVolatility = 0.15 +SWEP.vFireSpeed = 1 +SWEP.vFireSpawnDist = 30 +SWEP.vFireStopSound = Sound("draconic.vFireStopGeneric") +SWEP.Primary.isvFire = false +SWEP.Secondary.isvFire = false -- TTT SWEP.Kind = WEAPON_NONE @@ -302,19 +302,6 @@ function SWEP:IsEquipment() return self.IsEquipment end --- Small misc -SWEP.CanTFALean = true -SWEP.DManip_AllowFL = true - -SWEP.vFireLife = 2 -SWEP.vFireVolatility = 0.15 -SWEP.vFireSpeed = 1 -SWEP.vFireSpawnDist = 30 -SWEP.vFireStopSound = Sound("draconic.vFireStopGeneric") -SWEP.Primary.isvFire = false -SWEP.Secondary.isvFire = false - - -- nZombies SWEP.NZWonderWeapon = false -- Is this a Wonder-Weapon? If true, only one player can have it at a time. Cheats aren't stopped, though. -- SWEP.NZRePaPText = "your text here" -- When RePaPing, what should be shown? Example: Press E to your text here for 2000 points. @@ -344,6 +331,7 @@ SWEP.IsOverheated = false SWEP.SightsDown = false SWEP.BloomValue = 0 SWEP.PrevBS = 0 +SWEP.RealTime = 0 SWEP.VariablePos = Vector(0, 0, 0) SWEP.CRPo = Vector(0, 0, 0) SWEP.PRPos = Vector(0, 0, 0) @@ -361,10 +349,13 @@ SWEP.DistSound = Sound("") SWEP.Passive = false SWEP.Inspecting = false SWEP.Idle = 0 +SWEP.PlayingLoadAnimation = false +SWEP.PlayingShootAnimation = false SWEP.Loading = false SWEP.ManuallyReloading = false SWEP.PistolSlide = 1 SWEP.NPCBursting = false +SWEP.NPCBurstTime = 0 SWEP.NPCCharging = false SWEP.DualSettings = {} SWEP.SightSwapCD = false @@ -378,6 +369,12 @@ SWEP.CurAng = Vector(0, 0, 0) SWEP.FireMode = "none" SWEP.OwnerActivity = "standidle" SWEP.IsDoingMelee = false +SWEP.BurstQueue = {} +SWEP.MeleeQueue = {} +SWEP.DynOffsetPos = Vector() +SWEP.DynOffsetAng = Vector() +SWEP.WeaponSkinSubMaterials = {} +SWEP.WeaponSkinProxyMaterials = {} function SWEP:DoDrawCrosshair( x, y ) return true @@ -428,9 +425,6 @@ function SWEP:Initialize() if !game.SinglePlayer() then self:CallOnClient("Initialize") end self.IdleTimer = CurTime() + 5 - if self.Auhtor then -- jesus christ you people are fucking blind - self.Author = self.Auhtor - end self.Readied = false self:SetHoldType(self.HoldType) @@ -441,6 +435,9 @@ function SWEP:Initialize() self.VARSightAng = self.IronSightsAng self.LastMeleeImpactTime = 0 + if self.Sway_IsShouldered == nil then self.Sway_IsShouldered = DRC.HoldTypes[string.lower(self.HoldType)].shouldered end + if self.Sway_OffsetPowerPos == nil then self.Sway_OffsetPowerPos = Vector(self.SS, 1, 1) end + if self.KeepUpright == true then self:AddCallback( "PhysicsCollide", function( ent, newangle ) local vel = ent:GetVelocity() @@ -492,6 +489,13 @@ function SWEP:Initialize() } end + if !self.Primary.EmptySound then + self.Primary.EmptySound = DRC.HoldTypes[string.lower(self.HoldType)].drcsounds.dryfire + end + if !self.Secondary.EmptySound then + self.Secondary.EmptySound = DRC.HoldTypes[string.lower(self.HoldType)].drcsounds.dryfire + end + if !self.IsMelee then self.DefaultPimaryClipSize = self.Primary.ClipSize self:SetupAttachments("drc_abp_generic", "AmmunitionTypes", false, true) @@ -548,7 +552,7 @@ function SWEP:Initialize() end end - -- Metroid Prime HUD compatibility + -- Prime HUD compatibility if !self.LogBook && self.InfoDescription != nil then self.LogBook = { ["Description"] = self.InfoDescription @@ -600,11 +604,20 @@ function SWEP:Initialize() if !self.ModifyText then self.ModifyText = "modify ".. (self.InfoName or self.PrintName or "null") .."" end end) - if !self.IsMelee then - -- self:PreCalcSpreadAttachments() - -- self:PreCalcSpreadMain() - self:InitialFireMode() + if !self.IsMelee then self:InitialFireMode() end + + if self.WeaponSkinDefaultMat != nil then + if !istable(self.WeaponSkinDefaultMat) then self.WeaponSkinDefaultMat = {self.WeaponSkinDefaultMat} end + local mats = self:GetMaterials() + + for k,v in pairs(self.WeaponSkinDefaultMat) do + local id = table.KeyFromValue(mats, v) + self.WeaponSkinSubMaterials[id] = v + self.WeaponSkinProxyMaterials[id] = Material(v) + end end + + self:GetIdealSightFOV() self:DoCustomInitialize() -- SCK Stuff @@ -649,70 +662,21 @@ end function SWEP:DoCustomInitialize() end -FireTime = CurTime() -SWEP.RealTime = 0 -local ironsounds = { - ["ar2"] = {"draconic.IronInRifle", "draconic.IronOutRifle"}, - ["smg"] = {"draconic.IronInSMG", "draconic.IronOutSMG"}, - ["duel"] = {"draconic.IronInSMG", "draconic.IronOutSMG"}, - ["pistol"] = {"draconic.IronInPistol", "draconic.IronOutPistol"}, - ["revolver"] = {"draconic.IronInPistol", "draconic.IronOutPistol"}, - ["shotgun"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, - ["crossbow"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, - ["rpg"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, - ["physgun"] = {"draconic.IronInShotgun", "draconic.IronOutShotgun"}, - ["grenade"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["slam"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["melee"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["melee2"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["passive"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["normal"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["knife"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["camera"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, - ["magic"] = {"draconic.IronInGeneric", "draconic.IronOutGeneric"}, -} - function SWEP:Think() + if game.SinglePlayer() then self:CallOnClient("Think") end local ply = self:GetOwner() if !IsValid(ply) or DRC:Health(ply) < 0.01 then return end - local health = DRC:Health(ply) - local charge, heat = self:GetCharge(), self:GetHeat() - local ct = CurTime() self:DoCustomThink() - self:ManageAnims() + self:ManageAnims(ply, ct) + if self.EnableHeat == true then self:DisperseHeat() end if ct > self.LockoutTime then self.Idle = 1 else self.Idle = 0 end - local cv, vm, hands - if ply:IsPlayer() then - cv = ply:Crouching() - vm = ply:GetViewModel(0) - hands = ply:GetHands() - if CLIENT && game.SinglePlayer() && RealTime() > self.RealTime then - self.RealTime = RealTime() + RealFrameTime() -- For some reason, calling :GetCycle() inside of Think() will be called three times per frame. The first one will always return 0. This prevents it from being called multiple times and creating glitchy-looking-behaviour. - local seq, cycle = ply:GetViewModel(0):GetSequence(), ply:GetViewModel(0):GetCycle() - self.VMSequence = seq - self.VMCycle = cycle - elseif !game.SinglePlayer() then - local seq, cycle = ply:GetViewModel(0):GetSequence(), ply:GetViewModel(0):GetCycle() - self.VMSequence = seq - self.VMCycle = cycle - end - - if !self.IsMelee then -- For some other reason, this breaks animations on the melee base. - if self:HasViewModel() && string.lower(vm:GetModel()) != string.lower(self.ViewModel) then vm:SetModel(self.ViewModel) end - if self.ShowWorldModel == true && (self.WorldModel != nil or self.WorldModel != "") then self:SetModel(self.WorldModel) end - end - end - - - - if self.IdleTimer < CurTime() && self.IsDoingMelee == true then - self.IsDoingMelee = false - self.Loading = false - end + local primcharge = self.Primary.UsesCharge == true + local seccharge = self.Secondary.UsesCharge == true + local loaded = self:GetLoadedAmmo() > 0 if CLIENT && ply:IsPlayer() then local wl = ply:WaterLevel() @@ -737,27 +701,123 @@ function SWEP:Think() end end + local overheated = self:GetNWBool("Overheated") == true + local passive = self:GetNWBool("Passive") == true + + self:ManageSights(ply, ct) + self:ManageCharge(ply, primcharge, seccharge, loaded, primcharge, seccharge) + self:ManageLoopingSounds(ply, ct, passive, overheated, loaded, primcharge, seccharge) + + if CLIENT then + if ply != LocalPlayer() then + local b = self:GetNWBool("IntegratedLightState") + if self.IntegratedLight_DoVolume == true && b == true then + local att = self:LookupAttachment("muzzle") + local attinfo = self:GetAttachment(att) + local col = Color(self.IntegratedLight_Colour.r, self.IntegratedLight_Colour.g, self.IntegratedLight_Colour.b, self.IntegratedLight_Colour.a * 2) + DRC:DLight(self, attinfo.Pos + attinfo.Ang:Forward() * self.IntegratedLight_VolLength*0.5, col, self.IntegratedLight_Colour.a * 50, 5, false, 1, 0) + if !IsValid(self.FlashlightVolume) then + local att = self:LookupAttachment("muzzle") + local attinfo = self:GetAttachment(att) + local p1, p2 = attinfo.Pos, DRC:TraceDir(attinfo.Pos, attinfo.Ang, self.IntegratedLight_MaxDist) + local frac = Lerp(1-p2.Fraction * self.IntegratedLight_DistScale, 0, self.IntegratedLight_FOV) + local volcol = Color(self.IntegratedLight_Colour.r, self.IntegratedLight_Colour.g, self.IntegratedLight_Colour.b, self.IntegratedLight_VolPower) + self.FlashlightVolume = DRC:LightVolume(self, "muzzle", volcol, self.IntegratedLight_VolLength, frac*0.005, 25, nil, self.IntegratedLight_VolMaterial) + end + elseif self.IntegratedLight_DoVolume == true && b == false then + if IsValid(self.FlashlightVolume) then self.FlashlightVolume:Remove() end + end + end + end + + if self.MeleeQueue && IsFirstTimePredicted() then + if #self.MeleeQueue <= 0 then self:ClearMeleeQueue() end -- apparently a table with 0 elements isn't empty? + if !table.IsEmpty(self.MeleeQueue) then + self.IsDoingMelee = true + for i=1,#self.MeleeQueue do + local info = self.MeleeQueue[i] + if info && CurTime() >= info[1] then + local swing = info[2] + self:MeleeImpact(swing, Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), swing.x[1], swing.x[2]), Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), swing.y[1], swing.y[2]), i, "primary") + self.MeleeQueue[i] = nil + end + end + else + self.IsDoingMelee = false + end + end + + if self.BurstQueue then + if #self.BurstQueue <= 0 then self:ClearBurstQueue() end -- apparently a table with 0 elements isn't empty? + if !table.IsEmpty(self.BurstQueue) then + self.Bursting = true + for i=1,#self.BurstQueue do + local thyme = self.BurstQueue[i] + if thyme && CurTime() >= thyme then + -- PrintTable(self.BurstQueue) + if !IsValid(self) or !IsValid(self:GetOwner()) then return end + if self:GetLoadedAmmo() <= 0 then return end + local kill = false + if i >= self.FireModes_BurstShots && ply:IsPlayer() then kill = true end + -- print(#self.BurstQueue, i, self.FireModes_BurstShots, kill) + if kill == false then self.BurstQueue[i] = nil end + if self.Loading == false then + self:CallShoot("primary", true, kill) + end + -- print("---------------") + end + end + else + self.Bursting = false + end + if #self.BurstQueue <= 0 then self:ClearBurstQueue() end + end + + if ply:IsPlayer() && self.RegenAmmo == true then self:RegeneratingAmmo(self, self.RegenAmmo_Delay, self.RegenAmmo_Amount) end +end + +SWEP.desiredfov = 90 +SWEP.fovchecktime = 0 +function SWEP:ManageSights(ply, ct) + if ply:IsPlayer() && ct > self.fovchecktime + 5 then + self.fovchecktime = self.fovchecktime + 5 + self.desiredfov = ply:GetInfoNum("fov_desired", 90) + end + + if ply:IsPlayer() then + local fov = ply:GetFOV() + local newfov = fov + if !fov or !newfov then return end + if !self.fovgrace then self.fovgrace = 0 end + if self.SightsDown == true then newfov = self.IdealSightFOV + elseif self.SightsDown == false && ply:KeyDown(IN_ZOOM) then newfov = 25 end + if self:ShouldFixFOV() != false then newfov = self.desiredfov end + + local range = fov<=newfov+1 && fov>=newfov-1 + if !range && ct > self.fovgrace then + self.fovgrace = ct + 0.4 + ply:SetFOV(newfov, 0.4) + end + end + if self:CanUseSights() == false then self:SetIronsights(false, self.Owner) - ply:SetFOV(0, 0) elseif self:CanUseSights() && self.Secondary.Ironsights == true && self.IronCD == false && self.Secondary.Disabled == false then if self.SightsDown != self:GetNWBool("SightsDown") then self.SightsDown = self:GetNWBool("SightsDown") end - --if ply:KeyPressed(IN_ATTACK2) == true && self:GetNWBool("ironsights") == false && self:GetNWBool("Inspecting") == false && self.IronCD == false && self.Passive == false && !ply:KeyDown(IN_USE) then if ply:KeyPressed(IN_ATTACK2) == true && self.SightsDown == false && self:GetNWBool("Inspecting") == false && self.IronCD == false && self.Passive == false && !ply:KeyDown(IN_USE) then self:SetIronsights(true, self.Owner) - ply:SetFOV(ply:GetFOV() * (self.Secondary.IronFOV / 90), 0.35) + self:AdjustMouseSensitivity() self:IronCoolDown() - ply:EmitSound(ironsounds[string.lower(self:GetHoldType())][1]) + ply:EmitSound(DRCD.Weapons.ironsounds[string.lower(self:GetHoldType())][1]) if CLIENT && self.Secondary.IronInFP != nil then surface.PlaySound(Sound(self.Secondary.IronInFP)) end - --elseif ply:KeyReleased(IN_ATTACK2) == true && self:GetNWBool("ironsights") == true && self.IronCD == false && !ply:KeyDown(IN_USE) then elseif ply:KeyReleased(IN_ATTACK2) == true && self.SightsDown == true && self.IronCD == false && !ply:KeyDown(IN_USE) then self:SetIronsights(false, self.Owner) - ply:SetFOV(0, 0.35) + self:IronCoolDown() - ply:EmitSound(ironsounds[string.lower(self:GetHoldType())][2]) + ply:EmitSound(DRCD.Weapons.ironsounds[string.lower(self:GetHoldType())][2]) if CLIENT && self.Secondary.IronOutFP != nil then surface.PlaySound(Sound(self.Secondary.IronOutFP)) end @@ -768,16 +828,18 @@ function SWEP:Think() self:SetIronsights(false, self.Owner) end - if CurTime() > self.SightsSwapCD && self.IronSightsPosAlt != nil && ply:KeyDown(IN_WALK) && ply:KeyPressed(IN_RELOAD) then - self.SightsSwapCD = CurTime() + 0.25 + if ct > self.SightsSwapCD && self.IronSightsPosAlt != nil && ply:KeyDown(IN_WALK) && ply:KeyPressed(IN_RELOAD) then + self.SightsSwapCD = ct + 0.25 if self.AltSightBool == false or self.AltSightBool == nil then self.AltSightBool = true self.VARSightPos = self.IronSightsPosAlt self.VARSightAng = self.IronSightsAngAlt + self.IdealSightFOV = self.desiredfov * (self.Secondary.IronFOVAlt / 90) else self.AltSightBool = false self.VARSightPos = self.IronSightsPos self.VARSightAng = self.IronSightsAng + self.IdealSightFOV = self.desiredfov * (self.Secondary.IronFOV / 90) end if self.SightSwapCD == true then return end end @@ -787,58 +849,52 @@ function SWEP:Think() elseif CLIENT && self.ScopeUp == true then self.ScopeUp = false end +end - if ply:IsPlayer() && self.Primary.UsesCharge == true && self:GetLoadedAmmo() > 0 && self:CanPrimaryAttack() then - local m1p = ply:KeyPressed(IN_ATTACK) +function SWEP:ManageCharge(ply, primcharge, seccharge, loaded) + local canoc = self:CanOvercharge() + local charge = self.ChargeType + local chargeresponses = DRCD.Weapons.chargeresponses + + if ply:IsPlayer() && primcharge && loaded && self:CanPrimaryAttack() then local m1d = ply:KeyDown(IN_ATTACK) local m1r = ply:KeyReleased(IN_ATTACK) - local ukd = ply:KeyDown(IN_USE) - - -- if game.SinglePlayer() && !IsFirstTimePredicted() then return end - if self.ChargeType == "dualheld" then - if m1r && !self:CanOvercharge() && !ukd then - self:CallShoot("primary") - elseif m1r && self:CanOvercharge() then self:CallShoot("overcharge") end - elseif self.ChargeType == "dualaction" then - if m1d && self:CanOvercharge() then self:CallShoot("overcharge") end - if m1r && !self:CanOvercharge() && !ukd then self:CallShoot("primary") end - elseif self.ChargeType == "discharge" then - if m1d && self:CanOvercharge() && !ukd then - self:CallShoot("overcharge") - end - elseif self.ChargeType == "held" then - if m1r && self:CanOvercharge() then self:CallShoot("overcharge") end - elseif self.ChargeType == "default" then + + if m1r && self:CanOvercharge() then + if chargeresponses[charge][2] != nil then self:CallShoot("overcharge") end + elseif m1r && !canoc then + if chargeresponses[charge][1] != nil then self:CallShoot("primary") end + end + + if m1d && canoc then + if chargeresponses[charge][3] == false then self:CallShoot("overcharge") end end end - if self.Secondary.UsesCharge == true then + if ply:IsPlayer() && seccharge && loaded && self:CanSecondaryAttack() then local m1p = ply:KeyPressed(IN_ATTACK2) local m1d = ply:KeyDown(IN_ATTACK2) local m1r = ply:KeyReleased(IN_ATTACK2) local ukd = ply:KeyDown(IN_USE) - if (SERVER or !game.IsDedicated()) && ply:IsPlayer() then - if game.SinglePlayer() && !IsFirstTimePredicted() then return end - if self.ChargeType == "dualheld" then - if m1r && self:CanPrimaryAttack() == true && !self:CanOvercharge() && !ukd then - if FireTime < CurTime() then FireTime = CurTime() + 60 / self.Primary.RPM self:CallShoot("primary") end - elseif m1r && self:CanOvercharge() && self:CanPrimaryAttack() then self:CallShoot("overcharge") end - elseif self.ChargeType == "dualaction" then - if m1d && self:CanPrimaryAttack() && self:CanOvercharge() then self:CallShoot("overcharge") end - if m1r && self:CanPrimaryAttack() == true && !self:CanOvercharge() && !ukd then self:CallShoot("primary") end - elseif self.ChargeType == "discharge" then - if m1d && self:CanPrimaryAttack() == true && self:CanOvercharge() && !ukd then - self:CallShoot("overcharge") - end - elseif self.ChargeType == "held" then - if m1r && self:CanOvercharge() then self:CallShoot("overcharge") end --- elseif self.ChargeType == "default" then - end + if m1r && self:CanOvercharge() then + if chargeresponses[charge][2] != nil then self:CallShoot("overcharge") end + elseif m1r && !canoc then + if chargeresponses[charge][1] != nil then self:CallShoot("secondary") end + end + + if m1d && canoc then + if chargeresponses[charge][3] == false then self:CallShoot("overcharge") end end end + + if primcharge or seccharge then + if !self.ChargingSound then self.ChargingSound = CreateSound(self, self.ChargeSound) end + end +end - if self:GetNWBool("Passive") == true then +function SWEP:ManageLoopingSounds(ply, ct, passive, overheated, loaded, primcharge, seccharge) + if passive then if self.LoopingFireSound != nil then self.LoopingFireSound:Stop() end @@ -847,42 +903,52 @@ function SWEP:Think() end end - if self.Primary.UsesCharge == true or self.Secondary.UsesCharge == true then - if !self.ChargingSound then self.ChargingSound = CreateSound(self, self.ChargeSound) end - end - - if !game.IsDedicated() then - local oh = self:GetNWBool("Overheated") + if !game.IsDedicated() && ply:IsPlayer() then + local m1p = ply:KeyPressed(IN_ATTACK) + local m1d = ply:KeyDown(IN_ATTACK) + local m1r = ply:KeyReleased(IN_ATTACK) - if self.Primary.UsesCharge == true then - if ply:KeyPressed(IN_ATTACK) && self:GetNWBool("Passive") == false && !ply:KeyDown(IN_USE) && self:CanPrimaryAttack() then + local m2p = ply:KeyPressed(IN_ATTACK2) + local m2d = ply:KeyDown(IN_ATTACK2) + local m2r = ply:KeyReleased(IN_ATTACK2) + + local ekd = ply:KeyDown(IN_USE) + local ekp = ply:KeyPressed(IN_USE) + local skd = ply:KeyDown(IN_SPEED) + + if primcharge == true then + if m1p && !passive && !ekd && self:CanPrimaryAttack() then self.ChargingSound:Play() - elseif !ply:KeyDown(IN_ATTACK) or oh == true then + elseif !m1d or overheated == true then self.ChargingSound:Stop() end elseif self.Secondary.UsesCharge == true then - if ply:KeyPressed(IN_ATTACK2) && self:GetNWBool("Passive") == false && !ply:KeyDown(IN_USE) then + if m2p && !passive && !ekd then self.ChargingSound:Play() - elseif !ply:KeyDown(IN_ATTACK2) or oh == true then + elseif !m2d or overheated == true then self.ChargingSound:Stop() end end if self.Primary.LoopingFireSound != nil && self.Readied == true then - if ply:KeyPressed(IN_ATTACK) && self:CanPrimaryAttack() && self:GetNWBool("Passive") == false && !ply:KeyDown(IN_USE) && oh == false && self:Clip1() > 0 then + if m1p && self:CanPrimaryAttack() && !passive && !ekd && overheated == false && self:Clip1() > 0 then self:EmitSound(self.Primary.LoopingFireSoundIn) - -- self:EmitSound(self.Primary.LoopingFireSound) self.LoopFireSound:Play() else end - if !ply:KeyDown(IN_ATTACK) or oh == true or ply:KeyPressed(IN_USE) then - --self:StopSound(self.Primary.LoopingFireSound) + if !m1d or overheated == true or ply:KeyPressed(IN_USE) then if self.LoopFireSound then self.LoopFireSound:Stop() end end if self:Clip1() > 0 then - if (ply:KeyReleased(IN_ATTACK) && !ply:KeyDown(IN_USE) && oh == false) or (ply:KeyDown(IN_ATTACK) && oh == false && ply:KeyPressed(IN_USE)) then - if !ply:KeyDown(IN_SPEED) then self:EmitSound(self.Primary.LoopingFireSoundOut) end + if (m1r && !ekd && overheated == false) or (m1d && overheated == false && ekp) then + if (self.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1) && !skd then + self:EmitSound(self.Primary.LoopingFireSoundOut) + elseif (self.DoesPassiveSprint != true && DRC.SV.drc_force_sprint != 1) && skd then + self:EmitSound(self.Primary.LoopingFireSoundOut) + elseif (DRC.SV.drc_force_sprint == 2) && skd then + self:EmitSound(self.Primary.LoopingFireSoundOut) + end end end @@ -895,7 +961,7 @@ function SWEP:Think() end if self.LoopingFireSound != nil && (self.Primary.isvFire == true or self.Secondary.isvFire == true) then - if (self.Owner:KeyReleased(IN_ATTACK) && self:GetNWBool("Passive") == false || (!self.Owner:KeyDown(IN_ATTACK) && self.LoopingFireSound)) then + if (self.Owner:KeyReleased(IN_ATTACK) && !passive or (!self.Owner:KeyDown(IN_ATTACK) && self.LoopingFireSound)) then if self:CanPrimaryAttack() == true then if (self.LoopingFireSound) then self.LoopFireSound:Stop() @@ -908,7 +974,7 @@ function SWEP:Think() end if self.LoopingFireSoundSecondary != nil then - if (self.Owner:KeyReleased(IN_ATTACK2) && self:GetNWBool("Passive") == false || (!self.Owner:KeyDown(IN_ATTACK2) && self.LoopingFireSoundSecondary)) then + if (self.Owner:KeyReleased(IN_ATTACK2) && !passive or (!self.Owner:KeyDown(IN_ATTACK2) && self.LoopingFireSoundSecondary)) then if self:CanPrimaryAttack() == true then if (self.LoopingFireSoundSecondary) then self.LoopingFireSoundSecondary:Stop() @@ -919,73 +985,6 @@ function SWEP:Think() else self.LoopingFireSoundSecondary:Stop() end end end - - if self.MeleeQueue && IsFirstTimePredicted() then - if #self.MeleeQueue <= 0 then self:ClearMeleeQueue() end -- apparently a table with 0 elements isn't empty? - if !table.IsEmpty(self.MeleeQueue) then - self.IsDoingMelee = true - for i=1,#self.MeleeQueue do - local info = self.MeleeQueue[i] - if info && CurTime() >= info[1] then - local swing = info[2] - self:MeleeImpact(swing, Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), swing.x[1], swing.x[2]), Lerp(math.Round(i / (1 / engine.TickInterval() - 1), 3), swing.y[1], swing.y[2]), i, "primary") - self.MeleeQueue[i] = nil - end - end - else - self.IsDoingMelee = false - end - end - - if self.BurstQueue then - if !table.IsEmpty(self.BurstQueue) then - self.Bursting = true - for i=1,#self.BurstQueue do - local thyme = self.BurstQueue[i] - if thyme && CurTime() >= thyme then - -- PrintTable(self.BurstQueue) - if !IsValid(self) or !IsValid(self:GetOwner()) then return end - if self:GetLoadedAmmo() <= 0 then return end - local kill = false - if i >= self.FireModes_BurstShots then kill = true end - -- print(#self.BurstQueue, i, self.FireModes_BurstShots, kill) - if kill == false then self.BurstQueue[i] = nil end - if self.Loading == false then - self:CallShoot("primary", true, kill) - end - -- print("---------------") - end - end - else - self.Bursting = false - end - if #self.BurstQueue <= 0 then self:ClearBurstQueue() end - end - - if ply:IsPlayer() && self.RegenAmmo == true then self:RegeneratingAmmo(self, self.RegenAmmo_Delay, self.RegenAmmo_Amount) end - - if !game.SinglePlayer() then return end -- I have to set viewmodel poseparameters in here because they're controlled by the server in singleplayer for some reason, and PreDrawViewModel is client only. Epic. - if CLIENT then return end - - self.AmmoCL = Lerp(0.25, self.AmmoCL or self:Clip1(), self:Clip1()) - self.ChargeCL = Lerp(0.25, self.ChargeCL or charge, charge) - self.HeatCL = Lerp(0.25, self.HeatCL or heat, heat) - self.HealthCL = Lerp(0.25, self.HealthCL or health, health) - - if self.PistolSlide <= 0 then - self.EmptyMagCL = Lerp(FrameTime() * 50, self.EmptyMagCL or self.PistolSlide, 0) - else - self.EmptyMagCL = Lerp(FrameTime() * 50, self.EmptyMagCL or self.PistolSlide, 1) - end - - if ply:IsPlayer() then - if self.Primary.Ammo != nil && vm:GetPoseParameter("drc_ammo") != nil then vm:SetPoseParameter("drc_ammo", self.AmmoCL / self.Primary.ClipSize) end - if self.Primary.Ammo != nil && vm:GetPoseParameter("drc_emptymag") != nil then vm:SetPoseParameter("drc_emptymag", self.EmptyMagCL) end - if self.Primary.Ammo == "ammo_drc_battery" && vm:GetPoseParameter("drc_heat") != nil then vm:SetPoseParameter("drc_heat", self.HeatCL / 100) end - if self.Primary.Ammo == "ammo_drc_battery" && vm:GetPoseParameter("drc_battery") != nil then vm:SetPoseParameter("drc_battery", self.AmmoCL / 100) end - if vm:GetPoseParameter("drc_health") != nil then vm:SetPoseParameter("drc_health", (self.HealthCL / ply:GetMaxHealth()) / 100) end - if vm:GetPoseParameter("drc_charge") != nil then vm:SetPoseParameter("drc_charge", self.ChargeCL / 100) end - end end function SWEP:CanMelee() @@ -1004,18 +1003,64 @@ function SWEP:CanGunMelee() if sights == false && passive == false then return true else return false end end -function SWEP:ManageAnims() +local LoadingAnims = { + ACT_VM_DRAW, + ACT_VM_DRAW_EMPTY, + ACT_VM_RELOAD, + ACT_VM_RELOAD_EMPTY, + ACT_SHOTGUN_RELOAD_START, + ACT_SHOTGUN_RELOAD_FINISH, + ACT_SHOTGUN_PUMP, +} +local FiringAnims = { + ACT_VM_PRIMARYATTACK, + ACT_VM_SECONDARYATTACK, + ACT_SPECIAL_ATTACK1, + ACT_VM_DEPLOYED_IRON_FIRE, +} +function SWEP:ManageAnims(ply, ct) if !IsValid(self) then return end - if !self:IsIdle() then return end --- if !IsFirstTimePredicted() then return end - local ply = self:GetOwner() - if !ply:IsPlayer() then return end - if !IsValid(ply) then return end + if !ply:IsPlayer() then return end if !self:HasViewModel() then return end - local vm = ply:GetViewModel() + local vm = ply:GetViewModel(0) if !IsValid(vm) then return end if vm:GetModel() == "" or vm:GetModel() == nil then return end + + local cv, hands + if ply:IsPlayer() then + cv = ply:Crouching() + hands = ply:GetHands() + if CLIENT && game.SinglePlayer() && RealTime() > self.RealTime then + self.RealTime = RealTime() + RealFrameTime() -- For some reason, calling :GetCycle() inside of Think() will be called three times per frame. The first one will always return 0. This prevents it from being called multiple times and creating glitchy-looking-behaviour. + local seq, cycle = ply:GetViewModel(0):GetSequence(), ply:GetViewModel(0):GetCycle() + self.VMSequence = seq + self.VMCycle = cycle + elseif !game.SinglePlayer() then + local seq, cycle = ply:GetViewModel(0):GetSequence(), ply:GetViewModel(0):GetCycle() + self.VMSequence = seq + self.VMCycle = cycle + end + + if !self.IsMelee then -- For some other reason, this breaks animations on the melee base. + if self:HasViewModel() && string.lower(vm:GetModel()) != string.lower(self.ViewModel) then vm:SetModel(self.ViewModel) end + if self.ShowWorldModel == true && (self.WorldModel != nil or self.WorldModel != "") then self:SetModel(self.WorldModel) end + end + end + + if self.IdleTimer < CurTime() && self.IsDoingMelee == true then + self.IsDoingMelee = false + self.Loading = false + end + + if CLIENT then + local act = vm:GetSequenceActivity(vm:GetSequence()) + if table.HasValue(LoadingAnims, act) then self.PlayingLoadAnimation = true else self.PlayingLoadAnimation = false end + if !self.IsMelee && table.HasValue(FiringAnims, act) then self.PlayingShootAnimation = true else self.PlayingShootAnimation = false end + end + + if !self:IsIdle() then return end + local oa = self.OwnerActivity local cv = ply:Crouching() local slowvar = ply:Crouching() or ply:KeyDown(IN_WALK) @@ -1023,12 +1068,12 @@ function SWEP:ManageAnims() local n, s, e, w = ply:KeyDown(IN_FORWARD), ply:KeyDown(IN_BACK), ply:KeyDown(IN_MOVERIGHT), ply:KeyDown(IN_MOVELEFT) local walking = (n or s or e or w) local sprinting = walking && ply:KeyDown(IN_SPEED) - - local ct = CurTime() + if DRC.SV.drc_force_sprint == 2 then sprinting = false end if self.ManuallyReloading == true or self.Loading == true or self:GetNextPrimaryFire() > ct or self:GetNextSecondaryFire() > ct or self.PreventIdleTimer > ct then return end local idleanim = vm:SelectWeightedSequence(ACT_VM_IDLE) + local ironanim = vm:SelectWeightedSequence(ACT_VM_DEPLOYED_IRON_IDLE) local walkanim = vm:SelectWeightedSequence(ACT_WALK) local sprintanim = vm:SelectWeightedSequence(ACT_RUN) local swimidleanim = vm:SelectWeightedSequence(ACT_SWIM_IDLE) @@ -1048,7 +1093,11 @@ function SWEP:ManageAnims() local animact = animdata.activity if self.SightsDown && ct > self.LastFireAnimTime then - vm:SendViewModelMatchingSequence(idleanim) + if ironanim != -1 then + vm:SendViewModelMatchingSequence(ironanim) + else + vm:SendViewModelMatchingSequence(idleanim) + end return end if jumpanim != -1 && ply:KeyPressed(IN_JUMP) && (ct >= self.JumpWait) then @@ -1079,13 +1128,7 @@ function SWEP:ManageAnims() end end --- if animact != self.AnimToPlay then self.IdleTimer = CurTime() end --- ply:ChatPrint(""..tostring(animact).." - "..tostring(self.AnimToPlay).."") - if animact != self.AnimToPlay && (ct >= self.JumpWait) then self.IdleTimer = ct end - - --- self.AnimToPlay = ACT_VM_IDLE if self.IdleTimer <= ct then if idleanim == -1 then return end @@ -1098,419 +1141,100 @@ end SWEP.MulIns = 0 if CLIENT then -local dang = Angle(0, 0, 0) -local oang = Angle(0, 0, 0) -local LLTime = 0 - -SWEP.InterpolateHolsterBoolVal = 1 -SWEP.VelInterp = 0 -SWEP.KickOffset = Vector() -SWEP.KickVal = 0 -function SWEP:GetViewModelPosition( pos, ang ) - - local ply = self:GetOwner() - if !IsValid(ply) then return end - if !IsValid(self) then return end - if ply:IsWorld() then return end - - local vel = math.Clamp(ply:GetVelocity():LengthSqr()/36100, 0, 1) - self.VelInterp = Lerp(0.1, self.VelInterp or vel, vel) - - local vm = ply:GetViewModel() - local eyeangforward = ply:EyeAngles() - local sd = self.SightsDown - local cv = ply:Crouching() - local oa = self.OwnerActivity - local sk = ply:KeyDown(IN_SPEED) - local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) - local issprinting = sk && mk - local forcesprintoffset = DRC.SV.drc_force_sprint >= 1 - - local ironBool = self.SightsDown - local passiveBool = self:GetNWBool( "Passive" ) - local inspectBool = self:GetNWBool( "Inspecting" ) - - local holsterbool = false - if passiveBool == true or issprinting == true then self.InterpolateHolsterBoolVal = 1 holsterbool = true else self.InterpolateHolsterBoolVal = 0 end - self.InterpolatedHolsterVal = Lerp(RealFrameTime() * 10, self.InterpolatedHolsterVal or self.InterpolateHolsterBoolVal, self.InterpolateHolsterBoolVal) - - if self.DoesPassiveSprint == true or forcesprintoffset then - local upperstrength = math.abs(eyeangforward.x/2) / 45 - ang = ang + Angle(math.Clamp(-eyeangforward.x/2, -30, 45), 0, 0) * self.InterpolatedHolsterVal * upperstrength - local holsteroffset = (Vector(0, -7.5, -3) * self.InterpolatedHolsterVal) * (math.abs(eyeangforward.x/2) / 45) - pos:Add(ang:Right() * holsteroffset.x) - pos:Add(ang:Forward() * holsteroffset.y) - pos:Add(ang:Up() * holsteroffset.z) - end - - if ironBool == true or (ply:GetCanZoom() == true && ply:KeyDown(IN_ZOOM)) then - self.LoweredCrossHairMod = Lerp(RealFrameTime() * 10, self.LoweredCrossHairMod or 1, 0) - else - self.LoweredCrossHairMod = Lerp(RealFrameTime() * 10, self.LoweredCrossHairMod or 0, 1) - end - - if (ironBool != self.lastIron) then - self.lastIron = ironBool - self.fIronTime = CurTime() - end - - if (passiveBool != self.lastPassive) then - self.lastPassive = passiveBool - self.fPassiveTime = CurTime() - end + SWEP.InterpolateHolsterBoolVal = 1 + SWEP.VelInterp = 0 - if (inspectBool != self.LastInspect) then - self.LastInspect = inspectBool - self.fInspectTime = CurTime() - end - - if (cv != self.lastCV) then - self.lastCV = cv - self.fCrouchOffSTime = CurTime() - end - - if (issprinting != self.lastSK) then - self.lastSK = issprinting - self.SprintOffSTime = CurTime() - end - - local fIronTime = self.fIronTime or 0 - local fPassiveTime = self.fPassiveTime or 0 - local fInspectTime = self.fInspectTime or 0 - local fCrouchOffSTime = self.fCrouchOffSTime or 0 - local SprintOffSTime = self.SprintOffSTime or 0 - - self.MulI = math.Clamp((CurTime() - fIronTime) / 0.35, 0, 1) - local MulP = math.Clamp((CurTime() - fPassiveTime) / 0.325, 0, 1) - self.MulIns = math.Clamp((CurTime() - fInspectTime) / 0.325, 0, 1) - local MulC = math.Clamp((CurTime() - fCrouchOffSTime) / 0.265, 0, 1) - local MulS = math.Clamp((CurTime() - SprintOffSTime) / 0.23, 0, 1) - local MulSFade = math.Clamp((CurTime() - SprintOffSTime) / 0.5, 0, 1) - - local MulCx = math.Clamp((CurTime() - fCrouchOffSTime) / 0.3, 0, 1) - local MulCy = math.Clamp((CurTime() - fCrouchOffSTime) / 0.32, 0, 1) - local MulCz = math.Clamp((CurTime() - fCrouchOffSTime) / 0.265, 0, 1) - - self.VARSightPos_Lerped = Lerp(RealFrameTime() * 10, self.VARSightPos_Lerped or self.VARSightPos, self.VARSightPos) - self.VARSightAng_Lerped = Lerp(RealFrameTime() * 10, self.VARSightAng_Lerped or self.VARSightAng, self.VARSightAng) - - --[[ PERSPECTIVE OFFSETS ]]-- - --if self:GetNWBool("ironsights") == false then - if self.SightsDown == false then - local POX = (eyeangforward.x / 135) - local POY = (eyeangforward.x / 100 * 5) - local POZ = (eyeangforward.x / -45) - local AOX = (eyeangforward.x / 30) - - self.VAPos = Vector(POX, POY, POZ) - self.VAAng = Vector(AOX, 0, 0) - - self.VARPos = LerpVector(self.MulI, -self.VMPos + self.VARSightPos_Lerped / 255, self.VAPos ) * math.Clamp(self.PerspectivePower, 0, 1) - self.VARAng = LerpVector(self.MulI, Vector(0, 0, 0), self.VAAng ) * math.Clamp(self.PerspectivePower, 0, 1) - - self.DownCorrectionPos = Vector() - self.DownCorrectionAng = Vector() - self.DownCorrectionAng.z = self.DownCorrectionAng.z - (eyeangforward.x / 10) * math.Clamp(self.PerspectivePower, 0, 1) - self.DownCorrectionAng.z = math.Clamp(self.DownCorrectionAng.z, -10, 2) * math.Clamp(self.PerspectivePower, 0, 1) - self.DownCorrectionAng.y = self.DownCorrectionAng.y + math.abs(eyeangforward.x / 90) * math.Clamp(self.PerspectivePower, 0, 1) - - local eyepos = ply:EyePos() - - local onehand = { "pistol", "slam", "magic" } - local twohand = { "smg", "ar2", "shotgun", "crossbow", "camera", "revolver" } - local dualtypes = { "duel" } - local lowtypes = { "physgun" } - local hightypes = { "rpg" } - local meleetypes = { "melee", "knife", "grenade", "slam" } - local meleetwohand = { "melee2" } - local handguns = { "pistol", "revolver" } - - local walloffset, heft = {}, 10 - if CTFK(handguns, self:GetHoldType()) then - heft = 10 - walloffset = { - Vector(-2, -5, 1), - Vector(0, 0, 0), - } - elseif CTFK(meleetwohand, self:GetHoldType()) then - heft = 3 - walloffset = { - Vector(2, -5, -3), - Vector(25, -7.5, -15), - } - else - heft = 5 - walloffset = { - Vector(2, -5, -1), - Vector(5, 6, 0), - } - end - - local aids = ply:GetEyeTrace().HitPos - local hiv = math.Round(ply:EyePos():Distance(aids)) - hiv = math.Clamp(hiv, 0, 50) / 50 - hiv = 1 - hiv - self.walllerpval = Lerp((0.008) * heft, self.walllerpval or hiv, hiv) * math.Clamp(self.NearWallPower, 0, 1) - local wallpos = Lerp(self.walllerpval, Vector(), walloffset[1]) - local wallang = Lerp(self.walllerpval, Vector(), walloffset[2]) - - self.VARPos = self.VARPos + self.DownCorrectionPos + wallpos - self.VARAng = self.VARAng + self.DownCorrectionAng + wallang - else - - end - DynaPosLerp = Lerp(0.008, DynaPosLerp or self.VAPos, self.VAPos) - DynaAngLerp = Lerp(0.008, DynaAngLerp or self.VAAng, self.VAAng) - - --[[ CROUCH OFFSETS ]]-- - if cv == true then - local x = Lerp( MulCx, self.VMPos.x, self.VMPosCrouch.x + self.VMPos.x) - local y = Lerp( MulCy, self.VMPos.y, self.VMPosCrouch.y + self.VMPos.y) - local z = Lerp( MulCz, self.VMPos.z, self.VMPosCrouch.z + self.VMPos.z) - - self.CPos = Vector(x,y,z) - self.CRPos = LerpVector( MulC, self.VMPos, self.CPos) - else - local x = Lerp( MulCx, self.VMPosCrouch.x + self.VMPos.x, self.VMPos.x) - local y = Lerp( MulCy, self.VMPosCrouch.y + self.VMPos.y, self.VMPos.y) - local z = Lerp( MulCz, self.VMPosCrouch.z + self.VMPos.z, self.VMPos.z) - - self.CPos = Vector(x,y,z) - self.CRPos = LerpVector( MulC, self.CPos, self.VMPos) - end - - self.CPosLerp = LerpVector(MulC, self.CRPos, self.CPos) + function SWEP:GetViewModelPosition( pos, ang ) + local ply = self:GetOwner() + if !IsValid(ply) then return end + if !IsValid(self) then return end + if ply:IsWorld() then return end - if cv == true then - local x = Lerp( MulCx, self.VMAng.x, self.VMAngCrouch.x + self.VMAng.x) - local y = Lerp( MulCy, self.VMAng.y, self.VMAngCrouch.y + self.VMAng.y) - local z = Lerp( MulCz, self.VMAng.z, self.VMAngCrouch.z + self.VMAng.z) - - self.CAng = Vector(x,y,z) - self.CRAng = LerpVector( MulC, self.VMAng, self.CAng) - else - local x = Lerp( MulCx, self.VMAngCrouch.x + self.VMAng.x, self.VMAng.x) - local y = Lerp( MulCy, self.VMAngCrouch.y + self.VMAng.y, self.VMAng.y) - local z = Lerp( MulCz, self.VMAngCrouch.z + self.VMAng.z, self.VMAng.z) - - self.CAng = Vector(x,y,z) - self.CRAng = LerpVector( MulC, self.CAng, self.VMAng) - end - - self.CAngLerp = LerpVector(MulC, self.CRAng, self.CAng) - - --[[ PASSIVE OFFSETS ]]-- - --if self.PPosOG == nil then self.PPosOG = self.PassivePos end - -- if self.PAngOG == nil then self.PAngOG = self.PassiveAng end - -- self.PassivePos.x = self.PPosOG.x + ply:GetAngles().x / 2 - -- self.PassiveAng.y = self.PAngOG.y - eyeangforward.x / 10 - -- self.PassiveAng.z = self.PAngOG.z - math.abs(eyeangforward.x / 50) + local sk = ply:KeyDown(IN_SPEED) + local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) + local sprint = sk && mk && (self.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1) + local passive = self:GetNWBool("Passive", false) && DRC.SV.drc_passives >= 1 + local inspect = self:GetNWBool("Inspecting") && DRC.SV.drc_inspections >= 1 + local eyeangforward = ply:EyeAngles() + local sd = self.SightsDown + if DRC.SV.drc_force_sprint == 2 then sprint = false end - if passiveBool == true then - self.PPos = LerpVector( MulP, self.VMPos, self.PassivePos + self.VMPos) - self.PRPos = LerpVector( MulP, self.VMPos, -self.PassivePos + self.VMPos) - else - self.PPos = LerpVector( MulP, -self.PassivePos + self.VMPos, self.VMPos) - self.PRPos = LerpVector( MulP, -self.PassivePos + self.VMPos, self.VMPos) - end - - self.PRPosLerp = LerpVector( MulP, self.PPos, self.PRPos) + if passive or sprint then + self:DoPassiveHoldtype() + elseif inspect == true then + self:DoInspectHoldtype() + else + if self:GetHoldType() != self.HoldType then self:SetHoldType(self.HoldType) end + end - if passiveBool == true then - self.PAng = LerpVector( MulP, self.VMAng, self.PassiveAng + self.VMAng) - self.PRAng = LerpVector( MulP, self.VMAng, -self.PassiveAng + self.VMAng) - else - self.PAng = LerpVector( MulP, -self.PassiveAng + self.VMAng, self.VMAng) - self.PRAng = LerpVector( MulP, -self.PassiveAng - self.VMAng, self.VMAng ) - end - - self.PRAngLerp = LerpVector(MulP, self.PAng, self.PRAng) - - --[[ INSPECT OFFSETS ]]-- - if inspectBool == true then - self.InsPos = LerpVector( self.MulIns, self.VMPos, self.InspectPos + self.VMPos) - self.InsRPos = LerpVector( self.MulIns, self.VMPos, -self.InspectPos + self.VMPos) - else - self.InsPos = LerpVector( self.MulIns, -self.InspectPos + self.VMPos, self.VMPos) - self.InsRPos = LerpVector( self.MulIns, -self.InspectPos + self.VMPos, self.VMPos) - end - - self.InsRPosLerp = LerpVector( self.MulIns, self.InsPos, self.InsRPos) + local IronTime = self.IronTime or 0 + local InspectTime = self.InspectTime or 0 - if inspectBool == true then - self.InsAng = LerpVector( self.MulIns, self.VMAng, self.InspectAng + self.VMAng) - self.InsRAng = LerpVector( self.MulIns, self.VMAng, -self.InspectAng + self.VMAng) - else - self.InsAng = LerpVector( self.MulIns, -self.InspectAng + self.VMAng, self.VMAng) - self.InsRAng = LerpVector( self.MulIns, -self.InspectAng - self.VMAng, self.VMAng ) - end - - self.InsRAngLerp = LerpVector(self.MulIns, self.InsAng, self.InsRAng) - - --[[ SIGHT OFFSETS ]]-- - if sd == true then - self.IPos = LerpVector( self.MulI, self.VMPos, self.VARSightPos_Lerped + self.VMPos) - self.IRPos = LerpVector( self.MulI, self.VMPos, -self.VARSightPos_Lerped + self.VMPos) - else - self.IPos = LerpVector( self.MulI, -self.VARSightPos_Lerped + self.VMPos, self.VMPos) - self.IRPos = LerpVector( self.MulI, -self.VARSightPos_Lerped - self.VMPos, self.VMPos ) - end - - self.IRPosLerp = LerpVector(self.MulI, self.IPos, self.IRPos) + self.MulI = math.Clamp((CurTime() - IronTime) / 0.35, 0, 1) + self.MulIns = math.Clamp((CurTime() - InspectTime) / 0.325, 0, 1) - if sd == true then - self.IAng = LerpVector( self.MulI, self.VMAng, self.VARSightAng_Lerped + self.VMAng) - self.IRAng = LerpVector( self.MulI, self.VMAng, -self.VARSightAng_Lerped + self.VMAng) - else - self.IAng = LerpVector( self.MulI, -self.VARSightAng_Lerped + self.VMAng, self.VMAng) - self.IRAng = LerpVector( self.MulI, -self.VARSightAng_Lerped - self.VMAng, self.VMAng ) - end - - self.IRAngLerp = LerpVector(self.MulI, self.IAng, self.IRAng) - - --[[ SPRINT OFFSETS ]]-- - if issprinting == true then - self.SPos = LerpVector( MulS, self.VMPos, self.SprintPos + self.VMPos ) - self.SRPos = LerpVector( MulS, self.VMPos, -self.SprintPos + self.VMPos ) - else - self.SPos = LerpVector( MulS, -self.SprintPos + self.VMPos, self.VMPos ) - self.SRPos = LerpVector( MulS, -self.SprintPos - self.VMPos, self.VMPos ) - end - - self.SRPosLerp = LerpVector( MulS, self.SPos, self.SRPos ) + local vel = math.Clamp(ply:GetVelocity():LengthSqr()/36100, 0, 1) + self.VelInterp = Lerp(0.1, self.VelInterp or vel, vel) - if issprinting == true then - self.Sang = LerpVector( MulS, -self.VMAng, self.SprintAng + self.VMAng ) - self.SRAng = LerpVector( MulS, -self.VMAng, - self.SprintAng + self.VMAng ) - else - self.Sang = LerpVector( MulS, -self.SprintAng + self.VMAng, self.VMAng ) - self.SRAng = LerpVector( MulS, -self.SprintAng - self.VMAng, self.VMAng ) - end - - self.SRAngLerp = LerpVector( MulS, self.Sang, self.SRAng) - - if oa == "standidle" or oa == "running" or oa == "swimidle" or oa == "swimming" then -- STANDING | Controls final interp mixes - if self.DoesPassiveSprint == true or forcesprintoffset then - if passiveBool == true then - self:DoPassiveHoldtype() - elseif inspectBool == true then - self:DoInspectHoldtype() - else - if self:GetNWBool("Overheated") == true then -- fucking glua wont let me just call either self.Overheated or self.IsOverheated within this function AAAAAAAA - if self:GetHoldType() != self.OverheatHoldType then self:SetHoldType(self.OverheatHoldType) end - elseif self:GetNWBool("Venting") == true then - if self:GetHoldType() != self.VentingHoldType then self:SetHoldType(self.VentingHoldType) end - else - if self:GetHoldType() != self.HoldType then self:SetHoldType(self.HoldType) end - end - end - else - if passiveBool == true then - self:DoPassiveHoldtype() - elseif inspectBool == true then - self:DoInspectHoldtype() - end - end - elseif (oa == "sprinting" or oa =="fastswimming") then - if self.DoesPassiveSprint == true or forcesprintoffset then - self:DoPassiveHoldtype() - end - end - - local sightkill = 1 - local rollval = 0 if sd == true then - sightkill = 1 self.BobScale = 0.1 self.SwayScale = 0.25 else - sightkill = 1 self.BobScale = self.BS self.SwayScale = self.SS end - - self.IronPosLerp = Lerp(RealFrameTime() * 10, self.IronPosLerp or self.IRPosLerp, self.IRPosLerp) - self.IronAngLerp = Lerp(RealFrameTime() * 10, self.IronAngLerp or self.IRAngLerp, self.IRAngLerp) - - if issprinting == false then - self.PassivePosLerp = Lerp(RealFrameTime() * 10, self.PassivePosLerp or self.PRPosLerp, self.PRPosLerp) - self.PassiveAngLerp = Lerp(RealFrameTime() * 10, self.PassiveAngLerp or self.PRAngLerp, self.PRAngLerp) - else - self.PassivePosLerp = Lerp(RealFrameTime() * 10, self.PassivePosLerp or Vector(), Vector()) - self.PassiveAngLerp = Lerp(RealFrameTime() * 10, self.PassiveAngLerp or Vector(), Vector()) + + local holsterbool = false + if self.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1 then + if passive == true or sprint == true then self.InterpolateHolsterBoolVal = 1 holsterbool = true else self.InterpolateHolsterBoolVal = 0 end + self.InterpolatedHolsterVal = Lerp(RealFrameTime() * 10, self.InterpolatedHolsterVal or self.InterpolateHolsterBoolVal, self.InterpolateHolsterBoolVal) + + local upperstrength = math.abs(eyeangforward.x/2) / 45 + ang = ang + Angle(math.Clamp(-eyeangforward.x/2, -30, 45), 0, 0) * self.InterpolatedHolsterVal * upperstrength + local holsteroffset = (Vector(0, -7.5, -3) * self.InterpolatedHolsterVal) * (math.abs(eyeangforward.x/2) / 45) + pos:Add(ang:Right() * holsteroffset.x) + pos:Add(ang:Forward() * holsteroffset.y) + pos:Add(ang:Up() * holsteroffset.z) end - self.InspectPosLerp = Lerp(RealFrameTime() * 10, self.InspectPosLerp or self.InsRPosLerp, self.InsRPosLerp) - self.InspectAngLerp = Lerp(RealFrameTime() * 10, self.InspectAngLerp or self.InsRAngLerp, self.InsRAngLerp) - - self.CrouchPosLerp = Lerp(RealFrameTime() * 10, self.CrouchPosLerp or self.CRPos, self.CRPos) - self.CrouchAngLerp = Lerp(RealFrameTime() * 10, self.CrouchAngLerp or self.CRAng, self.CRAng) - - self.SprintPosLerp = Lerp(RealFrameTime() * 10, self.SprintPosLerp or self.SRPosLerp, self.SRPosLerp) - self.SprintAngLerp = Lerp(RealFrameTime() * 10, self.SprintAngLerp or self.SRAngLerp, self.SRAngLerp) + ang:RotateAroundAxis(ang:Right(), self.DynOffsetAng.x) + ang:RotateAroundAxis(ang:Up(), self.DynOffsetAng.y) + ang:RotateAroundAxis(ang:Forward(), self.DynOffsetAng.z) + pos:Add(ang:Right() * self.DynOffsetPos.x) + pos:Add(ang:Forward() * self.DynOffsetPos.y) + pos:Add(ang:Up() * self.DynOffsetPos.z) - local DrcGlobalVMOffset = Vector(GetConVar("cl_drc_vmoffset_x"):GetFloat(), GetConVar("cl_drc_vmoffset_y"):GetFloat(), GetConVar("cl_drc_vmoffset_z"):GetFloat()) - - if !self.dynmove then self.dynmove = {["Pos"] = Vector(), ["Ang"] = Vector(), ["Roll"] = 0} end - local dyn = self.dynmove - dyn.Ang = Vector(dyn.Ang.x, dyn.Ang.y, dyn.Ang.z) - if (self.DoesPassiveSprint == true or forcesprintoffset) then - self.VariablePos=( self.VMPos -(self.VMPos - self.CrouchPosLerp) + (self.VMPos - self.PassivePosLerp) + (self.VMPos - self.InspectPosLerp) + (self.VMPos - self.SprintPosLerp) + (self.VMPos - self.IronPosLerp) ) + DrcGlobalVMOffset - self.VariableAng=( self.VMAng -(self.VMAng - self.CrouchAngLerp) + (self.VMAng - self.PassiveAngLerp) + (self.VMAng - self.InspectAngLerp) + (self.VMAng - self.SprintAngLerp) + (self.VMAng - self.IronAngLerp) ) - self.VariableAng = self.VariableAng + dyn.Ang - self.VariablePos = self.VariablePos + Vector(dyn.Ang.y/8, 0, -dyn.Ang.x/8) + if sd == true or (ply:GetCanZoom() == true && ply:KeyDown(IN_ZOOM)) then + self.LoweredCrossHairMod = Lerp(RealFrameTime() * 10, self.LoweredCrossHairMod or 1, 0) + else + self.LoweredCrossHairMod = Lerp(RealFrameTime() * 10, self.LoweredCrossHairMod or 0, 1) + end - else - self.VariablePos=( self.VMPos -(self.VMPos - self.CrouchPosLerp) + (self.VMPos - self.PassivePosLerp) + (self.VMPos - self.InspectPosLerp) + (self.VMPos - self.IronPosLerp) ) + DrcGlobalVMOffset - self.VariableAng=( self.VMAng -(self.VMAng - self.CrouchAngLerp) + (self.VMAng - self.PassiveAngLerp) + (self.VMAng - self.InspectAngLerp) + (self.VMAng - self.IronAngLerp) ) - self.VariableAng = self.VariableAng + dyn.Ang - self.VariablePos = self.VariablePos + Vector(dyn.Ang.y/8, 0, -dyn.Ang.x/8) - end - - if ironBool == true then - self.VariablePos = self.VariablePos + Vector(-5, 0, -1) - self.VariableAng = self.VariableAng + Vector(0, -5, -15) - end - - if sd == false then - self.OffsetsCalc = LerpVector( self.MulI, self.VARSightPos_Lerped, self.VariablePos + self.VARPos) - self.AngleCalc = LerpVector( self.MulI, self.VARSightAng_Lerped, self.VariableAng + self.VARAng) - else - self.OffsetsCalc = LerpVector( self.MulI, self.VariablePos, self.VARSightPos_Lerped) - self.AngleCalc = LerpVector( self.MulI, self.VariableAng, self.VARSightAng_Lerped + Vector(0, 0, rollval_lerp)) - end - - VariablePosLerp = Lerp(self.MulI, VariablePosLerp or self.OffsetsCalc, self.OffsetsCalc) - VariableAngLerp = Lerp(self.MulI, VariableAngLerp or self.AngleCalc, self.AngleCalc) - --- PrintTable(self.dynmove) - - ang:RotateAroundAxis(ang:Right(), VariableAngLerp.x) - ang:RotateAroundAxis(ang:Up(), VariableAngLerp.y) - ang:RotateAroundAxis(ang:Forward(), VariableAngLerp.z) - pos:Add(ang:Right() * VariablePosLerp.x) - pos:Add(ang:Forward() * VariablePosLerp.y) - pos:Add(ang:Up() * VariablePosLerp.z) - - if GetTimeoutInfo() == true then return end - if GetConVar("cl_drc_lowered_crosshair"):GetFloat() == 1 then - return (pos + Vector(0, 0, 0.5) * self.LoweredCrossHairMod) + self.LoweredVMPos, (ang + Angle(-5, 0, 0) * self.LoweredCrossHairMod) + Angle(self.LoweredVMAng.x, self.LoweredVMAng.y, self.LoweredVMAng.z) - else - return pos, ang + if GetTimeoutInfo() == true then return end + if GetConVar("cl_drc_lowered_crosshair"):GetFloat() == 1 then + return (pos + Vector(0, 0, 0.5) * self.LoweredCrossHairMod) + self.LoweredVMPos, (ang + Angle(-5, 0, 0) * self.LoweredCrossHairMod) + Angle(self.LoweredVMAng.x, self.LoweredVMAng.y, self.LoweredVMAng.z) + else + return pos, ang + end end end -end function SWEP:Reload() end +function SWEP:GetIdealSightFOV() + local ply = self:GetOwner() + if !ply:IsPlayer() then return end + if IsValid(ply) then self.IdealSightFOV = ply:GetInfoNum("fov_desired", 90) * ((self.Secondary.IronFOV or 90) / 90) end +end + function SWEP:Deploy() if game.SinglePlayer() then self:CallOnClient("Deploy") end local ply = self:GetOwner() if !IsValid(ply) then return end self:DoCustomDeploy() - self:CallOnClient("DoCustomDeploy") +-- self:CallOnClient("DoCustomDeploy") local cv, vm = false, self if ply:IsPlayer() then cv = ply:Crouching() vm = ply:GetViewModel() end @@ -1525,13 +1249,17 @@ function SWEP:Deploy() self:SetIronsights(false) self.SightsDown = false if self:GetNWBool("Passive") == true then self:TogglePassive() end - self.Idle = 0 + self.Idle = 1 self.IsTaunting = 0 self.Inspecting = false self:SetNWBool("Inspecting", false) self.EmptyReload = 0 self.ManuallyReloading = false - self.Loading = true + self.Loading = false + + self:GetIdealSightFOV() + + if self.WeaponSkinApplied != nil then self:SetCamo(self.WeaponSkinApplied) end if self.Thirdperson == true && ply:IsPlayer() && CLIENT then DRC:ThirdPerson_PokeLiveAngle(ply) end @@ -1540,24 +1268,18 @@ function SWEP:Deploy() end if ply:IsPlayer() then + self.desiredfov = ply:GetInfoNum("fov_desired", 90) self.DManip_PlyID = "DRC_DManip_" ..ply:Name().. "" self.IdleTimer = CurTime() + drawanimdur if self.Readied == true or drawaniminitial == -1 then - self:PlayAnim( ACT_VM_DRAW ) + self:PlayAnim( ACT_VM_DRAW, true, true ) timer.Simple(drawanimdur, function() self.Readied = true - self.Loading = false - self.Idle = 1 end) - self.IdleTimer = CurTime() + drawanimdur else self:PlayAnim( ACT_VM_DRAW_EMPTY ) - -- self.IdleTimer = CurTime() + drawaniminitialdur timer.Simple(drawaniminitialdur, function() self.Readied = true - -- self:SetNWBool("Readied", true) - self.Loading = false - self.Idle = 1 end) end @@ -1575,9 +1297,7 @@ function SWEP:Deploy() self:GetMovementValues() end - if self.Primary.Ammo != nil then - self:SetNWInt("LoadedAmmo", self:Clip1() ) - else end + if self.Primary.Ammo != nil then self:SetNWInt("LoadedAmmo", self:Clip1()) end if ply:IsPlayer() && self.HealthRegen == true then self:RegeneratingHealth(ply) end if self.SpecialScripted != true then @@ -1587,10 +1307,7 @@ function SWEP:Deploy() end end - if self.Primary.Ammo == "ammo_drc_battery" then - self:SetNWFloat("HeatDispersePower", 1) - self:DisperseHeat() - end + self:SetNWFloat("HeatDispersePower", 1) if self.Primary.UsesCharge == true or self.Secondary.UsesCharge == true then self:DisperseCharge() @@ -1606,6 +1323,7 @@ function SWEP:OnRemove() self.IdleTimer = CurTime() self:DoCustomRemove() + self:ClearSubMaterials() if ( SERVER ) then if ply:IsPlayer() then @@ -1654,16 +1372,19 @@ end function SWEP:DoCustomRemove() end -function SWEP:Holster() +function SWEP:Holster(wpn) local ply = self:GetOwner() self.IdleTimer = CurTime() - + self:DoCustomHolster() --self:SetNWBool("Ironsights", false ) self.SightsDown = false self:SetNWBool("Inspecting", false) self:ClearBurstQueue() + self:ClearSubMaterials() + + self:SetNWBool("IntegratedLightState", false) if self.ChargeSound then self:StopSound(self.ChargeSound) end if self.Primary.LoopingFireSound then self:StopSound(self.Primary.LoopingFireSound) end @@ -1681,10 +1402,6 @@ function SWEP:Holster() local ply = self:GetOwner() if ply:IsPlayer() then ply:StopLoopingSound( 0 ) --- hook.Remove( "Move", self.HookUID_1 ) --- hook.Remove( "Move", self.HookUID_2 ) --- hook.Remove( "Move", self.HookUID_3 ) --- hook.Remove( "Move", self.HookUID_4 ) hook.Remove( "DManipPlayerSwitchFlashlight","DManip_PlyID" ) timer.Remove( self.PassiveHealing ) @@ -1718,8 +1435,8 @@ function SWEP:Holster() self:ResetBonePositions(vm) end end - -return true + + return true end function SWEP:RestoreMovement() @@ -1752,6 +1469,7 @@ function SWEP:OnDrop() if !IsValid(self) then return end self:SetOwner(nil) +-- self:ClearSubMaterials() self:DoCustomDrop() net.Start("DRC_WeaponDropped") @@ -1811,8 +1529,9 @@ end function SWEP:DoImpactEffect(tr, dt) if game.SinglePlayer() && CLIENT then return true end if !game.SinglePlayer() && SERVER then return true end - if CurTime() < self.LastMeleeImpactTime + 0.1 then return true else return false end - if self.HideImpacts == true then return true else return false end + if self.HideImpacts == true then return true end + if CurTime() < self.LastMeleeImpactTime + 0.1 then return true end + return false end function SWEP:DrawWeaponSelection( x, y, wide, tall, alpha ) @@ -1895,6 +1614,15 @@ function SWEP:CanUseSights() return true end +function SWEP:ShouldFixFOV() + if self.SightsDown == true then return false end + local ply = self:GetOwner() + if !ply:IsPlayer() then return end + if ply:InVehicle() then return false end + if ply:KeyDown(IN_ZOOM) then return false end + return true +end + function SWEP:IronCoolDown() self.IronCD = true timer.Simple( 0.5, function() self.IronCD = false end) @@ -2122,14 +1850,15 @@ end function SWEP:PreCalcRPM() self.PrimaryStats.PreCalcRPM = 60/self.Primary.RPM self.SecondaryStats.PreCalcRPM = 60/self.Secondary.RPM - self.OCStats.PreCalcRPM = 60/self.Primary.OCRPM + if self.OCStats && self.Primary.OCRPM then self.OCStats.PreCalcRPM = 60/self.Primary.OCRPM end end function SWEP:PreCalcSpreadAttachments() if !IsValid(self) then return end if !self.AttachmentStats then self.AttachmentStats = {} end + local spr, sprdiv = self:GetAttachmentValue("Ammunition", "Spread") or 1, self:GetAttachmentValue("Ammunition", "SpreadDiv") or 1 - self.AttachmentStats.PreCalcSpread = self:GetAttachmentValue("Ammunition", "Spread") / self:GetAttachmentValue("Ammunition", "SpreadDiv") + self.AttachmentStats.PreCalcSpread = spr / sprdiv end function SWEP:PreCalcSpreadMain() @@ -2143,14 +1872,76 @@ function SWEP:PreCalcSpreadMain() self.OCStats.PreCalcSpread = self.OCSpread / self.OCSpreadDiv end +SWEP.RecoilStats = { + ["primary"] = { + RecoilDown = SWEP.Primary.RecoilDown, + RecoilUp = SWEP.Primary.RecoilUp, + RecoilHoriz = SWEP.Primary.RecoilHoriz, + Kick = SWEP.Primary.Kick, + KickHoriz = SWEP.Primary.KickHoriz, + IronRecoilMul = SWEP.Primary.IronRecoilMul + }, + ["secondary"] = { + RecoilDown = SWEP.Secondary.RecoilDown, + RecoilUp = SWEP.Secondary.RecoilUp, + RecoilHoriz = SWEP.Secondary.RecoilHoriz, + Kick = SWEP.Secondary.Kick, + KickHoriz = SWEP.Secondary.KickHoriz, + IronRecoilMul = SWEP.Secondary.IronRecoilMul + }, + ["overcharge"] = { + RecoilDown = SWEP.OCRecoilDown, + RecoilUp = SWEP.OCRecoilUp, + RecoilHoriz = SWEP.OCRecoilHoriz, + Kick = SWEP.OCKick, + KickHoriz = SWEP.OCKickHoriz, + IronRecoilMul = SWEP.OCIronRecoilMul + } +} + +function SWEP:PreCalcRecoil() + local down = self:GetAttachmentValue("Ammunition", "RecoilDown") + local up = self:GetAttachmentValue("Ammunition", "RecoilUp") + local horiz = self:GetAttachmentValue("Ammunition", "RecoilHoriz") + local kick = self:GetAttachmentValue("Ammunition", "Kick") + local kickhoriz = self:GetAttachmentValue("Ammunition", "KickHoriz") + local iron = self:GetAttachmentValue("Ammunition", "IronRecoilMul") + + self.RecoilStats.primary = { + RecoilDown = self.Primary.RecoilDown * down, + RecoilUp = self.Primary.RecoilUp * up, + RecoilHoriz = self.Primary.RecoilHoriz * horiz, + Kick = self.Primary.Kick * kick, + KickHoriz = self.Primary.KickHoriz * kickhoriz, + IronRecoilMul = self.Primary.IronRecoilMul * iron + } + self.RecoilStats.secondary = { + RecoilDown = self.Secondary.RecoilDown * down, + RecoilUp = self.Secondary.RecoilUp * up, + RecoilHoriz = self.Secondary.RecoilHoriz * horiz, + Kick = self.Secondary.Kick * kick, + KickHoriz = self.Secondary.KickHoriz * kickhoriz, + IronRecoilMul = self.Secondary.IronRecoilMul * iron + } + self.RecoilStats.overcharge = { + RecoilDown = self.OCRecoilDown * down, + RecoilUp = self.OCRecoilUp * up, + RecoilHoriz = self.OCRecoilHoriz * horiz, + Kick = self.OCKick * kick, + KickHoriz = self.OCKickHoriz * kickhoriz, + IronRecoilMul = self.OCIronRecoilMul * iron + } +end + function SWEP:PreCalcSpread() self:PreCalcSpreadAttachments() self:PreCalcSpreadMain() + self:PreCalcRecoil() end + + function SWEP:SetupDataTables() --- self:SetNWInt("Heat", 0) --- self.ChargeValue = 0) self:SetNWFloat("Charge", 0) self:SetNWBool("Passive", false) self:SetNWBool("Inspecting", false) @@ -2160,7 +1951,11 @@ function SWEP:SetupDataTables() if self.IsMelee == false then self.PrimaryStats = { + BloomMul = self.Primary.BloomMul, + BloomMulCrouch = self.Primary.BloomMulCrouch, + BloomMulADS = self.Primary.BloomMulADS, Damage = self.Primary.Damage, + DamageNPC = self.Primary.DamageNPC, Projectile = self.Primary.Projectile, ProjSpeed = self.Primary.ProjSpeed, ProjInheritVelocity = self.Primary.ProjInheritVelocity, @@ -2201,7 +1996,11 @@ function SWEP:SetupDataTables() } self.SecondaryStats = { + BloomMul = self.Secondary.BloomMul, + BloomMulCrouch = self.Secondary.BloomMulCrouch, + BloomMulADS = self.Secondary.BloomMulADS, Damage = self.Secondary.Damage, + DamageNPC = self.Secondary.DamageNPC, Projectile = self.Secondary.Projectile, ProjSpeed = self.Secondary.ProjSpeed, ProjInheritVelocity = self.Secondary.ProjInheritVelocity, @@ -2241,7 +2040,11 @@ function SWEP:SetupDataTables() } self.OCStats = { + BloomMul = self.OCBloomMul, + BloomMulCrouch = self.OCBloomMulCrouch, + BloomMulADS = self.OCBloomMulADS, Damage = self.OCDamage, + DamageNPC = self.OCDamageNPC, Projectile = self.OCProjectile, ProjSpeed = self.OCProjSpeed, ProjInheritVelocity = self.OCProjInheritVelocity, @@ -2288,7 +2091,7 @@ function SWEP:SetupDataTables() Description = self.InfoDescription } - if self.IsBatteryBased == nil or self.IsBatteryBased == false then return end +-- if self.IsBatteryBased == nil or self.IsBatteryBased == false then return end self.BatteryStats = { HPS = self.HPS, OCHPS = self.OCHPS, @@ -2343,13 +2146,77 @@ function SWEP:PlayAnim(act, preventstuff, important) self:SetNextSecondaryFire(ct + seqdur) self.LockoutTime = ct + seqdur end +end + +function SWEP:ToggleIntegratedLight(b) + local ply = self:GetOwner() + local bool = self:GetNWBool("IntegratedLightState", false) + if b == nil then b = bool else b = !b end + + local dur = self:SequenceDuration(self:SelectWeightedSequence(ACT_OBJ_STARTUP)) * self.IntegratedLight_ToggleFrac + self:PlayAnim(ACT_OBJ_STARTUP, true) --- local ply = self:GetOwner() --- if IsValid(ply) && IsValid(self) && ply:IsPlayer() then --- local vm = ply:GetViewModel() --- vm:ResetSequence(seq) --- vm:ResetSequenceInfo() --- end + timer.Simple(dur, function() + if !IsValid(self) then return end + if b == false then + self:SetNWBool("IntegratedLightState", true) + self:EmitSound(self.IntegratedLight_OnSound) + else + self:SetNWBool("IntegratedLightState", false) + self:EmitSound(self.IntegratedLight_OffSound) + end + end) +end + +function SWEP:SetCamo(mat) + local ply = self:GetOwner() + if mat == "" then mat = nil end + self.WeaponSkinApplied = mat + + if !ply:IsPlayer() then + for k,v in pairs(self.WeaponSkinSubMaterials) do + if mat != nil then + if DRC.WeaponSkins[mat].proxy == true then + self:SetSubMaterial(k-1, "models/vuthakral/weaponskin_".. k-1 .."") + else + self:SetSubMaterial(k-1, mat) + end + else + self:SetSubMaterial(k-1, mat) + end + end + else + local vm = ply:GetViewModel() + for k,v in pairs(self.WeaponSkinSubMaterials) do + if mat != nil then + if DRC.WeaponSkins[mat].proxy == true then + self:SetSubMaterial(k-1, "models/vuthakral/weaponskin_".. k-1 .."") + vm:SetSubMaterial(k-1, "models/vuthakral/weaponskin_".. k-1 .."") + else + vm:SetSubMaterial(k-1, mat) + self:SetSubMaterial(k-1, mat) + end + else + vm:SetSubMaterial(k-1, mat) + self:SetSubMaterial(k-1, mat) + end + end + end +end + +function SWEP:ClearSubMaterials() + local ply = self:GetOwner() + local mats = self:GetMaterials() + + if !ply:IsPlayer() then + for i=0,#mats do self:SetSubMaterial(i, nil) end + else + local vm = ply:GetViewModel() + for i=0,#mats do + if IsValid(vm) then vm:SetSubMaterial(i, nil) end + self:SetSubMaterial(i, nil) + end + end end function SWEP:GetNPCBurstSettings() @@ -2432,10 +2299,8 @@ function SWEP:DrawHUD() end function SWEP:PreDrawViewModel(vm, wep, ply) + if game.SinglePlayer() then self:CallOnClient("PreDrawViewModel") end if ply:GetNWBool("Interacting") == true then return true end --- self:DoCustomVMDraw(vm, wep, ply) - - if game.SinglePlayer() then return end -- Find the singleplayer compatible version inside of Think() because why. local ammo = wep:Clip1() local slide = self.PistolSlide @@ -2451,12 +2316,7 @@ function SWEP:PreDrawViewModel(vm, wep, ply) self.ChargeCL = Lerp(FrameTime() * 9, self.ChargeCL or charge, charge) self.HeatCL = Lerp(FrameTime() * 9, self.HeatCL or heat, heat) self.HealthCL = Lerp(FrameTime() * 9, self.HealthCL or health, health) - - if slide <= 0 then - self.EmptyMagCL = Lerp(FrameTime() * 50, self.EmptyMagCL or slide, 0) - else - self.EmptyMagCL = Lerp(FrameTime() * 50, self.EmptyMagCL or slide, 1) - end + self.EmptyMagCL = Lerp(FrameTime() * 15, self.EmptyMagCL or slide, slide) if self.Primary.Ammo != nil && vm:GetPoseParameter("drc_ammo") != nil then vm:SetPoseParameter("drc_ammo", self.AmmoCL / self.Primary.ClipSize) @@ -2523,6 +2383,9 @@ function SWEP:OnReloaded() end function SWEP:OnRestore() + self.BurstQueue = {} + self.MeleeQueue = {} + self.AmmoCheck = 0 self:Initialize() timer.Simple(0.1, function() self:Deploy() end) end @@ -2676,13 +2539,8 @@ if CLIENT or game.SinglePlayer() then self.AmmoCL_TP = Lerp(0.25, self.AmmoCL_TP or ammo, ammo) self.ChargeCL_TP = Lerp(0.25, self.ChargeCL_TP or charge, charge) self.HeatCL_TP = Lerp(0.25, self.HeatCL_TP or heat, heat) - self.HealthCL_TP = Lerp(0.25, self.HealthCL_TP or health, health) - - if slide <= 0 then - self.EmptyMagCL_TP = Lerp(FrameTime() * 50, self.EmptyMagCL_TP or slide, 0) - else - self.EmptyMagCL_TP = Lerp(FrameTime() * 50, self.EmptyMagCL_TP or slide, 1) - end + self.HealthCL_TP = Lerp(0.25, self.HealthCL_TP or health, health) + self.EmptyMagCL_TP = Lerp(FrameTime() * 15, self.EmptyMagCL_TP or slide, slide) if self.Primary.Ammo != nil && self:GetPoseParameter("drc_ammo") != nil then self:SetPoseParameter("drc_ammo", self.AmmoCL_TP / self.Primary.ClipSize) diff --git a/lua/weapons/draconic_battery_base.lua b/lua/weapons/draconic_battery_base.lua index 206f60e..8fcf607 100644 --- a/lua/weapons/draconic_battery_base.lua +++ b/lua/weapons/draconic_battery_base.lua @@ -2,11 +2,10 @@ SWEP.Base = "draconic_gun_base" --[[ I M P O R T A N T -Please, go to the GitHub wiki for this, and not just rip settings from the base as reference. -https://github.com/Vuthakral/Draconic_Base/wiki +Please, go to the wiki for this, and not just rip settings from the base as reference. +http://vuthakral.com/draconic/ It contains all of the settings, explanations on how to use them, tutorials, helpful links, etc. - --]] SWEP.Category = "Draconic" @@ -30,41 +29,7 @@ SWEP.IronSightAng = Vector(0, 0, 0) SWEP.SS = 0 SWEP.BS = 0 -SWEP.InfAmmo = false - -SWEP.HPS = 6 -SWEP.OverHeatFinishPercent = 0.17 -SWEP.DisperseHeatPassively = true -SWEP.HeatLossInterval = 0.1 -SWEP.HeatLossPerInterval = 1 -SWEP.DoOverheatDamage = false -SWEP.OverheatDamagePerInt = 0 -SWEP.OverheatHoldType = "knife" -SWEP.OverheatStrength = 3 -SWEP.VentingHoldType = "slam" -SWEP.VentingStrength = 4 -SWEP.CanOverheat = true -SWEP.CanVent = false -SWEP.LowerRPMWithHeat = true -SWEP.HeatRPMAlterThreshold = 0 -SWEP.HeatRPMAlterThresholdMax = 100 -SWEP.HeatRPMmin = 120 -SWEP.DoOverheatAnimation = true -SWEP.DoVentingAnimation = true -SWEP.DoOverheatSound = true -SWEP.DoVentingSound = true -SWEP.OverheatSound = Sound("draconic.OverheatGeneric") -SWEP.VentingSound = Sound("draconic.VentGeneric") -SWEP.VentingStartSound = Sound("draconic.VentOpenGeneric") -SWEP.VentingStopSound = Sound("draconic.VentCloseGeneric") -SWEP.BatteryConsumePerShot = 0.5 - -SWEP.BatteryFromVec = Vector(255, 255, 255) -SWEP.BatteryToVec = Vector(255, 10, 0) - -SWEP.LoadAfterShot = false -SWEP.LoadAfterReloadEmpty = false -SWEP.ManualReload = false +SWEP.EnableHeat = true SWEP.Primary.IronRecoilMul = 0.5 SWEP.Primary.Spread = 1 @@ -98,12 +63,9 @@ SWEP.Secondary.ClipSize = 18 SWEP.Secondary.DefaultClip = 18 SWEP.Secondary.APS = 1 SWEP.Secondary.Tracer = "Tracer" -SWEP.Primary.EmptySound = Sound("draconic.BatteryDepleted") -SWEP.Secondary.Sound = Sound("") +SWEP.Primary.EmptySound = "draconic.BatteryDepleted" --- Settings for NPCs -SWEP.NPCBurstShots = 0 -SWEP.JackalSniper = false +SWEP.Secondary.Sound = "" -- the DO NOT TOUCH zone SWEP.Primary.Ammo = "ammo_drc_battery" @@ -133,37 +95,38 @@ function SWEP:CanPrimaryAttack() if self:GetNWBool("Overheated") == true then return false end if DRC.SV.drc_infiniteammo < 1 then - if ply:IsPlayer() then - if ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == true && self.InfAmmo == false then - self:Overheat(false, nil, true) - ply:SetFOV(0, 0.05) - return false - elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == false && self.InfAmmo == false then - ply:SetFOV(0, 0.05) - return true - elseif self:GetNWInt("LoadedAmmo") < 0.01 && self.InfAmmo == false then - if CLIENT then self:EmitSound(self.Primary.EmptySound) end - self:SetNextPrimaryFire (( CurTime() + 0.3 )) - return false - elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && eself:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == true && self.InfAmmo == true then - self:Overheat(false, nil, true) - ply:SetFOV(0, 0.05) - return false - elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == false && self.InfAmmo == true then - ply:SetFOV(0, 0.05) - return true - elseif self:GetNWInt("LoadedAmmo") <= 0.01 && self.InfAmmo == true && self.Loading == false && self.ManuallyReloading == false then - self:SetNextPrimaryFire (( CurTime() + 0.3 )) - return true - end - else - local heat = self:GetHeat() - if heat >= 100 then - self:Overheat(false, nil, true) - return false + if ply:IsPlayer() then + -- if self:GetLoadedAmmo() <= 0 then return false end + if ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == true && self.InfAmmo == false then + self:Overheat(false, nil, true) + ply:SetFOV(0, 0.05) + return false + elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == false && self.InfAmmo == false then + ply:SetFOV(0, 0.05) + return true + elseif self:GetLoadedAmmo() <= 0.01 then + if CLIENT then self:EmitSound(self.Primary.EmptySound) end + self:SetNextPrimaryFire (( CurTime() + 0.3 )) + return false + elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == true && self.InfAmmo == true then + self:Overheat(false, nil, true) + ply:SetFOV(0, 0.05) + return false + elseif ply:GetAmmoCount(self.Primary.Ammo) >= 100 && self:GetNWInt("LoadedAmmo") >= 0.01 && self.CanOverheat == false && self.InfAmmo == true then + ply:SetFOV(0, 0.05) + return true + elseif self:GetLoadedAmmo() <= 0.01 && self.Loading == false && self.ManuallyReloading == false then + self:SetNextPrimaryFire (( CurTime() + 0.3 )) + return true + end + else + local heat = self:GetHeat() + if heat >= 100 then + self:Overheat(false, nil, true) + return false + end end end - end if self:GetNWBool("Inspecting") == true then return false @@ -226,8 +189,8 @@ function SWEP:Reload() self:Taunt() elseif walkkey && reloadkey && self.IsTaunting == 1 then self:SetHoldType(self.VentingHoldType) - elseif reloadkey && !sprintkey && self.ManuallyReloading == false && self.CanVent == true && ( self:Clip1() < self.Primary.ClipSize ) then - if ( self:Clip1() < self.Primary.ClipSize ) && self:Ammo1() > 0 then + elseif reloadkey && !sprintkey && self.ManuallyReloading == false && self.CanVent == true && ( self:Clip1() <= self.Primary.ClipSize ) then + if self:Ammo1() > 0 then if self.DoVentingSound == true then local ventstart = self.VentingStartSound self:EmitSound(ventstart) @@ -241,7 +204,6 @@ function SWEP:Reload() self:EmitSound(ventingsound) else end return true - elseif ( self:Clip1() < self.Primary.ClipSize ) && self:Ammo1() > 1 then end elseif reloadkey && sprintkey && self.ManuallyReloading == false && self.Loading == false && ( self:Clip2() < self.Secondary.ClipSize ) && ply:GetAmmoCount(self.Secondary.Ammo) > 0 then if ( ply:GetAmmoCount(self.Secondary.Ammo) ) <= 0 then diff --git a/lua/weapons/draconic_gun_base.lua b/lua/weapons/draconic_gun_base.lua index e3ebd8b..f17f907 100644 --- a/lua/weapons/draconic_gun_base.lua +++ b/lua/weapons/draconic_gun_base.lua @@ -2,8 +2,8 @@ SWEP.Base = "draconic_base" --[[ I M P O R T A N T -Please, go to the GitHub wiki for this, and not just rip settings from the base as reference. -https://github.com/Vuthakral/Draconic_Base/wiki +Please, go to the wiki for this, and not just rip settings from the base as reference. +http://vuthakral.com/draconic/ It contains all of the settings, explanations on how to use them, tutorials, helpful links, etc. @@ -27,16 +27,50 @@ SWEP.HideImpacts = false SWEP.LoadAfterShot = false SWEP.LoadAfterReloadEmpty = false +SWEP.LoadAnimationTP = nil SWEP.ManualReload = false +SWEP.ManualReloadAutoLoop = true SWEP.MagazineEntity = nil +SWEP.FireModes_AnimPreventsFiring = false SWEP.FireModes_CustomScripted = false SWEP.FireModes_CanAuto = true SWEP.FireModes_CanBurst = false SWEP.FireModes_CanSemi = true SWEP.FireModes_BurstShots = 3 +SWEP.EnableHeat = false +SWEP.HPS = 6 +SWEP.DisperseHeatPassively = true +SWEP.HeatLossInterval = 0.1 +SWEP.HeatLossPerInterval = 1 +SWEP.LowerRPMWithHeat = false +SWEP.HeatRPMAlterThreshold = 0 +SWEP.HeatRPMAlterThresholdMax = 100 +SWEP.HeatRPMmin = 120 +SWEP.OverHeatFinishPercent = 0.17 +SWEP.DoOverheatDamage = false +SWEP.OverheatDamagePerInt = 0 +SWEP.OverheatHoldType = "knife" +SWEP.OverheatStrength = 3 +SWEP.VentingHoldType = "slam" +SWEP.VentingStrength = 4 +SWEP.CanOverheat = true +SWEP.CanVent = false +SWEP.DoOverheatAnimation = true +SWEP.DoVentingAnimation = true +SWEP.DoOverheatSound = true +SWEP.DoVentingSound = true +SWEP.OverheatSound = Sound("draconic.OverheatGeneric") +SWEP.VentingSound = Sound("draconic.VentGeneric") +SWEP.VentingStartSound = Sound("draconic.VentOpenGeneric") +SWEP.VentingStopSound = Sound("draconic.VentCloseGeneric") +SWEP.BatteryConsumePerShot = 0.5 + SWEP.Primary.IronRecoilMul = 0.5 +SWEP.Primary.BloomMul = 1 +SWEP.Primary.BloomMulCrouch = 0.5 +SWEP.Primary.BloomMulADS = 1 SWEP.Primary.Spread = 1 SWEP.Primary.SpreadDiv = 128 -- This is a remnant of an older era, and left at 128 to minimize the performance impact of using division on lower-spec CPUs. You can still change it in your weapons, but it's kinda pointless in hindsight. SWEP.Primary.SpreadXMul = 1 @@ -49,6 +83,7 @@ SWEP.Primary.RecoilHoriz = 0 SWEP.Primary.MuzzleAngle = Angle(0, 0, 0) SWEP.Primary.Force = 0 SWEP.Primary.Damage = 1 +SWEP.Primary.DamageNPC = nil SWEP.Primary.Ammo = "replaceme" SWEP.Primary.ReloadHoldType = "ar2" SWEP.Primary.Automatic = true @@ -64,9 +99,10 @@ SWEP.Primary.HealthPerShot = 0 SWEP.Primary.ArmourPerShot = 0 SWEP.Primary.Tracer = 1 -- https://wiki.garrysmod.com/page/Effects SWEP.Primary.TracerEffect = nil -- https://wiki.garrysmod.com/page/Effects -SWEP.Primary.EmptySound = Sound("draconic.EmptyGeneric") +SWEP.Primary.ActOverride = nil +SWEP.Primary.EmptySound = nil SWEP.Primary.SoundIsLooped = false -SWEP.Primary.Sound = Sound("") +SWEP.Primary.Sound = "" SWEP.Primary.DistSound = nil SWEP.Primary.SoundTable = nil SWEP.Primary.SoundDistance = 3500 @@ -121,8 +157,12 @@ SWEP.Secondary.SightsKickMul = 1.0 SWEP.Secondary.ScopePitch = 0 SWEP.Secondary.ScopeYOffset = -1 +SWEP.Secondary.UsesPrimaryMag = false SWEP.Secondary.NumShots = 0 SWEP.Secondary.IronRecoilMul = 0.5 +SWEP.Secondary.BloomMul = 1 +SWEP.Secondary.BloomMulCrouch = 0.5 +SWEP.Secondary.BloomMulADS = 1 SWEP.Secondary.Spread = 3.5 SWEP.Secondary.SpreadDiv = 100 SWEP.Secondary.SpreadXMul = 1 @@ -135,7 +175,8 @@ SWEP.Secondary.RecoilHoriz = 1 SWEP.Secondary.MuzzleAngle = Angle(0, 0, 0) SWEP.Secondary.Force = 0.2 SWEP.Secondary.Damage = 12 -SWEP.Secondary.Ammo = "none" +SWEP.Secondary.DamageNPC = nil +SWEP.Secondary.Ammo = "replaceme" SWEP.Secondary.ReloadHoldType = "ar2" SWEP.Secondary.Automatic = false SWEP.Secondary.AutoReload = true @@ -149,13 +190,18 @@ SWEP.Secondary.APS = 1 SWEP.Secondary.HealthPerShot = 0 SWEP.Secondary.ArmourPerShot = 0 SWEP.Secondary.Tracer = "Tracer" -SWEP.Secondary.Sound = Sound("") +SWEP.Secondary.ActOverride = nil +SWEP.Secondary.EmptySound = nil +SWEP.Secondary.Sound = "" SWEP.Secondary.Projectile = nil SWEP.Secondary.ProjSpeed = 750 SWEP.Secondary.ProjInheritVelocity = true SWEP.Secondary.ProjectileSpawnDelay = 0 +SWEP.OCBloomMul = 1 +SWEP.OCBloomMulCrouch = 0.5 +SWEP.OCBloomMulADS = 1 SWEP.OCSpread = 0 SWEP.OCSpreadDiv = 200 SWEP.OCSpreadXMul = 1 @@ -174,6 +220,7 @@ SWEP.OCHPS = 999 SWEP.OCRPM = 120 SWEP.OCTracer = "4" SWEP.OCTracerEffect = nil +SWEP.OCActOverride = nil SWEP.OCSound = "" SWEP.OCSoundDist = nil SWEP.OCNPCSound = nil @@ -217,9 +264,13 @@ function SWEP:CanSwitchFireModes() end function SWEP:CanPrimaryAttack() + if !IsValid(self) then return end if self.Primary.Disabled == true then return end + if self.Bursting == true then return false end + local ply = self:GetOwner() + if !IsValid(ply) then return end local charge = self:GetCharge() local sk = ply:KeyDown(IN_SPEED) local mk = (ply:KeyDown(IN_MOVELEFT) or ply:KeyDown(IN_MOVERIGHT) or ply:KeyDown(IN_FORWARD) or ply:KeyDown(IN_BACK)) @@ -230,12 +281,24 @@ function SWEP:CanPrimaryAttack() local curFOV = ply:GetFOV() local IronFOV = self.Secondary.IronFOV --- if !game.SinglePlayer() && CurTime() < self:GetNextPrimaryFire() then return end --- if game.SinglePlayer() && SERVER && CurTime() < self:GetNextPrimaryFire() then return end -- ugh +-- if ct < self:GetNextPrimaryFire() then return false end +-- if game.SinglePlayer() && SERVER && ct < self:GetNextPrimaryFire() then return end -- ugh if self:GetLoadedAmmo() <= 0 then if CLIENT then self:StopSound(self.Primary.EmptySound) self:EmitSound(self.Primary.EmptySound) end self:SetNextPrimaryFire(ct + 0.3) + + local sd = self.SightsDown + local emptyseq = self:SelectWeightedSequence(ACT_VM_DRYFIRE) + local adsemptyseq = self:SelectWeightedSequence(ACT_VM_DEPLOYED_IRON_DRYFIRE) + + if sd then + if adsemptyseq != -1 then self:PlayAnim(ACT_VM_DEPLOYED_IRON_DRYFIRE, true) + else self:PlayAnim(ACT_VM_DRYFIRE, true) end + else + self:PlayAnim(ACT_VM_DRYFIRE, true) + end + return false elseif ( self:Clip1() <= 0 ) && self.SecondaryAttacking == false then return true @@ -251,8 +314,8 @@ function SWEP:CanPrimaryAttack() return false end - if self.Loading == true or self.ManuallyReloading == true or self.SecondaryAttacking == true or self:GetNWBool("Passive") == true or self:GetNWBool("Inspecting") == true or ((self.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1) && issprinting) or (self.Primary.CanFireUnderwater == false && wl >= 3) then - if wl >= 3 then self:EmitSound ( "draconic.EmptyGeneric" ) end + if self.Loading == true or self.ManuallyReloading == true or self.SecondaryAttacking == true or self:GetNWBool("Passive") == true or self:GetNWBool("Inspecting") == true or (((self.DoesPassiveSprint == true or DRC.SV.drc_force_sprint == 1) && issprinting && DRC.SV.drc_force_sprint != 2)) or (self.Primary.CanFireUnderwater == false && wl >= 3) then + if wl >= 3 then self:EmitSound(self.Primary.EmptySound) end return false else return true @@ -262,6 +325,7 @@ end function SWEP:CanPrimaryAttackNPC() local npc = self:GetOwner() if self.Bursting == true then return false end + if self.NPCBurstTime >= CurTime() then return false end if self.NPCLoading == true or self.ManuallyReloading == true then return end if self:Clip1() < 1 or self:GetNWInt("LoadedAmmo") < 1 then @@ -282,9 +346,11 @@ local curFOV = ply:GetFOV() local IronFOV = self.Secondary.IronFOV if self.Secondary.Disabled == true then return end + local loaded = self:Clip2() + if self.Secondary.UsesPrimaryMag == true then loaded = self:Clip1() end - if ( self:Clip2() <= 0 ) then - self:EmitSound ( "draconic.EmptyGeneric" ) + if ( loaded <= 0 ) then + if CLIENT then self:StopSound(self.Secondary.EmptySound) self:EmitSound(self.Secondary.EmptySound) end self:SetNextPrimaryFire (( CurTime() + 0.3 )) return false end @@ -324,7 +390,7 @@ function SWEP:PrimaryAttackNPC(fs, ft, fm, dc) if self.FireDelay > CurTime() then return end if self.Owner:IsNPC() or self.Owner:IsNextBot() then - self.FireDelay = (CurTime() + self.PrimaryStarts.PreCalcRPM) + self.FireDelay = (CurTime() + self.PrimaryStats.PreCalcRPM) if !IsValid(self) or !IsValid(self:GetOwner()) then return end if !self:GetOwner():GetEnemy() or !self:CanPrimaryAttackNPC() then return end if !self.Loading then @@ -334,7 +400,7 @@ function SWEP:PrimaryAttackNPC(fs, ft, fm, dc) local rng = math.Rand(1,100) if rng < 50 then self:NPCCharge() - elseif self.NPCCharging == true && ch >= 100 then + elseif self.NPCCharging == true && self:GetCharge() >= 100 then self:NPCCharge() elseif self.NPCCharging == false then self:CallShoot("primary") @@ -358,7 +424,7 @@ function SWEP:DoGunMelee() ["lunge"] = {self.Primary.MeleeIsLunge, self.Primary.MeleeLungeMaxDist, self.Primary.MeleeLungeVelocity}, ["range"] = self.Primary.MeleeRange, ["x"] = {self.Primary.MeleeStartX, self.Primary.MeleeEndX}, - ["y"] = {self.Primary.MeleeStartY, self.Primary.MeleeStartY}, + ["y"] = {self.Primary.MeleeStartY, self.Primary.MeleeEndY}, ["delay"] = { self.Primary.MeleeDelayHit, self.Primary.MeleeDelayMiss, self.Primary.MeleeHitDelay }, -- hit, miss, tick ["screenshake"] = { true, self.Primary.MeleeShakeMul }, -- do shake, shake power ["anim_tp_miss"] = miss_tp, @@ -456,6 +522,7 @@ function SWEP:LoadNextShot() if ply:IsPlayer() && ply:IsValid() && ply:Alive() then if ply:IsPlayer() then self:PlayAnim( ACT_SHOTGUN_PUMP, true ) + if SERVER && self.LoadAnimationTP != nil then DRC:CallGesture(ply, GESTURE_SLOT_CUSTOM, self.LoadAnimationTP) end timer.Simple( loadtime, function() if ply:IsValid() && ply:Alive() then self:FinishLoading() end end) else end end @@ -466,6 +533,7 @@ function SWEP:FinishLoading() end function SWEP:SecondaryAttack() + if game.SinglePlayer() then self:CallOnClient("SecondaryAttack") end local ply = self:GetOwner() local cv = ply:Crouching() local usekey = ply:KeyDown(IN_USE) @@ -509,12 +577,10 @@ end function SWEP:TogglePassive() if !IsFirstTimePredicted() then return end --- if SERVER then self:CallOnClient("TogglePassive") end + if DRC.SV.drc_passives < 1 then return end local ply = self:GetOwner() self:EmitSound(self.FireModes_SwitchSound) - if DRC.SV.drc_passive == 0 then return end - if self:GetNWBool("Passive") == false then self.Passive = true self:DoPassiveHoldtype() @@ -562,19 +628,27 @@ function SWEP:SetFireMode(mode, showhint) if showhint == true then timer.Simple(0.05, function() self:DisplayFireMode() end) end end + local function SwitchAnim(act, fallback) + if act != -1 then self:PlayAnim(act, self.FireModes_AnimPreventsFiring, true) end + if act == -1 && fallback != -1 then self:PlayAnim(fallback, self.FireModes_AnimPreventsFiring, true) end + end + if self.FireModes_CustomScripted == true then if mode == "Semi" then self:SetNWString("FireMode", "Semi") self:SetNWInt("CurFireMode", 1) mode = "Semi" + SwitchAnim(ACT_VM_IFIREMODE, ACT_VM_IFIREMODE) elseif mode == "Auto" then self:SetNWString("FireMode", "Auto") self:SetNWInt("CurFireMode", 2) mode = "Auto" + SwitchAnim(ACT_VM_DFIREMODE, ACT_VM_IFIREMODE) elseif mode == "Burst" then self:SetNWString("FireMode", "Burst") self:SetNWInt("CurFireMode", 3) mode = "Burst" + SwitchAnim(ACT_VM_DIFIREMODE, ACT_VM_IFIREMODE) end self:DoCustomFireMode(mode) end @@ -590,11 +664,13 @@ function SWEP:SetFireMode(mode, showhint) self:SetNWString("FireMode", "Auto") self:SetNWInt("CurFireMode", 2) mode = "Auto" + SwitchAnim(ACT_VM_DFIREMODE, ACT_VM_IFIREMODE) elseif self.FireModes_CanBurst == true then self.Primary.Automatic = false self:SetNWString("FireMode", "Burst") self:SetNWInt("CurFireMode", 3) mode = "Burst" + SwitchAnim(ACT_VM_DIFIREMODE, ACT_VM_IFIREMODE) end elseif fmode == 2 then if self.FireModes_CanBurst == true then @@ -602,11 +678,13 @@ function SWEP:SetFireMode(mode, showhint) self:SetNWString("FireMode", "Burst") self:SetNWInt("CurFireMode", 3) mode = "Burst" + SwitchAnim(ACT_VM_DIFIREMODE, ACT_VM_IFIREMODE) elseif self.FireModes_CanSemi == true then self.Primary.Automatic = false self:SetNWString("FireMode", "Semi") self:SetNWInt("CurFireMode", 1) mode = "Semi" + SwitchAnim(ACT_VM_IFIREMODE, ACT_VM_IFIREMODE) end elseif fmode == 3 then if self.FireModes_CanSemi == true then @@ -614,19 +692,34 @@ function SWEP:SetFireMode(mode, showhint) self:SetNWString("FireMode", "Semi") self:SetNWInt("CurFireMode", 1) mode = "Semi" + SwitchAnim(ACT_VM_IFIREMODE, ACT_VM_IFIREMODE) elseif self.FireModes_CanAuto == true then self.Primary.Automatic = true self:SetNWString("FireMode", "Auto") self:SetNWInt("CurFireMode", 2) mode = "Auto" + SwitchAnim(ACT_VM_DFIREMODE, ACT_VM_IFIREMODE) end end elseif mode == "Semi" then - if self.FireModes_CanSemi == true then self:SetNWString("FireMode", "Semi") self:SetNWInt("CurFireMode", 1) end + if self.FireModes_CanSemi == true then + self:SetNWString("FireMode", "Semi") + self:SetNWInt("CurFireMode", 1) + SwitchAnim(ACT_VM_IFIREMODE, ACT_VM_IFIREMODE) + end elseif mode == "Auto" then - if self.FireModes_CanAuto == true then self.Primary.Automatic = true self:SetNWString("FireMode", "Auto") self:SetNWInt("CurFireMode", 2) end + if self.FireModes_CanAuto == true then + self.Primary.Automatic = true + self:SetNWString("FireMode", "Auto") + self:SetNWInt("CurFireMode", 2) + SwitchAnim(ACT_VM_DFIREMODE, ACT_VM_IFIREMODE) + end elseif mode == "Burst" then - if self.FireModes_CanBurst == true then self:SetNWString("FireMode", "Burst") self:SetNWInt("CurFireMode", 3) end + if self.FireModes_CanBurst == true then + self:SetNWString("FireMode", "Burst") + self:SetNWInt("CurFireMode", 3) + SwitchAnim(ACT_VM_DIFIREMODE, ACT_VM_IFIREMODE) + end end self:DoCustomFireMode(mode) end @@ -801,7 +894,10 @@ function SWEP:DoReload() self:SetIronsights(false) self.SightsDown = false - if SERVER then DRC:CallGesture(ply, GESTURE_SLOT_CUSTOM, self.Primary.ReloadAct) end + if SERVER then + local fallback = DRC:GetHoldTypeAnim(string.lower(self:GetHoldType()), "reload", false) + DRC:CallGesture(ply, GESTURE_SLOT_ATTACK_AND_RELOAD, self.Primary.ReloadAct, true, fallback) + end self:SetIronsights(false, self.Owner) @@ -879,7 +975,8 @@ function SWEP:EndReload() if self:GetNWBool("reloadedEmpty") == true && self.LoadAfterReloadEmpty == true then self:PlayAnim(ACT_SHOTGUN_PUMP, true) - else end + if SERVER && self.LoadAnimationTP != nil then DRC:CallGesture(ply, GESTURE_SLOT_CUSTOM, self.LoadAnimationTP) end + end if ply:GetAmmoCount(self.Primary.Ammo) < CM then self:SetLoadedAmmo(math.Clamp(self:Clip1() + ply:GetAmmoCount(self.Primary.Ammo), 0, CM)) @@ -966,7 +1063,7 @@ function SWEP:ManualReloadLoop() if self:IsValid() && ply:IsValid() && ply:Alive() then if self:Clip1() <= CM then - if ply:KeyDown(IN_RELOAD) && self:Clip1() < CM then + if (ply:KeyDown(IN_RELOAD) or self.ManualReloadAutoLoop == true) && self:Clip1() < CM then if ( ply:GetAmmoCount(self.Primary.Ammo) ) > 0 then self:DoManualReload(true) else @@ -981,22 +1078,24 @@ end function SWEP:FinishManualReload() local ply = self:GetOwner() - local loopseq = self:SelectWeightedSequence( ACT_SHOTGUN_RELOAD_FINISH ) - local looptime = self:SequenceDuration( loopseq ) + local endseq = self:SelectWeightedSequence(ACT_SHOTGUN_RELOAD_FINISH) + local endtime = self:SequenceDuration(endseq) + + if CLIENT then + local vm = ply:GetViewModel() + endseq = vm:SelectWeightedSequence(ACT_SHOTGUN_RELOAD_FINISH) + endtime = vm:SequenceDuration(endseq) + end + if self:IsValid() && ply:IsValid() && ply:Alive() then + self.Loading = true self:SetHoldType(self.HoldType) - -- self.IdleTimer = CurTime() + looptime - self:PlayAnim(ACT_SHOTGUN_RELOAD_FINISH, true) - -- self:SendWeaponAnim(ACT_SHOTGUN_RELOAD_FINISH) - - -- self:SetNextPrimaryFire( CurTime() + looptime) - -- self:SetNextSecondaryFire( CurTime() + looptime) + self:PlayAnim(ACT_SHOTGUN_RELOAD_FINISH, true, true) self.EndingManualReload = true - - timer.Simple( looptime, function() + timer.Simple(endtime, function() if IsValid(self) then self.ManuallyReloading = false - self.Loading = false + self:FinishLoading() self.IronCD = false self:ManuallyLoadAfterReload() end @@ -1011,17 +1110,14 @@ function SWEP:ManuallyLoadAfterReload() if IsFirstTimePredicted() then local loadseq = self:SelectWeightedSequence( ACT_SHOTGUN_PUMP ) local loadtime = self:SequenceDuration( loadseq ) - -- self:SetNextPrimaryFire( CurTime() + loadtime) - -- self:SetNextSecondaryFire( CurTime() + loadtime) self.Loading = true self:DoCustomManualLoadEvents() self:SetCycle(0) self:SetPlaybackRate(1) self:PlayAnim(ACT_SHOTGUN_PUMP, true) - timer.Simple(loadtime, function() - self.Loading = false - end) + if SERVER && self.LoadAnimationTP != nil then DRC:CallGesture(ply, GESTURE_SLOT_CUSTOM, self.LoadAnimationTP) end + timer.Simple(loadtime, function() self:FinishLoading() end) self:SetNWBool("NPCLoading", false) end else end @@ -1043,8 +1139,8 @@ function SWEP:GetShootPos() local attnum = self:LookupAttachment("muzzle") local attinfo = self:GetAttachment(attnum) - if attinfo == nil then - MsgC(Color(255, 0, 0), "Draconic: ".. self:GetModel() .." / ".. self.ViewModel .." does not have a muzzle attachment!") + if attinfo == nil then + DRC:Notify(self, nil, "critical", "Draconic: ".. self:GetModel() .." OR ".. self.ViewModel .." does not have a muzzle attachment!", NOTIFY_ERROR, 10) attinfo = { ["Pos"] = self:GetPos(), ["Ang"] = Angle() @@ -1124,30 +1220,25 @@ end function SWEP:NPC_ServerNextFire() -- VJ local ply = self:GetOwner() --- if !ply.IsVJBaseSNPC then return end --- if CLIENT or (!IsValid(self) or !IsValid(ply) or !ply:IsNPC()) then return end --- if self.NPCBursting == true then return end --- if ply:GetActiveWeapon() != self then return end + if ply:IsPlayer() then return end local enemy if ply.GetEnemy then enemy = ply:GetEnemy() end - --- if ply:GetActivity() == nil then return end - --- if enemy == nil then return end if IsValid(enemy) && self.ignorepcs[enemy:GetClass()] then ply:SetEnemy(nil, true) end --- if IsValid(enemy) && ply:GetEnemyLastTimeSeen(enemy) > CurTime() then return end -- if IsValid(enemy) && !ply:IsLineOfSightClear(enemy:GetPos()) then return end --- if IsValid(enemy) then + if IsValid(enemy) && self:CanPrimaryAttackNPC() then self:PrimaryAttack() --- end + end end -function SWEP:NPCAbleToShoot() -- VJ... --- if self:CanPrimaryAttackNPC() then return true end - return true +function SWEP:NPCAbleToShoot() -- VJ + local enemy + if ply.GetEnemy then enemy = ply:GetEnemy() end + if IsValid(enemy) && !ply:IsLineOfSightClear(enemy:GetPos()) then return end + + if self:CanPrimaryAttackNPC() then return true else return false end end function SWEP:NPC_Reload() -- Still VJ. diff --git a/lua/weapons/draconic_melee_base.lua b/lua/weapons/draconic_melee_base.lua index a82b3dc..b5ed34b 100644 --- a/lua/weapons/draconic_melee_base.lua +++ b/lua/weapons/draconic_melee_base.lua @@ -45,10 +45,11 @@ SWEP.Primary.Range = 20 SWEP.Primary.Force = 5 SWEP.Primary.DelayMiss = 0.42 SWEP.Primary.DelayHit = 0.54 -SWEP.Primary.CanAttackCrouched = false +SWEP.Primary.CanAttackCrouched = true SWEP.Primary.HitActivity = nil SWEP.Primary.CrouchHitActivity = nil SWEP.Primary.MissActivity = ACT_VM_PRIMARYATTACK +SWEP.Primary.MissActivity_TP = nil SWEP.Primary.CrouchMissActivity = nil SWEP.Primary.HitDelay = 0.07 SWEP.Primary.StartX = 20 @@ -57,34 +58,35 @@ SWEP.Primary.EndX = -20 SWEP.Primary.EndY = -10 SWEP.Primary.ShakeMul = 1 -SWEP.Primary.CanLunge = false -SWEP.Primary.LungeAutomatic = false -SWEP.Primary.LungeRequiresTarget= true -SWEP.Primary.LungeVelocity = 1000 -SWEP.Primary.LungeMaxDist = 250 -SWEP.Primary.LungeSwingSound = nil -SWEP.Primary.LungeHitSoundWorld = nil -SWEP.Primary.LungeHitSoundFlesh = nil -SWEP.Primary.LungeHitSoundEnt = nil -SWEP.Primary.LungeHitSound = "hl2meleehard" -SWEP.Primary.LungeImpactDecal = "" -SWEP.Primary.LungeBurnDecal = "" -SWEP.Primary.LungeHitAct = nil -SWEP.Primary.LungeHitActCrouch = nil -SWEP.Primary.LungeMissAct = ACT_VM_PRIMARYATTACK -SWEP.Primary.LungeMissActCrouch = nil -SWEP.Primary.LungeDelayMiss = 1.3 -SWEP.Primary.LungeDelayHit = 0.7 -SWEP.Primary.LungeHitDelay = 0.26 -SWEP.Primary.LungeDamage = 0 -SWEP.Primary.LungeDamageType = DMG_SLASH -SWEP.Primary.LungeRange = 25 -SWEP.Primary.LungeForce = 20 -SWEP.Primary.LungeStartX = 7 -SWEP.Primary.LungeStartY = -3 -SWEP.Primary.LungeEndX = -7 -SWEP.Primary.LungeEndY = 3 -SWEP.Primary.LungeShakeMul = 1 +SWEP.Primary.CanLunge = false +SWEP.Primary.LungeAutomatic = false +SWEP.Primary.LungeRequiresTarget = true +SWEP.Primary.LungeVelocity = 1000 +SWEP.Primary.LungeMaxDist = 250 +SWEP.Primary.LungeSwingSound = nil +SWEP.Primary.LungeHitSoundWorld = nil +SWEP.Primary.LungeHitSoundFlesh = nil +SWEP.Primary.LungeHitSoundEnt = nil +SWEP.Primary.LungeHitSound = "hl2meleehard" +SWEP.Primary.LungeImpactDecal = "" +SWEP.Primary.LungeBurnDecal = "" +SWEP.Primary.LungeHitAct = nil +SWEP.Primary.LungeHitActCrouch = nil +SWEP.Primary.LungeMissAct = ACT_VM_PRIMARYATTACK +SWEP.Primary.LungeMissActivity_TP = nil +SWEP.Primary.LungeMissActCrouch = nil +SWEP.Primary.LungeDelayMiss = 1.3 +SWEP.Primary.LungeDelayHit = 0.7 +SWEP.Primary.LungeHitDelay = 0.26 +SWEP.Primary.LungeDamage = 0 +SWEP.Primary.LungeDamageType = DMG_SLASH +SWEP.Primary.LungeRange = 25 +SWEP.Primary.LungeForce = 20 +SWEP.Primary.LungeStartX = 7 +SWEP.Primary.LungeStartY = -3 +SWEP.Primary.LungeEndX = -7 +SWEP.Primary.LungeEndY = 3 +SWEP.Primary.LungeShakeMul = 1 SWEP.Secondary.SwingSound = Sound( "" ) SWEP.Secondary.HitSoundWorld = nil @@ -106,6 +108,7 @@ SWEP.Secondary.CanAttackCrouched = true SWEP.Secondary.HitActivity = nil SWEP.Secondary.CrouchHitActivity = nil SWEP.Secondary.MissActivity = ACT_VM_MISSCENTER +SWEP.Secondary.MissActivity_TP = nil SWEP.Secondary.CrouchMissActivity = nil SWEP.Secondary.Velocity = Vector(0, 0, 0) SWEP.Secondary.HitDelay = 0.07 @@ -579,7 +582,6 @@ end function SWEP:TogglePassive() local ply = self:GetOwner() - self:EmitSound(self.FireModes_SwitchSound) if GetConVar("sv_drc_passives"):GetString() == "0" then return end @@ -598,7 +600,6 @@ function SWEP:TogglePassive() else self.Loading = true self.Idle = 0 - -- self:SendWeaponAnim( ACT_VM_DRAW ) self:SetHoldType(self.HoldType) self.Passive = false self:SetNWBool("Passive", false) diff --git a/lua/weapons/drc_cubemap.lua b/lua/weapons/drc_cubemap.lua index eb3b901..06b96f4 100644 --- a/lua/weapons/drc_cubemap.lua +++ b/lua/weapons/drc_cubemap.lua @@ -1,4 +1,4 @@ -SWEP.Base = "draconic_melee_base" +SWEP.Base = "draconic_gun_base" SWEP.HoldType = "normal" SWEP.CrouchHoldType = "normal" @@ -27,6 +27,7 @@ SWEP.VMPos = Vector(0, 0, 0) SWEP.VMAng = Vector(0, 0, 0) SWEP.VMPosCrouch = Vector(0, 0, 0) SWEP.VMAngCrouch = Vector(0, 0, 0) +SWEP.IronSightsPos = Vector(10, -25, -7) SWEP.SS = 0 SWEP.BS = 0 SWEP.NearWallPower = 0 @@ -34,7 +35,10 @@ SWEP.RollingPower = 0 SWEP.PerspectivePower = 0 SWEP.Primary.Disabled = true -SWEP.Secondary.Disabled = true +SWEP.Secondary.Disabled = false + +SWEP.Secondary.Ironsights = true +SWEP.Secondary.IronFOV = 90 function SWEP:DoCustomDeploy() local ply = self:GetOwner() @@ -73,11 +77,13 @@ function SWEP:DoCustomRemove() end function SWEP:DrawCustomCrosshairElements() - draw.DrawText( "Standard Cubemap", "TargetID", ScrW() * 0.25, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) - draw.DrawText( "Basic Proxy Cubemap", "TargetID", ScrW() * 0.5, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) - draw.DrawText( "Proxy Cubemap w/ Animated Normal", "TargetID", ScrW() * 0.75, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) - - draw.DrawText( "Basic Proxy Cubemap on Complex Model", "TargetID", ScrW() * 0.25, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) - draw.DrawText( "Colour-tinted Proxy Cubemap", "TargetID", ScrW() * 0.5, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) - draw.DrawText( "Normal mapped & Alpha Masked Proxy Cubemap", "TargetID", ScrW() * 0.75, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) + if self.SightsDown == false then + draw.DrawText( "Standard Cubemap", "TargetID", ScrW() * 0.25, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) + draw.DrawText( "Basic Proxy Cubemap", "TargetID", ScrW() * 0.5, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) + draw.DrawText( "Proxy Cubemap w/ Animated Normal", "TargetID", ScrW() * 0.75, ScrH() * 0.37, color_white, TEXT_ALIGN_CENTER ) + + draw.DrawText( "Basic Proxy Cubemap on Complex Model", "TargetID", ScrW() * 0.25, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) + draw.DrawText( "Colour-tinted Proxy Cubemap", "TargetID", ScrW() * 0.5, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) + draw.DrawText( "Normal mapped & Alpha Masked Proxy Cubemap", "TargetID", ScrW() * 0.75, ScrH() * 0.6, color_white, TEXT_ALIGN_CENTER ) + end end \ No newline at end of file diff --git a/lua/weapons/drc_cubemap2.lua b/lua/weapons/drc_cubemap2.lua deleted file mode 100644 index 1002b7a..0000000 --- a/lua/weapons/drc_cubemap2.lua +++ /dev/null @@ -1,37 +0,0 @@ -SWEP.Base = "draconic_melee_base" - -SWEP.HoldType = "normal" -SWEP.CrouchHoldType = "normal" -SWEP.Category = "Draconic" -SWEP.PrintName = "Cubemap Tester FP" -SWEP.InfoName = "Cubemap" - -SWEP.Purpose = "Viewming the current cubemap from a first-person perspective" -SWEP.Instructions = "Cry when you realize how many people don't know how to set up envmaps." - -SWEP.Spawnable = false -SWEP.AdminSpawnable = false -SWEP.NPCSpawnable = false -SWEP.CanStore = false - -SWEP.DrawCrosshair = false -SWEP.Slot = 2 -SWEP.SlotPos = 0 - -SWEP.UseHands = false -SWEP.DoesPassiveSprint = false -SWEP.ViewModel = "models/shadertest/envballs.mdl" -SWEP.WorldModel = "" -SWEP.ViewModelFOV = 54 -SWEP.VMPos = Vector(10, -25, -7) -SWEP.VMAng = Vector(0, 0, 0) -SWEP.VMPosCrouch = Vector(0, 0, 0) -SWEP.VMAngCrouch = Vector(0, 0, 0) -SWEP.SS = 0 -SWEP.BS = 0 -SWEP.NearWallPower = 0 -SWEP.RollingPower = 0 -SWEP.PerspectivePower = 0 - -SWEP.Primary.Disabled = true -SWEP.Secondary.Disabled = true \ No newline at end of file diff --git a/lua/weapons/drc_shieldgun.lua b/lua/weapons/drc_shieldgun.lua index 27040b1..9f31732 100644 --- a/lua/weapons/drc_shieldgun.lua +++ b/lua/weapons/drc_shieldgun.lua @@ -33,7 +33,7 @@ SWEP.Primary.Disabled = true SWEP.Secondary.Disabled = true local shieldtable = { - ["Regenerating"] = true, + ["Regenerating"] = false, ["RegenDelay"] = 5, ["RegenAmount"] = 33, ["Health"] = 100, diff --git a/lua/weapons/gmod_tool/stools/drc_colour.lua b/lua/weapons/gmod_tool/stools/drc_colour.lua index da81894..4a6c3eb 100644 --- a/lua/weapons/gmod_tool/stools/drc_colour.lua +++ b/lua/weapons/gmod_tool/stools/drc_colour.lua @@ -117,8 +117,6 @@ function TOOL:LeftClick( trace ) local ac2col = Vector(r,g,b) SetColour( self:GetOwner(), ent, {ac2col, "accent2"}) - print(self:GetClientNumber("grunge")) - SetColour( self:GetOwner(), ent, {math.Clamp(self:GetClientNumber( "grunge", 0 ), 0, 100), "grunge"}) return true diff --git a/materials/entities/drc_plate_battery.png b/materials/entities/drc_plate_battery.png new file mode 100644 index 0000000..b6d044c Binary files /dev/null and b/materials/entities/drc_plate_battery.png differ diff --git a/materials/entities/drc_plate_boolet.png b/materials/entities/drc_plate_boolet.png new file mode 100644 index 0000000..b6d044c Binary files /dev/null and b/materials/entities/drc_plate_boolet.png differ diff --git a/materials/entities/drc_plate_universal.png b/materials/entities/drc_plate_universal.png new file mode 100644 index 0000000..b6d044c Binary files /dev/null and b/materials/entities/drc_plate_universal.png differ diff --git a/materials/entities/drc_station_battery.png b/materials/entities/drc_station_battery.png new file mode 100644 index 0000000..e342fb7 Binary files /dev/null and b/materials/entities/drc_station_battery.png differ diff --git a/materials/entities/drc_station_boolet.png b/materials/entities/drc_station_boolet.png new file mode 100644 index 0000000..8e2b4b6 Binary files /dev/null and b/materials/entities/drc_station_boolet.png differ diff --git a/materials/entities/drc_station_universal.png b/materials/entities/drc_station_universal.png new file mode 100644 index 0000000..3691f45 Binary files /dev/null and b/materials/entities/drc_station_universal.png differ diff --git a/materials/models/vuthakral/fullbright.vmt b/materials/models/vuthakral/fullbright.vmt new file mode 100644 index 0000000..9e725bb --- /dev/null +++ b/materials/models/vuthakral/fullbright.vmt @@ -0,0 +1,4 @@ +"UnlitGeneric" +{ + $basetexture "models\vuthakral\white-100" +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaderexamples/Aftershock.vmt b/materials/models/vuthakral/shaderexamples/Aftershock.vmt new file mode 100644 index 0000000..e7e1007 --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/Aftershock.vmt @@ -0,0 +1,15 @@ +Aftershock +{ + $normalmap "models/shadertest/shader1_normal" + + $colortint "[ 1 1 1 ]" + + $SilhouetteColor "[ 1 1 1 ]" + $SilhouetteThickness 1 + + $GroundMin -3 + $GroundMax 3 + + $refractamount 2 + $bluramount 0 +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaderexamples/Cloud.vmt b/materials/models/vuthakral/shaderexamples/Cloud.vmt new file mode 100644 index 0000000..652609f --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/Cloud.vmt @@ -0,0 +1,17 @@ +Cloud // This does not work when used traditionally. Probably requires a special context. +{ + $basetexture "shadertest/cloud" + $cloudalphatexture "shadertest/cloudalpha" + $cloudscale "[ 2.00 2.00 2.00 ]" + $maskscale "[ 1.00 1.00 1.00 ]" + %tooltexture "shadertest/cloudalpha" + Proxies + { + TextureScroll + { + texturescrollvar $baseTextureTransform + texturescrollrate 0.01 + texturescrollangle 0.00 + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaderexamples/Modulate.vmt b/materials/models/vuthakral/shaderexamples/Modulate.vmt new file mode 100644 index 0000000..3c599bf --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/Modulate.vmt @@ -0,0 +1,8 @@ +Modulate +{ + $basetexture "models\vuthakral\white-100" + + $mod2x 0 + $nocull 0 + $color2 "[ 1 0 0 ]" +} diff --git a/materials/models/vuthakral/shaderexamples/Refract.vmt b/materials/models/vuthakral/shaderexamples/Refract.vmt new file mode 100644 index 0000000..d63459a --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/Refract.vmt @@ -0,0 +1,32 @@ +Refract +{ + $model 1 + $nowritez 0 + $forcealphawrite 1 + + $basetexture "models/shadertest/shader5" + $normalmap "models/shadertest/shader5_normal" + $normalmap2 "rubber_bump" + + $refracttint "[ 2 2 2 ]" + $refracttinttexture "models/shadertest/shader5" + $refractamount 0.2 + $bluramount 1 + $fadeoutonsilhouette 0 + + $envmap env_cubemap + $envmapsaturation 1 + $envmapcontrast 1 + + $localrefract 1 + $localrefractdepth 10 + + $bumpframe 0 + $bumpframe2 0 + $refracttinttextureframe 0 + + Proxies + { + drc_ReflectionTint{} + } +} diff --git a/materials/models/vuthakral/shaderexamples/SSAO.vmt b/materials/models/vuthakral/shaderexamples/SSAO.vmt new file mode 100644 index 0000000..a988ea7 --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/SSAO.vmt @@ -0,0 +1,16 @@ +SSAO // Not supported by Garry's Mod, throwing it in here in hopes that one day it may. +{ + $depth_texture "_rt_SSAO_depth" + $fog_factor 1.5 + $fow 0 + $intensity 1 + $normal_texture "_rt_deferred_normal" + $radius 105 + $random_texture "dev\ssao_random" + $specular_texture "_rt_deferred_specular" + + $final 0 + $bias 0.3 + $strength 0.45 + $tint "[ 0 0 0 1 ]" +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaderexamples/SolidEnergy.vmt b/materials/models/vuthakral/shaderexamples/SolidEnergy.vmt new file mode 100644 index 0000000..3fc6ed0 --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/SolidEnergy.vmt @@ -0,0 +1,98 @@ +SolidEnergy +{ + $basetexture "effects/projected_wall" + + $detail "effects/projected_wall_draw" + $detailscale 1 + $detailblendmode 1 + + $detail2 "effects/projected_wall_noise" + $detail2scale 1 + $detail2blendmode 0 + + $surfaceprop glass + "%keywords" Portal2 + $translucent 1 + $additive 1 + $vertexalpha 0 + $vertexcolor 0 + $nocull 1 + $detailscroll1 "[0 0]" + $detailscroll2 "[0 0]" + $detail2componentscale "[1 1]" + $basescroll "[0 0]" + $basescale "[1 1]" + + "!srgb?$outputintensity" .75 + + Proxies + { + Sine + { + sinemin 0 + sinemax 0.94 + sineperiod 5 + timeoffset 3 + resultVar "$detailscroll1[0]" + } + + LinearRamp + { + rate -3 + initialValue 0 + resultVar "$detailscroll1[1]" + } + + LinearRamp + { + rate 0.18 + initialValue 0 + resultVar "$detailscroll2[1]" + } + + Sine + { + sinemin 0.99 + sinemax 1.01 + sineperiod 0.125 + timeoffset 0 + resultVar "$detail2componentscale[0]" + } + + Sine + { + sinemin 0.995 + sinemax 1.005 + sineperiod 0.1 + timeoffset 0.05 + resultVar "$basescale[0]" + } + + LinearRamp + { + rate 0.15 + initialValue 0 + resultVar "$basescroll[1]" + } + + TextureTransform + { + translateVar $detailscroll1 + resultVar $detail1texturetransform + } + + TextureTransform + { + translateVar $detailscroll2 + scaleVar $detail2componentscale + resultVar $detail2texturetransform + } + + TextureTransform + { + translateVar $basescroll + scaleVar $basescale + resultVar $basetexturetransform + } + } +} diff --git a/materials/models/vuthakral/shaderexamples/VolumeClouds.vmt b/materials/models/vuthakral/shaderexamples/VolumeClouds.vmt new file mode 100644 index 0000000..0b370a8 --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/VolumeClouds.vmt @@ -0,0 +1,18 @@ +VolumeClouds +{ + $basetexture "shadertest\cloud" + $basetexture2 "shadertest\cloud" + $basetexture3 "shadertest\cloud" + +// $basetexturespeed 1 +// $basetexture2speed 1 +// $basetexture3speed 1 + + Proxies + { + CurrentTime + { + resultVar $Time + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaderexamples/VortWarp.vmt b/materials/models/vuthakral/shaderexamples/VortWarp.vmt new file mode 100644 index 0000000..a7277fa --- /dev/null +++ b/materials/models/vuthakral/shaderexamples/VortWarp.vmt @@ -0,0 +1,31 @@ +VortWarp +{ + $basetexture "models\vuthakral\grey127-100" + $bumpmap "models\vuthakral/flatnormal-100" + $color2 "[ 0 0 0 ]" + + $flowmap "models\vuthakral\shield_flow" + $selfillummap "models\vuthakral\shield_arcs" + $selfillumtint " [0 10 10 ]" + + $entityorigin "" + $warpparam 0 + + "Proxies" + { + + "EntityOrigin" + { + } + "MaterialModify" + { + } + Sine + { + sinemin 0.05 + sinemax 0.2 + sineperiod 3 + resultVar $warpparam + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaders/Fake_JellyFish.vmt b/materials/models/vuthakral/shaders/Fake_JellyFish.vmt new file mode 100644 index 0000000..64f06c3 --- /dev/null +++ b/materials/models/vuthakral/shaders/Fake_JellyFish.vmt @@ -0,0 +1,57 @@ +VertexLitGeneric +{ + $basetexture "shadertest\cloud" + $bumpmap "dev\water_normal" + $color2 "[ 1 1 1 ]" + $additive 1 + $nocull 1 + $selfillum 0 + + $emissiveBlendEnabled 1 + $emissiveBlendTexture "models\vuthakral\shield_arcs" + $emissiveBlendBaseTexture "shadertest\cloud" + $emissiveBlendFlowTexture "models\vuthakral\shield_flow" + $emissiveBlendTint "[ 0 38 63 ]" + $emissiveBlendStrength 1 + $emissiveBlendScrollVector "[ 0.005 0.005 ]" + + $fleshinteriorenabled 1 + $fleshdebugforcefleshon 1 + $fleshinteriortexture "shadertest\cloud" + $fleshinteriornoisetexture "models\vuthakral\shield_arcs" + $fleshbordertexture1d "models\alyx\alyx_flesh_border" + $fleshnormaltexture "shadertest\gooinglass_normal" + $fleshsubsurfacetexture "shadertest\cloud" + $fleshglobalopacity 0.5 + $fleshsubsurfacetint "[ 0 100 500 ]" + $fleshscrollspeed 5 + $fleshbordernoisescale 2 + $fleshborderwidth 0.5 + $fleshbordersoftness 0.5 + $fleshbordertint "[ 0.3 1 -1 ]" + $fleshcubetexture "env_cubemap" + $fleshglossbrightness 15 + + $normalmapalphaenvmapmask 1 + $phong 1 + $phongboost 5 + $phongexponent 18 + $phongfresnelranges "[ .03 3 1 ]" + $phongtint "[ 0 8 .8 ]" + + "Proxies" + { + TextureScroll + { + textureScrollVar $basetexturetransform + textureScrollRate 0.01 + textureScrollAngle 90 + } + AnimatedTexture + { + "animatedtexturevar" "$bumpmap" + "animatedtextureframenumvar" "$bumpframe" + "animatedtextureframerate" 5.00 + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaders/Fake_JellyFish_Interior.vmt b/materials/models/vuthakral/shaders/Fake_JellyFish_Interior.vmt new file mode 100644 index 0000000..2281b25 --- /dev/null +++ b/materials/models/vuthakral/shaders/Fake_JellyFish_Interior.vmt @@ -0,0 +1,63 @@ +VertexLitGeneric +{ + $basetexture "shadertest\cloud" + $bumpmap "dev\water_normal" + $color2 "[ 1 1 1 ]" + $additive 1 + $nocull 1 + $selfillum 1 + + $emissiveBlendEnabled 1 + $emissiveBlendTexture "models\vuthakral\shield_arcs" + $emissiveBlendBaseTexture "shadertest/cloud" + $emissiveBlendFlowTexture "models\vuthakral\shield_flow" + $emissiveBlendTint "[ 3 8 5 ]" + $emissiveBlendStrength 1 + $emissiveBlendScrollVector "[ 0.05 0.05 ]" + + $fleshinteriorenabled 1 + $fleshdebugforcefleshon 1 + $fleshinteriortexture "shadertest\cloud" + $fleshinteriornoisetexture "models\vuthakral\shield_arcs" + $fleshbordertexture1d "models\alyx\alyx_flesh_border" + $fleshnormaltexture "dev\water_normal" + $fleshsubsurfacetexture "shadertest\cloud" + $fleshglobalopacity 0.5 + $fleshsubsurfacetint "[ 1 1000 1000 ]" + $fleshscrollspeed 10 + $fleshbordernoisescale 6 + $fleshborderwidth 0.6 + $fleshbordersoftness 0.5 + $fleshbordertint "[ 0 50 0 ]" + $fleshcubetexture "env_cubemap" + $fleshglossbrightness 15 + + $cloakpassenabled 1 + $cloakfactor 0.255 + $cloakcolortint "[ 0 2 1 ]" + $refractamount 0.3 + + $normalmapalphaenvmapmask 1 + $phong 1 + $phongboost 5 + $phongexponent 18 + $phongfresnelranges "[ .03 3 1 ]" + $phongtint "[ 0 8 .8 ]" + + "Proxies" + { + TextureScroll + { + textureScrollVar $basetexturetransform + textureScrollRate 0.01 + textureScrollAngle 90 + } + + AnimatedTexture + { + "animatedtexturevar" "$bumpmap" + "animatedtextureframenumvar" "$bumpframe" + "animatedtextureframerate" 5 + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaders/cube.vmt b/materials/models/vuthakral/shaders/cube.vmt new file mode 100644 index 0000000..67b22a2 --- /dev/null +++ b/materials/models/vuthakral/shaders/cube.vmt @@ -0,0 +1,4 @@ +VertexLitGeneric +{ + $basetexture "shadertest/envmap" +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaders/glowie.vmt b/materials/models/vuthakral/shaders/glowie.vmt new file mode 100644 index 0000000..677ea9b --- /dev/null +++ b/materials/models/vuthakral/shaders/glowie.vmt @@ -0,0 +1,62 @@ +VertexLitGeneric +{ + $basetexture "shadertest\cloud" + $bumpmap "dev\water_normal" + $color2 "[ 1 1 1 ]" + $additive 0 + $nocull 1 + + $emissiveBlendEnabled 1 + $emissiveBlendTexture "models\vuthakral\shield_arcs" + $emissiveBlendBaseTexture "shadertest\cloud" + $emissiveBlendFlowTexture "models\vuthakral\shield_flow" + $emissiveBlendTint "[ 0 68 0 ]" + $emissiveBlendStrength 1 + $emissiveBlendScrollVector "[ 0.05 0.05 ]" + + $fleshinteriorenabled 1 + $fleshdebugforcefleshon 1 + $fleshinteriortexture "shadertest\cloud" + $fleshinteriornoisetexture "models\vuthakral\shield_arcs" + $fleshbordertexture1d "models\alyx\alyx_flesh_border" + $fleshnormaltexture "shadertest\gooinglass_normal" + $fleshsubsurfacetexture "shadertest\cloud" + $fleshglobalopacity 0.5 + $fleshsubsurfacetint "[ 0 500 100 ]" + $fleshscrollspeed 5 + $fleshbordernoisescale 2 + $fleshborderwidth 0.5 + $fleshbordersoftness 0.5 + $fleshbordertint "[ 0.3 1 -1 ]" + $fleshcubetexture "env_cubemap" + $fleshglossbrightness 15 + + $cloakpassenabled 1 + $cloakfactor 0.9 + $cloakcolortint "[ 0 2 1 ]" + $refractamount 1 + + $normalmapalphaenvmapmask 1 + $phong 1 + $phongboost 5 + $phongexponent 18 + $phongfresnelranges "[ .03 3 1 ]" + $phongtint "[ 0 8 .8 ]" + + "Proxies" + { + TextureScroll + { + textureScrollVar $basetexturetransform + textureScrollRate 0.01 + textureScrollAngle 90 + } + + AnimatedTexture + { + "animatedtexturevar" "$bumpmap" + "animatedtextureframenumvar" "$bumpframe" + "animatedtextureframerate" 60.00 + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/shaders/holotest.vmt b/materials/models/vuthakral/shaders/holotest.vmt new file mode 100644 index 0000000..2f83786 --- /dev/null +++ b/materials/models/vuthakral/shaders/holotest.vmt @@ -0,0 +1,18 @@ +VolumeClouds +{ //models/vortigaunt/vortigaunt_blue + $basetexture "models/vuthakral/holotest" + $basetexture2 "models/vuthakral/holotest" + $basetexture3 "models/vuthakral/holotest" + + $BaseTextureSpeed 0 + $BaseTexture2Speed 0 + $BaseTexture3Speed 0 + + Proxies + { + CurrentTime + { + resultVar $Time + } + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_0.vmt b/materials/models/vuthakral/weaponskin_0.vmt new file mode 100644 index 0000000..65ac04e --- /dev/null +++ b/materials/models/vuthakral/weaponskin_0.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 1 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_1.vmt b/materials/models/vuthakral/weaponskin_1.vmt new file mode 100644 index 0000000..e43a601 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_1.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 2 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_10.vmt b/materials/models/vuthakral/weaponskin_10.vmt new file mode 100644 index 0000000..5c8c1ad --- /dev/null +++ b/materials/models/vuthakral/weaponskin_10.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 11 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_11.vmt b/materials/models/vuthakral/weaponskin_11.vmt new file mode 100644 index 0000000..132a70b --- /dev/null +++ b/materials/models/vuthakral/weaponskin_11.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 12 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_12.vmt b/materials/models/vuthakral/weaponskin_12.vmt new file mode 100644 index 0000000..62db2d9 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_12.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 13 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_13.vmt b/materials/models/vuthakral/weaponskin_13.vmt new file mode 100644 index 0000000..4ed91c2 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_13.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 14 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_14.vmt b/materials/models/vuthakral/weaponskin_14.vmt new file mode 100644 index 0000000..b139a62 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_14.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 15 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_15.vmt b/materials/models/vuthakral/weaponskin_15.vmt new file mode 100644 index 0000000..2281d77 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_15.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 16 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_2.vmt b/materials/models/vuthakral/weaponskin_2.vmt new file mode 100644 index 0000000..7ca9979 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_2.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 3 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_3.vmt b/materials/models/vuthakral/weaponskin_3.vmt new file mode 100644 index 0000000..69f31e0 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_3.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 4 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_4.vmt b/materials/models/vuthakral/weaponskin_4.vmt new file mode 100644 index 0000000..0b5592f --- /dev/null +++ b/materials/models/vuthakral/weaponskin_4.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 5 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_5.vmt b/materials/models/vuthakral/weaponskin_5.vmt new file mode 100644 index 0000000..98a8adb --- /dev/null +++ b/materials/models/vuthakral/weaponskin_5.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 6 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_6.vmt b/materials/models/vuthakral/weaponskin_6.vmt new file mode 100644 index 0000000..36bb19e --- /dev/null +++ b/materials/models/vuthakral/weaponskin_6.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 7 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_7.vmt b/materials/models/vuthakral/weaponskin_7.vmt new file mode 100644 index 0000000..375ba48 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_7.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 8 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_8.vmt b/materials/models/vuthakral/weaponskin_8.vmt new file mode 100644 index 0000000..f38b550 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_8.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 9 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/materials/models/vuthakral/weaponskin_9.vmt b/materials/models/vuthakral/weaponskin_9.vmt new file mode 100644 index 0000000..3527547 --- /dev/null +++ b/materials/models/vuthakral/weaponskin_9.vmt @@ -0,0 +1,19 @@ +"VertexLitGeneric" +{ + $basetexture "models\vuthakral\black-100" + $bumpmap "models\vuthakral\flatnormal-50" + + $phong 1 + $phongboost 1 + $phongexponent 1 + $phongfresnelranges "[ 1 1 1 ]" + + $slotnum 10 + + Proxies + { + drc_WeaponCamo{} + drc_ReflectionTint{} + drc_ScalingRimLight{} + } +} \ No newline at end of file diff --git a/sound/draconic/NOW.ogg b/sound/draconic/NOW.ogg new file mode 100644 index 0000000..fa5004a Binary files /dev/null and b/sound/draconic/NOW.ogg differ diff --git a/sound/draconic/foley/generic0.wav b/sound/draconic/foley/generic0.wav new file mode 100644 index 0000000..f42596f Binary files /dev/null and b/sound/draconic/foley/generic0.wav differ diff --git a/sound/draconic/foley/generic1.wav b/sound/draconic/foley/generic1.wav new file mode 100644 index 0000000..29eb1e5 Binary files /dev/null and b/sound/draconic/foley/generic1.wav differ diff --git a/sound/draconic/foley/generic2.wav b/sound/draconic/foley/generic2.wav new file mode 100644 index 0000000..6e2ba01 Binary files /dev/null and b/sound/draconic/foley/generic2.wav differ diff --git a/sound/draconic/foley/generic3.wav b/sound/draconic/foley/generic3.wav new file mode 100644 index 0000000..b539277 Binary files /dev/null and b/sound/draconic/foley/generic3.wav differ diff --git a/sound/draconic/foley/generic4.wav b/sound/draconic/foley/generic4.wav new file mode 100644 index 0000000..4f46854 Binary files /dev/null and b/sound/draconic/foley/generic4.wav differ diff --git a/sound/draconic/foley/generic5.wav b/sound/draconic/foley/generic5.wav new file mode 100644 index 0000000..8dd8495 Binary files /dev/null and b/sound/draconic/foley/generic5.wav differ diff --git a/sound/draconic/foley/generic6.wav b/sound/draconic/foley/generic6.wav new file mode 100644 index 0000000..0a0d897 Binary files /dev/null and b/sound/draconic/foley/generic6.wav differ diff --git a/sound/draconic/foley/generic7.wav b/sound/draconic/foley/generic7.wav new file mode 100644 index 0000000..6aef586 Binary files /dev/null and b/sound/draconic/foley/generic7.wav differ diff --git a/sound/draconic/foley/generic8.wav b/sound/draconic/foley/generic8.wav new file mode 100644 index 0000000..853e761 Binary files /dev/null and b/sound/draconic/foley/generic8.wav differ diff --git a/sound/draconic/foley/generic9.wav b/sound/draconic/foley/generic9.wav new file mode 100644 index 0000000..142a737 Binary files /dev/null and b/sound/draconic/foley/generic9.wav differ diff --git a/sound/draconic/oof.ogg b/sound/draconic/oof.ogg index 500dfe0..4a6326b 100644 Binary files a/sound/draconic/oof.ogg and b/sound/draconic/oof.ogg differ diff --git a/sound/draconic/ui/click0.wav b/sound/draconic/ui/click0.wav new file mode 100644 index 0000000..0249e6d Binary files /dev/null and b/sound/draconic/ui/click0.wav differ diff --git a/sound/draconic/ui/deny0.wav b/sound/draconic/ui/deny0.wav new file mode 100644 index 0000000..6b4f1d3 Binary files /dev/null and b/sound/draconic/ui/deny0.wav differ diff --git a/sound/draconic/ui/deny1.wav b/sound/draconic/ui/deny1.wav new file mode 100644 index 0000000..693ed4d Binary files /dev/null and b/sound/draconic/ui/deny1.wav differ diff --git a/sound/draconic/weapons/dry_battery.wav b/sound/draconic/weapons/dry_battery.wav new file mode 100644 index 0000000..d65cb5f Binary files /dev/null and b/sound/draconic/weapons/dry_battery.wav differ diff --git a/sound/draconic/weapons/dry_heavy.wav b/sound/draconic/weapons/dry_heavy.wav new file mode 100644 index 0000000..2443adc Binary files /dev/null and b/sound/draconic/weapons/dry_heavy.wav differ diff --git a/sound/draconic/weapons/dry_pistol.wav b/sound/draconic/weapons/dry_pistol.wav new file mode 100644 index 0000000..237e665 Binary files /dev/null and b/sound/draconic/weapons/dry_pistol.wav differ