diff --git a/.github/workflows/GLuaFixer.yml b/.github/workflows/GLuaFixer.yml deleted file mode 100644 index 65211a71..00000000 --- a/.github/workflows/GLuaFixer.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: GLuaFixer - -on: - push: - paths: - - 'lua/**' - pull_request: - paths: - - 'lua/**' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Download GLuaFixer 1.17.2 - run: curl -o glualint.zip -L https://github.com/FPtje/GLuaFixer/releases/download/1.17.2/glualint-1.17.2-linux.zip - - name: Extract glualint.zip - run: unzip glualint.zip - - name: Initiate linting - run: ./glualint lua diff --git a/.github/workflows/GLuaLint.yml b/.github/workflows/GLuaLint.yml new file mode 100644 index 00000000..03eb1fd3 --- /dev/null +++ b/.github/workflows/GLuaLint.yml @@ -0,0 +1,15 @@ +name: GLuaLint + +on: + push: + paths: + - 'lua/**' + pull_request: + paths: + - 'lua/**' + +jobs: + Lint: + uses: FPtje/GLuaFixer/.github/workflows/glualint.yml@master + with: + config: "./.glualint.json" diff --git a/README.md b/README.md index 6f7c5f7f..e02cec4f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Armored Combat Framework 3: Missiles -[![Linter Status](https://img.shields.io/github/actions/workflow/status/TwistedTail/ACF-3-Missiles/GLuaFixer.yml?label=Linter%20Status&style=flat-square)](https://github.com/TwistedTail/ACF-3-Missiles/actions?query=workflow%3AGLuaFixer) +[![Linter Status](https://img.shields.io/github/actions/workflow/status/TwistedTail/ACF-3-Missiles/GLuaLint.yml?label=Linter%20Status&style=flat-square)](https://github.com/TwistedTail/ACF-3-Missiles/actions?query=workflow%3AGLuaLint) [![Repository Size](https://img.shields.io/github/repo-size/TwistedTail/ACF-3-Missiles?label=Repository%20Size&style=flat-square)](https://github.com/TwistedTail/ACF-3-Missiles) [![Commit Activity](https://img.shields.io/github/commit-activity/m/TwistedTail/ACF-3-Missiles?label=Commit%20Activity&style=flat-square)](https://github.com/TwistedTail/ACF-3-Missiles/commits/master) diff --git a/lua/acf/core/acfm_globals.lua b/lua/acf/core/acfm_globals.lua index a07e69ee..f257451c 100644 --- a/lua/acf/core/acfm_globals.lua +++ b/lua/acf/core/acfm_globals.lua @@ -14,10 +14,6 @@ game.AddParticles("particles/flares_fx.pcf") PrecacheParticleSystem("ACFM_Flare") -if SERVER then - resource.AddWorkshop("403587498") -end - do -- Update checker hook.Add("ACF_OnLoadAddon", "ACF Missiles Update Checker", function() ACF.AddRepository("TwistedTail", "ACF-3-Missiles", "lua/acf/core/acfm_globals.lua") diff --git a/lua/acf/core/classes/missiles/ammoBlacklist.lua b/lua/acf/core/classes/missiles/ammo_blacklist.lua similarity index 100% rename from lua/acf/core/classes/missiles/ammoBlacklist.lua rename to lua/acf/core/classes/missiles/ammo_blacklist.lua diff --git a/lua/acf/core/utilities/entityTracking_sv.lua b/lua/acf/core/utilities/entity_tracking_sv.lua similarity index 98% rename from lua/acf/core/utilities/entityTracking_sv.lua rename to lua/acf/core/utilities/entity_tracking_sv.lua index 5f5918b9..b23ad43f 100644 --- a/lua/acf/core/utilities/entityTracking_sv.lua +++ b/lua/acf/core/utilities/entity_tracking_sv.lua @@ -4,7 +4,7 @@ local NextUpdate = 0 local Entities = {} local Ancestors = {} -local Whitelist = { +local Whitelist = { -- Garry's Mod entities gmod_wheel = true, gmod_hoverball = true, @@ -50,6 +50,8 @@ local function GetAncestor(Entity) end local function UpdateValues(Entity) + if not IsValid(Entity) then return end + local PhysObj = Entity:GetPhysicsObject() local Velocity = Entity:GetVelocity() local PrevPos = Entity.Position diff --git a/lua/acf/core/utilities/missileHelpers.lua b/lua/acf/core/utilities/missile_helpers.lua similarity index 100% rename from lua/acf/core/utilities/missileHelpers.lua rename to lua/acf/core/utilities/missile_helpers.lua diff --git a/lua/acf/core/utilities/missileHelpers_sv.lua b/lua/acf/core/utilities/missile_helpers_sv.lua similarity index 100% rename from lua/acf/core/utilities/missileHelpers_sv.lua rename to lua/acf/core/utilities/missile_helpers_sv.lua diff --git a/lua/acf/core/utilities/missileLights_cl.lua b/lua/acf/core/utilities/missile_lights_cl.lua similarity index 100% rename from lua/acf/core/utilities/missileLights_cl.lua rename to lua/acf/core/utilities/missile_lights_cl.lua diff --git a/lua/acf/entities/components/computers.lua b/lua/acf/entities/components/computers.lua index d8ad7f28..ffdc0ce5 100644 --- a/lua/acf/entities/components/computers.lua +++ b/lua/acf/entities/components/computers.lua @@ -141,12 +141,16 @@ do -- Joystick Entity.Spread = 1 - math.Round(Entity.ACF.Health / Entity.ACF.MaxHealth, 2) end, OnEnabled = function(Entity) - if Entity.Inputs.InputPitch.Path then - Entity:TriggerInput("Pitch", Entity.Inputs.InputPitch.Value) + local Inputs = Entity.Inputs + local Pitch = Inputs.InputPitch + local Yaw = Inputs.InputYaw + + if Pitch and Pitch.Path then + Entity:TriggerInput("Pitch", Pitch.Value) end - if Entity.Inputs.InputYaw.Path then - Entity:TriggerInput("Yaw", Entity.Inputs.InputYaw.Value) + if Yaw and Yaw.Path then + Entity:TriggerInput("Yaw", Yaw.Value) end end, OnDisabled = function(Entity) @@ -381,12 +385,16 @@ do -- Optical guidance computer Entity.Spread = 1 - math.Round(Entity.ACF.Health / Entity.ACF.MaxHealth, 2) end, OnEnabled = function(Entity) - if Entity.Inputs.InputPitch.Path then - Entity:TriggerInput("Pitch", Entity.Inputs.InputPitch.Value) + local Inputs = Entity.Inputs + local Pitch = Inputs.InputPitch + local Yaw = Inputs.InputYaw + + if Pitch and Pitch.Path then + Entity:TriggerInput("Pitch", Pitch.Value) end - if Entity.Inputs.InputYaw.Path then - Entity:TriggerInput("Yaw", Entity.Inputs.InputYaw.Value) + if Yaw and Yaw.Path then + Entity:TriggerInput("Yaw", Yaw.Value) end end, OnDisabled = function(Entity) @@ -502,6 +510,7 @@ do -- Laser guidance computer OnUpdate = function(Entity, _, _, Computer) Entity.IsComputer = true Entity.Lasing = false + Entity.Offset = Computer.Offset Entity.OnCooldown = false Entity.HitPos = Vector() Entity.Distance = 0 @@ -591,16 +600,21 @@ do -- Laser guidance computer Entity.Spread = 1 - math.Round(Entity.ACF.Health / Entity.ACF.MaxHealth, 2) end, OnEnabled = function(Entity) - if Entity.Inputs.Lase.Path then - Entity:TriggerInput("Lase", Entity.Inputs.Lase.Value) + local Inputs = Entity.Inputs + local Lase = Inputs.Lase + local Pitch = Inputs.InputPitch + local Yaw = Inputs.InputYaw + + if Lase and Lase.Path then + Entity:TriggerInput("Lase", Lase.Value) end - if Entity.Inputs.InputPitch.Path then - Entity:TriggerInput("Pitch", Entity.Inputs.InputPitch.Value) + if Pitch and Pitch.Path then + Entity:TriggerInput("Pitch", Pitch.Value) end - if Entity.Inputs.InputYaw.Path then - Entity:TriggerInput("Yaw", Entity.Inputs.InputYaw.Value) + if Yaw and Yaw.Path then + Entity:TriggerInput("Yaw", Yaw.Value) end end, OnDisabled = function(Entity) @@ -771,8 +785,10 @@ do -- GPS transmitter Entity.Spread = ACF.MaxDamageInaccuracy * (1 - math.Round(Entity.ACF.Health / Entity.ACF.MaxHealth, 2)) end, OnEnabled = function(Entity) - if Entity.Inputs.Coordinates.Path then - Entity:TriggerInput("Coordinates", Entity.Inputs.Coordinates.Value) + local Coordinates = Entity.Inputs.Coordinates + + if Coordinates and Coordinates.Path then + Entity:TriggerInput("Coordinates", Coordinates.Value) end end, OnDisabled = function(Entity) diff --git a/lua/acf/entities/missiles/asm.lua b/lua/acf/entities/missiles/asm.lua index 4e0bc404..7f09098e 100644 --- a/lua/acf/entities/missiles/asm.lua +++ b/lua/acf/entities/missiles/asm.lua @@ -107,7 +107,7 @@ Missiles.RegisterItem("AGM-114 ASM", "ATGM", { Year = 1984, ReloadTime = 30, ExhaustPos = Vector(-29), - Racks = { ["1xRK"] = true, ["2x AGM-114"] = true, ["4x AGM-114"] = true }, + Racks = { ["1xRK"] = true, ["1xRK_small"] = true, ["2x AGM-114"] = true, ["4x AGM-114"] = true }, Guidance = { Dumb = true, Laser = true }, Navigation = "PN", Fuzes = { Contact = true }, @@ -276,7 +276,7 @@ Missiles.RegisterItem("AT-2 ASM", "ATGM", { Navigation = "Chase", Fuzes = { Contact = true }, ViewCone = 90, - Agility = 0.00008, + Agility = 0.00035, ArmDelay = 0.1, Round = { Model = "models/missiles/at2.mdl", diff --git a/lua/acf/entities/missiles/ffar.lua b/lua/acf/entities/missiles/ffar.lua index 1f09fedb..8a99b5a4 100644 --- a/lua/acf/entities/missiles/ffar.lua +++ b/lua/acf/entities/missiles/ffar.lua @@ -36,10 +36,10 @@ Missiles.RegisterItem("40mmFFAR", "FFAR", { FuelConsumption = 0.015, -- in g/s/f StarterPercent = 0.1, MaxAgilitySpeed = 1, -- in m/s - DragCoef = 0.0005, - FinMul = 0.01, + DragCoef = 0.004, + FinMul = 0, GLimit = 1, - TailFinMul = 0.004, + TailFinMul = 0.05, PenMul = 0.91, ActualLength = 60, ActualWidth = 4 @@ -73,14 +73,14 @@ Missiles.RegisterItem("57mmFFAR", "FFAR", { Armor = 2, ProjLength = 35, PropLength = 50, - Thrust = 210000, -- in kg*in/s^2 - FuelConsumption = 0.015, + Thrust = 113000, -- in kg*in/s^2 + FuelConsumption = 0.0095, -- S5 rocket motors burn for 1.1 seconds not 0.333 StarterPercent = 0.2, MaxAgilitySpeed = 1, - DragCoef = 0.0007, - FinMul = 0.01, + DragCoef = 0.007, + FinMul = 0.003, GLimit = 1, - TailFinMul = 0.003, + TailFinMul = 0.005, PenMul = 1.3, ActualLength = 85, ActualWidth = 5.7, @@ -114,14 +114,14 @@ Missiles.RegisterItem("70mmFFAR", "FFAR", { Armor = 2, ProjLength = 66, PropLength = 40, - Thrust = 850000, -- in kg*in/s^2 + Thrust = 128500, -- in kg*in/s^2 -- Why was old thrust 1565m/s FuelConsumption = 0.005, -- in g/s/f StarterPercent = 0.1, MaxAgilitySpeed = 1, -- in m/s - DragCoef = 0.002, - FinMul = 0.01, + DragCoef = 0.004, + FinMul = 0, GLimit = 1, - TailFinMul = 0.005, + TailFinMul = 0.04, PenMul = 0.85, ActualLength = 106, ActualWidth = 7 @@ -155,14 +155,14 @@ Missiles.RegisterItem("80mmFFAR", "FFAR", { Armor = 2, ProjLength = 76, PropLength = 51, - Thrust = 700000, -- in kg*in/s^2 - FuelConsumption = 0.006, -- in g/s/f - StarterPercent = 0.1, + Thrust = 290000, -- in kg*in/s^2 + FuelConsumption = 0.0044, -- in g/s/f -- 1.55 not 0.53 + StarterPercent = 0.191, MaxAgilitySpeed = 1, -- in m/s - DragCoef = 0.0023, - FinMul = 0.01, + DragCoef = 0.023, + FinMul = 0.003, GLimit = 1, - TailFinMul = 0.005, + TailFinMul = 0.08, PenMul = 0.85, ActualLength = 127, ActualWidth = 8 @@ -181,7 +181,7 @@ Missiles.RegisterItem("Zuni ASR", "FFAR", { Mass = 45, Length = 200, Year = 1957, - ReloadTime = 10, + ReloadTime = 5, ExhaustPos = Vector(-45), Racks = { ["127mm4xPOD"] = true }, Guidance = { Dumb = true }, @@ -196,14 +196,14 @@ Missiles.RegisterItem("Zuni ASR", "FFAR", { Armor = 2, ProjLength = 90, PropLength = 110, - Thrust = 1900000, -- in kg*in/s^2 - FuelConsumption = 0.010, -- in g/s/f - StarterPercent = 0.1, + Thrust = 663000, -- in kg*in/s^2 + FuelConsumption = 0.0098, -- in g/s/f + StarterPercent = 0.235, MaxAgilitySpeed = 1, -- in m/s - DragCoef = 0.004, - FinMul = 0.005, + DragCoef = 0.002, + FinMul = 0.002, GLimit = 1, - TailFinMul = 0.004, + TailFinMul = 0.08, PenMul = 1, ActualLength = 200, ActualWidth = 12.7 diff --git a/lua/acf/entities/missiles/uar.lua b/lua/acf/entities/missiles/uar.lua index bd9329e2..34a3c2a5 100644 --- a/lua/acf/entities/missiles/uar.lua +++ b/lua/acf/entities/missiles/uar.lua @@ -51,9 +51,9 @@ Missiles.RegisterItem("RS82 ASR", "UAR", { StarterPercent = 0.15, MaxAgilitySpeed = 1, -- in m/s DragCoef = 0.001, - FinMul = 0.01, + FinMul = 0, GLimit = 1, - TailFinMul = 0.05, + TailFinMul = 0.4, PenMul = 0.8, CanDelayLaunch = true, ActualLength = 60, @@ -93,10 +93,10 @@ Missiles.RegisterItem("HVAR ASR", "UAR", { FuelConsumption = 0.016, -- in g/s/f StarterPercent = 0.15, MaxAgilitySpeed = 1, -- in m/s - DragCoef = 0.005, - FinMul = 0.01, + DragCoef = 0.019, + FinMul = 0, GLimit = 1, - TailFinMul = 0.075, + TailFinMul = 0.844, PenMul = 1.148, FillerMul = 1, LinerMassMul = 1, @@ -125,7 +125,7 @@ Missiles.RegisterItem("SPG-9 ASR", "UAR", { Navigation = "Chase", Fuzes = { Contact = true }, Agility = 1, - ArmDelay = 0.1, + ArmDelay = 0, -- :) Round = { Model = "models/missiles/rs82.mdl", RackModel = "models/missiles/rs82.mdl", @@ -135,12 +135,12 @@ Missiles.RegisterItem("SPG-9 ASR", "UAR", { PropLength = 67.8, Thrust = 180000, -- in kg*in/s^2 FuelConsumption = 0.03, -- in g/s/f - StarterPercent = 0.1, + StarterPercent = 0.4, MaxAgilitySpeed = 1, -- in m/s DragCoef = 0.002, - FinMul = 0.01, + FinMul = 0, GLimit = 1, - TailFinMul = 0.023, + TailFinMul = 0.06, PenMul = 2.273, FillerMul = 1.06, LinerMassMul = 2.8, @@ -182,7 +182,7 @@ Missiles.RegisterItem("S-24 ASR", "UAR", { StarterPercent = 0.15, MaxAgilitySpeed = 1, -- in m/s DragCoef = 0.01, - FinMul = 0.1, + FinMul = 0, GLimit = 1, TailFinMul = 0.3, PenMul = 1.05, @@ -210,7 +210,7 @@ Missiles.RegisterItem("RW61 ASR", "UAR", { Navigation = "Chase", Fuzes = { Contact = true, Optical = true }, Agility = 1, - ArmDelay = 0.5, + ArmDelay = 0.2, Round = { Model = "models/missiles/RW61M.mdl", RackModel = "models/missiles/RW61M.mdl", @@ -225,7 +225,7 @@ Missiles.RegisterItem("RW61 ASR", "UAR", { DragCoef = 0.02, FinMul = 0, GLimit = 1, - TailFinMul = 10, + TailFinMul = 38.25, PenMul = 1.2, ActualLength = 150, ActualWidth = 38 diff --git a/lua/acf/entities/sensors/radarMenu_cl.lua b/lua/acf/entities/sensors/radar_menu_cl.lua similarity index 100% rename from lua/acf/entities/sensors/radarMenu_cl.lua rename to lua/acf/entities/sensors/radar_menu_cl.lua diff --git a/lua/acf/entities/sensors/receiver_menu_cl.lua b/lua/acf/entities/sensors/receiver_menu_cl.lua new file mode 100644 index 00000000..8b6c541d --- /dev/null +++ b/lua/acf/entities/sensors/receiver_menu_cl.lua @@ -0,0 +1,9 @@ +local ACF = ACF +local Text = "Mass : %s kg\n" + +function ACF.CreateReceiverMenu(Data, Menu) + + Menu:AddLabel(Text:format(Data.Mass)) + + ACF.SetClientData("PrimaryClass", "acf_receiver") +end diff --git a/lua/acf/entities/sensors/receivers/receivers.lua b/lua/acf/entities/sensors/receivers/receivers.lua new file mode 100644 index 00000000..7cd4dbb0 --- /dev/null +++ b/lua/acf/entities/sensors/receivers/receivers.lua @@ -0,0 +1,139 @@ +local ACF = ACF +local Sensors = ACF.Classes.Sensors +local TraceLine = util.TraceLine + +Sensors.Register("WARN-Receiver", { + Name = "Warning Receiver", + Entity = "acf_receiver", + CreateMenu = ACF.CreateReceiverMenu, + LimitConVar = { + Name = "_acf_receiver", + Amount = 4, + Text = "Maximum amount of ACF receivers a player can create." + }, +}) + +do -- Laser Receiver + local function ReceiveSource(Receiver) + local Lasers = {} + + local ReceiverOrigin = Receiver:LocalToWorld(Receiver.Origin) + + for k,v in pairs(ACF.ActiveLasers) do + local Dir = k.Dir or k:GetForward() + if v.Distance > 0 then Dir = (v.HitPos - v.Origin):GetNormalized() end + + if Dir:Dot((ReceiverOrigin - v.Origin):GetNormalized()) >= Receiver.Cone then Lasers[k] = true end + end + + -- Wiremod laser pointer, because it's, you know, a laser + for _,ply in pairs(player.GetAll()) do + local Wep = ply:GetWeapon("laserpointer") + if not IsValid(Wep) then continue end + + if Wep.Pointing then + local Las = {Dir = ply:EyeAngles():Forward(),Position = ply:EyePos(),Player = ply} + + if Las.Dir:Dot((ReceiverOrigin - Las.Position):GetNormalized()) >= Receiver.Cone then Lasers[Las] = true end + end + end + + return Lasers + end + + local TraceData = { start = true, endpos = true, mask = MASK_SOLID } + local function CheckLOS(Receiver, Source, Start, End) + TraceData.start = Start + TraceData.endpos = End + if IsValid(Source.Player) then + TraceData.filter = {Receiver,Source.Player} + else TraceData.filter = {Receiver,Source} end + + return not TraceLine(TraceData).Hit + end + + Sensors.RegisterItem("LAS-Receiver", "WARN-Receiver", { + Name = "Laser Warning Receiver", + Description = "An optical unit designed to detect laser sources and give a precise direction.", + Model = "models/bluemetaknight/laser_detector.mdl", + + Mass = 25, + Health = 10, + Armor = 10, + Offset = Vector(0,0,3), + + ThinkDelay = 0.25, + Divisor = 2.5, -- Divisor (pre-floor) and then multiplier to give a choppy angle + Cone = math.cos(2.5 / 90), + + Detect = ReceiveSource, + CheckLOS = CheckLOS, + + Preview = { + FOV = 145, + }, + }) +end + +do -- Radar Receiver + + -- ACF.ActiveRadars for radars, need to check for direction and range for these + local ValidMissileRadars = { + ["Active Radar"] = true + } + + local function ReceiveSource(Receiver) + local RadarSource = {} + + local ReceiverOrigin = Receiver:LocalToWorld(Receiver.Origin) + + for k in pairs(ACF.ActiveRadars) do -- Radar entities + if k.EntType ~= "Targeting Radar" then continue end + local RadarOrigin = k:LocalToWorld(k.Origin) + + if k.Range then -- Spherical + if RadarOrigin:DistToSqr(ReceiverOrigin) <= (k.Range ^ 2) then RadarSource[k] = true end + else -- Directional + if ACFM_ConeContainsPos(RadarOrigin, k:GetForward(), k.ConeDegs, ReceiverOrigin) then RadarSource[k] = true end + end + end + + for k in pairs(ACF.ActiveMissiles) do -- Missile entities + if not k.UseGuidance then continue end -- Don't waste time on missiles that don't have functional guidance + if not ValidMissileRadars[k.Guidance] then continue end -- Further filter for anything without radar on the missile itself + + if ACFM_ConeContainsPos(k.Position, k:GetForward(), k.ViewCone, ReceiverOrigin) then RadarSource[k] = true end + end + + return RadarSource + end + + local TraceData = { start = true, endpos = true, mask = MASK_SOLID_BRUSHONLY } + local function CheckLOS(_, _, Start, End) + TraceData.start = Start + TraceData.endpos = End + + return not TraceLine(TraceData).Hit + end + + Sensors.RegisterItem("RAD-Receiver", "WARN-Receiver", { + Name = "Radar Warning Receiver", + Description = "An unit designed to detect radar sources and give a vague direction.", + Model = "models/jaanus/wiretool/wiretool_siren.mdl", + + Mass = 25, + Health = 10, + Armor = 10, + Offset = Vector(0,0,6), + + ThinkDelay = 0.5, + Divisor = 30, -- Divisor (pre-floor) and then multiplier to give a choppy angle + + Detect = ReceiveSource, + CheckLOS = CheckLOS, + + Preview = { + FOV = 145, + }, + }) +end diff --git a/lua/acf/entities/weapons/flareLauncher.lua b/lua/acf/entities/weapons/flare_launcher.lua similarity index 100% rename from lua/acf/entities/weapons/flareLauncher.lua rename to lua/acf/entities/weapons/flare_launcher.lua diff --git a/lua/acf/missiles/acfm_roundinject.lua b/lua/acf/missiles/acfm_roundinject.lua index 0803d393..a29d75fe 100644 --- a/lua/acf/missiles/acfm_roundinject.lua +++ b/lua/acf/missiles/acfm_roundinject.lua @@ -227,6 +227,7 @@ else Guidance:Configure(Entity) Fuze:Configure(Entity) + Entity.Guidance = Data.Guidance Entity.IsMissileAmmo = true Entity.GuidanceData = Guidance Entity.FuzeData = Fuze diff --git a/lua/entities/acf_computer/init.lua b/lua/entities/acf_computer/init.lua index af162913..b8e892bf 100644 --- a/lua/entities/acf_computer/init.lua +++ b/lua/entities/acf_computer/init.lua @@ -67,7 +67,7 @@ end) -- Local Funcs and Vars --===============================================================================================-- -local CheckLegal = ACF_CheckLegal +local CheckLegal = ACF.CheckLegal local UnlinkSound = "physics/metal/metal_box_impact_bullet%s.wav" local MaxDistance = ACF.LinkDistance * ACF.LinkDistance local HookRun = hook.Run diff --git a/lua/entities/acf_glatgm/init.lua b/lua/entities/acf_glatgm/init.lua index 6d028979..60459ece 100644 --- a/lua/entities/acf_glatgm/init.lua +++ b/lua/entities/acf_glatgm/init.lua @@ -3,6 +3,7 @@ AddCSLuaFile("shared.lua") include("shared.lua") +local hook = hook local ACF = ACF local Missiles = ACF.ActiveMissiles local Ballistics = ACF.Ballistics @@ -14,14 +15,24 @@ local ZERO = Vector() local function CheckViewCone(Missile, HitPos) local Position = Missile.Position - local Forward = Missile:GetForward() + local Forward = Missile.Velocity:GetNormalized() local Direction = (HitPos - Position):GetNormalized() return Direction:Dot(Forward) >= Missile.ViewCone end +local function ClampAngle(Object, Limit) + local Pitch, Yaw, Roll = Object:Unpack() + + return Angle( + math.Clamp(Pitch, -Limit, Limit), + math.Clamp(Yaw, -Limit, Limit), + math.Clamp(Roll, -Limit, Limit) + ) +end + local function DetonateMissile(Missile, Inflictor) - if HookRun("ACF_AmmoExplode", Missile, Missile.BulletData) == false then return end + if hook.Run("ACF_AmmoExplode", Missile, Missile.BulletData) == false then return end if IsValid(Inflictor) and Inflictor:IsPlayer() then Missile.Inflictor = Inflictor @@ -83,10 +94,11 @@ function MakeACF_GLATGM(Gun, BulletData) Entity.AccelLength = math.Round(math.Clamp(BulletData.ProjMass / BulletData.PropMass + BulletData.Caliber / 7, 0.2, 10), 2) Entity.AccelTime = Entity.LastThink + Entity.AccelLength Entity.Speed = Entity.LaunchVel - Entity.SpiralRadius = Entity.IsSubcaliber and 3.5 or nil - Entity.SpiralSpeed = Entity.IsSubcaliber and 15 or nil + Entity.SpiralRadius = Entity.IsSubcaliber and 120 / Caliber or nil + Entity.SpiralSpeed = Entity.IsSubcaliber and 360 / Entity.AccelLength or nil Entity.SpiralAngle = Entity.IsSubcaliber and 0 or nil Entity.Position = BulletData.Pos + Entity.Velocity = BulletData.Flight:GetNormalized() * Entity.LaunchVel Entity.Innacuracy = 0 Entity.Filter[#Entity.Filter + 1] = Entity @@ -183,25 +195,6 @@ function ENT:GetComputer() return Computer end -local function ClampAng(Ang, Min, Max) - local Pitch, Yaw, Roll = Ang:Unpack() - - return Angle( - math.Clamp(Pitch, Min, Max), - math.Clamp(Yaw, Min, Max), - math.Clamp(Roll, Min, Max) - ) -end - -local function ClampVec(Vec, VMin, VMax) - - return Vector( - math.Clamp(Vec[1], VMin[1], VMax[1]), - math.Clamp(Vec[2], VMin[2], VMax[2]), - math.Clamp(Vec[3], VMin[3], VMax[3]) - ) -end - function ENT:Think() if self.Detonated then return end @@ -211,58 +204,53 @@ function ENT:Think() return self:Detonate() end - local IsGuided, Direction, Correction - local DeltaTime = Clock.CurTime - self.LastThink - local IsDelayed = self.GuideDelay > Time + local DeltaTime = Time - self.LastThink + local CanGuide = self.GuideDelay <= Time local Computer = self:GetComputer() local CanSee = IsValid(Computer) and CheckViewCone(self, Computer.HitPos) local Position = self.Position + local NextDir, NextAng self.Speed = self.LaunchVel + self.DiffVel * math.Clamp(1 - (self.AccelTime - Time) / self.AccelLength, 0, 1) - if not IsDelayed and CanSee then - local Agility = self.Agility * DeltaTime - local AgilityVector = Vector(self.Speed, Agility, Agility) - local ComputerCorrection = Computer:WorldToLocal(Position) - local Desired = AngleRand() * 0.005 - - ComputerCorrection = Computer:LocalToWorld(Vector(ComputerCorrection.X + self.Speed * 0.27)) - Correction = ClampVec(self:WorldToLocal(ComputerCorrection), -AgilityVector, AgilityVector) - - if math.abs(Correction.y) + math.abs(Correction.z) >= 0.2 then - Desired = self:WorldToLocalAngles((ComputerCorrection - Position):Angle()) + Desired - else - Desired = self:WorldToLocalAngles(Computer.TraceDir:Angle()) + Desired - end + if CanGuide and CanSee then + local Origin = Computer:LocalToWorld(Computer.Offset) + local Distance = Origin:Distance(Position) + self.Speed * 0.15 + local Target = Origin + Computer.TraceDir * Distance + local Expected = (Target - Position):GetNormalized():Angle() + local Current = self.Velocity:GetNormalized():Angle() + local _, LocalAng = WorldToLocal(Target, Expected, Position, Current) + local Clamped = ClampAngle(LocalAng, self.Agility * DeltaTime) + local _, WorldAng = LocalToWorld(Vector(), Clamped, Position, Current) - Direction = ClampAng(Desired, -Agility, Agility) - IsGuided = true + NextAng = WorldAng + NextDir = WorldAng:Forward() self.Innacuracy = 0 - end - - if not IsGuided then - local Innacuracy = self.Innacuracy * DeltaTime + else + local Spread = self.Innacuracy * DeltaTime * 0.005 + local Added = VectorRand() * Spread - Direction = AngleRand() * 0.0002 * Innacuracy - Correction = VectorRand() * 0.0007 * Innacuracy + NextDir = (self.Velocity:GetNormalized() + Added):GetNormalized() + NextAng = NextDir:Angle() - self.Innacuracy = self.Innacuracy + 100 * DeltaTime + self.Innacuracy = self.Innacuracy + DeltaTime * 50 end if self.IsSubcaliber then - local Radius = self.SpiralRadius - local CurAng = self.SpiralAngle + local Current = self.SpiralAngle + local SpiralRad = self.SpiralRadius + NextAng:RotateAroundAxis(NextAng:Forward(),Current) + + local Offset = NextDir * self.Speed * DeltaTime + NextAng:Up() * math.sin(Current) * SpiralRad + NextAng:Right() * math.cos(Current) * SpiralRad - Correction.y = Correction.y + Radius * math.cos(CurAng) - Correction.z = Correction.z + Radius * math.sin(CurAng) + NextDir = (Offset - NextDir):GetNormalized() - self.SpiralAngle = (CurAng + self.SpiralSpeed * DeltaTime) % 360 + self.SpiralAngle = (Current + self.SpiralSpeed * DeltaTime) % 360 end - self:SetAngles(self:LocalToWorldAngles(Direction)) - self.Position = self:LocalToWorld(Vector(self.Speed * DeltaTime, Correction.y, Correction.z)) + self.Position = self.Position + NextDir * self.Speed * DeltaTime self.Velocity = (self.Position - Position) / DeltaTime TraceData.start = Position @@ -278,6 +266,7 @@ function ENT:Think() end self:SetPos(self.Position) + self:SetAngles(NextAng) self:NextThink(Time) self.LastThink = Time @@ -288,18 +277,19 @@ end function ENT:Detonate() if self.Detonated then return end - self.Detonated = true - - local BulletData = self.BulletData + local BulletData = self.BulletData + local Position = self.Position + local Ammo = AmmoTypes.Get(BulletData.Type) BulletData.Filter = self.Filter - BulletData.Flight = self:GetForward() * self.Speed - BulletData.Pos = self.Position + BulletData.Flight = self.Velocity:GetNormalized() * self.Speed + BulletData.Pos = Position + + self.Detonated = true local Bullet = Ballistics.CreateBullet(BulletData) - local Ammo = AmmoTypes.Get(BulletData.Type) - Ammo:Detonate(Bullet, self.Position) + Ammo:Detonate(Bullet, Position) self:Remove() end diff --git a/lua/entities/acf_missile/init.lua b/lua/entities/acf_missile/init.lua index d2252015..63c58632 100644 --- a/lua/entities/acf_missile/init.lua +++ b/lua/entities/acf_missile/init.lua @@ -404,6 +404,8 @@ function MakeACF_Missile(Player, Pos, Ang, Rack, MountPoint, Crate) Missile.Inputs = WireLib.CreateInputs(Missile, Inputs) Missile.Outputs = WireLib.CreateOutputs(Missile, Outputs) + HookRun("ACF_OnEntitySpawn", "acf_missile", Missile, Data, Class, Crate) + WireLib.TriggerOutput(Missile, "Entity", Missile) Missile:UpdateModel(Missile.RackModel or Missile.RealModel) diff --git a/lua/entities/acf_rack/init.lua b/lua/entities/acf_rack/init.lua index d5f300a8..63dbe355 100644 --- a/lua/entities/acf_rack/init.lua +++ b/lua/entities/acf_rack/init.lua @@ -29,7 +29,7 @@ end do -- Spawning and Updating -------------------- local UnlinkSound = "physics/metal/metal_box_impact_bullet%s.wav" local MaxDistance = ACF.LinkDistance * ACF.LinkDistance - local CheckLegal = ACF_CheckLegal + local CheckLegal = ACF.CheckLegal local WireIO = Utilities.WireIO local Entities = Classes.Entities local Racks = Classes.Racks diff --git a/lua/entities/acf_radar/init.lua b/lua/entities/acf_radar/init.lua index bb2faf9b..152933fa 100644 --- a/lua/entities/acf_radar/init.lua +++ b/lua/entities/acf_radar/init.lua @@ -1,4 +1,3 @@ - AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") @@ -39,7 +38,7 @@ end) local Radars = ACF.ActiveRadars local Damage = ACF.Damage -local CheckLegal = ACF_CheckLegal +local CheckLegal = ACF.CheckLegal local UnlinkSound = "physics/metal/metal_box_impact_bullet%s.wav" local MaxDistance = ACF.LinkDistance * ACF.LinkDistance local TraceData = { start = true, endpos = true, mask = MASK_SOLID_BRUSHONLY } @@ -127,8 +126,8 @@ local function GetEntityIndex(Entity) end local function GetEntityOwner(Owner, Entity) - -- If the server is competitive and the radar owner doesn't has permissions on this entity then return Unknown - if ACF.Gamemode == 3 and not Entity:CPPICanTool(Owner) then + -- If entity info is restricted and the radar owner doesn't have permissions on this entity then return Unknown + if ACF.RestrictInfo and not Entity:CPPICanTool(Owner) then return "Unknown" end @@ -162,17 +161,20 @@ local function ScanForEntities(Entity) local Velocity = TargetInfo.Velocity local Distance = TargetInfo.Distance + local EntDamage = Entity.Damage + local Spread = ACF.MaxDamageInaccuracy * EntDamage + for Ent in pairs(Detected) do local EntPos = Ent.Position or Ent:GetPos() - if CheckLOS(Origin, EntPos) then - local Spread = VectorRand(-Entity.Spread, Entity.Spread) + if CheckLOS(Origin, EntPos) and (math.Rand(0,1) >= (EntDamage / 10)) then + local EntSpread = VectorRand(-Spread, Spread) local EntVel = Ent.Velocity or Ent:GetVelocity() local Owner = GetEntityOwner(Entity.Owner, Ent) local Index = GetEntityIndex(Ent) - EntPos = EntPos + Spread - EntVel = EntVel + Spread + EntPos = EntPos + EntSpread + EntVel = EntVel + EntSpread Count = Count + 1 local EntDist = Origin:Distance(EntPos) @@ -183,7 +185,7 @@ local function ScanForEntities(Entity) Position = EntPos, Velocity = EntVel, Distance = EntDist, - Spread = Spread, + Spread = EntSpread, } IDs[Count] = Index @@ -400,7 +402,7 @@ do -- Spawn and Update functions Radar.Active = false Radar.Scanning = false Radar.TargetCount = 0 - Radar.Spread = 0 + Radar.Damage = 0 Radar.Weapons = {} Radar.Targets = {} Radar.DataStore = Entities.GetArguments("acf_radar") @@ -494,11 +496,15 @@ end function ENT:ACF_OnDamage(DmgResult, DmgInfo) local HitRes = Damage.doPropDamage(self, DmgResult, DmgInfo) - self.Spread = ACF.MaxDamageInaccuracy * (1 - math.Round(self.ACF.Health / self.ACF.MaxHealth, 2)) + self.Damage = (1 - math.Round(self.ACF.Health / self.ACF.MaxHealth, 2)) return HitRes end +function ENT:ACF_OnRepaired() -- OldArmor, OldHealth, Armor, Health + self.Damage = (1 - math.Round(self.ACF.Health / self.ACF.MaxHealth, 2)) +end + function ENT:Enable() if not CheckLegal(self) then return end @@ -552,4 +558,4 @@ function ENT:OnRemove() timer.Remove("ACF Radar Clock " .. self:EntIndex()) WireLib.Remove(self) -end +end \ No newline at end of file diff --git a/lua/entities/acf_receiver/cl_init.lua b/lua/entities/acf_receiver/cl_init.lua new file mode 100644 index 00000000..274d1663 --- /dev/null +++ b/lua/entities/acf_receiver/cl_init.lua @@ -0,0 +1,5 @@ +include ("shared.lua") + +language.Add("Cleanup_acf_receiver", "ACF Receiver") +language.Add("Cleaned_acf_receiver", "Cleaned up all ACF Receiverss") +language.Add("SBoxLimit__acf_receiver", "You've hit the ACF Receiver limit!") diff --git a/lua/entities/acf_receiver/init.lua b/lua/entities/acf_receiver/init.lua new file mode 100644 index 00000000..53b89b12 --- /dev/null +++ b/lua/entities/acf_receiver/init.lua @@ -0,0 +1,338 @@ + +AddCSLuaFile("cl_init.lua") +AddCSLuaFile("shared.lua") + +include("shared.lua") + +local ACF = ACF + +--===============================================================================================-- +-- Local Funcs and Vars +--===============================================================================================-- + +local Damage = ACF.Damage +local CheckLegal = ACF.CheckLegal +local TimerExists = timer.Exists +local TimerCreate = timer.Create +local TimerRemove = timer.Remove +local HookRun = hook.Run + +local function ResetOutputs(Entity) + if not Entity.Detected then return end + + Entity.Detected = false + + WireLib.TriggerOutput(Entity, "Detected", 0) + WireLib.TriggerOutput(Entity, "Angle", Angle()) + WireLib.TriggerOutput(Entity, "Direction", Vector()) +end + +local function CheckReceive(Entity) + local IsDetected = false + local Dir = Vector() + local Ang = Angle() + + if not Entity.GetSources then return end + if not Entity.CheckLOS then return end + + local Sources = Entity:GetSources() + + local Origin = Entity:LocalToWorld(Entity.Origin) + + for Ent in pairs(Sources) do + local EntPos = Ent.Position or Ent:GetPos() + local EntDamage = Entity.Damage + local Spread = math.max(Entity.Divisor,15) * 2 * EntDamage + + if Entity.CheckLOS(Entity, Ent, Origin, EntPos) and (math.Rand(0,1) >= (EntDamage / 5)) then + IsDetected = true + + local PreAng = (EntPos - Origin):GetNormalized():Angle() + Ang = Angle(math.Round((PreAng.p + math.random(-Spread,Spread)) / Entity.Divisor),math.Round((PreAng.y + math.random(-Spread,Spread)) / Entity.Divisor),0) * Entity.Divisor + Dir = Ang:Forward() + + break -- Stop at the first valid source + end + end + + if IsDetected ~= Entity.Detected then + Entity.Detected = IsDetected + WireLib.TriggerOutput(Entity, "Detected", IsDetected and 1 or 0) + + if IsDetected then + Entity:EmitSound(Entity.SoundPath, 70, 100, ACF.Volume) + end + + Entity:UpdateOverlay() + end + + WireLib.TriggerOutput(Entity, "Direction", Dir) + WireLib.TriggerOutput(Entity, "Angle", Ang) +end + +local function SetActive(Entity,Bool) + ResetOutputs(Entity) + + if Bool then + if not TimerExists(Entity.TimerID) then + TimerCreate(Entity.TimerID, Entity.ThinkDelay, 0, function() + + if IsValid(Entity) then + return CheckReceive(Entity) + end + + TimerRemove(Entity.TimerID) + end) + end + else + TimerRemove(Entity.TimerID) + end +end + +--===============================================================================================-- + +do -- Spawn and Update functions + local Classes = ACF.Classes + local WireIO = ACF.Utilities.WireIO + local Entities = Classes.Entities + local Sensors = Classes.Sensors + + local Outputs = { + "Detected (Returns 1 if it)", + "Direction (The direction to a source) [VECTOR]", + "Angle (The direction to a source) [ANGLE]", + "Entity (The receiver itself.) [ENTITY]" + } + + local function VerifyData(Data) + if not Data.Receiver then + Data.Receiver = Data.Sensor or Data.Id + end + + local Class = Classes.GetGroup(Sensors, Data.Receiver) + + if not Class or Class.Entity ~= "acf_receiver" then + Data.Receiver = "LAS-Receiver" + + Class = Classes.GetGroup(Sensors, "LAS-Receiver") + end + + do -- External verifications + if Class.VerifyData then + Class.VerifyData(Data, Class) + end + + HookRun("ACF_VerifyData", "acf_receiver", Data, Class) + end + end + + local function UpdateReceiver(Entity, Data, Class, Receiver) + local Tick = engine.TickInterval() + local Delay = Receiver.ThinkDelay + + Entity.ACF = Entity.ACF or {} + Entity.ACF.Model = Receiver.Model -- Must be set before changing model + + Entity:SetModel(Receiver.Model) + + Entity:PhysicsInit(SOLID_VPHYSICS) + Entity:SetMoveType(MOVETYPE_VPHYSICS) + + -- Storing all the relevant information on the entity for duping + for _, V in ipairs(Entity.DataStore) do + Entity[V] = Data[V] + end + + Entity.Name = Receiver.Name + Entity.ShortName = Receiver.Name + Entity.EntType = Class.Name + Entity.ClassType = Class.ID + Entity.ClassData = Class + Entity.SoundPath = Class.Sound or ACF.DefaultRadarSound -- customizable sound? + Entity.DefaultSound = Entity.SoundPath + Entity.ThinkDelay = math.Round(Delay / Tick) * Tick -- Uses a timer, so has to be tied to CurTime/tickrate + Entity.GetSources = Receiver.Detect or Class.Detect + Entity.CheckLOS = Receiver.CheckLOS + Entity.Origin = Receiver.Offset + Entity.TimerID = "ACF Receiver Clock " .. Entity:EntIndex() + Entity.Divisor = Receiver.Divisor + Entity.Cone = Receiver.Cone + + Entity.ForcedHealth = Receiver.Health + Entity.ForcedArmor = Receiver.Armor + + WireIO.SetupOutputs(Entity, Outputs, Data, Class, Receiver) + + Entity:SetNWString("WireName", "ACF " .. Entity.Name) + + WireLib.TriggerOutput(Entity, "Think Delay", Entity.ThinkDelay) + + ACF.Activate(Entity, true) + + Entity.ACF.Model = Receiver.Model + Entity.ACF.LegalMass = Receiver.Mass + + local Phys = Entity:GetPhysicsObject() + if IsValid(Phys) then Phys:SetMass(Receiver.Mass) end + end + + function MakeACF_Receiver(Player, Pos, Ang, Data) + VerifyData(Data) + + local Class = Classes.GetGroup(Sensors, Data.Receiver) + local ReceiverData = Class.Lookup[Data.Receiver] + local Limit = Class.LimitConVar.Name + + if not Player:CheckLimit(Limit) then return false end + + local Receiver = ents.Create("acf_receiver") + + if not IsValid(Receiver) then return end + + Receiver:SetPlayer(Player) + Receiver:SetAngles(Ang) + Receiver:SetPos(Pos) + Receiver:Spawn() + + Player:AddCleanup("acf_receiver", Receiver) + Player:AddCount(Limit, Receiver) + + Receiver.Owner = Player -- MUST be stored on ent for PP + Receiver.DataStore = Entities.GetArguments("acf_receiver") + Receiver.Damage = 0 + + UpdateReceiver(Receiver, Data, Class, ReceiverData) + + if Class.OnSpawn then + Class.OnSpawn(Receiver, Data, Class, ReceiverData) + end + + HookRun("ACF_OnEntitySpawn", "acf_receiver", Receiver, Data, Class, ReceiverData) + + WireLib.TriggerOutput(Receiver, "Entity", Receiver) + + Receiver:UpdateOverlay(true) + + do -- Mass entity mod removal + local EntMods = Data and Data.EntityMods + + if EntMods and EntMods.mass then + EntMods.mass = nil + end + end + + CheckLegal(Receiver) + + SetActive(Receiver,true) + + return Receiver + end + + Entities.Register("acf_receiver", MakeACF_Receiver, "Receiver") + + ------------------- Updating --------------------- + + function ENT:Update(Data) + VerifyData(Data) + + local Class = Classes.GetGroup(Sensors, Data.Receiver) + local Receiver = Class.Lookup[Data.Receiver] + local OldClass = self.ClassData + + if OldClass.OnLast then + OldClass.OnLast(self, OldClass) + end + + HookRun("ACF_OnEntityLast", "acf_Receiver", self, OldClass) + + ACF.SaveEntity(self) + + UpdateReceiver(self, Data, Class, Receiver) + + ACF.RestoreEntity(self) + + if Class.OnUpdate then + Class.OnUpdate(self, Data, Class, Receiver) + end + + HookRun("ACF_OnEntityUpdate", "acf_Receiver", self, Data, Class, Receiver) + + self:UpdateOverlay(true) + + net.Start("ACF_UpdateEntity") + net.WriteEntity(self) + net.Broadcast() + + return true, "Receiver updated successfully!" + end +end + +--===============================================================================================-- +-- Meta Funcs +--===============================================================================================-- + +function ENT:ACF_OnDamage(DmgResult, DmgInfo) + local HitRes = Damage.doPropDamage(self, DmgResult, DmgInfo) + + self.Damage = 1 - math.Round(self.ACF.Health / self.ACF.MaxHealth, 2) + + return HitRes +end + +function ENT:ACF_OnRepaired() -- OldArmor, OldHealth, Armor, Health + self.Damage = 1 - math.Round(self.ACF.Health / self.ACF.MaxHealth, 2) +end + +function ENT:ACF_Activate(Recalc) + local PhysObj = self.ACF.PhysObj + local Area = PhysObj:GetSurfaceArea() + local Armor = self.ForcedArmor + local Health = self.ForcedHealth + local Percent = 1 + + if Recalc and self.ACF.Health and self.ACF.MaxHealth then + Percent = self.ACF.Health / self.ACF.MaxHealth + end + + self.ACF.Area = Area + self.ACF.Ductility = 0 + self.ACF.Health = Health * Percent + self.ACF.MaxHealth = Health + self.ACF.Armour = Armor * (0.5 + Percent * 0.5) + self.ACF.MaxArmour = Armor * ACF.ArmorMod + self.ACF.Type = "Prop" +end + +function ENT:Enable() + if not CheckLegal(self) then return end + + SetActive(self,true) + + self:UpdateOverlay() +end + +function ENT:Disable() + SetActive(self,false) +end + +local Text = "%s\n\n%s" + +function ENT:UpdateOverlayText() + local Status = self.Detected and "Detected" or "Undetected" + + return Text:format(Status, self.EntType) +end + +function ENT:OnRemove() + local OldClass = self.ClassData + + if OldClass.OnLast then + OldClass.OnLast(self, OldClass) + end + + HookRun("ACF_OnEntityLast", "acf_Receiver", self, OldClass) + + TimerRemove(self.TimerID) + + WireLib.Remove(self) +end diff --git a/lua/entities/acf_receiver/shared.lua b/lua/entities/acf_receiver/shared.lua new file mode 100644 index 00000000..5df63a2f --- /dev/null +++ b/lua/entities/acf_receiver/shared.lua @@ -0,0 +1,9 @@ +DEFINE_BASECLASS("acf_base_simple") + +ENT.PrintName = "ACF Receiver" +ENT.Author = "LiddulBOFH" +ENT.WireDebugName = "ACF Receiver" +ENT.PluralName = "ACF Receivers" +ENT.IsACFReceiver = true + +cleanup.Register("acf_receiver") diff --git a/materials/models/bluemetaknight/Body.vmt b/materials/models/bluemetaknight/Body.vmt new file mode 100644 index 00000000..2484a151 --- /dev/null +++ b/materials/models/bluemetaknight/Body.vmt @@ -0,0 +1,16 @@ +"VertexLitGeneric" +{ + "$baseTexture" "models/bluemetaknight/Detector_D" + "$bumpmap" "models/bluemetaknight/Detector_N" + + "$surfaceprop" "metal" + "$model" "1" + "$blendtintbybasealpha" "1" + + "$phong" "1" + "$phongexponent" "4" + "$phongboost" "0.5" + "$phongfresnelranges" "[0.2 0.5 1]" + "$halflambert" "1" +} + diff --git a/materials/models/bluemetaknight/Detector_D.vtf b/materials/models/bluemetaknight/Detector_D.vtf new file mode 100644 index 00000000..db7440e5 Binary files /dev/null and b/materials/models/bluemetaknight/Detector_D.vtf differ diff --git a/materials/models/bluemetaknight/Detector_EnvMask.vtf b/materials/models/bluemetaknight/Detector_EnvMask.vtf new file mode 100644 index 00000000..488aba3c Binary files /dev/null and b/materials/models/bluemetaknight/Detector_EnvMask.vtf differ diff --git a/materials/models/bluemetaknight/Detector_N.vtf b/materials/models/bluemetaknight/Detector_N.vtf new file mode 100644 index 00000000..490e1f2e Binary files /dev/null and b/materials/models/bluemetaknight/Detector_N.vtf differ diff --git a/materials/models/bluemetaknight/Lens.vmt b/materials/models/bluemetaknight/Lens.vmt new file mode 100644 index 00000000..70bae678 --- /dev/null +++ b/materials/models/bluemetaknight/Lens.vmt @@ -0,0 +1,13 @@ +"VertexLitGeneric" +{ + "$baseTexture" "models/bluemetaknight/Detector_D" + "$bumpmap" "models/bluemetaknight/Detector_N" + + "$surfaceprop" "glass" + "$model" 1 + "$translucent" 1 + + $envmap env_cubemap + $envmapmask "models/bluemetaknight/Detector_EnvMask" +} + diff --git a/materials/models/bombs/fab100.vtf b/materials/models/bombs/fab100.vtf index 5e91f07c..b9fa665d 100644 Binary files a/materials/models/bombs/fab100.vtf and b/materials/models/bombs/fab100.vtf differ diff --git a/materials/models/bombs/fab250.vtf b/materials/models/bombs/fab250.vtf index 936bb17b..d52db6d1 100644 Binary files a/materials/models/bombs/fab250.vtf and b/materials/models/bombs/fab250.vtf differ diff --git a/materials/models/bombs/fab50.vtf b/materials/models/bombs/fab50.vtf index e67a2e27..54a0ae55 100644 Binary files a/materials/models/bombs/fab50.vtf and b/materials/models/bombs/fab50.vtf differ diff --git a/materials/models/bombs/fab500.vtf b/materials/models/bombs/fab500.vtf index 901f80ae..5534976e 100644 Binary files a/materials/models/bombs/fab500.vtf and b/materials/models/bombs/fab500.vtf differ diff --git a/materials/models/ghosteh/lau10.vtf b/materials/models/ghosteh/lau10.vtf index f57e7bba..8aed6749 100644 Binary files a/materials/models/ghosteh/lau10.vtf and b/materials/models/ghosteh/lau10.vtf differ diff --git a/materials/models/ghosteh/lau10_norm.vtf b/materials/models/ghosteh/lau10_norm.vtf index f3fbb1f9..1e361417 100644 Binary files a/materials/models/ghosteh/lau10_norm.vtf and b/materials/models/ghosteh/lau10_norm.vtf differ diff --git a/materials/models/ghosteh/zuni.vtf b/materials/models/ghosteh/zuni.vtf index 9585754d..cbbeb672 100644 Binary files a/materials/models/ghosteh/zuni.vtf and b/materials/models/ghosteh/zuni.vtf differ diff --git a/materials/models/ghosteh/zuni_norm.vtf b/materials/models/ghosteh/zuni_norm.vtf index 80a410bd..45d56828 100644 Binary files a/materials/models/ghosteh/zuni_norm.vtf and b/materials/models/ghosteh/zuni_norm.vtf differ diff --git a/materials/models/kali/weapons/kornet/kornet_base_c.vtf b/materials/models/kali/weapons/kornet/kornet_base_c.vtf index d59830e2..f3bc557f 100644 Binary files a/materials/models/kali/weapons/kornet/kornet_base_c.vtf and b/materials/models/kali/weapons/kornet/kornet_base_c.vtf differ diff --git a/materials/models/kali/weapons/kornet/kornet_base_exp.vtf b/materials/models/kali/weapons/kornet/kornet_base_exp.vtf index 7f4a65d5..4ba68c80 100644 Binary files a/materials/models/kali/weapons/kornet/kornet_base_exp.vtf and b/materials/models/kali/weapons/kornet/kornet_base_exp.vtf differ diff --git a/materials/models/kali/weapons/kornet/kornet_base_n.vtf b/materials/models/kali/weapons/kornet/kornet_base_n.vtf index 3e23d028..0bb34ba8 100644 Binary files a/materials/models/kali/weapons/kornet/kornet_base_n.vtf and b/materials/models/kali/weapons/kornet/kornet_base_n.vtf differ diff --git a/materials/models/missiles/agm114.vtf b/materials/models/missiles/agm114.vtf index fd5c8dc7..fcf16721 100644 Binary files a/materials/models/missiles/agm114.vtf and b/materials/models/missiles/agm114.vtf differ diff --git a/materials/models/missiles/bru-42.vtf b/materials/models/missiles/bru-42.vtf index 908fa586..d54f603c 100644 Binary files a/materials/models/missiles/bru-42.vtf and b/materials/models/missiles/bru-42.vtf differ diff --git a/materials/models/missiles/fim92.vtf b/materials/models/missiles/fim92.vtf index de0308af..75db5573 100644 Binary files a/materials/models/missiles/fim92.vtf and b/materials/models/missiles/fim92.vtf differ diff --git a/materials/models/missiles/spg9.vtf b/materials/models/missiles/spg9.vtf index 1d789240..df765733 100644 Binary files a/materials/models/missiles/spg9.vtf and b/materials/models/missiles/spg9.vtf differ diff --git a/materials/models/missiles/stinger_rack1.vtf b/materials/models/missiles/stinger_rack1.vtf index c1fde172..1833602c 100644 Binary files a/materials/models/missiles/stinger_rack1.vtf and b/materials/models/missiles/stinger_rack1.vtf differ diff --git a/materials/models/missiles/stinger_rack1b.vtf b/materials/models/missiles/stinger_rack1b.vtf index 1f825b50..214a5057 100644 Binary files a/materials/models/missiles/stinger_rack1b.vtf and b/materials/models/missiles/stinger_rack1b.vtf differ diff --git a/materials/models/missiles/stinger_rack2.vtf b/materials/models/missiles/stinger_rack2.vtf index 27da19f3..9dd8d27d 100644 Binary files a/materials/models/missiles/stinger_rack2.vtf and b/materials/models/missiles/stinger_rack2.vtf differ diff --git a/materials/models/missiles/stinger_rack2b.vtf b/materials/models/missiles/stinger_rack2b.vtf index fb40b9f7..6df5803b 100644 Binary files a/materials/models/missiles/stinger_rack2b.vtf and b/materials/models/missiles/stinger_rack2b.vtf differ diff --git a/materials/models/missiles/stinger_rack3.vtf b/materials/models/missiles/stinger_rack3.vtf index 0daae0b5..ea058f6b 100644 Binary files a/materials/models/missiles/stinger_rack3.vtf and b/materials/models/missiles/stinger_rack3.vtf differ diff --git a/materials/models/missiles/stinger_rack4.vtf b/materials/models/missiles/stinger_rack4.vtf index 42daaaaa..cb05bb3d 100644 Binary files a/materials/models/missiles/stinger_rack4.vtf and b/materials/models/missiles/stinger_rack4.vtf differ diff --git a/materials/models/missiles/texture_rack.vtf b/materials/models/missiles/texture_rack.vtf index a978c94a..5c33a27b 100644 Binary files a/materials/models/missiles/texture_rack.vtf and b/materials/models/missiles/texture_rack.vtf differ diff --git a/materials/models/missiles/texture_rack2.vtf b/materials/models/missiles/texture_rack2.vtf index 63a7eda3..3637f446 100644 Binary files a/materials/models/missiles/texture_rack2.vtf and b/materials/models/missiles/texture_rack2.vtf differ diff --git a/materials/models/spg9/spg9.vtf b/materials/models/spg9/spg9.vtf index 1d789240..df765733 100644 Binary files a/materials/models/spg9/spg9.vtf and b/materials/models/spg9/spg9.vtf differ diff --git a/models/bluemetaknight/laser_detector.dx80.vtx b/models/bluemetaknight/laser_detector.dx80.vtx new file mode 100644 index 00000000..c1e3e1b8 Binary files /dev/null and b/models/bluemetaknight/laser_detector.dx80.vtx differ diff --git a/models/bluemetaknight/laser_detector.dx90.vtx b/models/bluemetaknight/laser_detector.dx90.vtx new file mode 100644 index 00000000..912ab610 Binary files /dev/null and b/models/bluemetaknight/laser_detector.dx90.vtx differ diff --git a/models/bluemetaknight/laser_detector.mdl b/models/bluemetaknight/laser_detector.mdl new file mode 100644 index 00000000..fd8dbed3 Binary files /dev/null and b/models/bluemetaknight/laser_detector.mdl differ diff --git a/models/bluemetaknight/laser_detector.phy b/models/bluemetaknight/laser_detector.phy new file mode 100644 index 00000000..3294e340 Binary files /dev/null and b/models/bluemetaknight/laser_detector.phy differ diff --git a/models/bluemetaknight/laser_detector.sw.vtx b/models/bluemetaknight/laser_detector.sw.vtx new file mode 100644 index 00000000..127ddf2e Binary files /dev/null and b/models/bluemetaknight/laser_detector.sw.vtx differ diff --git a/models/bluemetaknight/laser_detector.vvd b/models/bluemetaknight/laser_detector.vvd new file mode 100644 index 00000000..9dd1803a Binary files /dev/null and b/models/bluemetaknight/laser_detector.vvd differ