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_81_722_passscheme.lua
kosmik641 0923f4f893 81-722.
Новая система БНТ
Небольшие правки в ТНМ
2025-05-30 12:57:30 +03:00

178 lines
6.1 KiB
Lua

--------------------------------------------------------------------------------
-- 81-722 BNT-12 system
--------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information.
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("81_722_BNT")
TRAIN_SYSTEM.DontAccelerateSimulation = true
TRAIN_SYSTEM.CAN_ACTIVATE = 0x01
TRAIN_SYSTEM.CAN_BMTS_TEXT = 0x10
TRAIN_SYSTEM.CAN_CURR = 0x21
TRAIN_SYSTEM.CAN_NEXT = 0x22
TRAIN_SYSTEM.CAN_PATH = 0x23
TRAIN_SYSTEM.CAN_CLOSERING = 0x24
TRAIN_SYSTEM.CAN_VOLUMES = 0x25
TRAIN_SYSTEM.CAN_SPEED = 0x26
-- self.AnnouncerPositions[4]:
-- 0x43 - Cabin speaker
-- 0x4C - Left side
-- 0x52 - Right side
function TRAIN_SYSTEM:Initialize()
self.Volumes = {
Speed = 0,
Ann = 5,
UPO = 5,
V5 = 0
}
self.Left = {
Power = false,
CloseRing = false,
CloseRingState = false,
Init = false,
Curr = 0,
Next = 0,
Back = false
}
self.Right = {
Power = false,
CloseRing = false,
CloseRingState = false,
Init = false,
Curr = 0,
Next = 0,
Back = false
}
end
if TURBOSTROI then return end
function TRAIN_SYSTEM:CANReceive(source,sourceid,target,targetid,textdata,numdata)
if textdata == self.CAN_SPEED then
self.Volumes.Speed = numdata
return
end
if textdata == self.CAN_CURR then
self.Left.Init = true
self.Right.Init = true
self.Left.Curr = self.Left.Power and numdata or 0
self.Right.Curr = self.Right.Power and numdata or 0
end
if textdata == self.CAN_NEXT then
self.Left.Init = true
self.Right.Init = true
self.Left.Next = self.Left.Power and numdata or 0
self.Right.Next = self.Right.Power and numdata or 0
end
if textdata == self.CAN_PATH then
self.Left.Init = true
self.Right.Init = true
self.Left.Back = self.Left.Power and numdata or false
self.Right.Back = self.Right.Power and numdata or false
end
if textdata == self.CAN_CLOSERING then
self.Left.CloseRing = self.Left.Power and numdata or false
self.Right.CloseRing = self.Right.Power and numdata or false
end
if textdata == self.CAN_VOLUMES then
self.Volumes.Ann = numdata[1]
self.Volumes.UPO = numdata[2]
self.Volumes.V5 = numdata[3]
end
if textdata == self.CAN_ACTIVATE then
for k,v in ipairs(self.Train.AnnouncerPositions) do
if (v[4] == 0x4C and self.Left.Power) or (v[4] == 0x52 and self.Right.Power) then
self.Train:PlayOnce("announcer_sarmat_start"..k,nil,self.Volumes.Ann/10,1)
end
end
end
end
local function setBitValue(targetVar, value, offset, bitCount)
value = bit.band(value,bit.lshift(1,bitCount)-1)
return bit.bor(targetVar,bit.lshift(value,offset))
end
function TRAIN_SYSTEM:Think()
local Train = self.Train
self.BNT(self.Left,self.Train.Panel.PassSchemePowerL > 0)
self.BNT(self.Right,self.Train.Panel.PassSchemePowerR > 0)
local doorAlarm = 0
doorAlarm = setBitValue(doorAlarm,self.Left.CloseRing and 1 or self.Right.CloseRing and 1 or 0,0,1)
doorAlarm = setBitValue(doorAlarm,self.Left.CloseRingState and 1 or 0,1,1)
doorAlarm = setBitValue(doorAlarm,self.Right.CloseRingState and 1 or 0,2,1)
Train:SetNW2Int("BNT:DoorAlarm",doorAlarm)
local volumes = 0
local volAnn = self.Volumes.Ann
local volUPO = self.Volumes.UPO
if self.Volumes.Speed > 5 then
volAnn = math.min(10,self.Volumes.Ann + self.Volumes.V5)
volUPO = math.min(10,self.Volumes.UPO + self.Volumes.V5)
end
volumes = setBitValue(volumes,volAnn,0,4)
volumes = setBitValue(volumes,volUPO,4,4)
Train:SetNW2Int("BNT:Volumes",volumes)
local statesLeft,statesRight = 0,0
statesLeft = setBitValue(statesLeft,self.Left.Power and 1 or 0,0,1)
statesLeft = setBitValue(statesLeft,self.Left.Init and 1 or 0,1,1)
statesLeft = setBitValue(statesLeft,self.Left.Back and 1 or 0,2,1)
statesLeft = setBitValue(statesLeft,self.Left.Next, 3,6)
statesLeft = setBitValue(statesLeft,self.Left.Curr, 9,6)
statesRight = setBitValue(statesRight,self.Right.Power and 1 or 0,0,1)
statesRight = setBitValue(statesRight,self.Right.Init and 1 or 0,1,1)
statesRight = setBitValue(statesRight,self.Right.Back and 1 or 0,2,1)
statesRight = setBitValue(statesRight,self.Right.Next, 3,6)
statesRight = setBitValue(statesRight,self.Right.Curr, 9,6)
Train:SetNW2Int("BNT:Left",statesLeft)
Train:SetNW2Int("BNT:Right",statesRight)
end
function TRAIN_SYSTEM:BNT(Power)
if Power and not self.Power then
self.Power = true
end
if not Power and self.Power then
self.Power = false
self.CloseRing = false
self.CloseRingState = false
self.CloseRingTimer = nil
self.CurrTimer = nil
self.Init = false
self.Curr = 0
self.Next = 0
self.Back = false
end
if not self.Power then return end
if self.CloseRing then
if not self.CloseRingTimer then self.CloseRingTimer = CurTime() end
self.CloseRingState = (CurTime() - self.CloseRingTimer)%1<0.5
if CurTime() - self.CloseRingTimer > 30 then
self.CloseRing = false
end
else
if self.CloseRingTimer then
self.CloseRingTimer = nil
self.CloseRingState = false
end
end
if not self.Init then
if not self.CurrTimer then self.CurrTimer = CurTime() end
if CurTime() - self.CurrTimer > 0.5 then
self.Curr = self.Curr + 1
if self.Curr > 32 then self.Curr = 0 end
self.CurrTimer = CurTime()
end
else
if self.CurrTimer then self.CurrTimer = nil end
end
end