1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
Files
MetrostroiAddon/lua/entities/gmod_track_signal/cl_init.lua
kosmik641 aca7d7aa0a Дебаг сигнализации.
Почистил мусор
Перенес всю отрисовку дебаг информации в ENT:Draw()
2025-12-06 02:52:22 +03:00

726 lines
35 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
include("shared.lua")
--------------------------------------------------------------------------------
function ENT:Initialize()
self.Sig = ""
self.OldName = ""
self.Models = {{},{},{}}
self.Signals = {}
self.Anims = {}
end
function ENT:Animate(clientProp, value, min, max, speed, damping, stickyness)
local id = clientProp
if not self.Anims[id] then
self.Anims[id] = {}
self.Anims[id].val = value
self.Anims[id].V = 0.0
end
if damping == false then
local dX = speed * self.DeltaTime
if value > self.Anims[id].val then
self.Anims[id].val = self.Anims[id].val + dX
end
if value < self.Anims[id].val then
self.Anims[id].val = self.Anims[id].val - dX
end
if math.abs(value - self.Anims[id].val) < dX then
self.Anims[id].val = value
end
else
-- Prepare speed limiting
local delta = math.abs(value - self.Anims[id].val)
local max_speed = 1.5*delta / self.DeltaTime
local max_accel = 0.5 / self.DeltaTime
-- Simulate
local dX2dT = (speed or 128)*(value - self.Anims[id].val) - self.Anims[id].V * (damping or 8.0)
if dX2dT > max_accel then dX2dT = max_accel end
if dX2dT < -max_accel then dX2dT = -max_accel end
self.Anims[id].V = self.Anims[id].V + dX2dT * self.DeltaTime
if self.Anims[id].V > max_speed then self.Anims[id].V = max_speed end
if self.Anims[id].V < -max_speed then self.Anims[id].V = -max_speed end
self.Anims[id].val = math.max(0,math.min(1,self.Anims[id].val + self.Anims[id].V * self.DeltaTime))
-- Check if value got stuck
if (math.abs(dX2dT) < 0.001) and stickyness and (self.DeltaTime > 0) then
self.Anims[id].stuck = true
end
end
return min + (max-min)*self.Anims[id].val
end
--------------------------
-- MAIN SPAWN FUNCTIONS --
--------------------------
function ENT:SpawnMainModels(pos,ang,LenseNum,add)
local TLM = self.TrafficLightModels[self.LightType]
for k,v in pairs(TLM) do
if type(v) == "string" and not k:find("long") then
local idx = add and v..add or v
if IsValid(self.Models[1][idx]) then break else
local k_long = k.."_long"
if TLM[k_long] and LenseNum >= 7 then
self.Models[1][idx] = ClientsideModel(TLM[k_long],RENDERGROUP_OPAQUE)
self.LongOffset = Vector(0,0,TLM[k.."_long_pos"])
else
self.Models[1][idx] = ClientsideModel(v,RENDERGROUP_OPAQUE)
end
self.Models[1][idx]:SetPos(self:LocalToWorld(pos))
self.Models[1][idx]:SetAngles(self:LocalToWorldAngles(ang))
self.Models[1][idx]:SetParent(self)
end
end
end
end
function ENT:SpawnHeads(ID,model,pos,ang,glass,notM,add)
if not IsValid(self.Models[1][ID]) then
self.Models[1][ID] = ClientsideModel(model,RENDERGROUP_OPAQUE)
self.Models[1][ID]:SetPos(self:LocalToWorld(pos))
self.Models[1][ID]:SetAngles(self:LocalToWorldAngles(ang))
self.Models[1][ID]:SetParent(self)
end
if self.RN and self.RN == self.RouteNumbers.sep then
self.RN = self.RN + 1
end
local id = self.RN
local rouid = id and "rou"..id
if rouid and not IsValid(self.Models[1][rouid]) then
local rnadd = ((self.RouteNumbers[id] and self.RouteNumbers[id][1] ~= "X") and (self.RouteNumbers[id][3] and not self.RouteNumbers[id][2] and "2" or "") or "5")
local LampIndicator = self.TrafficLightModels[self.LightType].LampIndicator
self.Models[1][rouid] = ClientsideModel(LampIndicator.model..rnadd..".mdl",RENDERGROUP_OPAQUE)
self.Models[1][rouid]:SetPos(self:LocalToWorld(pos-self.RouteNumberOffset*(self.Left and LampIndicator[1] or LampIndicator[2])))
self.Models[1][rouid]:SetAngles(self:GetAngles())
self.Models[1][rouid]:SetParent(self)
if self.RouteNumbers[id] then self.RouteNumbers[id].pos = pos-self.RouteNumberOffset*(self.Left and LampIndicator[1] or LampIndicator[2]) end
self.RN = self.RN + 1
end
if notM then
if glass then
local ID_glass = tostring(ID).."_glass"
for i,tbl in pairs(glass) do
local ID_glassi = ID_glass..i
if not IsValid(self.Models[1][ID_glassi]) then --NEWLENSES
self.Models[1][ID_glassi] = ClientsideModel(tbl[1],RENDERGROUP_OPAQUE)
self.Models[1][ID_glassi]:SetPos(self:LocalToWorld(pos+tbl[2]*(add and Vector(-1,1,1) or 1)))
self.Models[1][ID_glassi]:SetAngles(self:LocalToWorldAngles(ang))
self.Models[1][ID_glassi]:SetParent(self)
end
end
end
end
end
function ENT:SetLight(ID,ID2,pos,ang,skin,State,Change)
local IsStateAboveZero = State > 0
local IDID2 = ID..ID2
local IsModelValid = IsValid(self.Models[3][IDID2])
if IsModelValid then
if IsStateAboveZero then
if Change then
self.Models[3][IDID2]:SetColor(Color(255,255,255,State*255))
end
else
self.Models[3][IDID2]:Remove()
end
elseif IsStateAboveZero then
self.Models[3][IDID2] = ClientsideModel(self.TrafficLightModels[self.LightType].LampBase.model,RENDERGROUP_OPAQUE)
self.Models[3][IDID2]:SetPos(self:LocalToWorld(pos))
self.Models[3][IDID2]:SetAngles(self:LocalToWorldAngles(ang))
self.Models[3][IDID2]:SetSkin(skin)
self.Models[3][IDID2]:SetParent(self)
self.Models[3][IDID2]:SetRenderMode(RENDERMODE_TRANSCOLOR)
-- self.Models[3][IDID2]:SetColor(Color(255, 255, 255, 0))
self.Models[3][IDID2]:SetColor(Color(255,255,255,State*255))
end
end
function ENT:SpawnLetter(i,model,pos,letter,double)
local LetMaterials = self.TrafficLightModels[self.LightType].LetMaterials.str
local LetMaterialsStart = LetMaterials.."let_start"
local LetMaterialsletter = LetMaterials..letter
if double ~= false and not IsValid(self.Models[2][i]) and (self.Double or not self.Left) and (not letter:match("s[1-3]") or letter == "s3" or self.Double and self.Left) then
self.Models[2][i] = ClientsideModel(model,RENDERGROUP_OPAQUE)
self.Models[2][i]:SetAngles(self:LocalToWorldAngles(Angle(0,180,0)))
self.Models[2][i]:SetPos(self:LocalToWorld(self.BasePosition+pos))
self.Models[2][i]:SetParent(self)
for k,v in pairs(self.Models[2][i]:GetMaterials()) do
if v:find(LetMaterialsStart) then
self.Models[2][i]:SetSubMaterial(k-1,LetMaterialsletter)
end
end
end
local id = i.."d"
if not double and not IsValid(self.Models[2][id]) and (self.Double or self.Left) and (not letter:match("s[1-3]") or letter == "s3" or self.Double and not self.Left) then
self.Models[2][id] = ClientsideModel(model,RENDERGROUP_OPAQUE)
self.Models[2][id]:SetAngles(self:LocalToWorldAngles(Angle(0,180,0)))
self.Models[2][id]:SetPos(self:LocalToWorld((self.BasePosition+pos)*Vector(-1,1,1)))
self.Models[2][id]:SetParent(self)
for k,v in pairs(self.Models[2][id]:GetMaterials()) do
if v:find(LetMaterialsStart) then
self.Models[2][id]:SetSubMaterial(k-1,LetMaterialsletter)
end
end
end
end
function ENT:OnRemove()
self:RemoveModels()
end
function ENT:RemoveModels(final)
if self.Models and self.Models.have then
for _,v in pairs(self.Models) do if type(v) == "table" then for _,v1 in pairs(v) do v1:Remove() end end end
end
self.Models = {{},{},{}}
self.ModelsCreated = false
end
net.Receive("metrostroi-signal", function()
local ent = net.ReadEntity()
if not IsValid(ent) then return end
ent.LightType = net.ReadInt(3)
ent.Name = net.ReadString()
--ent.Name = " BUDAPEiT"..string.gsub(ent.Name,"[A-Za-z]*","")
ent.Lenses = net.ReadString()
ent.ARSOnly = ent.Lenses == "ARSOnly"
ent.RouteNumberSetup = net.ReadString()
ent.Left = net.ReadBool()
ent.Double = net.ReadBool()
ent.DoubleL = net.ReadBool()
ent.AutostopPresent = net.ReadBool()
if not ent.ARSOnly then
ent.LensesTBL = string.Explode("-",ent.Lenses)
end
if ent.RemoveModels then ent:RemoveModels() end
end)
local C_RenderDistance = GetConVar("metrostroi_distance_signal")
local C_ScreenshotMode = GetConVar("metrostroi_screenshotmode")
local timer = CurTime()
hook.Add("Think","MetrostroiRenderSignals", function()
if CurTime() - timer < 1.5 or not IsValid(LocalPlayer()) or C_ScreenshotMode:GetBool() then return end
timer = CurTime()
local plyPos = LocalPlayer():GetPos()
local dist = C_RenderDistance:GetInt()/0.01905
for _,sig in pairs(ents.FindByClass("gmod_track_signal")) do
if not IsValid(sig) then continue end
local sigPos = sig:GetPos()
sig.RenderDisable = sigPos:Distance(plyPos) > dist or math.abs(plyPos.z - sigPos.z) > 1500
end
end)
function ENT:Think()
local CurTime = CurTime()
self:SetNextClientThink(CurTime + 0.0333)
self.PrevTime = self.PrevTime or RealTime()
self.DeltaTime = (RealTime() - self.PrevTime)
self.PrevTime = RealTime()
if (self:IsDormant() or Metrostroi and Metrostroi.ReloadClientside or self.RenderDisable and not C_ScreenshotMode:GetBool()) and not self.ReloadModels then
if self.ModelsCreated then
self:RemoveModels()
end
return true
end
if self.ReloadModels then
self.ReloadModels = false
self:RemoveModels()
end
if not self.Name then
if self.sended and (CurTime - self.sended) > 0 then
self.sended = nil
end
if not self.sended then
net.Start("metrostroi-signal")
net.WriteEntity(self)
net.SendToServer()
self.sended = CurTime + 1.5
end
return true
end
local TLM = self.TrafficLightModels[self.LightType]
if not self.ModelsCreated then
local ID = 0
local ID2 = 0
-- Create new clientside models
if not self.ARSOnly then
--SPAWN A OLD ROUTE Numbers
--оператор # съедает больше производительности, чем исопльзование своей переменной с хранением количества элементов в таблице
--поэтому добавляю каунтеры
--TODO вообще сравнить бы это здесь xD
local rn1 = {}
local rn1N = 0
local rn2 = {}
self.RouteNumbers = {}
self.SpecRouteNumbers = {}
for i=1,#self.RouteNumberSetup do
local CurRN = self.RouteNumberSetup[i]
if self.OldRouteNumberSetup[1]:find(CurRN) then
rn1N = table.insert(rn1,CurRN)
elseif self.OldRouteNumberSetup[2]:find(CurRN) then
table.insert(rn2,CurRN)
elseif self.OldRouteNumberSetup[3]:find(CurRN) then
table.insert(self.SpecRouteNumbers,{CurRN,CurRN == "F"})
end
end
for i=1,rn1N,2 do
table.insert(self.RouteNumbers,{rn1[i],rn1[i+1],true})
end
for k,v in pairs(rn2) do
table.insert(self.RouteNumbers,{v})
end
self.Arrow = nil
for k,v in pairs(self.SpecRouteNumbers) do
if not v[2] then
self.Arrow = k
self.SpecRouteNumbers = v
break
end
end
local LenseNum = self.Arrow and 1 or 0
local OneLense = self.Arrow == nil
for k,v in ipairs(self.LensesTBL) do
if k > 1 and v:find("[RGBWYM]+") then
OneLense = false
end
for i=1,#v do
if v[i]:find("[RGBWYM]") then
LenseNum = LenseNum+1
end
end
end
if LenseNum == 0 then OneLense = false end
local offset = self.RenderOffset[self.LightType] or Vector(0, 0, 0)
self.LongOffset = self.LongOffset or Vector(0, 0, 0)
if not self.Left or self.Double then self:SpawnMainModels(self.BasePosition,Angle(0, 0, 0),LenseNum) end
if self.Left or self.Double then self:SpawnMainModels(self.BasePosition*Vector(-1,1,1),Angle(0,180,0),LenseNum,self.Double and "d" or nil) end
if not self.RouteNumbers.sep and #self.RouteNumbers > 1 then
self.RouteNumbers.sep = 2
elseif not self.RouteNumbers.sep and #self.RouteNumbers > 0 then
self.RouteNumbers.sep = 1
end
if self.RouteNumbers.sep and self.RouteNumbers[self.RouteNumbers.sep][1] ~= "X" then
local id = self.RouteNumbers.sep
local rnadd = self.RouteNumbers[id][3] and not self.RouteNumbers[id][2] and "3" or "4"
self.Models[1]["rous"] = ClientsideModel(TLM.LampIndicator.model..rnadd..".mdl",RENDERGROUP_OPAQUE)
self.RouteNumbers[id].pos = (self.BasePosition+offset+self.LongOffset-TLM.LampIndicator[3])
if self.Left then self.RouteNumbers[id].pos = self.RouteNumbers[id].pos*TLM.LampIndicator[4] end
self.Models[1]["rous"]:SetPos(self:LocalToWorld(self.RouteNumbers[id].pos))
self.Models[1]["rous"]:SetAngles(self:GetAngles())
self.Models[1]["rous"]:SetParent(self)
end
if #self.RouteNumbers > 0 and (#self.RouteNumbers ~= 1 or not self.RouteNumbers.sep) then
self.RN = 1
self.RouteNumberOffset = TLM.RouteNumberOffset
offset = offset + self.RouteNumberOffset*(self.Left and Vector(-1,1,1) or 1)
else
self.RouteNumberOffset = nil
self.RN = nil
end
if self.AutostopPresent then
if not IsValid(self.Models[1]["autostop"]) then
self.Models[1]["autostop"] = ClientsideModel(self.AutostopModel[1],RENDERGROUP_OPAQUE)
self.Models[1]["autostop"]:SetPos(self:LocalToWorld(self.BasePosition+self.AutostopModel[2]))
self.Models[1]["autostop"]:SetAngles(self:GetAngles())
self.Models[1]["autostop"]:SetParent(self)
end
end
self.NamesOffset = Vector(0, 0, 0)
-- Create traffic light models
--if self.LightType > 2 then self.LightType = 2 end
--if self.LightType < 0 then self.LightType = 0 end
local first = true
for _,v in ipairs(self.LensesTBL) do
local data
if not self.TrafficLightModels[self.LightType][v] then
data = self.TrafficLightModels[self.LightType][#v-1]
else
if v == "M" then
self.RouteNumber = ID
end
data = self.TrafficLightModels[self.LightType][v]
end
if not data then continue end
local vec = Vector(0,0,data[1])
if first then
first = false
else
offset = offset - vec
end
self.NamesOffset = self.NamesOffset + vec
local offsetAndLongOffset = offset + self.LongOffset
if not self.Left or self.Double then self:SpawnHeads(ID,data[2],self.BasePosition + offsetAndLongOffset,Angle(0, 0, 0),data[3] and data[3].glass,v~="M") end
if self.Left or self.Double then self:SpawnHeads((self.Double and ID.."d" or ID),(not TLM.noleft) and data[2]:Replace(".mdl","_mirror.mdl") or data[2],self.BasePosition*Vector(-1,1,1) + offsetAndLongOffset,Angle(0, 0, 0),data[3] and data[3].glass,v~="M",true) end
if v ~= "M" then
for i = 1,#v do
ID2 = ID2 + 1
if not self.Signals[ID2] then self.Signals[ID2] = {} end
if not self.DoubleL then
self:SetLight(ID,ID2,self.BasePosition*(self.Left and Vector(-1,1,1) or 1) + offsetAndLongOffset + data[3][i-1]*(self.Left and Vector(-1,1,1) or 1),Angle(0, 0, 0),self.SignalConverter[v[i]]-1,0 )
else
self:SetLight(ID,ID2,self.BasePosition + offsetAndLongOffset + data[3][i-1],Angle(0, 0, 0),self.SignalConverter[v[i]]-1,0)
self:SetLight(ID,ID2.."x",self.BasePosition*Vector(-1,1,1) + offsetAndLongOffset + data[3][i-1]*Vector(-1,1,1),Angle(0, 0, 0),self.SignalConverter[v[i]]-1,0)
end
end
end
ID = ID + 1
end
if self.Arrow then
local id = self.Arrow
self.Models[1]["roua"] = ClientsideModel(TLM.LampIndicator.model.."4.mdl",RENDERGROUP_OPAQUE)
self.SpecRouteNumbers.pos = (self.BasePosition+offset+self.LongOffset-TLM.LampIndicator[5])*(self.Left and TLM.LampIndicator[6] or 1) - (self.RouteNumberOffset or Vector(0, 0, 0))
self.Models[1]["roua"]:SetPos(self:LocalToWorld(self.SpecRouteNumbers.pos))
self.Models[1]["roua"]:SetAngles(self:LocalToWorldAngles(self.Left and Angle(-90,0,0) or Angle(90,0,0)))
self.Models[1]["roua"]:SetParent(self)
end
offset = self.RenderOffset[self.LightType]+(OneLense and TLM.name_one or TLM.name)+(OneLense and self.RouteNumberOffset or Vector(0, 0, 0))
if self.LightType == 1 then
offset = offset - self.NamesOffset
end
local double = self.LightType ~= 1 and string.find(self.Name,"^[A-Z][A-Z]")
if double then
if not self.Left or self.Double then
self:SpawnLetter(0,TLM.SignLetterSmall.model,offset - TLM.SignLetterSmall[2],(Metrostroi.LiterWarper[self.Name[0+1]] or self.Name[0+1]),true)
self:SpawnLetter(1,TLM.SignLetterSmall.model,offset - TLM.SignLetterSmall[1],(Metrostroi.LiterWarper[self.Name[1+1]] or self.Name[1+1]),true)
end
if self.Left or self.Double then
self:SpawnLetter(0,TLM.SignLetterSmall.model,offset - TLM.SignLetterSmall[1],(Metrostroi.LiterWarper[self.Name[0+1]] or self.Name[0+1]),false)
self:SpawnLetter(1,TLM.SignLetterSmall.model,offset - TLM.SignLetterSmall[2],(Metrostroi.LiterWarper[self.Name[1+1]] or self.Name[1+1]),false)
end
end
local min = 0
for i = double and 2 or 0,#self.Name-1 do
local id = (double and i-1 or i) - min
if double and i == 2 then offset = offset + TLM.DoubleOffset end
if self.Name[i+1] == " " then continue end
if self.Name[i+1] == "/" then min = min + 1; continue end
--if not IsValid(self.Models[2][i]) then
self:SpawnLetter(i,TLM.SignLetter.model,offset - Vector(0,0,id*TLM.SignLetter.z),(Metrostroi.LiterWarper[self.Name[i+1]] or self.Name[i+1]))
--end
end
if self.Name and self.Name:match("(/+)$") then
local i = #self.Name
local id = (double and i-1 or i) - min
self:SpawnLetter(i,TLM.SignLetter.model,offset - Vector(0,0,id*TLM.SignLetter.z),Format("s%d",math.min(3,#self.Name:match("(/+)$"))))
end
else
local k = "m1"
if not IsValid(self.Models[1][k]) then
local v = TLM["m1"]
self.Models[1][k] = ClientsideModel(v,RENDERGROUP_OPAQUE)
self.Models[1][k]:SetPos(self:LocalToWorld(self.BasePosition*(self.Left and Vector(-1,1,1) or 1)))
self.Models[1][k]:SetAngles(self:LocalToWorldAngles(self.Left and Angle(-1,1,1) or Angle(1,1,1)))
self.Models[1][k]:SetParent(self)
end
end
self.Models.have = true
self.ModelsCreated = true
else
--TODO
if self.AutostopPresent then
if IsValid(self.Models[1]["autostop"]) then
self.Models[1]["autostop"]:SetPoseParameter("position",self:Animate("Autostop", self:GetNW2Bool("Autostop") and 1 or 0, 0,1, 0.4,false))
end
end
self.Sig = self:GetNW2String("Signal","")
self.Num = self:GetNW2String("Number",nil)
if self.OldNum ~= self.Num then
self.NextNumWork = CurTime + 1
end
self.OldNum = self.Num
if (self.NextNumWork or CurTime) - CurTime >= 0 then
self.Num = ""
end
if self.ARSOnly then return true end
local offset = (self.RenderOffset[self.LightType] or Vector(0, 0, 0))
if self.RouteNumberOffset then offset = offset + self.RouteNumberOffset*(self.Left and Vector(-1,1) or Vector(1,1)) end
local ID = 0
local ID2 = 0
local first = true
for _,v in ipairs(self.LensesTBL) do
local data
if not self.TrafficLightModels[self.LightType][v] then
data = self.TrafficLightModels[self.LightType][#v-1]
else
data = self.TrafficLightModels[self.LightType][v]
end
if not data then continue end
if first then
first = false
else
offset = offset - Vector(0,0,data[1])
end
--self.NamesOffset = self.NamesOffset + Vector(0,0,data[1])
if v ~= "M" then
for i = 1,#v do
ID2 = ID2 + 1
local n = tonumber(self.Sig[ID2])
if n and self.Signals[ID2].RealState ~= (n > 0) then
self.Signals[ID2].RealState = n > 0
self.Signals[ID2].Stop = CurTime + 0.5
end
if self.Signals[ID2].Stop and CurTime-self.Signals[ID2].Stop > 0 then
self.Signals[ID2].Stop = nil
end
local State = self:Animate(ID.."/"..i, ((n == 1 or (n == 2 and (RealTime() % 1.2 > 0.4))) and not self.Signals[ID2].Stop) and 1 or 0, 0,1, 128)
if not IsValid(self.Models[3][ID..ID2]) and State > 0 then self.Signals[ID2].State = nil end
local offsetAndLongOffset = offset + self.LongOffset
if not self.DoubleL then
self:SetLight(ID,ID2,self.BasePosition*(self.Left and Vector(-1,1,1) or 1) + offsetAndLongOffset + data[3][i-1]*(self.Left and Vector(-1,1,1) or 1),Angle(0, 0, 0),self.SignalConverter[v[i]]-1,State,self.Signals[ID2].State ~= State)
else
self:SetLight(ID,ID2,self.BasePosition + offsetAndLongOffset + data[3][i-1],Angle(0, 0, 0),self.SignalConverter[v[i]]-1,State,self.Signals[ID2].State ~= State)
self:SetLight(ID,ID2.."x",self.BasePosition*Vector(-1,1,1) + offsetAndLongOffset + data[3][i-1]*Vector(-1,1,1),Angle(0, 0, 0),self.SignalConverter[v[i]]-1,State,self.Signals[ID2].State ~= State)
end
self.Signals[ID2].State = State
end
else
if Metrostroi.RoutePointer[self.Num[1]] and IsValid(self.Models[1][self.RouteNumber]) then self.Models[1][self.RouteNumber]:SetSkin(Metrostroi.RoutePointer[self.Num[1]]) end
end
ID = ID + 1
end
local LampIndicatorModels_numb_mdl = TLM.LampIndicator.model.."_numb.mdl"
local LampIndicatorModels_lamp_mdl = TLM.LampIndicator.model.."_lamp.mdl"
for k,v in pairs(self.RouteNumbers) do
if k == "sep" then continue end
local rou1k = "rou1"..k
local State1 = self:Animate(rou1k,self.Num:find(v[1]) and 1 or 0, 0,1, 256)
local State2
--if v[3] then
local rou2k = "rou2"..k
if v[2] then State2 = self:Animate(rou2k,self.Num:find(v[2])and 1 or 0, 0,1, 256) end
if not IsValid(self.Models[3][rou1k]) and State1 > 0 then
self.Models[3][rou1k] = ClientsideModel(v[3] and LampIndicatorModels_numb_mdl or LampIndicatorModels_lamp_mdl,RENDERGROUP_OPAQUE)
self.Models[3][rou1k]:SetPos(self:LocalToWorld(v.pos + self.OldRouteNumberSetup[4]))
self.Models[3][rou1k]:SetAngles(self:GetAngles())
self.Models[3][rou1k]:SetParent(self)
self.Models[3][rou1k]:SetSkin(v[3] and self.OldRouteNumberSetup[5][v[1]] or self.OldRouteNumberSetup[6][v[1]] or tonumber(v[1])-1)
self.Models[3][rou1k]:SetRenderMode(RENDERMODE_TRANSCOLOR)
self.Models[3][rou1k]:SetColor(Color(255, 255, 255, 0))
end
if IsValid(self.Models[3][rou1k]) then
if State1 > 0 then
self.Models[3][rou1k]:SetColor(Color(255,255,255,State1*255))
elseif State1 == 0 then
self.Models[3][rou1k]:Remove()
end
end
if not IsValid(self.Models[3][rou2k]) and v[3] and v[2] and State2 > 0 then
self.Models[3][rou2k] = ClientsideModel(LampIndicatorModels_numb_mdl,RENDERGROUP_OPAQUE)
self.Models[3][rou2k]:SetPos(self:LocalToWorld(v.pos + self.OldRouteNumberSetup[4] + TLM.RouteNumberOffset2))
self.Models[3][rou2k]:SetAngles(self:GetAngles())
self.Models[3][rou2k]:SetParent(self)
self.Models[3][rou2k]:SetSkin(self.OldRouteNumberSetup[5][v[2]] or tonumber(v[2])-1)
self.Models[3][rou2k]:SetRenderMode(RENDERMODE_TRANSCOLOR)
self.Models[3][rou2k]:SetColor(Color(255, 255, 255, 0))
end
if IsValid(self.Models[3][rou2k]) then
if State2 > 0 then
self.Models[3][rou2k]:SetColor(Color(255,255,255,State2*255))
elseif State2 == 0 then
self.Models[3][rou2k]:Remove()
end
end
end
if self.Arrow then
local State = self:Animate("roua",self.Num:find(self.SpecRouteNumbers[1]) and 1 or 0, 0,1, 256)
if not IsValid(self.Models[3]["roua"]) and State > 0 then
self.Models[3]["roua"] = ClientsideModel(LampIndicatorModels_lamp_mdl,RENDERGROUP_OPAQUE)
self.SpecRouteNumbers.pos = (self.BasePosition+offset-TLM.SpecRouteNumberOffset)-(self.RouteNumberOffset or Vector(0, 0, 0))+TLM.RouteNumberOffset3
if self.Left then self.SpecRouteNumbers.pos = self.SpecRouteNumbers.pos*TLM.SpecRouteNumberOffset2 end
self.Models[3]["roua"]:SetPos(self.Models[1]["roua"]:LocalToWorld(TLM.RouaOffset))
self.Models[3]["roua"]:SetAngles(self.Models[1]["roua"]:LocalToWorldAngles(Angle(180,0,0)))
self.Models[3]["roua"]:SetParent(self)
if self.Left then
if self.Num[1] == "L" then
self.Models[3]["roua"]:SetSkin(self.OldRouteNumberSetup[6]["R"] or 0)
else
self.Models[3]["roua"]:SetSkin(self.OldRouteNumberSetup[6]["L"] or 0)
end
else
self.Models[3]["roua"]:SetSkin(self.OldRouteNumberSetup[6][self.Num[1]] or 0)
end
self.Models[3]["roua"]:SetRenderMode(RENDERMODE_TRANSCOLOR)
self.Models[3]["roua"]:SetColor(Color(255, 255, 255, 0))
end
if IsValid(self.Models[3]["roua"]) then
if State > 0 then
self.Models[3]["roua"]:SetColor(Color(255,255,255,State*255))
elseif State == 0 then
self.Models[3]["roua"]:Remove()
end
end
end
--self.SpecRouteNumbers
end
return true
end
local C_SignalDebug = GetConVar("metrostroi_drawsignaldebug")
function ENT:Draw(flags)
-- Draw model
self:DrawModel(flags)
if not C_SignalDebug:GetBool() then return end
if LocalPlayer():GetPos():DistToSqr(self:GetPos()) > 200000 then return end
if EyeVector():Dot(self:LocalToWorldAngles(Angle(0,90,90)):Forward()) > 0.1 then return end
local pos = self:LocalToWorld(Vector(48,0,150))
local ang = self:LocalToWorldAngles(Angle(0,180,90))
cam.Start3D2D(pos, ang, 0.25)
self:DrawDebug()
cam.End3D2D()
end
local ars = {
{"275 Hz", "0 KM/H"},
{"N/A Hz", "No frequency"},
{"275-N/A", "Absolute stop"},
nil,
{"225 Hz", "40 KM/H"},
nil,
{"175 Hz", "60 KM/H"},
{"125 Hz", "70 KM/H"},
{"75 Hz", "80 KM/H"},
}
local cols = {
R = Color(200,0,0),
Y = Color(200,200,0),
G = Color(0,200,0),
W = Color(200,200,200),
B = Color(0,0,200),
}
function ENT:DrawDebug()
surface.SetDrawColor(self.ARSOnly and 255 or 125, 125, 0, 255)
if not self:GetNW2Bool("Debug",false) then
surface.DrawRect(0, 0, 364, 25)
draw.DrawText("Debug disabled...","Trebuchet24",5,0,Color(0, 0, 0, 255))
return
end
if not self.Name then
surface.DrawRect(0, 0, 364, 25)
draw.DrawText("No data...","Trebuchet24",5,0,Color(0, 0, 0, 255))
return
end
surface.DrawRect(0, -60, 364, 210)
if not self.ARSOnly then
surface.DrawRect(0, 155, 240, 165)
surface.DrawRect(0, 325, 240, 190)
surface.SetDrawColor(0,0,0, 255)
surface.DrawRect(245, 155, 119, 365)
else
surface.DrawRect(0, 155, 364, 165)
surface.DrawRect(0, 325, 364, 190)
end
draw.DrawText(Format("Joint main info (%d)",self:EntIndex()),"Trebuchet24",5,-60,Color(200,0,0,255))
draw.DrawText("Signal name: "..self.Name,"Trebuchet24", 5, -40,Color(0, 0, 0, 255))
draw.DrawText("TrackID: "..self:GetNW2Int("PosID",0),"Trebuchet24", 25, -20,Color(0, 0, 0, 255))
draw.DrawText(Format("PosX: %.02f",self:GetNW2Float("Pos",0)),"Trebuchet24", 135, -20,Color(0, 0, 0, 255))
draw.DrawText(Format("NextSignalName: %s",self:GetNW2String("NextSignalName","N/A")),"Trebuchet24", 5, 0,Color(0, 0, 0, 255))
draw.DrawText(Format("TrackID: %s",self:GetNW2Int("NextPosID",0)),"Trebuchet24", 25, 20,Color(0, 0, 0, 255))
draw.DrawText(Format("PosX: %.02f",self:GetNW2Float("NextPos",0)),"Trebuchet24", 135, 20,Color(0, 0, 0, 255))
draw.DrawText(Format("Dist: %.02f",self:GetNW2Float("DistanceToNext",0)),"Trebuchet24", 5, 40,Color(0, 0, 0, 255))
draw.DrawText(Format("PrevSignalName: %s",self:GetNW2String("PrevSignalName","N/A")),"Trebuchet24", 5, 60,Color(0, 0, 0, 255))
draw.DrawText(Format("TrackID: %s",self:GetNW2Int("PrevPosID",0)),"Trebuchet24", 25, 80,Color(0, 0, 0, 255))
draw.DrawText(Format("PosX: %.02f",self:GetNW2Float("PrevPos",0)),"Trebuchet24", 135, 80,Color(0, 0, 0, 255))
draw.DrawText(Format("DistPrev: %.02f",self:GetNW2Float("DistanceToPrev",0)),"Trebuchet24", 5, 100,Color(0, 0, 0, 255))
draw.DrawText(Format("Current route: %d",self:GetNW2Int("CurrentRoute",-1)),"Trebuchet24", 5, 120,Color(0, 0, 0, 255))
draw.DrawText("AB info","Trebuchet24",5,155,Color(200,0,0,255))
draw.DrawText(Format("Occupied: %s",self:GetNW2Bool("Occupied",false) and "Y" or "N"),"Trebuchet24",5,175,Color(0, 0, 0, 255))
draw.DrawText(Format("Linked to controller: %s",self:GetNW2Bool("LinkedToController",false) and "Y" or "N"),"Trebuchet24",5,195,Color(0, 0, 0, 255))
draw.DrawText(Format("Num: %d",self:GetNW2Int("ControllersNumber",0)),"Trebuchet24",25,215,Color(0, 0, 0, 255))
draw.DrawText(Format("Controller logic: %s",self:GetNW2Bool("BlockedByController",false) and "Y" or "N"),"Trebuchet24",5,235,Color(0, 0, 0, 255))
draw.DrawText(Format("Autostop: %s",not self.ARSOnly and self.AutostopPresent and (self:GetNW2Bool("Autostop") and "Up" or "Down") or "No present"),"Trebuchet24",5,255,Color(0, 0, 0, 255))
draw.DrawText(Format("2/6: %s",self:GetNW2Bool("2/6",false) and "Y" or "N"),"Trebuchet24",5,275,Color(0, 0, 0, 255))
draw.DrawText(Format("FreeBS: %d",self:GetNW2Int("FreeBS")),"Trebuchet24",5,295,Color(0, 0, 0, 255))
draw.DrawText("ARS info","Trebuchet24",5,325,Color(200,0,0,255))
local num = 0
for i,tbl in pairs(ars) do
if not tbl then continue end
if self:GetNW2Bool("CurrentARS"..(i-1),false) then
draw.DrawText(Format("(% s)",tbl[1]),"Trebuchet24",5,345+num*20,Color(0,100,0,255))
draw.DrawText(Format("%s",tbl[2]),"Trebuchet24",105,345+num*20,Color(0,100,0,255))
else
draw.DrawText(Format("(% s)",tbl[1]),"Trebuchet24",5,345+num*20,Color(0, 0, 0, 255))
draw.DrawText(Format("%s",tbl[2]),"Trebuchet24",105,345+num*20,Color(0, 0, 0, 255))
end
num = num+1
end
if self:GetNW2Bool("CurrentARS325",false) or self:GetNW2Bool("CurrentARS325_2",false) then
draw.DrawText("(325 Hz)","Trebuchet24",5,345+num*20,Color(0,100,0,255))
draw.DrawText(Format("LN:%s Apr0:%s",self:GetNW2Bool("CurrentARS325",false) and "Y" or "N",self:GetNW2Bool("CurrentARS325_2",false) and "Y" or "N"),"Trebuchet24",105,345+num*20,Color(0,100,0,255))
else
draw.DrawText("(325 Hz)","Trebuchet24",5,345+num*20,Color(0, 0, 0, 255))
draw.DrawText(Format("LN:%s Apr0:%s",self:GetNW2Bool("CurrentARS325",false) and "Y" or "N",self:GetNW2Bool("CurrentARS325_2",false) and "Y" or "N"),"Trebuchet24",105,345+num*20,Color(0, 0, 0, 255))
end
if not self.ARSOnly then
draw.DrawText("Signal info","Trebuchet24",250,160,Color(200,0,0,255))
local ID = 0
local ID2 = 0
local first = true
for _,v in ipairs(self.LensesTBL) do
local data
if not self.TrafficLightModels[self.LightType][v] then
data = self.TrafficLightModels[self.LightType][#v-1]
else
data = self.TrafficLightModels[self.LightType][v]
end
if not data then continue end
--self.NamesOffset = self.NamesOffset + Vector(0,0,data[1])
if v ~= "M" then
for i = 1,#v do
ID2 = ID2 + 1
local n = tonumber(self.Sig[ID2])
local State = n == 1 and "X" or (n == 2 and (RealTime() % 1.2 > 0.4)) and "B" or false
draw.DrawText(Format(v[i],self:EntIndex()),"Trebuchet24",250,160 + ID*20 + ID2*20,cols[v[i]])
if State then
draw.DrawText(State,"Trebuchet24",280,160 + ID*20 + ID2*20,cols[v[i]])
end
end
else
ID2 = ID2 + 1
draw.DrawText("M","Trebuchet24",250,160 + ID*20 + ID2*20,Color(200,200,200))
draw.DrawText(self.Num or "none","Trebuchet24",280,160 + ID*20 + ID2*20,Color(200,200,200))
--if Metrostroi.RoutePointer[self.Num[1]] then self.Models[1][self.RouteNumber]:SetSkin(Metrostroi.RoutePointer[self.Num[1]]) end
end
ID = ID + 1
end
end
end
Metrostroi.OptimisationPatch()