AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') ENT.WireDebugName = "KeycardReader" local MODEL = Model("models/jaanus/wiretool/wiretool_range.mdl") function ENT:Initialize() self:SetModel( MODEL ) self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) self.Inputs = Wire_CreateInputs(self, { "ReadLocation", "WriteEnabled", "WriteLocation", "WriteValue" }) self.Outputs = Wire_CreateOutputs(self, {"Value", "SignedBy", "CardID", "Writable"}) self:SetReadMode(0) // 0 = Beam, 1 = Area self:SetLCMatchMode(0) // 0 = Inclusive, 1 = Exclusive self:SetRange(256) self.Clk = 0 self.Value = 0 self.ReadLocation = 0 self.WriteLocation = 0 end function ENT:Setup(mode, range, lcmode) self:SetReadMode(mode) self:SetLCMatchMode(lcmode) self:SetRange(range) self:ShowOutput() end function ENT:SetLockCode(value) self.LockCode = (value or 0) end function ENT:TriggerInput(iname, value) if (iname == "WriteEnabled") then self.Clk = (value or 0) elseif(iname == "WriteValue") then self.Value = (value or 0) elseif(iname == "ReadLocation") then self.ReadLocation = (value or 0) elseif(iname == "WriteLocation") then self.WriteLocation = (value or 0) end end function ENT:ShowOutput() local state // That which we call a ternary operator // By any other syntax would function as elegantly if (self.Writable == 1) then state = "Writable" else state = "Read Only" end local text = "Wire Keycard Reader" .. "\nSigned by: " .. tostring(self.Outputs["SignedBy"].Value) .. "\nCard ID: " .. tostring(self.Outputs["CardID"].Value) .. "\nLock Code: " .. tostring(self.LockCode) .. "\nTarget: " .. state self:SetOverlayText( text ) end function ENT:Think() self.BaseClass.Think(self) local foundEnt if(self:GetReadMode() == 0) then local vStart = self:GetPos() local vForward = self:GetUp() local trace = {} trace.start = vStart trace.endpos = vStart + (vForward * self:GetRange()) trace.filter = { self } local trace = util.TraceLine( trace ) foundEnt = trace.Entity if (!foundEnt) then self:ZeroOutputs() return false end if (!foundEnt:IsValid() ) then self:ZeroOutputs() return false end if (foundEnt:IsWorld()) then self:ZeroOutputs() return false end if (foundEnt:GetClass() ~= "gmod_wire_keycard") then self:ZeroOutputs() return false end else local i local nearbyEnts = ents.FindInSphere(self:GetPos(), self:GetRange()) local keycardEnts = ents.FindByClass("gmod_wire_keycard") local nkEnts = {} for _,k in pairs(keycardEnts) do for _,n in pairs(nearbyEnts) do if (k == n) then table.insert(nkEnts, k) end end end if (table.Count(nkEnts) == 0) then self:ZeroOutputs() return false end local nearestDist = self:GetRange() for _,k in pairs(nkEnts) do local dist = self:GetPos():Distance(k:GetPos()) if (dist <= nearestDist) then nearestDist = dist foundEnt = k end end if (!foundEnt) then self:ZeroOutputs() return false end if (!foundEnt:IsValid() ) then self:ZeroOutputs() return false end if (foundEnt:IsWorld()) then self:ZeroOutputs() return false end end if ( CLIENT ) then return true end local card_lockcode = foundEnt:GetLockCode() if (card_lockcode == self.LockCode ) then self.Writable = 1 else self.Writable = 0 end // If the card isn't yours, and exclusive is on, you haven't found a match after all // This has the consequence of deliberately ignoring the card rather than just not // seeing it. A near card that isn't yours will force 0 on the outputs all the time. if (self.Writable == 0 and self:GetLCMatchMode() == 1) then self:ZeroOutputs() return false end if (self.Clk == 1 and self.Writable == 1) then foundEnt:SetValue(self.WriteLocation, self.Value) end local value = foundEnt:GetValue(self.ReadLocation) local user = foundEnt:GetCardOwner() local userid local cardid = foundEnt:GetCardID() if (user:IsValid() and user:IsPlayer()) then userid = user:UserID() + 1 else userid = 0 end Wire_TriggerOutput(self,"Value", value) Wire_TriggerOutput(self,"SignedBy", userid) Wire_TriggerOutput(self,"CardID", cardid) Wire_TriggerOutput(self,"Writable", self.Writable) self:ShowOutput() self:NextThink(CurTime()+0.25) end function ENT:ZeroOutputs() self.Writable = 0 Wire_TriggerOutput(self,"Value", 0) Wire_TriggerOutput(self,"SignedBy", 0) Wire_TriggerOutput(self,"CardID", 0) Wire_TriggerOutput(self,"Writable", self.Writable) self:ShowOutput() end