1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
This commit is contained in:
g_brzhezinskiy
2021-01-02 12:51:45 +03:00
commit 1d05caf866
613 changed files with 337020 additions and 0 deletions

View File

@@ -0,0 +1,562 @@
--------------------------------------------------------------------------------
-- ASOTP "IGLA" white 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_CBKI1")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize()
self.Log = {}
self.States = {}
self.Messages = {}
self.MessagesCount = 0
if not self.Train.IGLA1 then
self.Train:LoadSystem("IGLA1","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA2","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA3","Relay","Switch",{bass = true})
self.Train:LoadSystem("IGLA4","Relay","Switch",{bass = true})
end
self.TriggerNames = {
"IGLA1",
"IGLA2",
"IGLA3",
"IGLA4",
}
self.Triggers = {}
self.State = 0
self.Timer = 0
if not TURBOSTROI then
self.BVolt = 3.0+math.random()*0.4
self.Train:SetNW2Int("IGLA:BVolt",self.BVolt*10)
end
end
if TURBOSTROI then return end
function TRAIN_SYSTEM:Inputs()
return { "" }
end
if CLIENT then
local Chars = {
full = utf8.char(0x2588),
lhalf = utf8.char(0x258C),
rhalf = utf8.char(0x2590),
shade = utf8.char(0x2592),
[1] = utf8.char(0x2776),
[2] = utf8.char(0x2777),
[3] = utf8.char(0x2778),
[4] = utf8.char(0x2779),
[5] = utf8.char(0x277A),
[6] = utf8.char(0x277B),
[7] = utf8.char(0x277C),
[8] = utf8.char(0x277D),
[9] = utf8.char(0x277E),
[0] = utf8.char(0x24FF),
}
local Converter = {
["\1"] = Chars[1],
["\2"] = Chars[2],
["\3"] = Chars[3],
["\4"] = Chars[4],
["\5"] = Chars[5],
["\6"] = Chars[6],
["\7"] = Chars[7],
["\8"] = Chars[8],
["\9"] = Chars[9],
["\0"] = Chars[0],
}
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
function TRAIN_SYSTEM:PrintText(x,y,text,col)
local str = {utf8.codepoint(text,1,-1)}
for i=1,#str do
local char = utf8.char(str[i])
local alpha = col.a
if alpha > 1 then
draw.SimpleText(char,"MetrostroiSubway_IGLAb",-8+(x+i)*25,30+y*43+1,ColorAlpha(col,alpha*0.08),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
end
draw.SimpleText(char,"MetrostroiSubway_IGLA",-8+(x+i)*25,30+y*43,col,TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
end
end
function TRAIN_SYSTEM:ClientThink()
if not self.Train:ShouldDrawPanel("IGLA") then return end
if not self.DrawTimer then
render.PushRenderTarget(self.Train.IGLA,0,0,512, 128)
render.Clear(0, 0, 0, 0)
render.PopRenderTarget()
end
self.DrawTimer = self.DrawTimer or CurTime()
if 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 = "прев арс 9км\\ч",
RU = "резерв котнрол",
}
local colorb = Color(60,160,140,1)
local colorf = Color(60,160,140,255)
local colorh = Color(60,160,140,75)
function TRAIN_SYSTEM:IGLA()
local Train = self.Train
surface.SetDrawColor(60*0.075,160*0.075,140*0.075)
surface.DrawRect(0,0,512,107)
self:PrintText(0,0,string.rep(Chars.full,20),colorb)
self:PrintText(0,1,string.rep(Chars.full,20),colorb)
local State = self.Train:GetNW2Int("IGLA:State",0)
if State == -3 then
self:PrintText(0,0,"обратитесь в службу",colorf)
self:PrintText(0,1,"ремонта чайников",colorf)
elseif State == 0 then
if RealTime()%0.6 > 0.3 then
self:PrintText(0,0,Chars.full,colorf)
end
elseif State == 1 then
self.VoltRandom = self.VoltRandom or RealTime()
if not self.Volt1 or CurTime()-self.VoltRandom > 0 then
self.VoltRandom = CurTime()+0.2+math.random()*0.6
self.Volt1 = 4.9+math.random()*0.2
self.Volt2 = 3.0+math.random()*0.2
end
self:PrintText(0,0,"к 15в 5в 3.3в бт пчм",colorf)
if not Train:GetNW2Bool("IGLA:E") or RealTime()%0.5 > 0.25 then
self:PrintText(0,1,Format("%X",Train:GetNW2Int("IGLA:B")),colorf)
end
self:PrintText(2,1,"15",colorf)
self:PrintText(5,1,Format("%.1f",self.Volt1 or 5),colorf)
self:PrintText(9,1,Format("%.1f",self.Volt2 or 3.2),colorf)
self:PrintText(13,1,Format("%.1f",Train:GetNW2Int("IGLA:BVolt",0)/10),colorf)
if Train:GetNW2Bool("IGLA:P") then self:PrintText(17,1,".",colorf) end
if Train:GetNW2Bool("IGLA:C") then self:PrintText(18,1,".",colorf) end
self:PrintText(19,1,".",colorf)
elseif State == 2 then
local State2 = Train:GetNW2Int("IGLA:State2",0)
--[[ for i=1,6 do
self:PrintText((i-1)*3,0,Format("%02d",i),colorf)
self:PrintText((i-1)*3,1,Format("%02d",Train:GetNW2Int("PUAV:RK" .. i,0)),colorf)
end--]]
if State2 == 0 then
local Standby = Train:GetNW2Bool("IGLA:Standby")
local ShowTime = Train:GetNW2Bool("IGLA:ShowTime")
if not Standby then
local count = Train:GetNW2Int("IGLA:Count")
self:PrintText(0,0,"асотп",colorf)
self:PrintText(6,0,Format("%2d",count),colorf)
self:PrintText(9,0,"комплект",colorf)
self:PrintText(17,0,FormatEnd1(count),colorf)
local d = Metrostroi.GetSyncTime()
self:PrintText(0,1,os.date("!%d-%m-%y",d),colorf)
self:PrintText(12,1,os.date("!%H:%M:%S",d),colorf)
elseif ShowTime then
local d = Metrostroi.GetSyncTime()
self:PrintText(0,1,os.date("!%d-%m-%y",d),colorh)
self:PrintText(12,1,os.date("!%H:%M:%S",d),colorh)
end
elseif State2 == 1 then
local w = Train:GetNW2Int("IGLA:WagNumber")
local m = Train:GetNW2String("IGLA:ErrorID")
if messages[m] then m = messages[m] end
if m == "PTROverheat" then
if CurTime()%2 > 1 then
self:PrintText(1,0,"!! PIZDA POEZDU !!",colorf)
else
self:PrintText(0,0,Format("%05d",w),colorf)
self:PrintText(6,0,"ПТР",colorf)
self:PrintText(10,0,Format ("% 3dC",Train:GetNW2Int("IGLA:Temp",0)),colorf)
self:PrintText(15,0,"пожар",colorf)
end
elseif m == "PTROverheating" then
self:PrintText(0,0,Format("%05d",w),colorf)
self:PrintText(6,0,"ПТР",colorf)
self:PrintText(9,0,Format ("% 3dC",Train:GetNW2Int("IGLA:Temp",0)),colorf)
self:PrintText(15,0,"перег",colorf)
else
self:PrintText(0,0,Format("%05d",w),colorf)
self:PrintText(6,0,m,colorf)
end
self:PrintText(0,1,"^",colorf)
if Train:GetNW2Bool("IGLA:ButtonL2") then self:PrintText(6,1,"<-",colorf) end
if Train:GetNW2Bool("IGLA:ButtonL3") then self:PrintText(11,1,"->",colorf) end
self:PrintText(15,1,Format("[%03d]",Train:GetNW2Int("IGLA:MessagesCount")),colorf)
elseif State2 == 2 then
self:PrintText(0,0,"введите код:",colorf)
elseif State2 == 3 then
local w = Train:GetNW2Int("IGLA:WagNumber")
local m = Train:GetNW2String("IGLA:LogID")
if messages[m] then m = messages[m] end
if w > 0 then
self:PrintText(0,0,Format("%05d",w),colorf)
if m == "PTROverheat" then
if CurTime()%2 > 1 then
self:PrintText(6,0,"PIZDA POEZDU",colorf)
else
self:PrintText(6,0,"ПТР",colorf)
self:PrintText(10,0,"пожар",colorf)
end
elseif m == "PTROverheating" then
self:PrintText(6,0,"ПТР",colorf)
self:PrintText(10,0,"перегрев",colorf)
else
self:PrintText(6,0,m,colorf)
end
else
self:PrintText(0,0,m,colorf)
end
self:PrintText(0,1,"^",colorf)
local d = Train:GetNW2Int("IGLA:LogDate")
self:PrintText(3,1,os.date("!%d-%m-%y",d),colorf)
self:PrintText(12,1,os.date("!%H:%M:%S",d),colorf)
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:Trigger(name,value)
if self.State == -3 then
local ID = tonumber(name[5])
if ID and bit.band(self.StartError,2^(ID-1)) == 0 then
self.Reset = true
end
elseif self.State == 2 then
local ID = tonumber(name[5])
if self.State2 == 0 then
if ID == 1 and self.MessagesCount > 0 and value then
self.State2 = 1
self.StandbyTimer = CurTime()
self.Selected = #self.Messages
elseif ID == 4 and CurTime()-self.StandbyTimer > 10 and value then
self.ShowTimeTimer = CurTime()
elseif ID==4 and not value and self.ShowTimeTimer then
if self.ShowTimeTimer ~= true then self.StandbyTimer = CurTime() end
self.ShowTimeTimer = nil
end
elseif self.State2 == 1 then
self.StandbyTimer = CurTime()
if ID==1 and value then
self.State2 = 0
elseif ID==2 and value and self.Selected > 1 then
self.Selected = self.Selected - 1
end
if ID==3 and value and self.Selected < #self.Messages then
self.Selected = self.Selected + 1
end
elseif self.State2 == 2 and ID and value then
self.Password = self.Password..ID
if #self.Password > 3 then
if self.Password == "3241" then
self.State2 = 3
self.StandbyTimer = CurTime()
self.Selected = #self.Log
else
self.State2 = 0
end
self.Password = nil
end
elseif self.State2 == 3 then
self.StandbyTimer = CurTime()
if ID==1 and value then
self.State2 = 0
elseif ID==2 and value and self.Selected > 1 then
self.Selected = self.Selected - 1
end
if ID==3 and value and self.Selected < #self.Log 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,status})
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)
local Train = self.Train
local Power = Train.Panel.CBKIPower > 0
if Power and --[[ Train.A63.Value > 0.5 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 --[[ Train.A63.Value < 0.5 or--]] self.Reset then
self.Reset = false
if self.State ~= -2 then
self.State = -2
self.Timer = nil
self.Timer1 = nil
self.Timer2 = nil
self.ButtonL1 = false
self.ButtonL2 = false
self.ButtonL3 = false
self.ButtonL4 = false
self.Fire = 0
self.Error = 0
self.States = {}
self.Messages = {}
end
end
if self.State == -2 and Power --[[ and Train.A63.Value > 0.5--]] 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_start2","cabin",nil,2)
self.Timer = CurTime()+math.random()*0.4
end
if self.State == 0 and CurTime()-self.Timer > 0.6 then
table.insert(self.Log,{"START",sourceid,Metrostroi.GetSyncTime()})
self.State = 1
Train:PlayOnce("igla_start1","cabin")
self.Timer = CurTime()+math.random()*0.4
self.Timer1 = 0.9+CurTime()+math.random()*0.2
self.Timer2 = 1.0+CurTime()+math.random()*1.2
self.StartError = Train.IGLA1.Value+Train.IGLA2.Value*2+Train.IGLA3.Value*4+Train.IGLA4.Value*8
Train:SetNW2Bool("IGLA:E",self.StartError > 0)
end
if self.State == 1 then
Train:SetNW2Bool("IGLA:P",CurTime()-self.Timer1 > 0)
Train:SetNW2Bool("IGLA:C",CurTime()-self.Timer2 > 0)
Train:SetNW2Int("IGLA:B",Train.IGLA1.Value+Train.IGLA2.Value*2+Train.IGLA3.Value*4+Train.IGLA4.Value*8)
self.ButtonL1 = self.StartError > 0 or CurTime()-self.Timer < 3
self.ButtonL2 = self.ButtonL1
self.ButtonL3 = self.ButtonL1
self.ButtonL4 = self.ButtonL1
self.Fire = true
self.Error = true
--Train:SetNW2Bool("IGLA:M",CurTime()-self.Timer3 > 0)
if CurTime()-self.Timer > 5 then
self.State = self.StartError > 0 and -3 or 2
self.State2 = 0
self.StandbyTimer = CurTime()
self.ShowTimeTimer = nil
self.ShowTime = false
self.FireAlarm = false
self.OverhAlarm = false
self.FireState = false
self.OverhState = false
Train:PlayOnce("igla_start2","cabin",nil,1)
self.PCBKTimer = nil
end
elseif self.State == -3 then
self.ButtonL1 = bit.band(self.StartError,1) == 0
self.ButtonL2 = bit.band(self.StartError,2) == 0
self.ButtonL3 = bit.band(self.StartError,4) == 0
self.ButtonL4 = bit.band(self.StartError,8) == 0
self.Fire = false
self.Error = CurTime()%0.5 > 0.25
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 10
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_alarm3","cabin",nil,1)
self.StandbyTimer = CurTime()
if self.State2 ~= 1 then
self.State2 = 1
self.Selected = mess
end
if self.Selected >= self.MessagesCount then
self.Selected = mess
end
end
if self.State2 == 1 and self.Selected > mess then self.Selected = mess end
if self.State2 == 1 and mess == 0 then
self.State2 = 0
end
self.MessagesCount = mess
end
if self.State2 == 0 then
if self.Triggers.IGLA2 and self.Triggers.IGLA3 then
self.Password = ""
self.State2 = 2
self.StandbyTimer = CurTime()
end
self.ButtonL1 = self.MessagesCount > 0
self.ButtonL2 = false
self.ButtonL3 = false
self.ButtonL4 = Standby
elseif self.State2 == 1 then
local err = self.Messages[self.Selected]
Train:SetNW2String("IGLA:ErrorID",err[1])
Train:SetNW2Int("IGLA:WagNumber",err[2])
if err[1] == "PTROverheating" or err[1] == "PTROverheat" then
Train:SetNW2Int("IGLA:Temp",math.floor(self.States[err[2]][err[1]]))
end
self.ButtonL1 = true
self.ButtonL2 = self.Selected > 1
self.ButtonL3 = self.Selected < #self.Messages
Train:SetNW2Int("IGLA:MessagesCount",self.MessagesCount)
self.ButtonL4 = false
elseif self.State2 == 2 then
self.ButtonL1 = true
self.ButtonL2 = true
self.ButtonL3 = true
self.ButtonL4 = true
elseif self.State2 == 3 then
if self.Selected >= #self.Log then self.Selected = #self.Log end
local log = self.Log[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
self.ButtonL1 = true
self.ButtonL2 = self.Selected > 1
self.ButtonL3 = self.Selected < #self.Log
self.ButtonL4 = false
end
Train:SetNW2Int("IGLA:Count",self.PCBKCount)
Train:SetNW2Int("IGLA:State2",self.State2)
Train:SetNW2Bool("IGLA:Standby",Standby)
Train:SetNW2Bool("IGLA:ShowTime",self.ShowTime)
self.Fire = false
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 = CurTime()%0.5>0.25
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_alarm2","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_alarm3","cabin",nil,1)
self.FireState = math.floor((CurTime()-self.FireAlarm)*1.5)
end
self.Error = false
end
Train:SetNW2Bool("IGLA:Messages",self.MessagesCount)
Train:SetNW2Bool("IGLA:ButtonL1",self.ButtonL1)
Train:SetNW2Bool("IGLA:ButtonL2",self.ButtonL2)
Train:SetNW2Bool("IGLA:ButtonL3",self.ButtonL3)
Train:SetNW2Bool("IGLA:ButtonL4",self.ButtonL4)
Train:SetNW2Bool("IGLA:Fire",self.Fire)
Train:SetNW2Bool("IGLA:Error",self.Error)
Train:SetNW2Int("IGLA:State",self.State)
end
end