dobrograd-13-06-2022/garrysmod/addons/feature-wire/lua/entities/gmod_wire_extbus.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

178 lines
4.9 KiB
Lua

AddCSLuaFile()
DEFINE_BASECLASS( "base_wire_entity" )
ENT.PrintName = "Wire Extended Bus"
ENT.WireDebugName = "Extended Bus"
if CLIENT then return end -- No more client
function ENT:Initialize()
self:PhysicsInit( SOLID_VPHYSICS)
self:SetMoveType( MOVETYPE_VPHYSICS)
self:SetSolid( SOLID_VPHYSICS)
self:SetUseType( SIMPLE_USE)
self.Outputs = Wire_CreateOutputs(self, {"Memory"})
self.Inputs = Wire_CreateInputs(self,{"Memory1","Memory2","Memory3","Memory4","Memory5","Memory6","Memory7","Memory8"})
self.DataRate = 0
self.DataBytes = 0
self.PerformRecursiveScan = 1
self.ControlDataSize = 32
self.ControlData = {}
self.Memory = {}
self.MemStart = {}
self.MemEnd = {}
for i = 1,8 do
self.Memory[i] = nil
self.MemStart[i] = 0
self.MemEnd[i] = 0
end
self:SetOverlayText("Data rate: 0 bps")
end
function ENT:Think()
BaseClass.Think(self)
self.DataRate = self.DataBytes
self.DataBytes = 0
Wire_TriggerOutput(self, "Memory", self.DataRate)
self:SetOverlayText("Data rate: "..math.floor(self.DataRate*2).." bps")
self:NextThink(CurTime()+0.5)
end
function ENT:ReadCell(Address)
Address = math.floor(Address)
if (Address >= 0) and (Address < self.ControlDataSize) then
if Address < 16 then
if Address % 2 == 0 then
return self.MemStart[Address/2+1]
else
return self.MemEnd[(Address-1)/2+1]
end
elseif Address == 16 then
return self.ControlDataSize
elseif Address == 18 then
return self.DataRate
elseif Address == 20 then
return self.PerformRecursiveScan
elseif Address >= 32 then
return self.ControlData[Address-31] or 0
end
return 0
else
for i = 1,8 do
if (Address-self.ControlDataSize >= self.MemStart[i]) and
(Address-self.ControlDataSize <= self.MemEnd[i]) then
if self.Memory[i] then
if self.Memory[i].ReadCell then
self.DataBytes = self.DataBytes + 1
local val = self.Memory[i]:ReadCell(Address-self.ControlDataSize-self.MemStart[i])
return val or 0
end
else
return 0
end
end
end
end
return nil
end
local recursiveCounter = 0
function ENT:GetDeviceInfo(deviceEnt)
local deviceType = CPULib.GetDeviceType(deviceEnt:GetClass())
if deviceEnt.Socket then
if deviceEnt.Socket.Inputs.Memory.Src then
self:GetDeviceInfo(deviceEnt.Socket.Inputs.Memory.Src)
else
table.insert(self.ControlData,14)
end
return
elseif deviceEnt.Plug then
if deviceEnt.Plug.Inputs.Memory.Src then
self:GetDeviceInfo(deviceEnt.Plug.Inputs.Memory.Src)
else
table.insert(self.ControlData,13)
end
return
end
table.insert(self.ControlData,deviceType)
if self.PerformRecursiveScan >= 1 then
recursiveCounter = recursiveCounter + 1
if recursiveCounter < 256 then
if (deviceEnt:GetClass() == "gmod_wire_addressbus") or
(deviceEnt:GetClass() == "gmod_wire_extbus") then
for i = 1,8 do
if deviceEnt.Memory[i] then
self:GetDeviceInfo(deviceEnt.Memory[i])
else
table.insert(self.ControlData,0)
end
end
end
end
end
end
function ENT:WriteCell(Address, Value)
Address = math.floor(Address)
if (Address >= 0) and (Address < self.ControlDataSize) then
-- [0..15] Address bus settings
-- [16] Control data area size
-- [17] Write to request device info
-- [18] Data transfer rate
-- [19] Override returned device type (0: no override)
-- [20] Perform recursive scan
-- [32..] Device types
if Address < 16 then
if Address % 2 == 0 then
self.MemStart[Address/2+1] = math.floor(Value)
else
self.MemEnd[(Address-1)/2+1] = math.floor(Value)
end
elseif Address == 16 then
self.ControlDataSize = math.max(32,math.floor(Value))
elseif Address == 17 then
recursiveCounter = 0
self.ControlData = {}
for i = 1,8 do
if self.Memory[i] then
self:GetDeviceInfo(self.Memory[i])
else
table.insert(self.ControlData,0)
end
end
elseif Address == 20 then
self.PerformRecursiveScan = Value
end
return true
else
local res = false
for i = 1,8 do
if (Address-self.ControlDataSize >= self.MemStart[i]) and
(Address-self.ControlDataSize <= self.MemEnd[i]) then
if self.Memory[i] then
if self.Memory[i].WriteCell then
self.Memory[i]:WriteCell(Address-self.ControlDataSize-self.MemStart[i], Value)
end
end
self.DataBytes = self.DataBytes + 1
res = true
end
end
return res
end
end
function ENT:TriggerInput(iname, value)
for i = 1,8 do
if iname == "Memory"..i then
self.Memory[i] = self.Inputs["Memory"..i].Src
end
end
end
duplicator.RegisterEntityClass("gmod_wire_extbus", WireLib.MakeWireEnt, "Data")