1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
Files
MetrostroiAddon/lua/metrostroi/systems/sys_igla_cbki2.lua
g_brzhezinskiy 1d05caf866 init
2021-01-02 12:51:45 +03:00

492 lines
20 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.
--------------------------------------------------------------------------------
-- ASOTP "IGLA" black indicator unit for 81-720
--------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information.
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("IGLA_CBKI2")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize()
self.Log = {}
self.States = {}
self.Messages = {}
self.MessagesCount = 0
if not self.Train.IGLA1U then
self.Train:LoadSystem("IGLA1U","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA1","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA1D","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA2U","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA2","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA2D","Relay","Switch",{bass = true})
end
self.TriggerNames = {
"IGLA1U",
"IGLA1",
"IGLA1D",
"IGLA2U",
"IGLA2",
"IGLA2D",
}
self.Triggers = {}
self.State = -2
end
if TURBOSTROI then return end
function TRAIN_SYSTEM:Inputs()
return { "Disable" }
end
if CLIENT then
local function FormatEnd1(num)
if num == 1 then return " "
elseif 1 < num and num < 5 then return "а" end
return "ов"
end
local function FormatEnd2(num)
if num == 1 then return "ка"
elseif 1 < num and num < 5 then return "ки" end
return "ок"
end
surface.CreateFont("Metrostroi_ILGAo", {
font = "Liquid Crystal Display",
size = 40,
weight = 800,
blursize = false,
antialias = true,
underline = false,
italic = false,
strikeout = false,
symbol = false,
rotary = false,
shadow = false,
additive = false,
outline = false,
extended = true,
scanlines = false,
})
function TRAIN_SYSTEM:PrintText(x,text,inverse)
local str = {utf8.codepoint(text,1,-1)}
for i=1,#str do
local char = utf8.char(str[i])
if inverse then
draw.SimpleText(string.char(0x7f),"Metrostroi_ILGAo",(x+i)*30,42,Color(0,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
draw.SimpleText(char,"Metrostroi_ILGAo",(x+i)*30,42,Color(140,190,0,150),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
else
draw.SimpleText(char,"Metrostroi_ILGAo",(x+i)*30,42,Color(0,0,0,255),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
end
end
end
function TRAIN_SYSTEM:ClientThink()
if not self.Train:ShouldDrawPanel("IGLA") then return end
--RunConsoleCommand("say","президент!!!")
if not self.DrawTimer then
render.PushRenderTarget(self.Train.IGLA,0,0,512, 128)
render.Clear(0, 0, 0, 0)
render.PopRenderTarget()
end
if self.DrawTimer and CurTime()-self.DrawTimer < 0.1 then return end
self.DrawTimer = CurTime()
render.PushRenderTarget(self.Train.IGLA,0,0,512, 128)
--render.Clear(0, 0, 0, 0)
cam.Start2D()
self:IGLA(self.Train)
cam.End2D()
render.PopRenderTarget()
end
local messages = {
START = "пит цбки вкл",
CONN = "подкл",
DISCONN = "отк пцбк",
SCHEME = "несб сх",
RP = "сраб рп",
DOORS = "откр дв",
BPSN = "выкл дип",
PARKING = "вкл ст т",
MANUAL = "вкл рч т",
BRAKES = "вкл пн т",
UAVA = "сраб СК",
UAVAK = "кон уава",
EPK = "сраб эпв",
ARS = "прев арс",
RU = "вкл ру",
}
function TRAIN_SYSTEM:IGLA()
local Train = self.Train
local State = self.Train:GetNW2Int("IGLA:State",0)
if State > -2 then
surface.SetDrawColor(81,223,0,self.Warm and 100 or 255)
surface.DrawRect(0,0,512,80)
self.Warm = true
else
surface.SetDrawColor(81*0.2,223*0.2,0,230)
surface.DrawRect(0,0,512,80)
self.Warm = false
end
if State == 0 then
self:PrintText(0,"Chip test Ok Ok")
elseif State == 1 then
self:PrintText(0,"АСОТП-\"ИГЛА\" V02")
elseif State == 2 then
local State2 = Train:GetNW2Int("IGLA:State2",0)
if State ~= self.OldState then
self.Timer = RealTime()
self.OldState = State
end
if State2 == 0 then
--self:PrintText(0,"")
self:PrintText(0,Format("[%03d]",Train:GetNW2Int("IGLA:Messages")))
self:PrintText(7,"ПЦБК-"..Train:GetNW2Int("IGLA:Count",0))
elseif State2 == 1 then
local w = Train:GetNW2Int("IGLA:WagNumber")
local m = Train:GetNW2String("IGLA:LogID")
local s = Train:GetNW2Int("IGLA:Selected")
if s ~= self.OldSel then
self.Timer = RealTime()-0.01
self.OldSel = s
end
if messages[m] then m = messages[m] end
local timer = math.ceil((RealTime()-self.Timer)%3)
if m ~= "PTROverheat" or timer == 1 then
if w > 0 then self:PrintText(0,Format("[%05d]",w)) else self:PrintText(0,"[]") end
end
if timer == 1 then
if w > 0 then
if m == "PTROverheating" then
self:PrintText(7,"перегрев")
elseif m == "PTROverheat" then
self:PrintText(7,"пожар")
else
self:PrintText(7,m)
end
else
self:PrintText(2,m)
end
elseif m == "PTROverheat" then
self:PrintText(0,"!PIZDA POEZDU!")
elseif timer == 2 then
local d = Train:GetNW2Int("IGLA:LogDate")
self:PrintText(w > 0 and 7 or 2,os.date("!%H:%M:%S",d))
else
local d = Train:GetNW2Int("IGLA:LogDate")
self:PrintText(w > 0 and 7 or 2,os.date("!%d-%m-%y",d))
end
if Train:GetNW2Int("IGLA:Arrow") == -1 then
self:PrintText(15,"<")
elseif Train:GetNW2Int("IGLA:Arrow") == 1 then
self:PrintText(15,">")
else
self:PrintText(15,"<")
self:PrintText(15,">")
end
elseif State2 == 2 then
local w = Train:GetNW2Int("IGLA:WagNumber")
local m = Train:GetNW2String("IGLA:ErrorID")
local s = Train:GetNW2Int("IGLA:Selected")
if s ~= self.OldSel then
self.Timer = RealTime()-0.01
self.OldSel = s
end
if messages[m] then m = messages[m] end
local timer = math.ceil((RealTime()-self.Timer)%3)
if m ~= "PTROverheat" or timer == 1 then
if w > 0 then self:PrintText(0,Format("[%05d]",w)) else self:PrintText(0,"[]") end
end
if timer == 1 then
if w > 0 then
if m == "PTROverheating" then
self:PrintText(7,Format("пер % 3d",Train:GetNW2Int("IGLA:Temp",0)))
elseif m == "PTROverheat" then
self:PrintText(7,Format("пож % 3d",Train:GetNW2Int("IGLA:Temp",0)))
else
self:PrintText(7,m)
end
else
self:PrintText(2,m)
end
elseif m == "PTROverheat" then
self:PrintText(0,"!PIZDA POEZDU!")
elseif timer == 2 then
local d = Train:GetNW2Int("IGLA:LogDate")
self:PrintText(w > 0 and 7 or 2,os.date("!%H:%M:%S",d))
else
local d = Train:GetNW2Int("IGLA:LogDate")
self:PrintText(w > 0 and 7 or 2,os.date("!%d-%m-%y",d))
end
if Train:GetNW2Int("IGLA:Arrow") == -1 then
self:PrintText(15,"<")
elseif Train:GetNW2Int("IGLA:Arrow") == 1 then
self:PrintText(15,">")
else
self:PrintText(15,"<")
self:PrintText(15,">")
end
end
end
end
else
function TRAIN_SYSTEM:CANReceive(source,sourceid,target,targetid,textdata,numdata)
if self.State < 2 then return end
if not self.States[sourceid] then
self.States[sourceid] = {}
table.insert(self.Log,{"CONN",sourceid,Metrostroi.GetSyncTime()})
end
self.States[sourceid][textdata] = numdata
end
function TRAIN_SYSTEM:CANWrite(name,value)
self.Train:CANWrite("IGLA_CBKI",self.Train:GetWagonNumber(),"IGLA_PCBK",nil,name,value)
end
function TRAIN_SYSTEM:TriggerInput(name,value)
if name == "Disable" then
self.Disable = value>0
if self.Disable then self:Initialize() end
end
end
function TRAIN_SYSTEM:Trigger(name,value)
if self.State == 2 then
if self.State2 == 0 then
if name == "IGLA2D" and value and #self.Log > 0 then
self.State2 = 1
self.StandbyTimer = CurTime()
self.Selected = #self.Log
end
if name == "IGLA1D" and value and #self.Messages > 0 then
self.State2 = 2
self.StandbyTimer = CurTime()
self.Selected = #self.Messages
end
elseif self.State2 == 1 then
self.StandbyTimer = CurTime()
if name == "IGLA2D" and value and self.Selected > 1 then
self.Selected = self.Selected - 1
end
if name == "IGLA2" and value then
self.State2 = 0
end
if name == "IGLA2U" and value and self.Selected < #self.Log then
self.Selected = self.Selected + 1
end
elseif self.State2 == 2 then
self.StandbyTimer = CurTime()
if name == "IGLA1D" and value and self.Selected > 1 then
self.Selected = self.Selected - 1
end
if name == "IGLA1" and value then
self.State2 = 0
end
if name == "IGLA1U" and value and self.Selected < #self.Messages then
self.Selected = self.Selected + 1
end
end
end
end
local Logging = {
PTROverheat = true,
PTROverheating = true,
SCHEME = false,
RP = true,
DOORS = true,
BPSN = true,
PARKING = true,
MANUAL = true,
BRAKES = true,
UAVA = true,
UAVAK = true,
EPK = true,
ARS = true,
RU = true,
}
function TRAIN_SYSTEM:CError(WagID,ErrID,status)
local ID = WagID..ErrID
if not self.Messages[ID] and status then
self.Messages[ID] = table.insert(self.Messages,{ErrID,WagID,Metrostroi.GetSyncTime(),ID})
if Logging[ErrID] then
table.insert(self.Log,self.Messages[self.Messages[ID]])
end
--print(Format("Message with ErrID '%s' have ID:%d",ID,self.Messages[ID]))
elseif self.Messages[ID] and not status then
--print(Format("Removed message with ErrID '%s' have ID:%d",ID,self.Messages[ID]))
table.remove(self.Messages,self.Messages[ID])
self.Messages[ID] = nil
for k,v in ipairs(self.Messages) do
self.Messages[v[4]] = k
end
end
end
function TRAIN_SYSTEM:Think(dT)
if self.Disable then return end
local Train = self.Train
local Power = Train.Panel.CBKIPower > 0
if Power and self.State ~= -2 then
for k,v in pairs(self.TriggerNames) do
if Train[v] and (Train[v].Value > 0.5) ~= self.Triggers[v] then
self:Trigger(v,Train[v].Value > 0.5)
self.Triggers[v] = Train[v].Value > 0.5
end
end
end
if not Power or self.Reset then
self.Reset = false
if self.State ~= -2 then
self.State = -2
self.Timer = nil
self.Fire = false
self.Error = false
self.OverhAlarm = false
self.OverhState = false
self.FireAlarm = false
self.FireState = false
self.PCBKCount = 0
self.States = {}
self.Messages = {}
end
end
if self.State == -2 and Power then
self.State = -1
self.Timer = CurTime()+math.random()*0.3
self.StartError = false
end
if self.State == -1 and CurTime()-self.Timer > 0.3 then
self.State = 0
Train:PlayOnce("igla_start1","cabin")
self.Timer = CurTime()+math.random()*0.6
end
if self.State == 0 and CurTime()-self.Timer > 3.4 then
table.insert(self.Log,{"START",sourceid,Metrostroi.GetSyncTime()})
self.State = 1
Train:PlayOnce("igla_start2","cabin")
self.Timer = CurTime()+math.random()*0.4
end
if self.State == 1 then
self.Error = true
if CurTime()-self.Timer > 4 then
self.State = 2
self.State2 = 0
self.StandbyTimer = CurTime()
self.ShowTimeTimer = nil
self.ShowTime = false
self.PCBKTimer = nil
end
elseif self.State == 2 then
if #self.Log > 100 then table.remove(self.Log,1) end
local Standby = CurTime()-self.StandbyTimer > 10
if self.State2 > 0 and Standby then self.State2 = 0 end
if self.ShowTimeTimer and self.ShowTimeTimer ~= true and CurTime()-self.ShowTimeTimer > 1.5 then
self.ShowTime = not self.ShowTime
self.ShowTimeTimer = true
end
if not self.PCBKTimer or CurTime()-self.PCBKTimer > 1.4 then
self:CANWrite("Update",1)
self.PCBKTimer = CurTime()+math.random()*0.4
end
local count = 0
for k,v in pairs(self.States) do
local timer = v.Timer and CurTime()-v.Timer or 100
if timer <= 5 then
for id in pairs(Logging) do self:CError(k,id,v[id]) end
count = count + 1
else
for k1,v1 in ipairs(self.Messages) do
if v1[2] == k then
--print(Format("Removed message with ErrID '%s' have ID:%d, PCBK discon",v1[4],self.Messages[v1[4]]))
self.Messages[v1[4]] = nil
table.remove(self.Messages,k1)
end
end
table.insert(self.Log,{"DISCONN",k,Metrostroi.GetSyncTime()})
self.States[k] = nil
end
end
self.PCBKCount = count
if self.MessagesCount ~= #self.Messages then
local mess = #self.Messages
if self.MessagesCount < mess then
Train:PlayOnce("igla_start2","cabin",nil,1)
self.StandbyTimer = CurTime()
if self.State2 ~= 2 then
self.State2 = 2
self.Selected = mess
end
if self.Selected >= self.MessagesCount then
self.Selected = mess
end
end
if self.State2 == 2 and self.Selected > mess then self.Selected = mess end
if self.State2 == 2 and mess == 0 then
self.State2 = 0
end
self.MessagesCount = mess
end
if self.State2 == 0 then
self.Error = self.MessagesCount > 0
elseif self.State2 == 1 then
if self.Selected >= #self.Log then self.Selected = #self.Log end
local log = self.Log[self.Selected]
Train:SetNW2Int("IGLA:Selected",self.Selected)
Train:SetNW2String("IGLA:LogID",log[1])
Train:SetNW2Int("IGLA:WagNumber",log[2])
Train:SetNW2Int("IGLA:LogDate",log[3])
for i=4,#log do
Train:SetNW2Int("IGLA:Log"..i,log[i])
end
if CurTime()-self.StandbyTimer > 10 then self.State2 = 0 end
Train:SetNW2Int("IGLA:Arrow",self.Selected == 1 and 1 or self.Selected == #self.Log and -1 or 0)
self.Error = false
elseif self.State2 == 2 then
local err = self.Messages[self.Selected]
if err[1] == "PTROverheating" or err[1] == "PTROverheat" then
Train:SetNW2Int("IGLA:Temp",math.floor(self.States[err[2]][err[1]]))
end
Train:SetNW2Int("IGLA:Selected",self.Selected)
Train:SetNW2String("IGLA:ErrorID",err[1])
Train:SetNW2Int("IGLA:WagNumber",err[2])
Train:SetNW2Int("IGLA:Arrow",self.Selected == 1 and 1 or self.Selected == #self.Messages and -1 or 0)
if CurTime()-self.StandbyTimer > 10 then self.State2 = 0 end
end
local overh = false
for i,v in ipairs(self.Messages) do
if v[1] == "PTROverheat" then
if not self.FireAlarm then self.FireAlarm = CurTime() end
self.Fire = true
self.OverhAlarm = true
elseif v[1] == "PTROverheating" and self.OverhAlarm ~= true then
overh = true
end
end
if overh and not self.OverhAlarm then
self.OverhAlarm = CurTime()
elseif not overh and self.OverhAlarm then
self.OverhAlarm = false
self.OverhState = false
end
if self.OverhAlarm and self.OverhAlarm ~= true and self.OverhState ~= math.floor((CurTime()-self.OverhAlarm)*2) and (not self.OverhState or self.OverhState < 5) then
Train:PlayOnce("igla_start1","cabin",nil,1)
self.OverhState = math.floor((CurTime()-self.OverhAlarm)*2)
end
if self.FireAlarm and self.FireState ~= math.floor((CurTime()-self.FireAlarm)*1.5) and (not self.FireState or self.FireState < 10) then
Train:PlayOnce("igla_start2","cabin",nil,1)
self.FireState = math.floor((CurTime()-self.FireAlarm)*1.5)
end
end
self.Error = self.MessagesCount > 0
Train:SetNW2Int("IGLA:Count",self.PCBKCount)
Train:SetNW2Int("IGLA:State2",self.State2)
Train:SetNW2Bool("IGLA:Messages",#self.Log)
Train:SetNW2Bool("IGLASR",self.State > -2)
Train:SetNW2Bool("IGLARX",self.State > -2 and self.PCBKCount == 0)
Train:SetNW2Bool("IGLAErr",self.State > 0 and self.Error or self.State == 1)
Train:SetNW2Bool("IGLAOSP", self.State == 1)
Train:SetNW2Bool("IGLAPI", self.Fire or self.State == 1)
Train:SetNW2Bool("IGLAOff", self.State == 1)
Train:SetNW2Int("IGLA:State",self.State)
end
end