mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
Merge pull request #104 from metrostroi-repo/#RemoveObsoleteContent
Removed obsolete content
This commit is contained in:
@@ -1,131 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Props81717()
|
||||
--if self.PropsInit then return end
|
||||
--self.PropsInit = true
|
||||
|
||||
local function GetDoorPosition(i,k,j)
|
||||
if j == 0
|
||||
then return Vector(349.0 - 32*k - 230*i,-65*(1-2*k),-2.8)
|
||||
else return Vector(349.0 - 32*(1-k) - 230*i,-65*(1-2*k),-2.8)
|
||||
end
|
||||
end
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
self.ClientProps["door"..i.."x"..k.."a"] = {
|
||||
model = "models/metrostroi/81/81-7036_door1.mdl",
|
||||
pos = GetDoorPosition(i,k,0),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
self.ClientProps["door"..i.."x"..k.."b"] = {
|
||||
model = "models/metrostroi/81/81-7036_door2.mdl",
|
||||
pos = GetDoorPosition(i,k,1),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
end
|
||||
end
|
||||
self.ClientProps["d1"] = {
|
||||
model = "models/metrostroi/81/81-7036_door4.mdl",
|
||||
pos = Vector(-487.0,-2.2,-4.5),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
self.ClientProps["d2"] = {
|
||||
model = "models/metrostroi/81/81-7036_door3.mdl",
|
||||
pos = Vector(414.0,65.0,-1.8),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
self.ClientProps["d3"] = {
|
||||
model = "models/metrostroi/81/81-7036_door5.mdl",
|
||||
pos = Vector(414.3,-65.0,-1.8),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
|
||||
local trainType = self:GetNW2String("TrainType")
|
||||
if trainType == "81-717" and not self.ClientProps["d1"] then
|
||||
--self:Props81717()
|
||||
end
|
||||
|
||||
-- Animate doors
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
local n_l = "door"..i.."x"..k.."a"
|
||||
local n_r = "door"..i.."x"..k.."b"
|
||||
local animation = self:Animate(n_l,self:GetPackedBool(21+i+4-k*4) and 1 or 0,0,1, 0.8 + (-0.2+0.4*math.random()),0)
|
||||
local offset_l = Vector(math.abs(31*animation),0,0)
|
||||
local offset_r = Vector(math.abs(32*animation),0,0)
|
||||
if self.ClientEnts[n_l] and IsValid(self.ClientEnts[n_l]) then
|
||||
self.ClientEnts[n_l]:SetPos(self:LocalToWorld(self.ClientProps[n_l].pos + (1.0 - 2.0*k)*offset_l))
|
||||
end
|
||||
if self.ClientEnts[n_r] and IsValid(self.ClientEnts[n_r]) then
|
||||
self.ClientEnts[n_r]:SetPos(self:LocalToWorld(self.ClientProps[n_r].pos - (1.0 - 2.0*k)*offset_r))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Brake-related sounds
|
||||
local brakeLinedPdT = self:GetPackedRatio(9)
|
||||
local dT = self.DeltaTime
|
||||
self.BrakeLineRamp1 = self.BrakeLineRamp1 or 0
|
||||
|
||||
if (brakeLinedPdT > -0.001)
|
||||
then self.BrakeLineRamp1 = self.BrakeLineRamp1 + 2.0*(0-self.BrakeLineRamp1)*dT
|
||||
else self.BrakeLineRamp1 = self.BrakeLineRamp1 + 2.0*((-0.4*brakeLinedPdT)-self.BrakeLineRamp1)*dT
|
||||
end
|
||||
self:SetSoundState("release2",self.BrakeLineRamp1,1.0)
|
||||
|
||||
self.BrakeLineRamp2 = self.BrakeLineRamp2 or 0
|
||||
if (brakeLinedPdT < 0.001)
|
||||
then self.BrakeLineRamp2 = self.BrakeLineRamp2 + 2.0*(0-self.BrakeLineRamp2)*dT
|
||||
else self.BrakeLineRamp2 = self.BrakeLineRamp2 + 2.0*(0.02*brakeLinedPdT-self.BrakeLineRamp2)*dT
|
||||
end
|
||||
self:SetSoundState("release3",self.BrakeLineRamp2,1.0)
|
||||
|
||||
-- Compressor
|
||||
local state = self:GetPackedBool(20)
|
||||
self.PreviousCompressorState = self.PreviousCompressorState or false
|
||||
if self.PreviousCompressorState ~= state then
|
||||
self.PreviousCompressorState = state
|
||||
if state then
|
||||
self:SetSoundState("compressor",1,1)
|
||||
else
|
||||
self:SetSoundState("compressor",0,0)
|
||||
self:PlayOnce("compressor_end",nil,0.75)
|
||||
end
|
||||
end
|
||||
|
||||
-- ARS/ringer alert
|
||||
local state = self:GetPackedBool(39)
|
||||
self.PreviousAlertState = self.PreviousAlertState or false
|
||||
if self.PreviousAlertState ~= state then
|
||||
self.PreviousAlertState = state
|
||||
if state then
|
||||
self:SetSoundState("ring",0.20,1)
|
||||
else
|
||||
self:SetSoundState("ring",0,0)
|
||||
self:PlayOnce("ring_end","cabin",0.45)
|
||||
end
|
||||
end
|
||||
|
||||
-- DIP sound
|
||||
self:SetSoundState("bpsn1",self:GetPackedBool(52) and 1 or 0,1.0)
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
self.BaseClass.OnRemove(self)
|
||||
for k,v in pairs(self.ClientProps) do
|
||||
self.ClientProps[k] = nil
|
||||
end
|
||||
for k,v in pairs(self.ClientEnts) do
|
||||
v:Remove()
|
||||
end
|
||||
self.ClientEnts = nil
|
||||
self.ClientProps = {}
|
||||
end
|
||||
@@ -1,538 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Initialize()
|
||||
-- Defined train information
|
||||
self.SubwayTrain = {
|
||||
Type = "AI",
|
||||
Name = "",
|
||||
}
|
||||
if not self.TrainType then self.TrainType = "81-717" end
|
||||
-- Set model and initialize
|
||||
self.NoPhysics = true
|
||||
if self.TrainType == "81-717" then self:SetModel("models/metrostroi/81/81-7036.mdl") end
|
||||
if self.TrainType == "81-714" then self:SetModel("models/metrostroi/81/81-7037.mdl") end
|
||||
self.BaseClass.Initialize(self)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 325-20,0,-75),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-325-10,0,-75),Angle(0,0,0),false)
|
||||
|
||||
-- Seats
|
||||
if self.TrainType == "81-717" then
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(410,-2,-23))
|
||||
--self.InstructorsSeat = self:CreateSeat("instructor",Vector(410,35,-28))
|
||||
--self.ExtraSeat = self:CreateSeat("instructor",Vector(410,-35,-28))
|
||||
end
|
||||
--[[
|
||||
for i=1,1 do --17
|
||||
local pos = Vector(280-(i-1)*30-math.floor((i-1)/5)*80,-47,-32)
|
||||
local p1 = self:CreateSeat("passenger",pos,Angle(0,90,0))
|
||||
pos.y = -pos.y
|
||||
local p2 = self:CreateSeat("passenger",pos,Angle(0,270,0))
|
||||
end]]
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- Find SOME sort of route
|
||||
local route
|
||||
for k,v in pairs(Metrostroi.AIConfiguration) do
|
||||
if not route then route = k end
|
||||
end
|
||||
|
||||
-- Initial setup
|
||||
if not self.Route then self.Route = route end
|
||||
if (not self.PathID) and (route) and Metrostroi.AIConfiguration[route] then
|
||||
self.PathID = Metrostroi.AIConfiguration[route].Path
|
||||
end
|
||||
self.Position = self.Position or 100
|
||||
self.Velocity = 0
|
||||
self.RheostatPosition = 0
|
||||
|
||||
-- Lights
|
||||
if self.TrainType == "81-717" then
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[1] = { "headlight", Vector(465,0,-20), Angle(0,0,0), Color(176,161,132), fov = 100 },
|
||||
[2] = { "glow", Vector(460, 51,-23), Angle(0,0,0), Color(255,255,255), brightness = 2 },
|
||||
[3] = { "glow", Vector(460,-51,-23), Angle(0,0,0), Color(255,255,255), brightness = 2 },
|
||||
[4] = { "glow", Vector(460,-8, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[5] = { "glow", Vector(460,-8, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[6] = { "glow", Vector(460, 2, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[7] = { "glow", Vector(460, 2, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
|
||||
-- Reverse
|
||||
[8] = { "light", Vector(458,-45, 55), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
[9] = { "light", Vector(458, 45, 55), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
|
||||
-- Cabin
|
||||
[10] = { "dynamiclight", Vector( 420, 0, 35), Angle(0,0,0), Color(255,255,255), brightness = 0.1, distance = 550 },
|
||||
|
||||
-- Interior
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
|
||||
-- Side lights
|
||||
[14] = { "light", Vector(-50, 68, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[15] = { "light", Vector(4, 68, 54), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[16] = { "light", Vector(1, 68, 54), Angle(0,0,0), Color(0,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[17] = { "light", Vector(-2, 68, 54), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[18] = { "light", Vector(-50, -69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[19] = { "light", Vector(5, -69, 54), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[20] = { "light", Vector(2, -69, 54), Angle(0,0,0), Color(0,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[21] = { "light", Vector(-1, -69, 54), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
}
|
||||
end
|
||||
if self.TrainType == "81-714" then
|
||||
self.Lights = {
|
||||
-- Interior
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
|
||||
-- Side lights
|
||||
[14] = { "light", Vector(-50, 68, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[15] = { "light", Vector(4, 68, 54), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[16] = { "light", Vector(1, 68, 54), Angle(0,0,0), Color(0,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[17] = { "light", Vector(-2, 68, 54), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[18] = { "light", Vector(-50, -69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[19] = { "light", Vector(5, -69, 54), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[20] = { "light", Vector(2, -69, 54), Angle(0,0,0), Color(0,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[21] = { "light", Vector(-1, -69, 54), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
}
|
||||
end
|
||||
|
||||
-- Prop-protection related
|
||||
if CPPI and IsValid(self.Owner) then
|
||||
self:CPPISetOwner(self.Owner)
|
||||
end
|
||||
-- Spawn a dummy consist
|
||||
if (self.TrainType == "81-717") and (not self.TrainHead) then
|
||||
for i=2,5 do
|
||||
local ent = ents.Create("gmod_subway_ai")
|
||||
if i == 5
|
||||
then ent.TrainType = "81-717"
|
||||
else ent.TrainType = "81-714"
|
||||
end
|
||||
ent.TrainIndex = i
|
||||
ent.TrainHead = self
|
||||
ent.Owner = self.Owner
|
||||
ent:Spawn()
|
||||
table.insert(self.TrainEntities,ent)
|
||||
end
|
||||
end
|
||||
--self:Remove()
|
||||
-- Type
|
||||
self:SetNW2String("TrainType",self.TrainType)
|
||||
end
|
||||
|
||||
--[[concommand.Add("metrostroi_ai_spawn", function(ply, _, args)
|
||||
if (ply:IsValid()) and (not ply:IsAdmin()) then return end
|
||||
|
||||
local pathid = tonumber(args[2]) or 1
|
||||
local trainCounter = tonumber(args[1]) or 1
|
||||
local prevEnt
|
||||
timer.Create("metrostroi-ai-spawntimer-"..pathid,1.0,0,function()
|
||||
if prevEnt then
|
||||
if (pathid == 1) and (prevEnt.Position < 260) then
|
||||
return
|
||||
end
|
||||
if (pathid == 2) and (prevEnt.Position < 960) then
|
||||
return
|
||||
end
|
||||
end
|
||||
if trainCounter < 1 then return end
|
||||
|
||||
local ent = ents.Create("gmod_subway_ai")
|
||||
ent.Position = 150
|
||||
ent.PathID = pathid
|
||||
ent:Spawn()
|
||||
prevEnt = ent
|
||||
trainCounter = trainCounter - 1
|
||||
print("Spawning AI trains (path "..pathid.."), left: "..trainCounter)
|
||||
end)
|
||||
end)
|
||||
|
||||
concommand.Add("metrostroi_ai_clear", function(ply, _, args)
|
||||
if (ply:IsValid()) and (not ply:IsAdmin()) then return end
|
||||
for k,v in pairs(ents.FindByClass("gmod_subway_ai")) do
|
||||
SafeRemoveEntity(v)
|
||||
if args[1] then print("Removed one") return end
|
||||
end
|
||||
--timer.Create("metrostroi-ai-spawntimer",1.0,0,function()end)
|
||||
end)]]--
|
||||
|
||||
concommand.Add("metrostroi_ai_info", function(ply, _, args)
|
||||
if (ply:IsValid()) and (not ply:IsAdmin()) then return end
|
||||
for k,v in pairs(ents.FindByClass("gmod_subway_ai")) do
|
||||
if not v.TrainHead then
|
||||
print(Format("Train to [%03d][%02d] (%.0f m %.02f km/h, left %0.3f m)",
|
||||
v.TargetStation or 0,v.TargetPlatform or 0,v.Position,v.Speed,
|
||||
(v.PlatformEdgeX or 0) - v.Position))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Train driving AI
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:DoAI(dT)
|
||||
-- Get a schedule
|
||||
if self.Schedule and (#self.Schedule == 0) then
|
||||
self.Schedule = nil
|
||||
end
|
||||
if (not self.Schedule) and (not self.NoStation) then
|
||||
self.Schedule = Metrostroi.GenerateSchedule(self.Route)
|
||||
self.StopTimer = 10
|
||||
end
|
||||
|
||||
-- See if must move to next station
|
||||
if self.Schedule then
|
||||
if ((Metrostroi.ServerTime()+10000 > (self.Schedule[1][3]*60)) and (self.StopTimer < 0)) or
|
||||
(self.StopTimer < -200) then
|
||||
table.remove(self.Schedule,1)
|
||||
self.StopTimer = 10
|
||||
end
|
||||
end
|
||||
|
||||
-- Get current target station info
|
||||
local platformEdgeX
|
||||
if self.Schedule and self.Schedule[1] then
|
||||
local targetStation = self.Schedule[1][1]
|
||||
local targetPlatform = self.Schedule[1][2]
|
||||
local stationData = Metrostroi.Stations[targetStation]
|
||||
local platformData
|
||||
if stationData then platformData = stationData[targetPlatform] end
|
||||
if platformData then
|
||||
platformEdgeX = math.max(platformData.x_end,platformData.x_start)
|
||||
end
|
||||
if platformData and platformData.node_end then
|
||||
if platformData.node_end.path.id ~= self.PathID then
|
||||
--print("WRONG PATH")
|
||||
platformEdgeX = nil
|
||||
end
|
||||
end
|
||||
self.TargetStation = targetStation
|
||||
self.TargetPlatform = targetPlatform
|
||||
else
|
||||
self.NoStation = true
|
||||
end
|
||||
self.PlatformEdgeX = platformEdgeX
|
||||
|
||||
if platformEdgeX then
|
||||
if self.Position > platformEdgeX then
|
||||
--print("Overrun!",self.Position,platformEdgeX)
|
||||
table.remove(self.Schedule,1)
|
||||
self.StopTimer = 10
|
||||
end
|
||||
end
|
||||
|
||||
-- Get current information on driving
|
||||
local speedLimit = self.ALS_ARS.SpeedLimit
|
||||
local nextLimit = self.ALS_ARS.NextLimit
|
||||
local targetSpeed = nextLimit
|
||||
--print()
|
||||
if nextLimit == 0 then targetSpeed = speedLimit end
|
||||
|
||||
-- Move at slow speed to next red light or blocked section
|
||||
if targetSpeed == 0 then targetSpeed = 20 end
|
||||
-- If there is a red light ahead, stop once in its range
|
||||
if self.RedLightDistance and (self.RedLightDistance < 20) then
|
||||
targetSpeed = 0
|
||||
end
|
||||
|
||||
-- Stop at station gradually
|
||||
if platformEdgeX and (platformEdgeX > self.Position) then
|
||||
local dX = platformEdgeX - self.Position
|
||||
if dX < 100 then
|
||||
targetSpeed = math.min(targetSpeed,55) * (math.max(0.0,math.min(1.0,(dX-12)/90))^0.5)
|
||||
if dX > 18 then targetSpeed = math.max(targetSpeed,20) end
|
||||
if self.Speed < 1 then
|
||||
self.StopTimer = self.StopTimer - dT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Wait for schedule start
|
||||
if (self.PathID == 1) and (self.Position < 250) and
|
||||
(self.Schedule) and (self.Schedule[1]) then
|
||||
local dT = self.Schedule[1][3]*60 - Metrostroi.ServerTime()
|
||||
--if dT > 90 then targetSpeed = 0 end
|
||||
end
|
||||
--targetSpeed = 0
|
||||
-- Reached target speed, stop accelerating
|
||||
if self.Speed > (targetSpeed-2) then
|
||||
self.Accelerating = false
|
||||
end
|
||||
-- Speed is below required, try to accelerate
|
||||
if self.Speed < (targetSpeed-10) then
|
||||
self.Accelerating = true
|
||||
end
|
||||
-- Exceeding speed limit, apply brakes
|
||||
if self.Speed > targetSpeed then
|
||||
self.Braking = true
|
||||
end
|
||||
-- Braked enough, stop braking
|
||||
if (self.Speed < (targetSpeed-5)) and (self.Braking) then
|
||||
self.Braking = false
|
||||
end
|
||||
|
||||
-- ARS system logic
|
||||
if false and self.ALS_ARS.LVD then
|
||||
self.Braking = true
|
||||
self.Accelerating = false
|
||||
end
|
||||
--print(self.ALS_ARS.LVD)
|
||||
if self.ALS_ARS.LVD
|
||||
then self.ALS_ARS.AttentionPedal = true
|
||||
else self.ALS_ARS.AttentionPedal = false
|
||||
end
|
||||
if speedLimit == 0 then self.ALS_ARS.AttentionPedal = true end
|
||||
|
||||
-- Apply pneumatic brakes if overspeeding much or stopped
|
||||
self.Pneumo = false
|
||||
if (self.Speed < 7) and (not self.Accelerating) then
|
||||
self.Pneumo = true
|
||||
end
|
||||
if (self.Speed > (targetSpeed+5)) then
|
||||
--self.Pneumo = true
|
||||
end
|
||||
|
||||
-- Save for statistics
|
||||
self.TargetSpeed = targetSpeed
|
||||
--if self.RedLightDistance and (self.RedLightDistance < 30) then self.Pneumo = true end
|
||||
end
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Train physics
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:DoPhysics(dT)
|
||||
-- Slopes code
|
||||
local slopeAngle = self:GetAngles().p
|
||||
if slopeAngle > 180 then slopeAngle = slopeAngle-360 end
|
||||
local slopeFactor = math.min(8.0,math.max(-8.0,slopeAngle))/8.0
|
||||
|
||||
-- Motor code
|
||||
local motorPower = 0
|
||||
if self.Accelerating then motorPower = 1.0 end
|
||||
if self.Braking then motorPower = -1.0 end
|
||||
|
||||
local motorForce = 0
|
||||
if motorPower > 0 then motorForce = 1.25*motorPower end
|
||||
if motorPower < 0 then motorForce = -1.3*math.abs(motorPower) * math.max(-1.0,math.min(1.0,0.25*self.Velocity)) end
|
||||
|
||||
-- Brake code
|
||||
local brakeForce = 0
|
||||
if self.Pneumo then
|
||||
brakeForce = -1.4*math.max(-1.0,math.min(1.0,3.0*self.Velocity))
|
||||
slopeFactor = slopeFactor*math.max(-1.0,math.min(1.0,3.0*self.Velocity))
|
||||
end
|
||||
self.PneumoForce = brakeForce
|
||||
|
||||
-- Integrate position and velocity
|
||||
self.Acceleration = 0
|
||||
+motorForce
|
||||
+brakeForce
|
||||
-self.Velocity*0.0045
|
||||
+slopeFactor*1.52
|
||||
self.Velocity = self.Velocity + dT*self.Acceleration
|
||||
self.Position = self.Position + dT*self.Velocity
|
||||
--print(Format("%.2f/%.2f km/h %.0f m A-%s B-%s P-%s",
|
||||
--self.Speed,self.TargetSpeed,self.Position,
|
||||
--tostring(self.Accelerating),tostring(self.Braking),tostring(self.Pneumo)))
|
||||
|
||||
-- Info
|
||||
self.MotorPower = motorPower
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
-- Basic think loop
|
||||
self.PrevTime = self.PrevTime or CurTime()
|
||||
self.DeltaTime = (CurTime() - self.PrevTime)
|
||||
self.PrevTime = CurTime()
|
||||
|
||||
--self:RecvPackedData()
|
||||
self:NextThink(CurTime()+0.10)
|
||||
|
||||
-- Simulate equipment specific to trains
|
||||
local dT = self.DeltaTime
|
||||
if (self.TrainType == "81-717") and (not self.TrainHead) then
|
||||
self.ALS_ARS:Think(dT,1)
|
||||
end
|
||||
|
||||
-- Select path
|
||||
if (not self.PathID) or (not self.Route) then return true end
|
||||
local path = Metrostroi.Paths[self.PathID]
|
||||
local config = Metrostroi.AIConfiguration[self.Route]
|
||||
if self.Position > config.EndPosition then
|
||||
self.Route = config.NextRoute
|
||||
config = Metrostroi.AIConfiguration[self.Route]
|
||||
self.PathID = config.Path
|
||||
self.Position = config.SpawnPosition
|
||||
self.Velocity = 0
|
||||
|
||||
self.Schedule = nil
|
||||
self.NoStation = false
|
||||
end
|
||||
--self.Velocity = 0
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- If needed, update train physics and AI
|
||||
if not self.TrainHead then
|
||||
self:DoAI(dT)
|
||||
self:DoPhysics(dT)
|
||||
else
|
||||
if not IsValid(self.TrainHead) then
|
||||
SafeRemoveEntity(self)
|
||||
return
|
||||
end
|
||||
|
||||
self.Route = self.TrainHead.Route
|
||||
self.PathID = self.TrainHead.PathID
|
||||
self.Position = self.TrainHead.Position - 18.6*(self.TrainIndex-1)
|
||||
self.Velocity = self.TrainHead.Velocity
|
||||
self.MotorPower = self.TrainHead.MotorPower
|
||||
self.PneumoForce = self.TrainHead.PneumoForce
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Lighting
|
||||
if self.TrainType == "81-717" then
|
||||
self:SetLightPower(1, self.TrainHead == nil)
|
||||
self:SetLightPower(2, self.TrainHead == nil)
|
||||
self:SetLightPower(3, self.TrainHead == nil)
|
||||
self:SetLightPower(4, self.TrainHead == nil)
|
||||
self:SetLightPower(5, self.TrainHead == nil)
|
||||
self:SetLightPower(6, self.TrainHead == nil)
|
||||
self:SetLightPower(7, self.TrainHead == nil)
|
||||
self:SetLightPower(8, self.TrainHead ~= nil)
|
||||
self:SetLightPower(9, self.TrainHead ~= nil)
|
||||
self:SetLightPower(10, (CurTime() % 60) > 0.1)
|
||||
self:SetLightPower(12, (CurTime() % 60) > 0.1)
|
||||
end
|
||||
if self.TrainType == "81-714" then
|
||||
self:SetLightPower(12, (CurTime() % 60) > 0.1)
|
||||
end
|
||||
-- Pneumatic brakes
|
||||
self.PneumaticPressure = self.PneumaticPressure or 0
|
||||
self.PneumaticPressure_dPdT = self.PneumaticPressure_dPdT or 0
|
||||
if self.Pneumo
|
||||
then self.PneumaticPressure_dPdT = 0.65*(1.5 - self.PneumaticPressure)
|
||||
else self.PneumaticPressure_dPdT = 0.65*(0.0 - self.PneumaticPressure)
|
||||
end
|
||||
self.PneumaticPressure = self.PneumaticPressure + self.PneumaticPressure_dPdT*dT
|
||||
|
||||
-- Minor state
|
||||
if self.TrainHead then
|
||||
self.LeftDoorsOpen = self.TrainHead.LeftDoorsOpen
|
||||
self.RightDoorsOpen = self.TrainHead.RightDoorsOpen
|
||||
else
|
||||
self.LeftDoorsOpen = self.StopTimer and (self.StopTimer < 9)
|
||||
self.RightDoorsOpen = self.StopTimer and (self.StopTimer < 9)
|
||||
end
|
||||
if self.LeftDoorsOpen ~= self.PrevLeftDoorsOpen then
|
||||
self.PrevLeftDoorsOpen = self.LeftDoorsOpen
|
||||
if self.LeftDoorsOpen then
|
||||
self:PlayOnce("door_open1")
|
||||
else
|
||||
self:PlayOnce("door_close1")
|
||||
end
|
||||
end
|
||||
if self.RightDoorsOpen ~= self.PrevRightDoorsOpen then
|
||||
self.PrevRightDoorsOpen = self.RightDoorsOpen
|
||||
if self.RightDoorsOpen then
|
||||
self:PlayOnce("door_open1")
|
||||
else
|
||||
self:PlayOnce("door_close1")
|
||||
end
|
||||
end
|
||||
self:SetPackedBool(21,self.LeftDoorsOpen)
|
||||
self:SetPackedBool(22,self.LeftDoorsOpen)
|
||||
self:SetPackedBool(23,self.LeftDoorsOpen)
|
||||
self:SetPackedBool(24,self.LeftDoorsOpen)
|
||||
self:SetPackedBool(25,self.RightDoorsOpen)
|
||||
self:SetPackedBool(26,self.RightDoorsOpen)
|
||||
self:SetPackedBool(27,self.RightDoorsOpen)
|
||||
self:SetPackedBool(28,self.RightDoorsOpen)
|
||||
self:SetPackedBool(52,1)
|
||||
self:SetPackedBool(39,self.ALS_ARS.LVD and (not self.TrainHead))
|
||||
|
||||
-- Update state of all objects and sounds
|
||||
self.Speed = math.abs(self.Velocity/0.277778)
|
||||
self.FrontBogey.Speed = self.Speed
|
||||
self.RearBogey.Speed = self.Speed
|
||||
self.FrontBogey.MotorPower = self.MotorPower
|
||||
self.RearBogey.MotorPower = self.MotorPower
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.PneumaticPressure_dPdT
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.PneumaticPressure_dPdT
|
||||
self.FrontBogey.BrakeSqueal = math.min(1,(3*math.abs(self.PneumoForce or 0))^1)
|
||||
self.RearBogey.BrakeSqueal = math.min(1,(3*math.abs(self.PneumoForce or 0))^1)
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Update train position
|
||||
local vec,dir,node = Metrostroi.GetTrackPosition(path,self.Position)
|
||||
if vec then
|
||||
--local vec1,dir1 = Metrostroi.GetTrackPosition(path,self.Position+0)
|
||||
local vec2,dir2 = Metrostroi.GetTrackPosition(path,self.Position-5)
|
||||
if dir2 then
|
||||
dir = dir2
|
||||
end
|
||||
|
||||
if self.TrainHead then dir = -dir end
|
||||
--[[local trace = {
|
||||
start = vec,
|
||||
endpos = vec + Vector(0,0,-384),
|
||||
mask = MASK_NPCWORLDSTATIC
|
||||
}
|
||||
local result = util.TraceLine(trace)]]--
|
||||
local rollAngle = Angle(0,0,0)--Angle(0,0,(180.0/math.pi)*math.acos(result.HitNormal.z))
|
||||
|
||||
self:SetPos(vec)
|
||||
self:SetAngles(dir:Angle() + rollAngle)
|
||||
end
|
||||
|
||||
-- Update information about restrictions in driving
|
||||
self.RestrictionTimeout = self.RestrictionTimeout or 0
|
||||
if (CurTime() - self.RestrictionTimeout) > 0.50 then
|
||||
self.RestrictionTimeout = CurTime()
|
||||
if node and (not self.TrainHead) then
|
||||
self.RedLightDistance = nil
|
||||
|
||||
-- Check ARS signal/traffic light being red
|
||||
local nextARS = Metrostroi.GetARSJoint(node,self.Position,true)
|
||||
if nextARS and nextARS.AutoEnabled then
|
||||
local arsOffset = (nextARS.ARSOffset or self.Position)
|
||||
local dX = math.abs(arsOffset - self.Position)
|
||||
if (not self.PlatformEdgeX) or (arsOffset < self.PlatformEdgeX) then
|
||||
self.RedLightDistance = dX
|
||||
end
|
||||
end
|
||||
|
||||
-- Find other trains on the same line
|
||||
if not self.RedLightDistance then
|
||||
for k,v in pairs(ents.FindByClass("gmod_subway_ai")) do
|
||||
if (v.PathID == self.PathID) and (v ~= self) and (v.Position > self.Position) then
|
||||
self.RedLightDistance = math.abs(v.Position - self.Position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- self:SendPackedData()
|
||||
return true
|
||||
end
|
||||
@@ -1,24 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameT = "AI Train"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
self:LoadSystem("ALS_ARS")
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,86 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameTranslated = "81-703"
|
||||
ENT.Author = "Oldy"
|
||||
ENT.Contact = "oldy702@gmail.com"
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["relay_close2"] = nil
|
||||
self.SoundNames["rvt_close"] = nil
|
||||
self.SoundNames["r1_5_close"] = nil
|
||||
self.SoundNames["rvt_open"] = nil
|
||||
self.SoundNames["r1_5_open"] = nil
|
||||
--[[self.SoundNames["relay_close4"] = {"subway_trains/new/relay_7.wav","subway_trains/new/lsd_4.wav"}
|
||||
self.SoundNames["pneumo_switch"] = {
|
||||
"subway_trains/pneumo_8.wav",
|
||||
"subway_trains/pneumo_9.wav",
|
||||
}]]
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема 81-710
|
||||
self:LoadSystem("Electric","81_701_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_117DM")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A","KF_47A")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_70")
|
||||
-- Контроллер резервного управления
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A")
|
||||
--self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
-- Панель управления Е
|
||||
self:LoadSystem("Panel","81_701_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
self:LoadSystem("DURA")
|
||||
self:LoadSystem("ALS_ARS")
|
||||
self:LoadSystem("Horn")
|
||||
self:LoadSystem("Announcer")
|
||||
--self:LoadSystem("RRI")
|
||||
end
|
||||
@@ -1,995 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
|
||||
-- Main panel
|
||||
ENT.ButtonMap["Main"] = {
|
||||
pos = Vector(460.968903,-32.25375,0.064331),
|
||||
ang = Angle(0,-90,90-27),
|
||||
width = 315,
|
||||
height = 240,
|
||||
scale = 0.0588,
|
||||
|
||||
buttons = {
|
||||
{ID = "DIPonSet", x=35 + 48.3*0, y=96, radius=20, tooltip="КУ4:Включение ДИП и освещения\nTurn DIP and interior lights on"},
|
||||
{ID = "DIPoffSet", x=35 + 48.3*1, y=96, radius=20, tooltip="КУ5:Отключение ДИП и освещения\nTurn DIP and interior lights off"},
|
||||
{ID = "VozvratRPSet", x=35 + 48.3*2, y=96, radius=20, tooltip="КУ9:Возврат РП\nReset overload relay"},
|
||||
{ID = "KSNSet", x=35 + 48.3*3, y=96, radius=20, tooltip="КУ8:Принудительное срабатывание РП на неисправном вагоне (сигнализация неисправности)\nKSN: Failure indication button"},
|
||||
{ID = "KDPSet", x=35 + 48.3*5, y=96, radius=20, tooltip="КДП:Правые двери\nKDP: Right doors open"},
|
||||
----Down Panel
|
||||
{ID = "KU1Toggle", x=16,y=129,w=45,h=90, tooltip="КУ1:Включение мотор-компрессора\nTurn motor-compressor on"},
|
||||
{ID = "VUD1Toggle", x=248,y=129,w=45,h=90, tooltip="КУ2: Закрытие дверей\nVUD: Door control toggle (close doors)"},
|
||||
----Lamps
|
||||
--{ID = "Lamp1", x=42, y=30, radius=20, tooltip="ЛВД: Лампа включения двигателей\nLVD: Engines engaged"},
|
||||
--{ID = "Lamp6", x=86, y=30, radius=20, tooltip="ЛСТ: Лампа сигнализации торможения\nLST: Brakes engaged"},
|
||||
--{ID = "Lamp2", x=134, y=30, radius=20, tooltip="Красная лампа РК (Вращение Реостатного контроллера)\nRK: Rheostat controller motion "},
|
||||
--{ID = "DoorsWag", x=134, y=30, radius=20, tooltip="Синяя лампа СД: Сигнализация дверей вагона\nBlue door state light (doors on wagon are closed)"},
|
||||
{ID = "RedRP", x=177, y=30, radius=20, tooltip="Красная РП: Красная лампа реле перегрузки\nRP: Red overload relay (power circuits failed to assemble)"},
|
||||
{ID = "GreenRP", x=223, y=30, radius=20, tooltip="Зеленая РП: Зелёная лампа реле перегрузки (Сигнализация перегрузки)\nRP: Green overload relay (overload relay open on current train)"},
|
||||
{ID = "DoorsWag", x=265, y=30, radius=20, tooltip="Белая лампа СД: Сигнализация дверей поезда\nWhite door state light (doors on train are closed)"},
|
||||
|
||||
{ID = "KDLSet", x=92, y=169, radius=20, tooltip="КУ12: Кнопка левых дверей\nKDL: Left doors open"},
|
||||
{ID = "KRZDSet", x=212, y=169, radius=20, tooltip="КУ10: Кнопка резервного закрытия дверей\nKRZD: Emergency door closing"},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Metrostroi.ClientPropForButton("GreenRP",{
|
||||
panel = "Main",
|
||||
button = "GreenRP",
|
||||
model = "models/metrostroi_train/e/lampgreen.mdl",
|
||||
z = 6,
|
||||
ang = 90,
|
||||
staylabel = true,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("RedRP",{
|
||||
panel = "Main",
|
||||
button = "RedRP",
|
||||
model = "models/metrostroi_train/e/lampred1.mdl",
|
||||
z = 6,
|
||||
ang = 90,
|
||||
staylabel = true,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("DoorsWag",{
|
||||
panel = "Main",
|
||||
button = "DoorsWag",
|
||||
model = "models/metrostroi_train/e/lampblue.mdl",
|
||||
z = 6,
|
||||
ang = 90,
|
||||
staylabel = true,
|
||||
})
|
||||
|
||||
|
||||
Metrostroi.ClientPropForButton("DIPon",{
|
||||
panel = "Main",
|
||||
button = "DIPonSet",
|
||||
model = "models/metrostroi_train/em/buttonred.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("DIPoff",{
|
||||
panel = "Main",
|
||||
button = "DIPoffSet",
|
||||
model = "models/metrostroi_train/em/buttonblack.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("VozvratRP",{
|
||||
panel = "Main",
|
||||
button = "VozvratRPSet",
|
||||
model = "models/metrostroi_train/em/buttonblack.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
|
||||
Metrostroi.ClientPropForButton("KSN",{
|
||||
panel = "Main",
|
||||
button = "KSNSet",
|
||||
model = "models/metrostroi_train/em/buttonred.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("KDP",{
|
||||
panel = "Main",
|
||||
button = "KDPSet",
|
||||
model = "models/metrostroi_train/em/buttonred.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
|
||||
Metrostroi.ClientPropForButton("KDL",{
|
||||
panel = "Main",
|
||||
button = "KDLSet",
|
||||
model = "models/metrostroi_train/em/buttonred.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("KRZD",{
|
||||
panel = "Main",
|
||||
button = "KRZDSet",
|
||||
model = "models/metrostroi_train/em/buttonblack.mdl",
|
||||
ang = 90,
|
||||
z = 0,
|
||||
})
|
||||
|
||||
Metrostroi.ClientPropForButton("VUD",{
|
||||
panel = "Main",
|
||||
button = "VUD1Toggle",
|
||||
model = "models/metrostroi_train/switches/vudwhite.mdl",
|
||||
z=-20,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("KU1",{
|
||||
panel = "Main",
|
||||
button = "KU1Toggle",
|
||||
model = "models/metrostroi_train/switches/vudbrown.mdl",
|
||||
z=-20,
|
||||
})
|
||||
|
||||
ENT.ButtonMap["RezMK"] = {
|
||||
pos = Vector(469.0,-19.75,37),
|
||||
ang = Angle(0,270,90),
|
||||
width = 50,
|
||||
height = 80,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "RezMKSet", x=0, y=0, w=50, h=80, tooltip="КУ15:Резервное включение мотор-компрессора\nRezMKSet"},
|
||||
}
|
||||
}
|
||||
Metrostroi.ClientPropForButton("RezMK",{
|
||||
panel = "RezMK",
|
||||
button = "RezMKSet",
|
||||
model = "models/metrostroi_train/switches/vudblack.mdl",
|
||||
})
|
||||
|
||||
ENT.ButtonMap["AVMain"] = {
|
||||
pos = Vector(408.06,40.8,56),
|
||||
ang = Angle(0,90,90),
|
||||
width = 335,
|
||||
height = 380,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "AV8BToggle", x=0, y=0, w=300, h=380, tooltip="АВ-8Б: Автоматическй выключатель (Вспомогательные цепи высокого напряжения)\n"},
|
||||
}
|
||||
}
|
||||
Metrostroi.ClientPropForButton("AV8B",{
|
||||
panel = "AVMain",
|
||||
button = "AV8BToggle",
|
||||
model = "models/metrostroi_train/switches/automain.mdl",
|
||||
z=43,
|
||||
})
|
||||
|
||||
---AV1 Panel
|
||||
ENT.ButtonMap["AV1"] = {
|
||||
pos = Vector(408.06,41,30),
|
||||
ang = Angle(0,90,90),
|
||||
width = 290+0,
|
||||
height = 155,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "VU3Toggle", x=0, y=0, w=100, h=140, tooltip="ВУ3: Освещение кабины\n"},
|
||||
{ID = "VU2Toggle", x=100, y=0, w=100, h=140, tooltip="ВУ2: Аварийное освещение 25В\n"},
|
||||
{ID = "VU1Toggle", x=200, y=0, w=100, h=140, tooltip="ВУ1: Печь отопления кабины ПТ-6\n"},
|
||||
}
|
||||
}
|
||||
for k,v in pairs(ENT.ButtonMap["AV1"].buttons) do
|
||||
if not v.ID then continue end
|
||||
Metrostroi.ClientPropForButton(v.ID:sub(0,-7),{
|
||||
panel = "AV1",
|
||||
button = v.ID,
|
||||
model = "models/metrostroi_train/switches/autobl.mdl",
|
||||
z=10,
|
||||
})
|
||||
end
|
||||
-- Battery panel
|
||||
ENT.ButtonMap["Battery"] = {
|
||||
pos = Vector(408.98,20.24,30.5),
|
||||
ang = Angle(0,90,90),
|
||||
width = 250,
|
||||
height = 136,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "VBToggle", x=0, y=0, w=250, h=136, tooltip="АБ: Выключатель аккумуляторной батареи (Вспомогательные цепи низкого напряжения)\nVB: Battery on/off"},
|
||||
}
|
||||
}
|
||||
Metrostroi.ClientPropForButton("VB",{
|
||||
panel = "Battery",
|
||||
button = "VBToggle",
|
||||
model = "models/metrostroi_train/switches/autobl2.mdl",
|
||||
z=15,
|
||||
})
|
||||
|
||||
--VU Panel
|
||||
ENT.ButtonMap["VU"] = {
|
||||
pos = Vector(469.5,-18.5,20),
|
||||
ang = Angle(0,270,90),
|
||||
width = 90,
|
||||
height = 120,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "VUToggle", x=0, y=0, w=90, h=120, tooltip="ВУ: Выключатель Управления\nVUToggle"},
|
||||
{ID = "VUPl", x=0, y=70, w=90, h=50, tooltip="Пломба ВУ\nVU plomb"},
|
||||
}
|
||||
}
|
||||
Metrostroi.ClientPropForButton("VU",{
|
||||
panel = "VU",
|
||||
button = "VUToggle",
|
||||
model = "models/metrostroi_train/switches/autobl.mdl",
|
||||
z=20,
|
||||
})
|
||||
|
||||
Metrostroi.ClientPropForButton("VUPl",{
|
||||
panel = "VU",
|
||||
button = "VUToggle",
|
||||
model = "models/metrostroi_train/switches/autoplombr.mdl",
|
||||
z=19,
|
||||
propname = false,
|
||||
ang=0,
|
||||
})
|
||||
--[[
|
||||
Metrostroi.ClientPropForButton("AVVB",{
|
||||
panel = "BatteryAV",
|
||||
button = "AVVBToggle",
|
||||
model = "models/metrostroi_train/switches/autobl2.mdl",
|
||||
z=15,
|
||||
})
|
||||
]]
|
||||
|
||||
-- Parking brake panel
|
||||
ENT.ButtonMap["ParkingBrake"] = {
|
||||
pos = Vector(460,49.0,6.0),
|
||||
ang = Angle(0,-82,90),
|
||||
width = 400,
|
||||
height = 400,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "ParkingBrakeLeft",x=0, y=0, w=200, h=400, tooltip="Поворот колеса ручного тормоза"},
|
||||
{ID = "ParkingBrakeRight",x=200, y=0, w=200, h=400, tooltip="Поворот колеса ручного тормоза"},
|
||||
}
|
||||
}
|
||||
|
||||
-- Train driver helpers panel
|
||||
ENT.ButtonMap["HelperPanel"] = {
|
||||
pos = Vector(455.13,58.99,24.44),
|
||||
ang = Angle(0,-17.5,90),
|
||||
width = 60,
|
||||
height = 188,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "VDLSet", x=30, y=42, radius=30, tooltip="ВДЛ: Выключатель левых дверей\nVDL: Left doors open"},
|
||||
{ID = "VUD2LToggle", x=0, y=110, w=60,h=20, tooltip="Блокировка ВУД2\nVUD2 lock"},
|
||||
{ID = "VUD2Toggle", x=30, y=138, radius=30, tooltip="ВУД2: Выключатель управления дверьми\nVUD2: Door control toggle (close doors)"},
|
||||
}
|
||||
}
|
||||
Metrostroi.ClientPropForButton("VUD2",{
|
||||
panel = "HelperPanel",
|
||||
button = "VUD2Toggle",
|
||||
model = "models/metrostroi_train/switches/vudwhite.mdl",
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("VUD2l",{
|
||||
panel = "HelperPanel",
|
||||
button = "VUD2Toggle",
|
||||
model = "models/metrostroi_train/switches/vudlock.mdl",
|
||||
z = 0,
|
||||
})
|
||||
Metrostroi.ClientPropForButton("VDL",{
|
||||
panel = "HelperPanel",
|
||||
button = "VDLSet",
|
||||
model = "models/metrostroi_train/switches/vudblack.mdl",
|
||||
z = 0,
|
||||
})
|
||||
|
||||
-- Pneumatic instrument panel 2
|
||||
ENT.ButtonMap["PneumaticManometer"] = {
|
||||
pos = Vector(459.247131,-54.307846,16.197767),
|
||||
ang = Angle(0,-90-51,90),
|
||||
|
||||
width = 70,
|
||||
height = 70,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{x=35,y=35,radius=35,tooltip="Давление в магистралях (красная: тормозной, чёрная: напорной)\nPressure in pneumatic lines (red: brake line, black: train line)"},
|
||||
}
|
||||
}
|
||||
-- Pneumatic instrument panel
|
||||
ENT.ButtonMap["PneumaticPanels"] = {
|
||||
pos = Vector(463.281189,-53.228256,11.310288),
|
||||
ang = Angle(0,-90-44,90),
|
||||
|
||||
width = 70,
|
||||
height = 70,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{x=35,y=35,radius=35,tooltip="Тормозной манометр: Давление в тормозных цилиндрах (ТЦ)\nBrake cylinder pressure"},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["DriverValveBLDisconnect"] = {
|
||||
pos = Vector(453.57,-54.37,-27.61),
|
||||
ang = Angle(-90,0,0),
|
||||
width = 200,
|
||||
height = 90,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "DriverValveBLDisconnectToggle", x=0, y=0, w=200, h=90, tooltip="Кран двойной тяги тормозной магистрали\nTrain line disconnect valve"},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["DriverValveTLDisconnect"] = {
|
||||
pos = Vector(455.482483,-54,-15),
|
||||
ang = Angle(90,180-11.79,0),
|
||||
width = 200,
|
||||
height = 90,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "DriverValveTLDisconnectToggle", x=0, y=0, w=200, h=90, tooltip="Кран двойной тяги напорной магистрали\nBrake line disconnect valve"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ENT.ButtonMap["Meters"] = {
|
||||
pos = Vector(461.65213,-56.696617,37.528275),
|
||||
ang = Angle(0,-148,90),
|
||||
width = 73,
|
||||
height = 140,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{x=13, y=22, w=60, h=50, tooltip="Вольтметр высокого напряжения (кВ)\nHV voltmeter (kV)"},
|
||||
{x=13, y=81, w=60, h=50, tooltip="Амперметр (А)\nTotal ampermeter (A)"},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["Speedometer"] = {
|
||||
pos = Vector(459.649109,-53.19582,26.624441),
|
||||
ang = Angle(0,-149,97),
|
||||
width = 110,
|
||||
height = 110,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{x=0, y=0, w=110, h=110, tooltip="Скоростемер"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
--These values should be identical to those drawing the schedule
|
||||
local col1w = 80 -- 1st Column width
|
||||
local col2w = 32 -- The other column widths
|
||||
local rowtall = 30 -- Row height, includes -only- the usable space and not any lines
|
||||
|
||||
local rowamount = 16 -- How many rows to show (total)
|
||||
--[[ENT.ButtonMap["Schedule"] = {
|
||||
pos = Vector(442.1,-60.7,26),
|
||||
ang = Angle(0,-110,90),
|
||||
width = (col1w + 2 + (1 + col2w) * 3),
|
||||
height = (rowtall+1)*rowamount+1,
|
||||
scale = 0.0625/2,
|
||||
|
||||
buttons = {
|
||||
{x=1, y=1, w=col1w, h=rowtall, tooltip="М №\nRoute number"},
|
||||
{x=1, y=rowtall*2+3, w=col1w, h=rowtall, tooltip="П №\nPath number"},
|
||||
|
||||
{x=col1w+2, y=1, w=col2w*3+2, h=rowtall, tooltip="ВРЕМЯ ХОДА\nTotal schedule time"},
|
||||
{x=col1w+2, y=rowtall+2, w=col2w*3+2, h=rowtall, tooltip="ИНТ\nTrain interval"},
|
||||
|
||||
{x=col1w+2, y=rowtall*2+3, w=col2w, h=rowtall, tooltip="ЧАС\nHour"},
|
||||
{x=col1w+col2w+3, y=rowtall*2+3, w=col2w, h=rowtall, tooltip="МИН\nMinute"},
|
||||
{x=col1w+col2w*2+4, y=rowtall*2+3, w=col2w, h=rowtall, tooltip="СЕК\nSecond"},
|
||||
{x=col1w+2, y=rowtall*3+4, w=col2w*3+2, h=(rowtall+1)*(rowamount-3)-1, tooltip="Arrival times"}, -- NEEDS TRANSLATING
|
||||
|
||||
{x=1, y=rowtall*3+4, w=col1w, h=(rowtall+1)*(rowamount-3)-1, tooltip="Station name"}, -- NEEDS TRANSLATING
|
||||
}
|
||||
}]]
|
||||
|
||||
-- Temporary panels (possibly temporary)
|
||||
ENT.ButtonMap["FrontPneumatic"] = {
|
||||
pos = Vector(475,-45.0,-50.0),
|
||||
ang = Angle(0,90,90),
|
||||
width = 900,
|
||||
height = 100,
|
||||
scale = 0.1,
|
||||
buttons = {
|
||||
{ID = "FrontBrakeLineIsolationToggle",x=150, y=50, radius=32, tooltip="Концевой кран тормозной магистрали"},
|
||||
{ID = "FrontTrainLineIsolationToggle",x=750, y=50, radius=32, tooltip="Концевой кран напорной магистрали"},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["RearPneumatic"] = {
|
||||
pos = Vector(-475,45.0,-50.0),
|
||||
ang = Angle(0,270,90),
|
||||
width = 900,
|
||||
height = 100,
|
||||
scale = 0.1,
|
||||
buttons = {
|
||||
{ID = "RearTrainLineIsolationToggle",x=150, y=50, radius=32, tooltip="Концевой кран напорной магистрали"},
|
||||
{ID = "RearBrakeLineIsolationToggle",x=750, y=50, radius=32, tooltip="Концевой кран тормозной магистрали"},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["GV"] = {
|
||||
pos = Vector(139,66,-54),
|
||||
ang = Angle(0,180,90),
|
||||
width = 170,
|
||||
height = 170,
|
||||
scale = 0.1,
|
||||
buttons = {
|
||||
{ID = "GVToggle",x=0, y=0, w= 170,h = 150, tooltip="Главный выключатель", model = {
|
||||
var="GV",sndid = "gv",
|
||||
sndvol = 0.8,sndmin = 80, sndmax = 1e3/3, sndang = Angle(-90,0,0),
|
||||
snd = function(val) return val and "gv_f" or "gv_b" end,
|
||||
}},
|
||||
}
|
||||
}
|
||||
ENT.ButtonMap["AirDistributor"] = {
|
||||
pos = Vector(-168,68.6,-50),
|
||||
ang = Angle(0,180,90),
|
||||
width = 170,
|
||||
height = 80,
|
||||
scale = 0.1,
|
||||
buttons = {
|
||||
{ID = "AirDistributorDisconnectToggle",x=0, y=0, w= 170,h = 80, tooltip="Выключение воздухораспределителя"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-- UAVA
|
||||
ENT.ButtonMap["UAVAPanel"] = {
|
||||
pos = Vector(450,52,-20),
|
||||
ang = Angle(0,-70,90),
|
||||
width = 230,
|
||||
height = 170,
|
||||
scale = 0.0625,
|
||||
|
||||
buttons = {
|
||||
{ID = "UAVAToggle",x=230/2, y=0, w=230/2, h=170, tooltip="УАВА: Универсальный Автоматический Выключатель Автостопа\nUAVA: Universal Automatic Autostop Disabler"},
|
||||
{ID = "UAVAContactSet",x=0, y=0, w=230/2, h=170, tooltip="УАВА: Универсальный Автоматический Выключатель Автостопа (восстановление контактов)\nUAVA: Universal Automatic Autostop Disabler(contacts reset)"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- Wagon numbers
|
||||
ENT.ButtonMap["TrainNumber1"] = {
|
||||
pos = Vector(-440,-68,-11),
|
||||
ang = Angle(0,0,90),
|
||||
width = 130,
|
||||
height = 55,
|
||||
scale = 0.20,
|
||||
}
|
||||
ENT.ButtonMap["TrainNumber2"] = {
|
||||
pos = Vector(416,68,-11),
|
||||
ang = Angle(0,180,90),
|
||||
width = 130,
|
||||
height = 55,
|
||||
scale = 0.20,
|
||||
}
|
||||
|
||||
|
||||
ENT.ButtonMap["FrontDoor"] = {
|
||||
pos = Vector(472,16,43.4),
|
||||
ang = Angle(0,-90,90),
|
||||
width = 650,
|
||||
height = 1780,
|
||||
scale = 0.1/2,
|
||||
buttons = {
|
||||
{ID = "FrontDoor",x=0,y=0,w=650,h=1780, tooltip="Передняя дверь\nFront door"},
|
||||
}
|
||||
}
|
||||
|
||||
ENT.ButtonMap["CabinDoor"] = {
|
||||
pos = Vector(420,64,43.4),
|
||||
ang = Angle(0,0,90),
|
||||
width = 642,
|
||||
height = 1780,
|
||||
scale = 0.1/2,
|
||||
buttons = {
|
||||
{ID = "CabinDoor1",x=0,y=0,w=642,h=1780, tooltip="Дверь в кабину машиниста\nCabin door"},
|
||||
}
|
||||
}
|
||||
|
||||
ENT.ButtonMap["PassengerDoor"] = {
|
||||
pos = Vector(384,-16,43.4),
|
||||
ang = Angle(0,90,90),
|
||||
width = 642,
|
||||
height = 1900,
|
||||
scale = 0.1/2,
|
||||
buttons = {
|
||||
{ID = "PassengerDoor",x=0,y=0,w=642,h=1900, tooltip="Дверь из салона\nPassenger door"},
|
||||
}
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientPropsInitialized = false
|
||||
ENT.ClientProps["brake"] = {
|
||||
model = "models/metrostroi_train/81/334cran.mdl",
|
||||
pos = Vector(460.11,-53.7,3.7),
|
||||
ang = Angle(0,34,0)
|
||||
}
|
||||
ENT.ClientProps["controller"] = {
|
||||
model = "models/metrostroi_train/em/kv.mdl",
|
||||
pos = Vector(461.65,-24.63,3.9),
|
||||
ang = Angle(0,-32,0)
|
||||
}
|
||||
ENT.ClientProps["reverser"] = {
|
||||
model = "models/metrostroi/81-717/reverser.mdl",
|
||||
pos = Vector(461.65,-24.63,3.2),
|
||||
ang = Angle(0,45,90)
|
||||
}
|
||||
ENT.ClientProps["brake_disconnect"] = {
|
||||
model = "models/metrostroi/81-717/uava.mdl",
|
||||
pos = Vector(452.9,-57.33,-25.61),
|
||||
ang = Angle(0,-90,0),
|
||||
color = Color(144,74,0),
|
||||
}
|
||||
ENT.ClientProps["train_disconnect"] = {
|
||||
model = "models/metrostroi/81-717/uava.mdl",
|
||||
pos = Vector(455.482483,-52.546734,-19.333017),
|
||||
ang = Angle(0.000000,-101.794258,0.000000),
|
||||
color = Color(0,212,255),
|
||||
}
|
||||
|
||||
ENT.ClientProps["parking_brake"] = {
|
||||
model = "models/metrostroi/81-717/ezh_koleso.mdl",
|
||||
pos = Vector(460.316742,37.144958,-6.000000),
|
||||
ang = Angle(-90.000000,8.000000,0.000000),
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps["train_line"] = {
|
||||
model = "models/metrostroi_train/e/small_pneumo_needle.mdl",
|
||||
pos = Vector(457.722778,-56.060150,13.877457),
|
||||
ang = Angle(314.669312,40.953403,-90.000000),
|
||||
}
|
||||
ENT.ClientProps["brake_line"] = {
|
||||
model = "models/metrostroi_train/e/small_pneumo_needle.mdl",
|
||||
pos = Vector(457.688568,-56.020660,13.877457),
|
||||
ang = Angle(314.669312,40.953403,-90.000000),
|
||||
color = Color(255,120,120),
|
||||
}
|
||||
|
||||
ENT.ClientProps["brake_cylinder"] = {
|
||||
model = "models/metrostroi_train/e/small_pneumo_needle.mdl",
|
||||
pos = Vector(462.104797,-55.268986,9.050000),
|
||||
ang = Angle(313.335266,48.532555,-90.000000),
|
||||
}
|
||||
----------------------------------------------------------------
|
||||
ENT.ClientProps["voltmeter"] = {
|
||||
model = "models/metrostroi_train/e/volt_needle.mdl",
|
||||
pos = Vector(460.647858,-58.177208,35.553993),
|
||||
ang = Angle(237.732468,23.827326,270.135559),
|
||||
}
|
||||
|
||||
ENT.ClientProps["ampermeter"] = {
|
||||
model = "models/metrostroi_train/e/volt_needle.mdl",
|
||||
pos = Vector(460.647858,-58.177208,32.055382),
|
||||
ang = Angle(222.645691,23.000584,270.135559),
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps["gv"] = {
|
||||
model = "models/metrostroi/81-717/gv.mdl",
|
||||
pos = Vector(130,62.5,-65),
|
||||
ang = Angle(-90,0,-90)
|
||||
}
|
||||
ENT.ClientProps["gv_wrench"] = {
|
||||
model = "models/metrostroi/81-717/reverser.mdl",
|
||||
pos = Vector(130,62.5,-65),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
|
||||
ENT.ClientProps["Em_salon"] = {
|
||||
model = "models/metrostroi_train/em/em_salon.mdl",
|
||||
pos = Vector(0,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
ENT.ClientProps["Em_salon2"] = {
|
||||
model = "models/metrostroi_train/em/em_salon2.mdl",
|
||||
pos = Vector(0,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
ENT.ClientProps["Lamps_emer"] = {
|
||||
model = "models/metrostroi_train/em/lamps_emer.mdl",
|
||||
pos = Vector(0,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
ENT.ClientProps["Lamps_full"] = {
|
||||
model = "models/metrostroi_train/em/lamps_full.mdl",
|
||||
pos = Vector(0,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
|
||||
ENT.ClientProps["Lamps_full2"] = {
|
||||
model = "models/metrostroi_train/em/lamps_full_em.mdl",
|
||||
pos = Vector(0.007439,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
|
||||
ENT.ClientProps["Lamps_cab_em"] = {
|
||||
model = "models/metrostroi_train/em/lamps_cab_em.mdl",
|
||||
pos = Vector(0.007439,0,0),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
|
||||
ENT.ClientProps["FrontBrake"] = {--
|
||||
model = "models/metrostroi_train/81/tmiso.mdl",
|
||||
pos = Vector(460, -30, -55),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
ENT.ClientProps["FrontTrain"] = {--
|
||||
model = "models/metrostroi_train/81/nmsio.mdl",
|
||||
pos = Vector(460, 30, -55),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
ENT.ClientProps["RearBrake"] = {--
|
||||
model = "models/metrostroi_train/81/tmiso.mdl",
|
||||
pos = Vector(-460, -30, -55),
|
||||
ang = Angle(0,90,0)
|
||||
}
|
||||
ENT.ClientProps["RearTrain"] = {--
|
||||
model = "models/metrostroi_train/81/nmsio.mdl",
|
||||
pos = Vector(-460, 30, -55),
|
||||
ang = Angle(0,90,0)
|
||||
}
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Add doors
|
||||
local function GetDoorPosition(i,k,j)
|
||||
if j == 0
|
||||
then return Vector(383.0 - 67.49*k - 233.4*i,-64.56*(1-2*k),1)
|
||||
else return Vector(383.0 - 67.49*(1-k) - 233.4*i,-64.56*(1-2*k),1)
|
||||
end
|
||||
end
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
ENT.ClientProps["door"..i.."x"..k.."a"] = {
|
||||
model = "models/metrostroi_train/em/doorright.mdl",
|
||||
pos = GetDoorPosition(i,k,0),
|
||||
ang = Angle(0,90 + 180*k,0)
|
||||
}
|
||||
ENT.ClientProps["door"..i.."x"..k.."b"] = {
|
||||
model = "models/metrostroi_train/em/doorleft.mdl",
|
||||
pos = GetDoorPosition(i,k,1),
|
||||
ang = Angle(0,90 + 180*k,0)
|
||||
}
|
||||
end
|
||||
end
|
||||
ENT.ClientProps["door1"] = {
|
||||
model = "models/metrostroi_train/em/doorfront.mdl",
|
||||
pos = Vector(471.71,-17.1,-1),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
ENT.ClientProps["door2"] = {
|
||||
model = "models/metrostroi_train/em/doorback.mdl",
|
||||
pos = Vector(-471.24,17.19,-1),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
ENT.ClientProps["door3"] = {
|
||||
model = "models/metrostroi_train/em/doorpass.mdl",
|
||||
pos = Vector(403.69,16.95,-2.2),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
ENT.ClientProps["door4"] = {
|
||||
model = "models/metrostroi_train/em/doorcab.mdl",
|
||||
pos = Vector(420.75,64.26,1.5),
|
||||
ang = Angle(0,-90,0)
|
||||
}
|
||||
--[[ENT.ClientProps["UAVA"] = {
|
||||
model = "models/metrostroi/81-717/uava_body.mdl",
|
||||
pos = Vector(400,61,-8),--Vector(415.0,-58.5,-18.2),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
ENT.ClientProps["UAVALever"] = {
|
||||
model = "models/metrostroi_train/81/uavalever.mdl",
|
||||
pos = Vector(452.84598,51,-21.813349),
|
||||
ang = Angle(0,90,90)
|
||||
}
|
||||
]]
|
||||
ENT.ClientProps["RedLights"] = {
|
||||
model = "models/metrostroi_train/Em/redlights.mdl",
|
||||
pos = Vector(474.674042,-0.885458,55.695278),
|
||||
ang = Angle(90.000000,-0.212120,0.000000),
|
||||
}
|
||||
ENT.ClientProps["DistantLights"] = {
|
||||
model = "models/metrostroi_train/Em/distantlights.mdl",
|
||||
pos = Vector(471.731842,-0.651488,54.413082),
|
||||
ang = Angle(90.000000,0.000000,0.000000),
|
||||
}
|
||||
ENT.ClientProps["WhiteLights"] = {
|
||||
model = "models/metrostroi_train/Em/whitelights.mdl",
|
||||
pos = Vector(475.597565,-0.525079,-29.160791),
|
||||
ang = Angle(90.267662,0.000000,0.000000),
|
||||
}
|
||||
|
||||
ENT.Texture = "7"
|
||||
ENT.OldTexture = nil
|
||||
--local X = Material( "metrostroi_skins/81-717/6.png")
|
||||
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self:GetNW2String("texture")]
|
||||
local passtexture = Metrostroi.Skins["pass"][self:GetNW2String("passtexture")]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self:GetNW2String("cabtexture")]
|
||||
for _,self in pairs(self.ClientEnts) do
|
||||
if not IsValid(self) then continue end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
if self.Texture ~= self:GetNW2String("texture") then
|
||||
self.Texture = self:GetNW2String("texture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
if self.PassTexture ~= self:GetNW2String("passtexture") then
|
||||
self.PassTexture = self:GetNW2String("passtexture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
if self.CabinTexture ~= self:GetNW2String("cabtexture") then
|
||||
self.CabinTexture = self:GetNW2String("cabtexture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
--print(self.FrontDoor,self:GetPackedBool(114))
|
||||
--print(self.RearDoor,self:GetPackedBool(156))
|
||||
local transient = (self.Transient or 0)*0.05
|
||||
if (self.Transient or 0) ~= 0.0 then self.Transient = 0.0 end
|
||||
|
||||
-- Parking brake animation
|
||||
self.ParkingBrakeAngle = self.ParkingBrakeAngle or 0
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle or 0
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle + (self.ParkingBrakeAngle - self.TrueBrakeAngle)*2.0*(self.DeltaTime or 0)
|
||||
if self.ClientEnts and self.ClientEnts["parking_brake"] then
|
||||
self.ClientEnts["parking_brake"]:SetPoseParameter("position",1.0-((self.TrueBrakeAngle % 360)/360))
|
||||
end
|
||||
|
||||
local Lamps = self:GetPackedBool(20) and 0.6 or 1
|
||||
self:ShowHideSmooth("Lamps_emer",self:Animate("lamps_emer",self:GetPackedBool("Lamps_emer") and Lamps or 0,0,1,6,false))
|
||||
self:ShowHideSmooth("Lamps_full",self:Animate("lamps_full",self:GetPackedBool("Lamps_full") and Lamps or 0,0,1,6,false))
|
||||
self:ShowHideSmooth("Lamps_cab_em",self.Anims["lamps_full"].val)
|
||||
self:ShowHideSmooth("Lamps_full2",self.Anims["lamps_full"].val)
|
||||
|
||||
--self:ShowHideSmooth("Lamp2",self:Animate("Lamp2_hs",self:GetPackedBool("Lamp2") and 1 or 0,0,1,5,false))
|
||||
--self:ShowHideSmooth("Lamp1",self:Animate("Lamp1_hs",self:GetPackedBool("Lamp1") and 1 or 0,0,1,5,false))
|
||||
--self:ShowHideSmooth("Lamp6",self:Animate("Lamp6_hs",self:GetPackedBool("Lamp6") and 1 or 0,0,1,5,false))
|
||||
--self:ShowHideSmooth("Doors",self:Animate("Doors_hs",self:GetPackedBool(40) and 1 or 0,0,1,5,false))
|
||||
self:ShowHideSmooth("DoorsWag",self:Animate("DoorsWag_hs",self:GetPackedBool("DoorsWag") and 1 or 0,0,1,5,false))
|
||||
self:ShowHideSmooth("GreenRP",self:Animate("GreenRP_hs",self:GetPackedBool(36) and 1 or 0,0,1,5,false))
|
||||
self:ShowHideSmooth("RedRP",self:Animate("RedRP_hs",self:GetPackedBool(35) and 1 or 0,0,1,5,false) + self:Animate("RedLSN_hs",self:GetPackedBool(131) and 1 or 0,0,0.4,5,false))
|
||||
|
||||
|
||||
self:Animate("AV8B",self:GetPackedBool("AV8B") and 1 or 0, 0,1, 8, false)
|
||||
|
||||
self:Animate("VU1",self:GetPackedBool("VU1") and 0 or 1, 0,1, 12, false)
|
||||
self:Animate("VU3",self:GetPackedBool("VU3") and 0 or 1, 0,1, 12, false)
|
||||
self:Animate("VU2",self:GetPackedBool("VU2") and 0 or 1, 0,1, 12, false)
|
||||
|
||||
self:Animate("VU",self:GetPackedBool("VU") and 0 or 1, 0,1, 12, false)
|
||||
self:Animate("RezMK",self:GetPackedBool("RezMK") and 1 or 0, 0,1, 7, false)
|
||||
|
||||
self:HideButton("VUToggle",self:GetPackedBool("VUPl"))
|
||||
self:HideButton("VUPl",not self:GetPackedBool("VUPl"))
|
||||
|
||||
self:SetCSBodygroup("VUPl",1,self:GetPackedBool("VUPl") and 0 or 1)
|
||||
|
||||
|
||||
self:Animate("VB",self:GetPackedBool("VB") and 0 or 1, 0,1, 8, false)
|
||||
|
||||
|
||||
self:Animate("KRZD",self:GetPackedBool("KRZD") and 1 or 0, 0,1, 12, false)
|
||||
|
||||
self:ShowHideSmooth("RedLights",self:Animate("redlights",self:GetPackedBool("RedLight") and 1 or 0,0,1,5,false))
|
||||
self:ShowHideSmooth("WhiteLights",self:Animate("whitelights",self:GetPackedBool("HeadLights2") and 1 or 0,0,1,5,false))
|
||||
self:ShowHideSmooth("DistantLights",self:Animate("distantlights",self:GetPackedBool("HeadLights1") and 1 or 0,0,1,5,false))
|
||||
|
||||
self:Animate("KDL",self:GetPackedBool("KDL") and 1 or 0, 0,1, 12, false)
|
||||
self:Animate("DIPon",self:GetPackedBool("DIPon") and 1 or 0, 0,1, 12, false)
|
||||
self:Animate("DIPoff",self:GetPackedBool("DIPoff") and 1 or 0, 0,1, 12, false)
|
||||
self:Animate("VozvratRP",self:GetPackedBool("VozvratRP") and 1 or 0, 0,1, 12, false)
|
||||
self:Animate("KSN",self:GetPackedBool("KSN") and 1 or 0, 0,1, 12, false)
|
||||
self:Animate("KDP",self:GetPackedBool("KDP") and 1 or 0, 0,1, 12, false)
|
||||
|
||||
self:Animate("KU1",self:GetPackedBool("KU1") and 1 or 0, 0,1, 7, false)
|
||||
self:Animate("VUD",self:GetPackedBool("VUD1") and 1 or 0, 0,1, 7, false)
|
||||
|
||||
|
||||
-- self:Animate("VDL",self:GetPackedBool("VDL") and 1 or 0, 0,1, 7, false)
|
||||
|
||||
self:Animate("VUD2",self:GetPackedBool("VUD2") and 0 or 1, 0,1, 7, false)
|
||||
self:Animate("VUD2l",self:GetPackedBool("VUD2L") and 1 or 0, 0,1, 7, false)
|
||||
|
||||
self:Animate("brake_disconnect",self:GetPackedBool("DriverValveBLDisconnect") and 1 or 0,0,0.5, 3,false)
|
||||
self:Animate("train_disconnect",self:GetPackedBool("DriverValveTLDisconnect") and 1 or 0,0,0.5, 3,false)
|
||||
|
||||
-- DIP sound
|
||||
--self:SetSoundState("bpsn2",self:GetPackedBool(52) and 1 or 0,1.0)
|
||||
|
||||
-- Simulate pressure gauges getting stuck a little
|
||||
self:Animate("brake", 1-self:GetPackedRatio(0), 0.00, 0.65, 256,24)
|
||||
self:Animate("controller", self:GetPackedRatio(1), 0, 0.31, 2,false)
|
||||
self:Animate("reverser", self:GetPackedRatio(2), 0.26, 0.35, 4,false)
|
||||
self:ShowHide("reverser", self:GetPackedBool(0))
|
||||
|
||||
self:Animate("brake_line", self:GetPackedRatio(4), 0, 0.725, 256,2)--,,0.01)
|
||||
self:Animate("train_line", self:GetPackedRatio(5)-transient, 0, 0.725, 256,2)--,,0.01)
|
||||
self:Animate("brake_cylinder", self:GetPackedRatio(6), 0, 0.721, 256,2)--,,0.03)
|
||||
self:Animate("voltmeter", self:GetPackedRatio(7), 0.014, 0.298,256,2)
|
||||
self:Animate("ampermeter", self:GetPackedRatio(8), 0, 0.248,256,2)
|
||||
--self:Animate("volt2", 0, 0.38, 0.63)
|
||||
----
|
||||
self:Animate("door1", self:GetPackedBool(157) and (self.Door1 or 0.99) or 0,0,0.22, 1024, 1)
|
||||
self:Animate("door3", self:GetPackedBool(158) and (self.Door2 or 0.99) or 0,0,0.25, 1024, 1)
|
||||
self:Animate("door2", self:GetPackedBool(156) and (self.Door3 or 0.99) or 0,0,0.25, 1024, 1)
|
||||
self:Animate("door4", self:GetPackedBool(159) and (self.Door2 or 0.99) or 0,1,0.77, 1024, 1)
|
||||
|
||||
self:Animate("FrontBrake", self:GetNW2Bool("FbI") and 0 or 1,0,0.35, 3, false)
|
||||
self:Animate("FrontTrain", self:GetNW2Bool("FtI") and 0 or 1,0,0.35, 3, false)
|
||||
self:Animate("RearBrake", self:GetNW2Bool("RbI") and 1 or 0,0,0.35, 3, false)
|
||||
self:Animate("RearTrain", self:GetNW2Bool("RtI") and 1 or 0,0,0.35, 3, false)
|
||||
|
||||
-- Main switch
|
||||
if self.LastValue ~= self:GetPackedBool(5) then
|
||||
self.ResetTime = CurTime()+1.5
|
||||
self.LastValue = self:GetPackedBool(5)
|
||||
end
|
||||
self:Animate("gv_wrench", (self:GetPackedBool(5) and 1 or 0), 0,0.51, 128, 1,false)
|
||||
self:ShowHide("gv_wrench", CurTime() < self.ResetTime)
|
||||
|
||||
-- Animate doors
|
||||
for i=0,4 do
|
||||
for k=0,1 do
|
||||
local n_l = "door"..i.."x"..k.."a"
|
||||
local n_r = "door"..i.."x"..k.."b"
|
||||
self:Animate(n_l,self:GetPackedBool(21+(1-k)*4) and 1 or 0,0.11,0.93, 0.8 + (-0.2+0.4*math.random()),0)
|
||||
self:Animate(n_r,self:GetPackedBool(21+(1-k)*4) and 1 or 0,0.11,0.93, 0.8 + (-0.2+0.4*math.random()),0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Brake-related sounds
|
||||
local brakeLinedPdT = self:GetPackedRatio(9)
|
||||
local dT = self.DeltaTime
|
||||
self.BrakeLineRamp1 = self.BrakeLineRamp1 or 0
|
||||
|
||||
if (brakeLinedPdT > -0.001)
|
||||
then self.BrakeLineRamp1 = self.BrakeLineRamp1 + 4.0*(0-self.BrakeLineRamp1)*dT
|
||||
else self.BrakeLineRamp1 = self.BrakeLineRamp1 + 4.0*((-0.6*brakeLinedPdT)-self.BrakeLineRamp1)*dT
|
||||
end
|
||||
self.BrakeLineRamp1 = math.Clamp(self.BrakeLineRamp1,0,1)
|
||||
self:SetSoundState("release2",self.BrakeLineRamp1^1.65,1.0)
|
||||
|
||||
self.BrakeLineRamp2 = self.BrakeLineRamp2 or 0
|
||||
if (brakeLinedPdT < 0.001)
|
||||
then self.BrakeLineRamp2 = self.BrakeLineRamp2 + 4.0*(0-self.BrakeLineRamp2)*dT
|
||||
else self.BrakeLineRamp2 = self.BrakeLineRamp2 + 8.0*(0.1*brakeLinedPdT-self.BrakeLineRamp2)*dT
|
||||
end
|
||||
self.BrakeLineRamp2 = math.Clamp(self.BrakeLineRamp2,0,1)
|
||||
self:SetSoundState("release3",self.BrakeLineRamp2 + math.max(0,self.BrakeLineRamp1/2-0.15),1.0)
|
||||
|
||||
self:SetSoundState("cran1",math.min(1,self:GetPackedRatio(4)/50*(self:GetPackedBool(6) and 1 or 0)),1.0)
|
||||
|
||||
-- Compressor
|
||||
local state = self:GetPackedBool(20)
|
||||
self.PreviousCompressorState = self.PreviousCompressorState or false
|
||||
if self.PreviousCompressorState ~= state then
|
||||
self.PreviousCompressorState = state
|
||||
if state then
|
||||
self:SetSoundState("compressor_ezh",1,1)
|
||||
else
|
||||
self:SetSoundState("compressor_ezh",0,1)
|
||||
self:SetSoundState("compressor_ezh_end",0,1)
|
||||
self:SetSoundState("compressor_ezh_end",1,1)
|
||||
--self:PlayOnce("compressor_e_end",nil,1,nil,true)
|
||||
end
|
||||
end
|
||||
|
||||
-- ARS/ringer alert
|
||||
local state = self:GetPackedBool(39)
|
||||
self.PreviousAlertState = self.PreviousAlertState or false
|
||||
if self.PreviousAlertState ~= state then
|
||||
self.PreviousAlertState = state
|
||||
if state then
|
||||
self:SetSoundState("ring4",1,1)
|
||||
else
|
||||
self:SetSoundState("ring4",0,0)
|
||||
self:SetSoundState("ring4_end",0,1)
|
||||
self:SetSoundState("ring4_end",1,1)
|
||||
--self:PlayOnce("ring4_end","cabin",0,101)
|
||||
end
|
||||
end
|
||||
|
||||
-- RK rotation
|
||||
if self:GetPackedBool(112) then self.RKTimer = CurTime() end
|
||||
local state = (CurTime() - (self.RKTimer or 0)) < 0.2
|
||||
self.PreviousRKState = self.PreviousRKState or false
|
||||
if self.PreviousRKState ~= state then
|
||||
self.PreviousRKState = state
|
||||
if state then
|
||||
self:SetSoundState("rk_spin",0.7,1,nil,0.75)
|
||||
else
|
||||
self:SetSoundState("rk_spin",0,0,nil,0.75)
|
||||
self:SetSoundState("rk_stop",0,1,nil,0.75)
|
||||
self:SetSoundState("rk_stop",0.7,1,nil,0.75)
|
||||
end
|
||||
end
|
||||
|
||||
--DIP sound
|
||||
--self:SetSoundState("bpsn2",self:GetPackedBool(32) and 1 or 0,1.0)
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
|
||||
function ENT:DrawPost()
|
||||
|
||||
self:DrawOnPanel("FrontPneumatic",function()
|
||||
draw.DrawText(self:GetNW2Bool("FbI") and "Isolated" or "Open","Trebuchet24",150,0,Color(0,0,0,255))
|
||||
draw.DrawText(self:GetNW2Bool("FtI") and "Isolated" or "Open","Trebuchet24",670,0,Color(0,0,0,255))
|
||||
end)
|
||||
self:DrawOnPanel("RearPneumatic",function()
|
||||
draw.DrawText(self:GetNW2Bool("RbI") and "Isolated" or "Open","Trebuchet24",150,0,Color(0,0,0,255))
|
||||
draw.DrawText(self:GetNW2Bool("RtI") and "Isolated" or "Open","Trebuchet24",670,0,Color(0,0,0,255))
|
||||
end)
|
||||
self:DrawOnPanel("AirDistributor",function()
|
||||
draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255))
|
||||
end)
|
||||
|
||||
-- Draw train numbers
|
||||
local dc = render.GetLightColor(self:GetPos())
|
||||
self:DrawOnPanel("TrainNumber1",function()
|
||||
draw.DrawText(Format("%04d",self:EntIndex()),"MetrostroiSubway_LargeText3",0,0,Color(255*dc.x,255*dc.y,255*dc.z,255))
|
||||
end)
|
||||
self:DrawOnPanel("TrainNumber2",function()
|
||||
draw.DrawText(Format("%04d",self:EntIndex()),"MetrostroiSubway_LargeText3",0,0,Color(255*dc.x,255*dc.y,255*dc.z,255))
|
||||
end)
|
||||
end
|
||||
|
||||
function ENT:OnButtonPressed(button)
|
||||
if button == "ShowHelp" then
|
||||
RunConsoleCommand("metrostroi_train_manual")
|
||||
end
|
||||
local bp_press = self:GetPackedRatio(6)
|
||||
local blocked_l = self:GetPackedBool(132) and 0 or 1
|
||||
local blocked_r = self:GetPackedBool(133) and 0 or 1
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ParkingBrakeAngle = (self.ParkingBrakeAngle or 0) - blocked_l*45
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ParkingBrakeAngle = (self.ParkingBrakeAngle or 0) + blocked_r*45
|
||||
end
|
||||
if button == "ShowHelp" then
|
||||
RunConsoleCommand("metrostroi_train_manual")
|
||||
end
|
||||
|
||||
if button == "PrevSign" then
|
||||
self.InfoTableTimeout = CurTime() + 2.0
|
||||
end
|
||||
if button == "NextSign" then
|
||||
self.InfoTableTimeout = CurTime() + 2.0
|
||||
end
|
||||
|
||||
if button and button:sub(1,3) == "Num" then
|
||||
self.InfoTableTimeout = CurTime() + 2.0
|
||||
end
|
||||
end
|
||||
@@ -1,896 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Em",
|
||||
WagType = 0,
|
||||
ARS = {
|
||||
HaveASNP = false,
|
||||
}
|
||||
}
|
||||
function ENT:Initialize()
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi_train/em/em.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(430,-39,-21.5),Angle(0,0,0))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(430,40,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat1 = self:CreateSeat("instructor",Vector(443,0,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat2 = self:CreateSeat("instructor",Vector(420,-20,-48+6),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.InstructorsSeat:SetColor(Color(0,0,0,0))
|
||||
self.InstructorsSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
self.ExtraSeat1:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat1:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.ExtraSeat2:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat2:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 320,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-320,0,-80),Angle(0,0,0),false)
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
-- Initialize key mapping
|
||||
self.KeyMap = {
|
||||
[KEY_1] = "KVSetX1",
|
||||
--[KEY_2] = "KVSetX2",
|
||||
--[KEY_3] = "KVSetX3",
|
||||
[KEY_4] = "KVSet0",
|
||||
[KEY_5] = "KVSetT1",
|
||||
[KEY_6] = "KVSetT1AB",
|
||||
[KEY_7] = "KVSetT2",
|
||||
[KEY_8] = "KRP",
|
||||
|
||||
[KEY_G] = "VozvratRPSet",
|
||||
|
||||
[KEY_0] = "KVReverserUp",
|
||||
[KEY_9] = "KVReverserDown",
|
||||
[KEY_PAD_PLUS] = "KVReverserUp",
|
||||
[KEY_PAD_MINUS] = "KVReverserDown",
|
||||
[KEY_W] = "KVUp",
|
||||
[KEY_S] = "KVDown",
|
||||
[KEY_F] = "PneumaticBrakeUp",
|
||||
[KEY_R] = "PneumaticBrakeDown",
|
||||
|
||||
[KEY_A] = "KDL",
|
||||
[KEY_D] = "KDP",
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "HornEngage",
|
||||
[KEY_PAD_1] = "PneumaticBrakeSet1",
|
||||
[KEY_PAD_2] = "PneumaticBrakeSet2",
|
||||
[KEY_PAD_3] = "PneumaticBrakeSet3",
|
||||
[KEY_PAD_4] = "PneumaticBrakeSet4",
|
||||
[KEY_PAD_5] = "PneumaticBrakeSet5",
|
||||
|
||||
[KEY_BACKSPACE] = "EmergencyBrake",
|
||||
|
||||
[KEY_PAD_0] = "DriverValveDisconnect",
|
||||
[KEY_LSHIFT] = {
|
||||
[KEY_W] = "KVUp_Unlocked",
|
||||
[KEY_SPACE] = "KVTSet",
|
||||
|
||||
[KEY_1] = "DIPonSet",
|
||||
[KEY_2] = "DIPoffSet",
|
||||
[KEY_4] = "KVSet0Fast",
|
||||
[KEY_L] = "DriverValveDisconnect",
|
||||
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_6] = "KVSetT1A",
|
||||
},
|
||||
|
||||
[KEY_RSHIFT] = {
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_L] = "DriverValveDisconnect",
|
||||
},
|
||||
[KEY_LALT] = {
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
},
|
||||
[KEY_RALT] = {
|
||||
},
|
||||
}
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(-471,-30,0),
|
||||
Radius = 28,
|
||||
ID = "RearDoor"
|
||||
},
|
||||
{ Pos = Vector(473,32,28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor1"
|
||||
},
|
||||
{ Pos = Vector(473,32,-28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor2"
|
||||
},
|
||||
{ Pos = Vector(383.02,31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor1"
|
||||
},
|
||||
{ Pos = Vector(383.02,-31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor1"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor3"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor4"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor5"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor6"
|
||||
},
|
||||
}
|
||||
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[1] = { "headlight", Vector(475,0,-20), Angle(0,0,0), Color(216,161,92), fov = 100 },
|
||||
[2] = { "glow", Vector(469.4, 45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[3] = { "glow", Vector(469.4,-45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[4] = { "glow", Vector(458+9,-14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[5] = { "glow", Vector(458+9,0, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[6] = { "glow", Vector(458+9, 14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
|
||||
-- Reverse
|
||||
--[8] = { "light", Vector(458+11,-30.7, 54.2), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
--[9] = { "light", Vector(458+11, 30.7, 54.2), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
|
||||
-- Cabin
|
||||
[10] = { "dynamiclight", Vector(434,-32,18), Angle(0,-0,0), Color(255,107,50), brightness = 0.4, distance = 600, shadows = 1},
|
||||
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 300 , fov=180,farz = 128 },
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 400, fov=180,farz = 128 },
|
||||
[13] = { "dynamiclight", Vector(-300, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 400 , fov=180,farz = 128 },
|
||||
|
||||
-- Side lights
|
||||
--//[14] = { "light", Vector(390+12.15, 69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[15] = { "light", Vector(390+12.15, 69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[16] = { "light", Vector(390+12.15, 69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[17] = { "light", Vector(390+12.15, 69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
--[18] = { "light", Vector(390+12.15, -69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[19] = { "light", Vector(390+12.15, -69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[20] = { "light", Vector(390+12.15, -69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[21] = { "light", Vector(390+12.15, -69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[15] = { "light", Vector(402.202942,69.270073,44.79285), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[16] = { "light", Vector(402.202942,69.270073,41.509621), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[17] = { "light", Vector(402.202942,69.270073,37.3862), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
|
||||
--[19] = { "light", Vector(15, -69, 58.3), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
--[20] = { "light", Vector(12, -69, 58.3), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
--[21] = { "light", Vector(9, -69, 58.3), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[32] = { "headlight", Vector(450.70,-56.3,28), Angle(-90,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 77 },
|
||||
[33] = { "headlight", Vector(450.70,-56.3,32), Angle(-90,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 77 },
|
||||
|
||||
[34] = { "headlight", Vector(448.65,-56.40,22.60), Angle(-30,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 140 },
|
||||
|
||||
[35] = { "headlight", Vector(450.6,-55.84,12.73), Angle(-90,-90,-180), Color(216,161,92), farz = 7, nearz = 4, shadows = 0, brightness = 2, fov = 130 },
|
||||
|
||||
[36] = { "headlight", Vector(455.2,-53.2,5.35), Angle(-90,-90,-180), Color(216,161,92), farz = 4, nearz = 4, shadows = 0, brightness = 2, fov = 130 },
|
||||
|
||||
[37] = { "headlight", Vector(458.3,-20.32,19.6), Angle(-90,-120,-180), Color(216,161,92), farz = 4, nearz = 4, shadows = 0, brightness = 3, fov = 160 },
|
||||
|
||||
[38] = { "headlight", Vector( -20, 0, 30), Angle(90,0,90), Color(255,95,10), brightness = 1, distance = 999,fov=179, shadows = 0, farz = 500},
|
||||
[39] = { "headlight", Vector( -20, 0, 10), Angle(-90,0,90), Color(255,95,10), brightness = 1, distance = 999,fov=179, shadows = 0, farz = 500},
|
||||
[70 ] = { "headlight", Vector( 450, -60, -47), Angle(45,-90,0), Color(255,255,255), brightness = 0.5, distance = 400 , fov=120, shadows = 1 },
|
||||
|
||||
}
|
||||
self.NetworkSwitches = {
|
||||
"VB",
|
||||
"RezMK",
|
||||
"VU3","VU1","VU2","AV8B","VU",
|
||||
"VUD2","VUD2L","VDL",
|
||||
"KDL","DIPon","DIPoff","VozvratRP","KSN","KDP",
|
||||
"KU1","KRZD","VUD1",
|
||||
--[["VB","VBA",
|
||||
|
||||
"KVT","VZP","VZD","KRZD",
|
||||
|
||||
"KDL","DIPon","DIPoff","VozvratRP","KSN","KDP",
|
||||
|
||||
"KU1","Ring","VUS","KAK","VAutodrive","VUD1",
|
||||
|
||||
"RezMK",
|
||||
|
||||
"VUD2","VUD2L","VDL",
|
||||
|
||||
"VRU","VAH","VAD","OVT","KSD","DP","VKF",
|
||||
|
||||
"OtklAVU","KRP",
|
||||
|
||||
"RC1","RC2","VRD",
|
||||
|
||||
"PB","VU3","VU1","VU2","AV8B","VU","KDLK","VDLK","KDPK","KAHK","L_3","RST","VSOSD",]]
|
||||
}
|
||||
self.Plombs = {
|
||||
VU = true,
|
||||
--[[RST = true,
|
||||
VAH = true,
|
||||
VAD = true,
|
||||
OVT = true,
|
||||
RC1 = true,
|
||||
RC2 = true,]]
|
||||
Init = true,
|
||||
}
|
||||
-- Lights
|
||||
--[[
|
||||
for i = 1,23 do
|
||||
self.Lights[69+i] = { "light", Vector(-470 + 35*i, 0, 65), Angle(180,0,0), Color(255,220,180), brightness = 0.25, scale = 0.75}
|
||||
--self:SetLightPower(69+i,RealTime()%1*2>1)
|
||||
end]]
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- KV wrench mode
|
||||
self.KVWrenchMode = 0
|
||||
|
||||
-- Parking brake ratio
|
||||
self.ManualBrake = 0.0
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self.CabinDoor = false
|
||||
self.PassengerDoor = false
|
||||
-- self.A5:TriggerInput("Set",0)
|
||||
self:UpdateTextures()
|
||||
end
|
||||
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self.CabTexture]
|
||||
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
self:SetNW2String("texture",self.Texture)
|
||||
self:SetNW2String("passtexture",self.PassTexture)
|
||||
self:SetNW2String("cabtexture",self.CabTexture)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
self.RetVal = self.BaseClass.Think(self)
|
||||
|
||||
-- Check if wrench was pulled out
|
||||
if self.DriversWrenchPresent then
|
||||
self.KV:TriggerInput("Enabled",self:IsWrenchPresent() and 1 or 0)
|
||||
end
|
||||
self:SetLightPower(1, self.Panel["HeadLights3"] > 0.5,(math.min(1,self.Panel["HeadLights1"])*0.50 +
|
||||
math.min(1,self.Panel["HeadLights2"])*0.25 +
|
||||
math.min(1,self.Panel["HeadLights3"])*0.25)
|
||||
)
|
||||
--self:SetLightPower(2, self.Panel["HeadLights2"] > 0.5)
|
||||
--self:SetLightPower(3, self.Panel["HeadLights2"] > 0.5)
|
||||
--self:SetLightPower(4, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(5, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(6, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(7, self.Panel["HeadLights2"] > 0.5)
|
||||
-- Reverser lights
|
||||
--self:SetLightPower(8, self.Panel["RedLightRight"] > 0.5)
|
||||
--self:SetLightPower(9, self.Panel["RedLightLeft"] > 0.5)
|
||||
self:SetPackedBool("HeadLights1",self.Panel["HeadLights1"] > 0.5)
|
||||
self:SetPackedBool("HeadLights2",self.Panel["HeadLights2"] > 0.5)
|
||||
self:SetPackedBool("RedLight",((self.Panel["RedLightLeft"] > 0.5 or self.Panel["RedLightRight"] > 0.5 ) and IsValid(self.FrontTrain)))
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = self.Panel["EmergencyLight"] > 0.5 or lightsActive2
|
||||
self:SetPackedBool("Lamps_emer",lightsActive1)
|
||||
self:SetPackedBool("Lamps_full",lightsActive2)
|
||||
|
||||
-- Interior/cabin lights
|
||||
self:SetLightPower(10, lightsActive2, 0.8)--self.Panel["CabinLight"] > 0.5)
|
||||
--local I = math.Round((self.Electric.I24-150)/1000.0,1.5)
|
||||
if self.Pneumatic.Compressor == 1 then
|
||||
local Light = (lightsActive2 and 0.6 or 0.3)
|
||||
--[[
|
||||
if I > 0 then
|
||||
Light = Light*(1-math.abs(I*0.1))
|
||||
end
|
||||
]]
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
else
|
||||
local Light = (lightsActive2 and 0.8 or 0.4)
|
||||
--[[
|
||||
if I > 0 then
|
||||
Light = Light*(1-math.abs(I*0.1))
|
||||
end
|
||||
]]
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
end
|
||||
|
||||
--self:SetLightPower(12, lightsActive1,0.1 + ((self.PowerSupply.XT3_4 > 65.0) and 0.7 or 0))
|
||||
--self:SetLightPower(13, lightsActive2, 0.8)
|
||||
--for i = 1,23 do
|
||||
--self:SetLightPower(69+i,lightsActive2 and true or lightsActive1 and i%5==1 or false)
|
||||
--end
|
||||
--self:SetLightPower(12, self.Panel["EmergencyLight"] > 0.5)
|
||||
--self:SetLightPower(13, self.PowerSupply.XT3_4 > 65.0)
|
||||
|
||||
-- Side lights
|
||||
--self:SetLightPower(15, self.Panel["TrainDoors"] > 0.5)
|
||||
--self:SetLightPower(19, self.Panel["TrainDoors"] > 0.5)
|
||||
|
||||
--self:SetLightPower(16, self.Panel["GreenRP"] > 0.5)
|
||||
--self:SetLightPower(20, self.Panel["GreenRP"] > 0.5)
|
||||
|
||||
--self:SetLightPower(17, self.Panel["TrainBrakes"] > 0.5)
|
||||
--self:SetLightPower(21, self.Panel["TrainBrakes"] > 0.5)
|
||||
|
||||
-- Total temperature
|
||||
local IGLA_Temperature = math.max(self.Electric.T1,self.Electric.T2)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:WriteTrainWire(35,(self.Pneumatic.BrakeCylinderPressure > 0.1) and 1 or 0)
|
||||
|
||||
-- DIP/power
|
||||
self:SetPackedBool(32,self.Panel["V1"] > 0.5)
|
||||
-- Red RP
|
||||
local TW18 = self:GetTrainWire18()
|
||||
if self:ReadTrainWire(20) == 0 or (self.Panel["V1"] < 0.5) then TW18 = 0 end--(self.KV.ControllerPositionAutodrive == 0 and self.KV.ControllerPosition == 0)
|
||||
self:SetPackedBool(35,TW18 > 0.5)
|
||||
self:SetPackedBool(131,TW18 > 0)
|
||||
-- Green RP
|
||||
self:SetPackedBool(36,self.Panel["GreenRP"] > 0.5)
|
||||
-- Cabin heating
|
||||
--self:SetPackedBool(37,self.Panel["KUP"] > 0.5)
|
||||
-- AVU
|
||||
--self:SetPackedBool(38,self.Panel["AVU"] > 0.5)
|
||||
-- Ring
|
||||
self:SetPackedBool(39,self.Panel["Ring"] > 0.5)
|
||||
-- SD
|
||||
--self:SetPackedBool(40,self.Panel["SD"] > 0.5)
|
||||
self:SetPackedBool("DriverValveBLDisconnect",self.DriverValveBLDisconnect.Value == 1.0)
|
||||
self:SetPackedBool("DriverValveTLDisconnect",self.DriverValveTLDisconnect.Value == 1.0)
|
||||
for i=1,#self.NetworkSwitches do
|
||||
local switch = self.NetworkSwitches[i]
|
||||
self:SetPackedBool(switch,self[switch].Value == 1.0)
|
||||
end
|
||||
--self:SetPackedBool("Lamp6",self:ReadTrainWire(6) > 0.5)
|
||||
--self:SetPackedBool("Lamp1",self:ReadTrainWire(1) > 0.5)
|
||||
--self:SetPackedBool("Lamp2",self:ReadTrainWire(2) > 0.5)
|
||||
self:SetPackedBool("DoorsWag",self.BD.Value == 0.0 and self.Panel["V1"] > 0.5)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
self:SetPackedBool(158,self.PassengerDoor)
|
||||
self:SetPackedBool(159,self.CabinDoor)
|
||||
if self.VUD2.Blocked > 0 and self.VUD2L.Value > 0.5 then
|
||||
self.VUD2:TriggerInput("Block",0)
|
||||
end
|
||||
if self.VUD2.Blocked == 0 and self.VUD2L.Value == 0 then
|
||||
self.VUD2:TriggerInput("Block",1)
|
||||
end
|
||||
if self.VUD2L.Blocked > 0 and self.VUD2.Value > 0 then
|
||||
self.VUD2L:TriggerInput("Block",0)
|
||||
end
|
||||
if self.VUD2L.Blocked == 0 and self.VUD2.Value == 0 then
|
||||
self.VUD2L:TriggerInput("Block",1)
|
||||
end
|
||||
self:SetPackedBool("VUD2Bl",self.VUD2.Blocked > 0)
|
||||
self:SetPackedBool("VUD2LBl",self.VUD2L.Blocked > 0)
|
||||
--[[
|
||||
-- LST
|
||||
self:SetPackedBool(49,self:ReadTrainWire(6) > 0.5)
|
||||
-- LVD
|
||||
self:SetPackedBool(50,self:ReadTrainWire(1) > 0.5)
|
||||
|
||||
self:SetPackedBool(165,self.PB.Value > 0)
|
||||
|
||||
-- AV states
|
||||
-- for i,v in ipairs(self.Panel.AVMap) do
|
||||
-- if tonumber(v)
|
||||
-- then self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
-- elseif self[v] then self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
self:SetPackedBool(62,self.L_3.Value > 0.5)
|
||||
self:SetPackedBool(64+19,self.VU1.Value > 0.5)
|
||||
self:SetPackedBool(64+12,self.VU.Value > 0.5)
|
||||
self:SetPackedBool(64+24,self.RST.Value > 0.5)
|
||||
self:SetPackedBool(64+7 ,self.AV8B.Value > 0.5)
|
||||
self:SetPackedBool(64+36,self.VU2.Value > 0.5)
|
||||
self:SetPackedBool(64+13,self.VU3.Value > 0.5)
|
||||
self:SetPackedBool("VPR",self.RST.Value == 1.0 and self.Panel["V1"])
|
||||
]]
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/7)
|
||||
self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.ReservoirPressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, math.min(2.7,self.Pneumatic.BrakeCylinderPressure + 4.0*self.ManualBrake)/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, math.abs(self.Electric.I24)/1000.0)
|
||||
--self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 82.0)
|
||||
self:SetPackedRatio(11,IGLA_Temperature)
|
||||
|
||||
-- Update ARS system
|
||||
self:SetPackedRatio(3, self.ALS_ARS.Speed/100.0)
|
||||
self:SetPackedRatio("Speed", self.Speed/120)
|
||||
if (self.ALS_ARS.Ring == true) then
|
||||
self:SetPackedBool(39,true)
|
||||
end
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = false
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
--self.RearBogey.ParkingBrake = self.ManualBrake.Value > 0.5
|
||||
end
|
||||
|
||||
-- Generate bogey sounds
|
||||
local jerk = math.abs((self.Acceleration - (self.PrevAcceleration or 0)) / self.DeltaTime)
|
||||
self.PrevAcceleration = self.Acceleration
|
||||
|
||||
if jerk > (2.0 + self.Speed/15.0) then
|
||||
self.PrevTriggerTime1 = self.PrevTriggerTime1 or CurTime()
|
||||
self.PrevTriggerTime2 = self.PrevTriggerTime2 or CurTime()
|
||||
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime1 > 1.5) then
|
||||
self.PrevTriggerTime1 = CurTime()
|
||||
self.FrontBogey:EmitSound("subway_trains/chassis_"..math.random(1,3)..".wav", 70, math.random(90,110))
|
||||
end
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime2 > 1.5) then
|
||||
self.PrevTriggerTime2 = CurTime()
|
||||
self.RearBogey:EmitSound("subway_trains/chassis_"..math.random(1,3)..".wav", 70, math.random(90,110))
|
||||
end
|
||||
end
|
||||
|
||||
-- Temporary hacks
|
||||
--self:SetNW2Float("V",self.Speed)
|
||||
--self:SetNW2Float("A",self.Acceleration)
|
||||
|
||||
return self.RetVal
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
-- Parking brake
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,(self.ManualBrake or 0) - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,(self.ManualBrake or 0) + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",tonumber(button:sub(-1,-1)))
|
||||
return
|
||||
end
|
||||
if button:find("FrontDoor") then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("RearDoor") then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button:find("PassengerDoor") then
|
||||
self.PassengerDoor = not self.PassengerDoor
|
||||
if self.PassengerDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("CabinDoor") then
|
||||
self.CabinDoor = not self.CabinDoor
|
||||
if self.CabinDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button == "UAVAToggle" then
|
||||
local state = self.UAVA.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." UAVA!")
|
||||
end
|
||||
if button == "VRDToggle" then
|
||||
local state = self.VRD.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." VRD!")
|
||||
end
|
||||
if button == "NextSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex + 1
|
||||
if self.SignsIndex > #self.SignsList then self.SignsIndex = 1 end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
if button == "PrevSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex - 1
|
||||
if self.SignsIndex < 1 then self.SignsIndex = #self.SignsList end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
|
||||
if button == "Num1P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num1M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
|
||||
-- Parking brake
|
||||
if button == "ManualBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,self.ManualBrake - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ManualBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,self.ManualBrake + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
|
||||
if button == "KVUp" then
|
||||
if self.KV.ControllerPosition ~= -1 then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
end
|
||||
if button == "KVUp_Unlocked" then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
if button == "KVDown" then
|
||||
self.KV:TriggerInput("ControllerDown",1.0)
|
||||
end
|
||||
|
||||
-- KRU
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserUp") then
|
||||
self.KRU:TriggerInput("Up",1)
|
||||
self:OnButtonPress("KRUUp")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserDown") then
|
||||
self.KRU:TriggerInput("Down",1)
|
||||
self:OnButtonPress("KRUDown")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX1") then
|
||||
self.KRU:TriggerInput("SetX1",1)
|
||||
self:OnButtonPress("KRUSetX1")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX2") then
|
||||
self.KRU:TriggerInput("SetX2",1)
|
||||
self:OnButtonPress("KRUSetX2")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX3") then
|
||||
self.KRU:TriggerInput("SetX3",1)
|
||||
self:OnButtonPress("KRUSetX3")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSet0") then
|
||||
self.KRU:TriggerInput("Set0",1)
|
||||
self:OnButtonPress("KRUSet0")
|
||||
end
|
||||
|
||||
if button == "KVSetT1AB" then
|
||||
if self.KV.ControllerPosition == -2 then
|
||||
self.KV:TriggerInput("ControllerSet",-1)
|
||||
timer.Simple(0.20,function()
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end)
|
||||
else
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end
|
||||
end
|
||||
if button == "KVWrench0" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 1 then
|
||||
if self.KVWrenchMode ~= 1 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 0
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
if button == "KVWrenchKV" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 0 then
|
||||
if self.KVWrenchMode ~= 0 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 1
|
||||
self.DriversWrenchPresent = true
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--THERE IS NO KRU IN THIS EZH MODEL
|
||||
--[[
|
||||
if button == "KVWrenchKRU" then
|
||||
if self.KVWrenchMode == 3 then
|
||||
self:PlayOnce("kru_in","cabin",0.7)
|
||||
self.KVWrenchMode = 2
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("LockX3",1)
|
||||
end
|
||||
end]]
|
||||
if button == "KVWrenchNone" then
|
||||
if self.KVWrenchMode ~= 3 and self.KV.ReverserPosition == 0 then
|
||||
if self.KVWrenchMode == 2 then
|
||||
self:PlayOnce("kru_out","cabin",0.7)
|
||||
else
|
||||
self:PlayOnce("revers_out","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 3
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Close",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Close",1) self:OnButtonPress("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Close",1) self:OnButtonPress("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Close",1) self:OnButtonPress("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",1)
|
||||
self:OnButtonPress("KRPSet")
|
||||
end
|
||||
if button == "EmergencyBrake" then
|
||||
self.KV:TriggerInput("ControllerSet",-3)
|
||||
self.Pneumatic:TriggerInput("BrakeSet",7)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
return
|
||||
end
|
||||
if button == "DriverValveDisconnect" then
|
||||
if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",1)
|
||||
else
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",0)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Special logic
|
||||
if (button == "VDL") or (button == "KDL") or (button == "KDP") then
|
||||
--self.VUD1:TriggerInput("Open",1)
|
||||
end
|
||||
if (button == "KDP") then
|
||||
--self.DoorSelect:TriggerInput("Close",1)
|
||||
end
|
||||
if (button == "VUD1Set") or (button == "VUD1Toggle") or
|
||||
(button == "VUD2Set") or (button == "VUD2Toggle") then
|
||||
self.VDL:TriggerInput("Open",1)
|
||||
self.KDL:TriggerInput("Open",1)
|
||||
self.KDP:TriggerInput("Open",1)
|
||||
end
|
||||
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if (button == "UAVAToggle") then
|
||||
if self.UAVA then
|
||||
if self.UAVA.Value > 0.5 then
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
else
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnButtonRelease(button)
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
return
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Open",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Open",1) self:OnButtonRelease("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Open",1) self:OnButtonRelease("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Open",1) self:OnButtonRelease("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",0)
|
||||
self:OnButtonRelease("KRPSet")
|
||||
end
|
||||
|
||||
--[[
|
||||
if (button == "PneumaticBrakeDown") and (self.Pneumatic.DriverValvePosition == 1) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",2)
|
||||
end
|
||||
if self.Pneumatic.ValveType == 1 then
|
||||
if (button == "PneumaticBrakeUp") and (self.Pneumatic.DriverValvePosition == 5) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",4)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
if (not string.find(button,"KVT")) and string.find(button,"KV") then return end
|
||||
if string.find(button,"KRU") then return end
|
||||
end
|
||||
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
@@ -1,91 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.Em"
|
||||
ENT.Author = "Oldy"
|
||||
ENT.Contact = "oldy702@gmail.com"
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["relay_close2"] = nil
|
||||
self.SoundNames["rvt_close"] = nil
|
||||
self.SoundNames["r1_5_close"] = nil
|
||||
self.SoundNames["rvt_open"] = nil
|
||||
self.SoundNames["r1_5_open"] = nil
|
||||
--[[self.SoundNames["relay_close4"] = {"subway_trains/new/relay_7.wav","subway_trains/new/lsd_4.wav"}
|
||||
self.SoundNames["pneumo_switch"] = {
|
||||
"subway_trains/pneumo_8.wav",
|
||||
"subway_trains/pneumo_9.wav",
|
||||
}
|
||||
self.SoundNames["rk_spin"] = "subway_trains/rk_3.wav"
|
||||
self.SoundNames["rk_stop"] = "subway_trains/rk_4.wav"
|
||||
]]
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема 81-710
|
||||
self:LoadSystem("Electric","81_704_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_117DM")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A","KF_47A")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_70")--_lite")
|
||||
-- Контроллер резервного управления
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
self.Pneumatic.ValveType = 1
|
||||
-- Панель управления Е
|
||||
self:LoadSystem("Panel","81_704_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
self:LoadSystem("Horn")
|
||||
self:LoadSystem("Announcer")
|
||||
|
||||
self:LoadSystem("ADoorDisable","Relay")
|
||||
|
||||
self:LoadSystem("ALS_ARS","NoARS")
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,857 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
--"DURASelectMain","DURASelectAlternate","DURAToggleChannel","DURAPowerToggle",
|
||||
ENT.SyncTable = {
|
||||
"CustomC","Custom1","Custom2","Custom3","CustomD",
|
||||
"CustomE","CustomF","CustomG","R_UNch","R_ZS","R_G","R_Radio","R_Program1","R_Program2","KVT","KB","KSD",
|
||||
"VZ1","VUD1","KDL","KDLR","KDLK","KDP","KDLRK","DoorSelect","Ring","UKS","AGS",
|
||||
"KRZD","R_VPR","VozvratRP","AVU","KVP","ConverterProtection","RZP",
|
||||
"KSN","ARS","ALS","OtklAVU","TormAT","L_1","L_3","DIPoff",
|
||||
"VMK","BPSNon","RezMK","ARS13","L_4","VUS","VAH","VAD","EmergencyBrakeValve",
|
||||
"KAH","KAHK","KDPK","CabinHeat","KRR","KRP",
|
||||
"RC1","VB","BPS","UOS", "PB", "UAVA","AVULight_light","PD","AVU",
|
||||
"DriverValveBLDisconnect","DriverValveTLDisconnect","DriverValveTLDisconnect","ParkingBrake","EPK",
|
||||
"VUD2","VDL", "GV","DIPon","DIPoff","VozvratRP","KU1","RezMK",
|
||||
"VU3","VU1","VU2","AV8B","VU","KDLK","VDLK","KDPK","RST", "DoorSelect","LPU","R_ASNPMenu","R_ASNPUp","R_ASNPDown","R_ASNPOn",
|
||||
}
|
||||
ENT.SyncFunctions = {
|
||||
""
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
self.Plombs = {
|
||||
RST = true,
|
||||
Init = true,
|
||||
OtklAVU = true,
|
||||
UAVA = true,
|
||||
}
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi_train/81-508/81-508.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(425,-39,-27.5),Angle(0,0,0))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(430,40,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat1 = self:CreateSeat("instructor",Vector(443,0,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat2 = self:CreateSeat("instructor",Vector(420,-20,-48+6),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.InstructorsSeat:SetColor(Color(0,0,0,0))
|
||||
self.InstructorsSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
self.ExtraSeat1:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat1:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.ExtraSeat2:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat2:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 317-5,0,-89),Angle(0,180,0),true,"717")
|
||||
self.RearBogey = self:CreateBogey(Vector(-317+0,0,-89),Angle(0,0,0),false,"717")
|
||||
self.FrontCouple = self:CreateCouple(Vector( 419.5+3.5,0,-75),Angle(0,0,0),true,"717")
|
||||
self.RearCouple = self:CreateCouple(Vector(-421.5-3.5,0,-75),Angle(0,180,0),false,"717")
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
-- Initialize key mapping
|
||||
self.KeyMap = {
|
||||
[KEY_1] = "KVSetX1",
|
||||
[KEY_2] = "KVSetX2",
|
||||
[KEY_3] = "KVSetX3",
|
||||
[KEY_4] = "KVSet0",
|
||||
[KEY_5] = "KVSetT1",
|
||||
[KEY_6] = "KVSetT1AB",
|
||||
[KEY_7] = "KVSetT2",
|
||||
[KEY_8] = "KRP",
|
||||
|
||||
[KEY_EQUAL] = "R_Program1Set",
|
||||
[KEY_MINUS] = "R_Program2Set",
|
||||
|
||||
[KEY_G] = "VozvratRPSet",
|
||||
|
||||
[KEY_0] = "KVReverserUp",
|
||||
[KEY_9] = "KVReverserDown",
|
||||
[KEY_PAD_PLUS] = "KVReverserUp",
|
||||
[KEY_PAD_MINUS] = "KVReverserDown",
|
||||
[KEY_W] = "KVUp",
|
||||
[KEY_S] = "KVDown",
|
||||
[KEY_F] = "PneumaticBrakeUp",
|
||||
[KEY_R] = "PneumaticBrakeDown",
|
||||
|
||||
[KEY_A] = "KDL",
|
||||
[KEY_D] = "KDP",
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "HornEngage",
|
||||
[KEY_N] = "VZ1Set",
|
||||
[KEY_PAD_1] = "PneumaticBrakeSet1",
|
||||
[KEY_PAD_2] = "PneumaticBrakeSet2",
|
||||
[KEY_PAD_3] = "PneumaticBrakeSet3",
|
||||
[KEY_PAD_4] = "PneumaticBrakeSet4",
|
||||
[KEY_PAD_5] = "PneumaticBrakeSet5",
|
||||
[KEY_PAD_6] = "PneumaticBrakeSet6",
|
||||
[KEY_PAD_7] = "PneumaticBrakeSet7",
|
||||
[KEY_PAD_DIVIDE] = "KRPSet",
|
||||
[KEY_PAD_MULTIPLY] = "KAHSet",
|
||||
--[KEY_J] = "KVWrenchKRU",
|
||||
|
||||
--[KEY_SPACE] = "PBSet",
|
||||
[KEY_BACKSPACE] = "EmergencyBrake",
|
||||
|
||||
[KEY_PAD_0] = "DriverValveDisconnect",
|
||||
[KEY_LSHIFT] = {
|
||||
[KEY_W] = "KVUp_Unlocked",
|
||||
[KEY_SPACE] = "KVTSet",
|
||||
|
||||
[KEY_A] = "DURASelectAlternate",
|
||||
[KEY_D] = "DURASelectMain",
|
||||
[KEY_V] = "DURAToggleChannel",
|
||||
[KEY_1] = "DIPonSet",
|
||||
[KEY_2] = "DIPoffSet",
|
||||
[KEY_4] = "KVSet0Fast",
|
||||
--[KEY_L] = "DriverValveDisconnect",
|
||||
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_6] = "KVSetT1A",
|
||||
},
|
||||
|
||||
[KEY_RSHIFT] = {
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
--[KEY_L] = "DriverValveDisconnect",
|
||||
[KEY_F] = "BCCDSet",
|
||||
[KEY_R] = "VZPSet",
|
||||
},
|
||||
[KEY_LALT] = {
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
},
|
||||
}
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(-471,-30,0),
|
||||
Radius = 28,
|
||||
ID = "RearDoor"
|
||||
},
|
||||
{ Pos = Vector(473,32,28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor1"
|
||||
},
|
||||
{ Pos = Vector(473,32,-28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor2"
|
||||
},
|
||||
{ Pos = Vector(383.02,31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor1"
|
||||
},
|
||||
{ Pos = Vector(383.02,-31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor1"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor3"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor4"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor5"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor6"
|
||||
},
|
||||
}
|
||||
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[2] = { "glow", Vector(469.4, 45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[4] = { "glow", Vector(458+9,-14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[5] = { "glow", Vector(458+9,0, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[6] = { "glow", Vector(458+9, 14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
|
||||
-- Emergency lit
|
||||
[9] = { "headlight", Vector(412,0,51), Angle(80,0,0), Color(255,255,255), brightness = 1, farz = 117, nearz = 0.01, shadows = 0, fov = 120 },
|
||||
-- Cabin
|
||||
[22] = { "light", Vector(432+5.9,-54.5,42.2), Angle(90,0,0), Color(255,180,128), brightness = 0.75, scale = 0.4, texture = "sprites/light_glow03.vmt" },
|
||||
[23] = { "dynamiclight", Vector(432,-10.0,20), Angle(0,0,0), Color(255,255,255), brightness = 0.0005, distance = 600},
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, -5), Angle(0,0,0), Color(255,125,25), brightness = 6, distance = 250},
|
||||
[12] = { "dynamiclight", Vector( 0, 0, -5), Angle(0,0,0), Color(255,125,25), brightness = 6, distance = 300},
|
||||
[13] = { "dynamiclight", Vector(-250, 0, -5), Angle(0,0,0), Color(255,125,25), brightness = 6, distance = 250},
|
||||
|
||||
[15] = { "light", Vector(402.202942,69.270073,44.79285), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[16] = { "light", Vector(402.202942,69.270073,41.509621), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[17] = { "light", Vector(402.202942,69.270073,37.3862), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
|
||||
[70 ] = { "headlight", Vector( 450, -60, -47), Angle(45,-90,0), Color(255,255,255), brightness = 0.5, distance = 400 , fov=120, shadows = 1 },
|
||||
|
||||
}
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- KV wrench mode
|
||||
self.KVWrenchMode = 0
|
||||
|
||||
-- Parking brake ratio
|
||||
self.ManualBrake = 0.0
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self.CabinDoor = false
|
||||
self.PassengerDoor = false
|
||||
|
||||
-- self.A5:TriggerInput("Set",0)
|
||||
self:TrainSpawnerUpdate()
|
||||
end
|
||||
|
||||
function ENT:TrainSpawnerUpdate()
|
||||
self.Texture = self:GetNW2String("Texture")
|
||||
self.PassTexture = self:GetNW2String("PassTexture")
|
||||
self.CabTexture = self:GetNW2String("CabTexture")
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self.CabTexture]
|
||||
|
||||
for k in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
elseif v == "models/metrostroi_train/81/tabl" then
|
||||
if not self.SignsList then
|
||||
self:PrepareSigns()
|
||||
end
|
||||
if self.SignsList[self.SignsIndex] then self:SetSubMaterial(k-1,self.SignsList[self.SignsIndex][1]) end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
local RetVal = self.BaseClass.Think(self)
|
||||
|
||||
-- Check if wrench was pulled out
|
||||
if self.DriversWrenchPresent then
|
||||
self.KV:TriggerInput("Enabled",self:IsWrenchPresent() and 1 or 0)
|
||||
end
|
||||
self:SetPackedBool("RedLight",(self.Panel["RedLightLeft"] > 0.5 or self.Panel["RedLightRight"] > 0.5 ) and not IsValid(self.FrontTrain))
|
||||
|
||||
-- Emergency Ezh cabin lights
|
||||
self:SetLightPower(9, self.AV8B.Value < 0.5 and self.VU2.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
|
||||
-- Cabin lights
|
||||
--self:SetLightPower(22, self.L_2.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
self:SetLightPower(23, self.VU3.Value > 0.5)
|
||||
|
||||
--Gauges lights
|
||||
self:SetPackedBool("PanelLights",self.L_3.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = (self.VU2.Value > 0.5 and self.Panel["V1"] > 0.5) or lightsActive2
|
||||
self:SetPackedBool("Lamps_emer",lightsActive1)
|
||||
self:SetPackedBool("Lamps_full",lightsActive2)
|
||||
local Light
|
||||
if self.Pneumatic.Compressor == 1 then
|
||||
Light = (lightsActive2 and 0.6 or 0.3)
|
||||
else
|
||||
Light = (lightsActive2 and 0.8 or 0.4)
|
||||
end
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
self:SetPackedRatio("LampsI",math.Round((self.Electric.I24-150)/1000.0,1.5))
|
||||
|
||||
-- Total temperature
|
||||
local IGLA_Temperature = math.max(self.Electric.T1,self.Electric.T2)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:WriteTrainWire(35,(self.Pneumatic.BrakeCylinderPressure > 0.1) and 1 or 0)
|
||||
|
||||
-- DIP/power
|
||||
self:SetPackedBool(32,self.Panel["V1"] > 0.5)
|
||||
-- Red RP
|
||||
local TW18 = self:GetTrainWire18()
|
||||
if self:ReadTrainWire(20) == 0 or (self.Panel["V1"] < 0.5) then TW18 = 0 end
|
||||
self:SetPackedBool(131,TW18 > 0)
|
||||
self:SetPackedRatio("LRP",TW18)
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle or 0
|
||||
if self.ManualBrake < 0.001 and self.ManualBrake > self.TrueBrakeAngle then self.TrueBrakeAngle = self.ManualBrake end
|
||||
if self.ManualBrake > 0.999 and self.ManualBrake < self.TrueBrakeAngle then self.TrueBrakeAngle = self.ManualBrake end
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle + (self.ManualBrake - self.TrueBrakeAngle)*2.0*(self.DeltaTime or 0)
|
||||
self:SetPackedRatio("ManualBrake",self.TrueBrakeAngle)
|
||||
-- Green RP
|
||||
self:SetPackedBool(36,self.Panel["GreenRP"] > 0.5)
|
||||
-- Cabin heating
|
||||
self:SetPackedBool(37,self.Panel["KUP"] > 0.5)
|
||||
-- AVU
|
||||
self:SetPackedBool(38,self.Panel["AVU"] > 0.5)
|
||||
-- Ring
|
||||
self:SetPackedBool(39,self.Panel["Ring"] > 0.5)
|
||||
-- SD
|
||||
self:SetPackedBool(40,self.Panel["V1"] > 0.5 and self.Panel["SD"] < 0.5)
|
||||
-- KSD
|
||||
self:SetPackedBool("KSD",self.KSD.Value == 0.00)
|
||||
-- KRP
|
||||
self:SetPackedBool(113,self.KRP.Value == 1.0)
|
||||
|
||||
|
||||
self:SetPackedBool("DriverValveBLDisconnect",self.DriverValveBLDisconnect.Value == 1.0)
|
||||
self:SetPackedBool("DriverValveTLDisconnect",self.DriverValveTLDisconnect.Value == 1.0)
|
||||
if self.DriverValveDisconnect.Blocked > 0 and self.Pneumatic.ValveType == 2 then
|
||||
self.DriverValveDisconnect:TriggerInput("Block",0)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Block",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Block",1)
|
||||
end
|
||||
if self.DriverValveDisconnect.Blocked == 0 and self.Pneumatic.ValveType == 1 then
|
||||
self.DriverValveDisconnect:TriggerInput("Block",1)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Block",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Block",0)
|
||||
end
|
||||
self:SetPackedBool("EPK",self.EPK.Value == 1.0)
|
||||
self:SetPackedBool("VPR",self.RST.Value > 0 and self.Panel["V1"] > 0)
|
||||
self:SetPackedBool("LST",self:ReadTrainWire(6) > 0.5)
|
||||
self:SetPackedBool("LVD",self:ReadTrainWire(1) > 0.5)
|
||||
self:SetPackedBool("RK",self:ReadTrainWire(2) > 0.5)
|
||||
self:SetPackedBool(19,self.OtklAVU.Value == 1.0)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(55,(self.DoorSelect.Value == 1.0))
|
||||
self:SetPackedBool("VZ1",(self.VZ1.Value == 1))
|
||||
|
||||
self:SetPackedBool(17,self.KRZD.Value == 1.0)
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
self:SetPackedBool(158,self.PassengerDoor)
|
||||
self:SetPackedBool(159,self.CabinDoor)
|
||||
|
||||
self:SetNW2Bool("ASNPPlay",self.VB.Value > 0 and self:ReadTrainWire(47) > 0)
|
||||
--KRR
|
||||
self:SetPackedBool("KRR",self.KRR.Value > 0.5)
|
||||
|
||||
--Radiostation
|
||||
self:SetPackedBool(125,self.R_G.Value == 1.0)
|
||||
self:SetPackedBool(127,self.R_ZS.Value == 1.0)
|
||||
self:SetPackedBool(126,self.R_Radio.Value == 1.0)
|
||||
self:SetPackedBool(128,self.R_Program1.Value == 1.0)
|
||||
self:SetPackedBool(129,self.R_Program2.Value == 1.0)
|
||||
|
||||
--[[
|
||||
-- LST
|
||||
self:SetPackedBool(49,self:ReadTrainWire(6) > 0.5)
|
||||
-- LVD
|
||||
self:SetPackedBool(50,self:ReadTrainWire(1) > 0.5)
|
||||
|
||||
self:SetPackedBool(165,self.PB.Value > 0)
|
||||
|
||||
-- AV states
|
||||
-- for i,v in ipairs(self.Panel.AVMap) do
|
||||
-- if tonumber(v)
|
||||
-- then self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
-- elseif self[v] then self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
self:SetPackedBool(62,self.L_3.Value > 0.5)
|
||||
self:SetPackedBool(64+19,self.VU1.Value > 0.5)
|
||||
self:SetPackedBool(64+12,self.VU.Value > 0.5)
|
||||
self:SetPackedBool(64+24,self.RST.Value > 0.5)
|
||||
self:SetPackedBool(64+7 ,self.AV8B.Value > 0.5)
|
||||
self:SetPackedBool(64+36,self.VU2.Value > 0.5)
|
||||
self:SetPackedBool(64+13,self.VU3.Value > 0.5)
|
||||
self:SetPackedBool("VPR",self.RST.Value == 1.0 and self.Panel["V1"])
|
||||
]]
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/7)
|
||||
self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.ReservoirPressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, math.min(2.7,self.Pneumatic.BrakeCylinderPressure)/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, 0.5 + 0.5*(self.Electric.I24/500.0))
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 82.0)
|
||||
self:SetPackedRatio(11,IGLA_Temperature)
|
||||
self:SetPackedBool("EmergencyBrakeValve",self.EmergencyBrakeValve.Value > 0)
|
||||
self:SetPackedBool(152,self.UAVA.Value == 1.0)
|
||||
|
||||
self:SetPackedBool(128,self.R_Program1.Value == 1.0)
|
||||
self:SetPackedBool(129,self.R_Program2.Value == 1.0)
|
||||
self:SetPackedBool(22,self.Pneumatic.ValveType == 2)
|
||||
|
||||
-- Update ARS system (no ars on E)
|
||||
self:SetPackedRatio(3, self.ALS_ARS.Speed/100.0)
|
||||
self:SetPackedRatio("Speed", self.Speed/100)
|
||||
---print (self.Speed)
|
||||
if (self.ALS_ARS.Ring == true) then
|
||||
self:SetPackedBool(39,true)
|
||||
end
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 27000+13000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 27000+13000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
local add = 1
|
||||
if math.abs(self:GetAngles().pitch) > 4 then
|
||||
add = math.min((math.abs(self:GetAngles().pitch)-4)/2,1)*2
|
||||
end
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure*add
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = self.ParkingBrake.Value > 0.5
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure*add
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
end
|
||||
|
||||
-- Generate bogey sounds
|
||||
local jerk = math.abs((self.Acceleration - (self.PrevAcceleration or 0)) / self.DeltaTime)
|
||||
self.PrevAcceleration = self.Acceleration
|
||||
|
||||
if jerk > (2.0 + self.Speed/15.0) then
|
||||
self.PrevTriggerTime1 = self.PrevTriggerTime1 or CurTime()
|
||||
self.PrevTriggerTime2 = self.PrevTriggerTime2 or CurTime()
|
||||
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime1 > 1.5) then
|
||||
self.PrevTriggerTime1 = CurTime()
|
||||
self.FrontBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 85, math.random(96,110))
|
||||
end
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime2 > 1.5) then
|
||||
self.PrevTriggerTime2 = CurTime()
|
||||
self.RearBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 85, math.random(96,110))
|
||||
end
|
||||
end
|
||||
|
||||
-- Temporary hacks
|
||||
--self:SetNW2Float("V",self.Speed)
|
||||
--self:SetNW2Float("A",self.Acceleration)
|
||||
|
||||
return RetVal
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
-- Parking brake
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,(self.ManualBrake or 0) - 0.05)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,(self.ManualBrake or 0) + 0.05)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
end
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",tonumber(button:sub(-1,-1)))
|
||||
return
|
||||
end
|
||||
if button:find("FrontDoor") then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("RearDoor") then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button:find("PassengerDoor") then
|
||||
self.PassengerDoor = not self.PassengerDoor
|
||||
if self.PassengerDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("CabinDoor") then
|
||||
self.CabinDoor = not self.CabinDoor
|
||||
if self.CabinDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button == "NextSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex + 1
|
||||
if self.SignsIndex > #self.SignsList then self.SignsIndex = 1 end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
if button == "PrevSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex - 1
|
||||
if self.SignsIndex < 1 then self.SignsIndex = #self.SignsList end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
|
||||
if button == "Num1P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num1M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
|
||||
-- Parking brake
|
||||
if button == "ManualBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,self.ManualBrake - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ManualBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,self.ManualBrake + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
|
||||
if button == "KVUp" then
|
||||
if self.KV.ControllerPosition ~= -1 then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
end
|
||||
if button == "KVUp_Unlocked" then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
if button == "KVDown" then
|
||||
self.KV:TriggerInput("ControllerDown",1.0)
|
||||
end
|
||||
|
||||
-- KRU
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserUp") then
|
||||
self.KRU:TriggerInput("Up",1)
|
||||
self:OnButtonPress("KRUUp")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserDown") then
|
||||
self.KRU:TriggerInput("Down",1)
|
||||
self:OnButtonPress("KRUDown")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX1") then
|
||||
self.KRU:TriggerInput("SetX1",1)
|
||||
self:OnButtonPress("KRUSetX1")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX2") then
|
||||
self.KRU:TriggerInput("SetX2",1)
|
||||
self:OnButtonPress("KRUSetX2")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX3") then
|
||||
self.KRU:TriggerInput("SetX3",1)
|
||||
self:OnButtonPress("KRUSetX3")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSet0") then
|
||||
self.KRU:TriggerInput("Set0",1)
|
||||
self:OnButtonPress("KRUSet0")
|
||||
end
|
||||
|
||||
if button == "KVSetT1AB" then
|
||||
if self.KV.ControllerPosition == -2 then
|
||||
self.KV:TriggerInput("ControllerSet",-1)
|
||||
timer.Simple(0.20,function()
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end)
|
||||
else
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end
|
||||
end
|
||||
if button == "KVWrench0" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 1 then
|
||||
if self.KVWrenchMode ~= 1 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 0
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
if button == "KVWrenchKV" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 0 then
|
||||
if self.KVWrenchMode ~= 0 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 1
|
||||
self.DriversWrenchPresent = true
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--THERE IS NO KRU IN THIS EZH MODEL
|
||||
--[[
|
||||
if button == "KVWrenchKRU" then
|
||||
if self.KVWrenchMode == 3 then
|
||||
self:PlayOnce("kru_in","cabin",0.7)
|
||||
self.KVWrenchMode = 2
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("LockX3",1)
|
||||
end
|
||||
end]]
|
||||
if button == "KVWrenchNone" then
|
||||
if self.KVWrenchMode ~= 3 and self.KV.ReverserPosition == 0 then
|
||||
if self.KVWrenchMode == 2 then
|
||||
self:PlayOnce("kru_out","cabin",0.7)
|
||||
else
|
||||
self:PlayOnce("revers_out","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 3
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Close",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Close",1) self:OnButtonPress("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Close",1) self:OnButtonPress("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Close",1) self:OnButtonPress("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",1)
|
||||
self:OnButtonPress("KRPSet")
|
||||
end
|
||||
if button == "EmergencyBrake" then
|
||||
self.KV:TriggerInput("ControllerSet",-3)
|
||||
self.Pneumatic:TriggerInput("BrakeSet",7)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
return
|
||||
end
|
||||
if button == "DriverValveDisconnect" then
|
||||
if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",1)
|
||||
else
|
||||
--self:PlayOnce("pneumo_disconnect1","cabin",0.9)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",0)
|
||||
end
|
||||
if self.DriverValveBLDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_on","cabin",0.9) end
|
||||
else
|
||||
--self:PlayOnce("pneumo_disconnect2","cabin",0.9)
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_off","cabin",0.9) end
|
||||
end
|
||||
return
|
||||
end
|
||||
-- Special logic
|
||||
if (button == "VDL") or (button == "KDL") or (button == "KDP") then
|
||||
--self.VUD1:TriggerInput("Open",1)
|
||||
end
|
||||
if (button == "KDP") then
|
||||
--self.DoorSelect:TriggerInput("Close",1)
|
||||
end
|
||||
if (button == "VUD1Set") or (button == "VUD1Toggle") or
|
||||
(button == "VUD2Set") or (button == "VUD2Toggle") then
|
||||
self.VDL:TriggerInput("Open",1)
|
||||
self.KDL:TriggerInput("Open",1)
|
||||
self.KDP:TriggerInput("Open",1)
|
||||
end
|
||||
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--[[if (button == "UAVAToggle") then
|
||||
if self.UAVA then
|
||||
if self.UAVA.Value > 0.5 then
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
else
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
end
|
||||
end
|
||||
return
|
||||
end]]
|
||||
end
|
||||
|
||||
function ENT:OnButtonRelease(button)
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
return
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Open",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Open",1) self:OnButtonRelease("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Open",1) self:OnButtonRelease("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Open",1) self:OnButtonRelease("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",0)
|
||||
self:OnButtonRelease("KRPSet")
|
||||
end
|
||||
|
||||
--[[
|
||||
if (button == "PneumaticBrakeDown") and (self.Pneumatic.DriverValvePosition == 1) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",2)
|
||||
end
|
||||
if self.Pneumatic.ValveType == 1 then
|
||||
if (button == "PneumaticBrakeUp") and (self.Pneumatic.DriverValvePosition == 5) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",4)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
if (not string.find(button,"KVT")) and string.find(button,"KV") then return end
|
||||
if string.find(button,"KRU") then return end
|
||||
end
|
||||
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
|
||||
function ENT:TriggerTurbostroiInput(sys,name,val)
|
||||
self.BaseClass.TriggerTurbostroiInput(self,sys,name,val)
|
||||
if sys == "Panel" and name:find("HeadLights") or sys == "L_4" then
|
||||
local brightness = math.min(1,self.Panel["HeadLights1"])*0.50 +
|
||||
math.min(1,self.Panel["HeadLights2"])*0.25 +
|
||||
math.min(1,self.Panel["HeadLights3"])*0.25
|
||||
if (self.Panel["HeadLights3"] > 0.5 or self.Panel["HeadLights1"] > 0.5) then-- and (self.L_4.Value > 0.5) then
|
||||
self:SetPackedRatio("Headlight",brightness)
|
||||
else
|
||||
self:SetPackedRatio("Headlight",0)
|
||||
end
|
||||
self:SetPackedBool("HeadLights1",self.Panel["HeadLights1"] > 0)
|
||||
self:SetPackedBool("HeadLights2",self.Panel["HeadLights2"] > 0)
|
||||
end
|
||||
end
|
||||
@@ -1,604 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintName = "Entities.Em508"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = true
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
local function GetDoorPosition(i,k)
|
||||
return Vector(359.0 - 35/2 - 229.5*i,-65*(1-2*k),7.5)
|
||||
end
|
||||
ENT.AnnouncerPositions = {
|
||||
{Vector(412,-49 ,61),80,1},
|
||||
{Vector(-3,-60, 62),300,1},
|
||||
{Vector(-3,60 ,62),300,1},
|
||||
}
|
||||
ENT.Cameras = {
|
||||
{Vector(407.5+15,32,16),Angle(0,180,0),"Train.703.Breakers1"},
|
||||
{Vector(407.5+11,46,20),Angle(0,180,0),"Train.703.Breakers2"},
|
||||
{Vector(407.5+28,48,16),Angle(0,40,0),"Train.703.Left"},
|
||||
{Vector(407.5+11,37,-5),Angle(0,0,0),"Train.703.Parking"},
|
||||
{Vector(407.5+29,-45,43),Angle(0,-90,0),"Train.703.ASNP"},
|
||||
{Vector(407.5+10,-45,7),Angle(0,-90,0),"Train.703.IGLA"},
|
||||
}
|
||||
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["rolling_10"] = {loop=true,"subway_trains/717/rolling/10_rolling.wav"}
|
||||
self.SoundNames["rolling_40"] = {loop=true,"subway_trains/717/rolling/40_rolling.wav"}
|
||||
self.SoundNames["rolling_70"] = {loop=true,"subway_trains/717/rolling/70_rolling.wav"}
|
||||
self.SoundNames["rolling_80"] = {loop=true,"subway_trains/717/rolling/80_rolling.wav"}
|
||||
self.SoundPositions["rolling_10"] = {1200,1e9,Vector(0,0,0),1}
|
||||
self.SoundPositions["rolling_40"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundPositions["rolling_70"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundPositions["rolling_80"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundNames["pneumo_disconnect2"] = "subway_trains/common/pneumatic/pneumo_close.mp3"
|
||||
self.SoundNames["pneumo_disconnect1"] = {
|
||||
"subway_trains/common/pneumatic/pneumo_open.mp3",
|
||||
"subway_trains/common/pneumatic/pneumo_open2.mp3",
|
||||
}
|
||||
self.SoundPositions["pneumo_disconnect2"] = {60,1e9,Vector(431.8,-50.1+1.5,-33.7),1}
|
||||
self.SoundPositions["pneumo_disconnect1"] = {60,1e9,Vector(431.8,-50.1+1.5,-33.7),1}
|
||||
self.SoundNames["epv_on"] = "subway_trains/common/pneumatic/epv_on.mp3"
|
||||
self.SoundNames["epv_off"] = "subway_trains/common/pneumatic/epv_off.mp3"
|
||||
self.SoundPositions["epv_on"] = {100,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
self.SoundPositions["epv_off"] = {100,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
self.SoundPositions["epv_off"] = {60,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
-- Релюшки
|
||||
self.SoundNames["rpb_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["rpb_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["rpb_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["rpb_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["rvt_on"] = {
|
||||
"subway_trains/717/relays/brake_on1.mp3",
|
||||
}
|
||||
self.SoundNames["rvt_off"] = {
|
||||
"subway_trains/717/relays/brake_off1.mp3",
|
||||
"subway_trains/717/relays/brake_off2.mp3",
|
||||
"subway_trains/717/relays/brake_off3.mp3",
|
||||
}
|
||||
self.SoundPositions["rvt_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["rvt_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
if self.Breakers then
|
||||
self.SoundNames["r1_5_on"] = "subway_trains/717/relays/drive_on1.mp3"
|
||||
else
|
||||
self.SoundNames["r1_5_on"] = "subway_trains/717/relays/drive2_on.mp3"
|
||||
end
|
||||
self.SoundNames["r1_5_off"] = "subway_trains/717/relays/drive_off.mp3"
|
||||
self.SoundPositions["r1_5_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["r1_5_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
|
||||
self.SoundNames["kd_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["kd_on"] = "subway_trains/717/relays/lsd_1.mp3"
|
||||
self.SoundPositions["kd_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["kd_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["k25_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["k25_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["k25_on"] = {120,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["k25_off"] = {120,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["ro_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["ro_on"] = "subway_trains/717/relays/RO_on.mp3"
|
||||
self.SoundPositions["ro_on"] = {140,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["ro_off"] = {140,1e9,Vector(400,25,-35),1}
|
||||
|
||||
|
||||
self.SoundNames["avu_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["avu_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["avu_on"] = {60,1e9, Vector(400,-40,-45),1}
|
||||
self.SoundPositions["avu_off"] = {60,1e9, Vector(400,-40,-45),1}
|
||||
--Подвагонка
|
||||
self.SoundNames["lk2_on"] = "subway_trains/717/pneumatic/lk/lk2_on.mp3"
|
||||
self.SoundNames["lk2_off"] = "subway_trains/717/pneumatic/lk/lk2_off.mp3"
|
||||
self.SoundNames["lk3_on"] = "subway_trains/717/pneumatic/lk/lk3_on.mp3"
|
||||
self.SoundNames["lk3_off"] = "subway_trains/717/pneumatic/lk/lk3_off.mp3"
|
||||
self.SoundPositions["lk2_on"] = {440,1e9,Vector(-60,-40,-66),0.2}
|
||||
self.SoundPositions["lk2_off"] = {400,1e9,Vector(-60,-40,-66),0.6}
|
||||
self.SoundPositions["lk3_on"] = {440,1e9,Vector(-60,-40,-66),0.2}
|
||||
self.SoundPositions["lk3_off"] = {400,1e9,Vector(-60,-40,-66),0.6}
|
||||
|
||||
self.SoundNames["compressor"] = {loop=2.0,"subway_trains/ezh/compressor/ezh_compressor_start.mp3","subway_trains/ezh/compressor/ezh_compressor_loop.mp3", "subway_trains/ezh/compressor/ezh_compressor_end.mp3"}
|
||||
self.SoundPositions["compressor"] = {700,1e9,Vector(-118,-40,-66)}
|
||||
self.SoundNames["rk"] = {"subway_trains/717/rk/rk_start.wav","subway_trains/717/rk/rk_spin.wav","subway_trains/717/rk/rk_stop.mp3"}
|
||||
self.SoundPositions["rk"] = {70,1e3,Vector(110,-40,-75)}
|
||||
|
||||
self.SoundNames["ezh3_revers_0-f"] = {"subway_trains/717/kv70/reverser_0-f_1.mp3","subway_trains/717/kv70/reverser_0-f_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_f-0"] = {"subway_trains/717/kv70/reverser_f-0_1.mp3","subway_trains/717/kv70/reverser_f-0_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_0-b"] = {"subway_trains/717/kv70/reverser_0-b_1.mp3","subway_trains/717/kv70/reverser_0-b_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_b-0"] = {"subway_trains/717/kv70/reverser_b-0_1.mp3","subway_trains/717/kv70/reverser_b-0_2.mp3"}
|
||||
self.SoundNames["revers_in"] = {"subway_trains/ezh3/kv66/revers_in.wav"}
|
||||
self.SoundNames["revers_out"] = {"subway_trains/ezh3/kv66/revers_out.wav"}
|
||||
self.SoundPositions["ezh3_revers_0-f"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_f-0"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_0-b"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_b-0"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_in"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_out"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
|
||||
self.SoundNames["kru_in"] = {
|
||||
"subway_trains/717/kru/kru_insert1.mp3",
|
||||
"subway_trains/717/kru/kru_insert2.mp3"
|
||||
}
|
||||
self.SoundPositions["kru_in"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundNames["kru_out"] = {
|
||||
"subway_trains/717/kru/kru_eject1.mp3",
|
||||
"subway_trains/717/kru/kru_eject2.mp3",
|
||||
"subway_trains/717/kru/kru_eject3.mp3",
|
||||
}
|
||||
self.SoundPositions["kru_out"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
|
||||
self.SoundNames["kru_0_1"] = {
|
||||
"subway_trains/717/kru/kru0-1_1.mp3",
|
||||
"subway_trains/717/kru/kru0-1_2.mp3",
|
||||
"subway_trains/717/kru/kru0-1_3.mp3",
|
||||
"subway_trains/717/kru/kru0-1_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_1_2"] = {
|
||||
"subway_trains/717/kru/kru1-2_1.mp3",
|
||||
"subway_trains/717/kru/kru1-2_2.mp3",
|
||||
"subway_trains/717/kru/kru1-2_3.mp3",
|
||||
"subway_trains/717/kru/kru1-2_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_2_1"] = {
|
||||
"subway_trains/717/kru/kru2-1_1.mp3",
|
||||
"subway_trains/717/kru/kru2-1_2.mp3",
|
||||
"subway_trains/717/kru/kru2-1_3.mp3",
|
||||
"subway_trains/717/kru/kru2-1_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_1_0"] = {
|
||||
"subway_trains/717/kru/kru1-0_1.mp3",
|
||||
"subway_trains/717/kru/kru1-0_2.mp3",
|
||||
"subway_trains/717/kru/kru1-0_3.mp3",
|
||||
"subway_trains/717/kru/kru1-0_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_2_3"] = {
|
||||
"subway_trains/717/kru/kru2-3_1.mp3",
|
||||
"subway_trains/717/kru/kru2-3_2.mp3",
|
||||
"subway_trains/717/kru/kru2-3_3.mp3",
|
||||
"subway_trains/717/kru/kru2-3_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_3_2"] = {
|
||||
"subway_trains/717/kru/kru3-2_1.mp3",
|
||||
"subway_trains/717/kru/kru3-2_2.mp3",
|
||||
"subway_trains/717/kru/kru3-2_3.mp3",
|
||||
"subway_trains/717/kru/kru3-2_4.mp3",
|
||||
}
|
||||
self.SoundPositions["kru_0_1"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_1_2"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_2_1"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_1_0"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_2_3"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_3_2"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
|
||||
self.SoundNames["kr_open"] = {
|
||||
"subway_trains/717/cover/cover_open1.mp3",
|
||||
"subway_trains/717/cover/cover_open2.mp3",
|
||||
"subway_trains/717/cover/cover_open3.mp3",
|
||||
}
|
||||
self.SoundNames["kr_close"] = {
|
||||
"subway_trains/717/cover/cover_close1.mp3",
|
||||
"subway_trains/717/cover/cover_close2.mp3",
|
||||
"subway_trains/717/cover/cover_close3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["switch_off"] = {
|
||||
"subway_trains/717/switches/tumbler_slim_off1.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off2.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off3.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off4.mp3",
|
||||
}
|
||||
self.SoundNames["switch_on"] = {
|
||||
"subway_trains/717/switches/tumbler_slim_on1.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on2.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on3.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on4.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["switchbl_off"] = {
|
||||
"subway_trains/717/switches/tumbler_fatb_off1.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_off2.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_off3.mp3",
|
||||
}
|
||||
self.SoundNames["switchbl_on"] = {
|
||||
"subway_trains/717/switches/tumbler_fatb_on1.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_on2.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_on3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["triple_down-0"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_down-0_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_down-0_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_0-up"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_0-up_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_0-up_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_up-0"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_up-0_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_up-0_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_0-down"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_0-down_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_0-down_2.mp3",
|
||||
}
|
||||
self.SoundNames["button1_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off1.mp3",
|
||||
"subway_trains/ezh3/switches/button_off2.mp3",
|
||||
}
|
||||
self.SoundNames["button1_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on1.mp3",
|
||||
"subway_trains/ezh3/switches/button_on2.mp3",
|
||||
}
|
||||
self.SoundNames["button2_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off3.mp3",
|
||||
"subway_trains/ezh3/switches/button_off4.mp3",
|
||||
}
|
||||
self.SoundNames["button2_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on3.mp3",
|
||||
"subway_trains/ezh3/switches/button_on4.mp3",
|
||||
}
|
||||
self.SoundNames["button3_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off6.mp3",
|
||||
"subway_trains/ezh3/switches/button_off5.mp3",
|
||||
}
|
||||
self.SoundNames["button3_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on5.mp3",
|
||||
"subway_trains/ezh3/switches/button_on6.mp3",
|
||||
}
|
||||
self.SoundNames["button4_off"] = {
|
||||
"subway_trains/ezh3/switches/button_on1.mp3",
|
||||
"subway_trains/ezh3/switches/button_on2.mp3",
|
||||
}
|
||||
self.SoundNames["button4_on"] = {
|
||||
"subway_trains/717/switches/button4_on1.mp3",
|
||||
"subway_trains/717/switches/button4_on2.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["uava_reset"] = {
|
||||
"subway_trains/common/uava/uava_reset1.mp3",
|
||||
"subway_trains/common/uava/uava_reset2.mp3",
|
||||
"subway_trains/common/uava/uava_reset4.mp3",
|
||||
}
|
||||
self.SoundPositions["uava_reset"] = {80,1e9,Vector(449+7.7,56.0,-10.24349),0.6}
|
||||
self.SoundNames["gv_f"] = self.SoundNames["revers_0-b"]
|
||||
self.SoundNames["gv_b"] = self.SoundNames["revers_b-0"]
|
||||
self.SoundPositions["gv_f"] = {80,1e2,Vector(120,62.0+0.0,-60),0.5}
|
||||
self.SoundPositions["gv_b"] = {80,1e2,Vector(120,62.0+0.0,-60),0.5}
|
||||
|
||||
--Краны
|
||||
self.SoundNames["brake"] = {"subway_trains/common/pneumatic/vz_brake_on1.mp3","subway_trains/common/pneumatic/vz_brake_on2.mp3"}
|
||||
self.SoundPositions["brake"] = {600,1e9,Vector(0,0,0),0.5}
|
||||
self.SoundNames["release1"] = {loop=true,"subway_trains/common/pneumatic/release.wav"} --TODO разделение отпуска и срыва по позициям в кабине\вне
|
||||
self.SoundPositions["release1"] = {1200,1e9,Vector(-183,0,-70)}
|
||||
self.SoundNames["crane334_brake"] = {loop=true,"subway_trains/common/pneumatic/334_brake.wav"} --TODO добавить жужжащий звук
|
||||
self.SoundPositions["crane334_brake"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
self.SoundNames["crane334_brake_slow"] = {loop=true,"subway_trains/common/pneumatic/334_brake_slow.wav"} --TODO добавить жужжащий звук
|
||||
self.SoundPositions["crane334_brake_slow"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
self.SoundNames["crane334_release"] = {loop=true,"subway_trains/common/pneumatic/334_release.wav"}
|
||||
self.SoundPositions["crane334_release"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
|
||||
self.SoundNames["epk_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["epk_brake"] = {200,1e9,Vector(437.2,-53.1,-50.0)}
|
||||
self.SoundNames["epk_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["epk_brake_start"] = self.SoundPositions["epk_brake"]
|
||||
|
||||
self.SoundNames["valve_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["valve_brake"] = {200,1e9,Vector(402,-63,-50)}
|
||||
self.SoundNames["valve_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["valve_brake_start"] = self.SoundPositions["valve_brake"]
|
||||
|
||||
self.SoundNames["emer_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["emer_brake"] = {200,1e9,Vector(380,-45,-75)}
|
||||
self.SoundNames["emer_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["emer_brake_start"] = self.SoundPositions["emer_brake"]
|
||||
|
||||
self.SoundNames["pneumo_TL_open"] = {
|
||||
"subway_trains/common/334/334_open.mp3",
|
||||
}
|
||||
self.SoundNames["pneumo_TL_disconnect"] = {
|
||||
"subway_trains/common/334/334_close.mp3",
|
||||
}
|
||||
self.SoundNames["pneumo_BL_disconnect"] = {
|
||||
"subway_trains/common/334/334_close.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pak_on"] = "subway_trains/717/switches/rc_on.mp3"
|
||||
self.SoundNames["pak_off"] = "subway_trains/717/switches/rc_off.mp3"
|
||||
|
||||
--self.SoundNames["kv70_fix_on"] = {"subway_trains/717/kv70/kv70_fix_on1.mp3","subway_trains/717/kv70/kv70_fix_on2.mp3"}
|
||||
-- self.SoundNames["kv70_fix_off"] = {"subway_trains/717/kv70/kv70_fix_off1.mp3","subway_trains/717/kv70/kv70_fix_off2.mp3"}
|
||||
self.SoundNames["kv40_0_t1"] = {"subway_trains/ezh/kv40/kv40_0_T1.mp3"}
|
||||
self.SoundNames["kv40_t1_0"] = {"subway_trains/ezh/kv40/kv40_T1_0.mp3"}
|
||||
self.SoundNames["kv40_t1_t1a"] = {"subway_trains/ezh/kv40/kv40_T1_T1A.mp3"}
|
||||
self.SoundNames["kv40_t1a_t1"] = {"subway_trains/ezh/kv40/kv40_T1A_T1.mp3"}
|
||||
self.SoundNames["kv40_t1a_t2"] = {"subway_trains/ezh/kv40/kv40_T1A_T2.mp3"}
|
||||
self.SoundNames["kv40_t2_t1a"] = {"subway_trains/ezh/kv40/kv40_T2_T1A.mp3"}
|
||||
self.SoundNames["kv40_0_x1"] = {"subway_trains/ezh/kv40/kv40_0_X1.mp3"}
|
||||
self.SoundNames["kv40_x1_0"] = {"subway_trains/ezh/kv40/kv40_X1_0.mp3"}
|
||||
self.SoundNames["kv40_x1_x2"] = {"subway_trains/ezh/kv40/kv40_X1_X2.mp3"}
|
||||
self.SoundNames["kv40_x2_x1"] = {"subway_trains/ezh/kv40/kv40_X2_X1.mp3"}
|
||||
self.SoundNames["kv40_x2_x3"] = {"subway_trains/ezh/kv40/kv40_X2_X3.mp3"}
|
||||
self.SoundNames["kv40_x3_x2"] = {"subway_trains/ezh/kv40/kv40_X3_X2.mp3"}
|
||||
--self.SoundPositions["kv70_fix_on"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
--self.SoundPositions["kv70_fix_off"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
self.SoundPositions["kv40_0_t1"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
self.SoundPositions["kv40_t1_0"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1_t1a"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1a_t1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1a_t2"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t2_t1a"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_0_x1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x1_0"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x1_x2"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x2_x1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x2_x3"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x3_x2"] = self.SoundPositions["kv40_0_t1"]
|
||||
|
||||
self.SoundNames["ring"] = {"subway_trains/717/ring/ring_start.wav","subway_trains/717/ring/ring_loop.wav","subway_trains/717/ring/ring_end.wav"}
|
||||
self.SoundPositions["ring"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["ring2"] = {loop=0.1,"subway_trains/717/ring/ringc_start.wav","subway_trains/717/ring/ringc_loop.wav","subway_trains/717/ring/ringc_end.mp3"}
|
||||
self.SoundPositions["ring2"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["ring_old"] = {loop=0.15,"subway_trains/717/ring/ringo_start.wav","subway_trains/717/ring/ringo_loop.wav","subway_trains/717/ring/ringo_end.mp3"}
|
||||
self.SoundPositions["ring_old"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["cab_door_open"] = {
|
||||
"subway_trains/common/door/cab/cab_door_open2.mp3",
|
||||
"subway_trains/common/door/cab/cab_door_open.mp3",
|
||||
}
|
||||
self.SoundPositions["cab_door_open"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["cab_door_close"] = {
|
||||
"subway_trains/common/door/cab/cab_door_close2.mp3",
|
||||
"subway_trains/common/door/cab/cab_door_close.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["parking_brake_rolling"] = {"subway_trains/ezh3/parking_brake_rolling1.mp3","subway_trains/ezh3/parking_brake_rolling2.mp3","subway_trains/ezh3/parking_brake_rolling3.mp3","subway_trains/ezh3/parking_brake_rolling4.mp3"}
|
||||
self.SoundPositions["parking_brake_rolling"] = {120,1e9,Vector(449.118378+7.6,33.493385,-14.713276)}
|
||||
self.SoundNames["av8_on"] = {"subway_trains/common/switches/av8/av8_on.mp3","subway_trains/common/switches/av8/av8_on2.mp3"}
|
||||
self.SoundNames["av8_off"] = {"subway_trains/common/switches/av8/av8_off.mp3","subway_trains/common/switches/av8/av8_off2.mp3"}
|
||||
self.SoundPositions["av8_on"] = {100,1e9,Vector(405,40,30)}
|
||||
self.SoundPositions["av8_off"] = {100,1e9,Vector(405,40,30)}
|
||||
|
||||
self.SoundNames["vu22_on"] = {"subway_trains/ezh3/vu/vu22_on1.mp3", "subway_trains/ezh3/vu/vu22_on2.mp3", "subway_trains/ezh3/vu/vu22_on3.mp3"}
|
||||
self.SoundNames["vu22_off"] = {"subway_trains/ezh3/vu/vu22_off1.mp3", "subway_trains/ezh3/vu/vu22_off2.mp3", "subway_trains/ezh3/vu/vu22_off3.mp3"}
|
||||
self.SoundNames["vu223_on"] = {"subway_trains/common/switches/vu22/vu22_3_on.mp3"}
|
||||
self.SoundNames["vu223_off"] = {"subway_trains/common/switches/vu22/vu22_3_off.mp3"}
|
||||
|
||||
self.SoundNames["igla_on"] = "subway_trains/common/other/igla/igla_on1.mp3"
|
||||
self.SoundNames["igla_off"] = "subway_trains/common/other/igla/igla_off2.mp3"
|
||||
self.SoundNames["igla_start1"] = "subway_trains/common/other/igla/igla2_start1.mp3"
|
||||
self.SoundNames["igla_start2"] = "subway_trains/common/other/igla/igla2_start2.mp3"
|
||||
self.SoundPositions["igla_on"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_off"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_start1"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_start2"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.2}
|
||||
|
||||
self.SoundNames["upps"] = {"subway_trains/common/other/upps/upps1.mp3","subway_trains/common/other/upps/upps2.mp3"}
|
||||
self.SoundPositions["upps"] = {60,1e9,Vector(443,-64,4),0.5}
|
||||
|
||||
self.SoundNames["pnm_on"] = {"subway_trains/common/pnm/pnm_switch_on.mp3","subway_trains/common/pnm/pnm_switch_on2.mp3"}
|
||||
self.SoundNames["pnm_off"] = {"subway_trains/common/pnm/pnm_switch_off.mp3","subway_trains/common/pnm/pnm_switch_off2.mp3"}
|
||||
self.SoundNames["pnm_button1_on"] = {
|
||||
"subway_trains/common/pnm/pnm_button_push.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push2.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button2_on"] = {
|
||||
"subway_trains/common/pnm/pnm_button_push4.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push5.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push6.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button1_off"] = {
|
||||
"subway_trains/common/pnm/pnm_button_release.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release2.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button2_off"] = {
|
||||
"subway_trains/common/pnm/pnm_button_release4.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release5.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release6.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["horn1"] = {loop=0.6,"subway_trains/common/pneumatic/horn/horn1_start.wav","subway_trains/common/pneumatic/horn/horn1_loop.wav", "subway_trains/common/pneumatic/horn/horn1_end.mp3"}
|
||||
self.SoundNames["horn2"] = {loop=0.8,"subway_trains/common/pneumatic/horn/horn3_start.wav","subway_trains/common/pneumatic/horn/horn3_loop.wav", "subway_trains/common/pneumatic/horn/horn3_end.wav"}
|
||||
self.SoundPositions["horn1"] = {1100,1e9,Vector(450,0,-55)}
|
||||
self.SoundPositions["horn2"] = self.SoundPositions["horn1"]
|
||||
|
||||
--DOORS
|
||||
self.SoundNames["vdol_on"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDO_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDO2_on.mp3",
|
||||
}
|
||||
self.SoundNames["vdol_off"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDO_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDO2_off.mp3",
|
||||
}
|
||||
self.SoundPositions["vdol_on"] = {100,1e9,Vector(410,20,-45)}
|
||||
self.SoundPositions["vdol_off"] = self.SoundPositions["vdol_on"]
|
||||
self.SoundNames["vdor_on"] = self.SoundNames["vdol_on"]
|
||||
self.SoundNames["vdor_off"] = self.SoundNames["vdol_off"]
|
||||
self.SoundPositions["vdor_on"] = self.SoundPositions["vdol_on"]
|
||||
self.SoundPositions["vdor_off"] = self.SoundPositions["vdol_off"]
|
||||
self.SoundNames["vdz_on"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ2_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ3_on.mp3",
|
||||
}
|
||||
self.SoundNames["vdz_off"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ2_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ3_off.mp3",
|
||||
}
|
||||
self.SoundPositions["vdz_on"] = {100,1e9,Vector(410,20,-45)}
|
||||
self.SoundPositions["vdz_off"] = {100,1e9,Vector(410,20,-45)}
|
||||
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
self.SoundNames["door"..i.."x"..k.."r"] = {"subway_trains/common/door/door_roll.wav",loop=true}
|
||||
self.SoundPositions["door"..i.."x"..k.."r"] = {150,1e9,GetDoorPosition(i,k),0.2}
|
||||
self.SoundNames["door"..i.."x"..k.."o"] = {"subway_trains/common/door/door_open_end1.mp3","subway_trains/common/door/door_open_end2.mp3","subway_trains/common/door/door_open_end3.mp3","subway_trains/common/door/door_open_end4.mp3"}
|
||||
self.SoundPositions["door"..i.."x"..k.."o"] = {300,1e9,GetDoorPosition(i,k),1}
|
||||
self.SoundNames["door"..i.."x"..k.."c"] = {"subway_trains/common/door/door_close_end.mp3","subway_trains/common/door/door_close_end2.mp3","subway_trains/common/door/door_close_end3.mp3"}
|
||||
self.SoundPositions["door"..i.."x"..k.."c"] = self.SoundPositions["door"..i.."x"..k.."o"]
|
||||
end
|
||||
end
|
||||
self.SoundNames["PN2end"] = "subway_trains/common/pneumatic/vz2_end.mp3"
|
||||
self.SoundPositions["PN2end"] = {600,1e9,Vector(-183,0,-70),0.5}
|
||||
|
||||
|
||||
for k,v in ipairs(self.AnnouncerPositions) do
|
||||
self.SoundNames["announcer_noise1_"..k] = {loop=true,"subway_announcers/upo/noiseS1.wav"}
|
||||
self.SoundPositions["announcer_noise1_"..k] = {v[2] or 300,1e9,v[1],v[3]*0.5}
|
||||
self.SoundNames["announcer_noise2_"..k] = {loop=true,"subway_announcers/upo/noiseS2.wav"}
|
||||
self.SoundPositions["announcer_noise2_"..k] = {v[2] or 300,1e9,v[1],v[3]*0.5}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема Е (АРС)
|
||||
self:LoadSystem("Electric","81_701_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_108D")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A","KF_47A6")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_40")
|
||||
-- Контроллер резервного управления (KRP)
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A","YAR_15A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
self.Pneumatic.ValveType = 1
|
||||
-- Панель управления Еж АРС МП
|
||||
self:LoadSystem("Panel","81_508_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
--self:LoadSystem("DURA")
|
||||
self:LoadSystem("ALS_ARS","NoARS")
|
||||
|
||||
self:LoadSystem("ASNP31","Relay","Switch")
|
||||
self:LoadSystem("ASNP32","Relay","Switch")
|
||||
self:LoadSystem("Horn")
|
||||
|
||||
self:LoadSystem("Announcer","81_722_Announcer", "AnnouncementsASNP")
|
||||
self:LoadSystem("ASNP","81_71_ASNP")
|
||||
self:LoadSystem("IGLA_CBKI","IGLA_CBKI2")
|
||||
self:LoadSystem("IGLA_PCBK")
|
||||
end
|
||||
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Em508",
|
||||
WagType = 0,
|
||||
ARS = {
|
||||
HaveASNP = true,
|
||||
NoEPK = true,
|
||||
},
|
||||
ALS = {
|
||||
HaveAutostop = true,
|
||||
},
|
||||
EKKType = 703,
|
||||
NoFrontEKK=true,
|
||||
}
|
||||
ENT.NumberRanges = {{3905,3954},{6001,6100},{6201,6251}}
|
||||
|
||||
local Texture = {}
|
||||
for k,v in pairs(Metrostroi.Skins["train"]) do
|
||||
if v.typ == "em508" then Texture[k] = v.name or k end
|
||||
end
|
||||
local PassTexture = {}
|
||||
for k,v in pairs(Metrostroi.Skins["pass"] or {}) do
|
||||
if v.typ == "em508" then PassTexture[k] = v.name or k end
|
||||
end
|
||||
local CabTexture = {}
|
||||
for k,v in pairs(Metrostroi.Skins["cab"] or {}) do
|
||||
if v.typ == "em508" then CabTexture[k] = v.name or k end
|
||||
end
|
||||
local Announcer = {}
|
||||
for k,v in pairs(Metrostroi.AnnouncementsASNP or {}) do Announcer[k] = v.name or k end
|
||||
ENT.Spawner = {
|
||||
model = "models/metrostroi_train/81-508/81-508.mdl",
|
||||
interim = "gmod_subway_em508_int",
|
||||
func = function(ent,i,maxi)
|
||||
if i > 1 and i < maxi then
|
||||
ent.VU:TriggerInput("Set",0)
|
||||
ent.UAVA:TriggerInput("Set",1)
|
||||
ent.Plombs.VU = false
|
||||
ent.Plombs.UAVA = nil
|
||||
else
|
||||
ent.VU:TriggerInput("Set",1)
|
||||
ent.UAVA:TriggerInput("Set",0)
|
||||
ent.Plombs.VU = nil
|
||||
ent.Plombs.UAVA = true
|
||||
end
|
||||
end,
|
||||
Metrostroi.Skins.GetTable("Texture","Texture",Texture,"train"),
|
||||
Metrostroi.Skins.GetTable("PassTexture","PassTexture",PassTexture,"pass"),
|
||||
Metrostroi.Skins.GetTable("CabTexture","CabTexture",CabTexture,"cab"),
|
||||
{"Announcer","Announcer","List",Announcer},
|
||||
{"HornType","Piter horn","Boolean"},
|
||||
{"NM","NM","Slider",1,0,9.0,8.2,function(ent,val) ent.Pneumatic.TrainLinePressure = val end},
|
||||
{"Battery","Battery","Boolean",true,function(ent,val) ent.VB:TriggerInput("Set",val) end},
|
||||
{"AV8B","AV8B","Boolean",true,function(ent,val) ent.AV8B:TriggerInput("Set",val) end},
|
||||
{"DoorsL","DoorsL","Boolean",false, function(ent,val,rot)
|
||||
if rot then
|
||||
ent.Pneumatic.RightDoorState = val and {1,1,1,1} or {0,0,0,0}
|
||||
else
|
||||
ent.Pneumatic.LeftDoorState = val and {1,1,1,1} or {0,0,0,0}
|
||||
end
|
||||
end},
|
||||
{"DoorsR","DoorsR","Boolean",false, function(ent,val,rot)
|
||||
if rot then
|
||||
ent.Pneumatic.LeftDoorState = val and {1,1,1,1} or {0,0,0,0}
|
||||
else
|
||||
ent.Pneumatic.RightDoorState = val and {1,1,1,1} or {0,0,0,0}
|
||||
end
|
||||
end},
|
||||
{"GV","GV","Boolean",true,function(ent,val) ent.GV:TriggerInput("Set",val) end},
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,861 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
--"DURASelectMain","DURASelectAlternate","DURAToggleChannel","DURAPowerToggle",
|
||||
ENT.SyncTable = {
|
||||
"CustomC","Custom1","Custom2","Custom3","CustomD",
|
||||
"CustomE","CustomF","CustomG","R_UNch","R_ZS","R_G","R_Radio","R_Program1","R_Program2","KVT","KB","KSD",
|
||||
"VZ1","VUD1","KDL","KDLR","KDLK","KDP","KDLRK","DoorSelect","Ring","UKS","AGS",
|
||||
"KRZD","R_VPR","VozvratRP","AVU","KVP","ConverterProtection","RZP",
|
||||
"KSN","ARS","ALS","OtklAVU","TormAT","L_1","L_3","DIPoff",
|
||||
"VMK","BPSNon","RezMK","ARS13","L_4","VUS","VAH","VAD","EmergencyBrakeValve",
|
||||
"KAH","KAHK","KDPK","CabinHeat","KRR","KRP",
|
||||
"RC1","VB","BPS","UOS", "PB", "UAVA","AVULight_light","PD","AVU",
|
||||
"DriverValveBLDisconnect","DriverValveTLDisconnect","DriverValveTLDisconnect","ParkingBrake","EPK",
|
||||
"VUD2","VDL", "GV","DIPon","DIPoff","VozvratRP","KU1","RezMK",
|
||||
"VU3","VU1","VU2","AV8B","VU","KDLK","VDLK","KDPK","RST", "DoorSelect","LPU","R_ASNPMenu","R_ASNPUp","R_ASNPDown","R_ASNPOn",
|
||||
}
|
||||
ENT.SyncFunctions = {
|
||||
""
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
self.Plombs = {
|
||||
RST = true,
|
||||
Init = true,
|
||||
OtklAVU = true,
|
||||
UAVA = true,
|
||||
VU=true,
|
||||
}
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi_train/81-508/81-508.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(425,-39,-27.5),Angle(0,0,0))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(430,40,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat1 = self:CreateSeat("instructor",Vector(443,0,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat2 = self:CreateSeat("instructor",Vector(420,-20,-48+6),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.InstructorsSeat:SetColor(Color(0,0,0,0))
|
||||
self.InstructorsSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
self.ExtraSeat1:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat1:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.ExtraSeat2:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat2:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 317-5,0,-89),Angle(0,180,0),true,"717")
|
||||
self.RearBogey = self:CreateBogey(Vector(-317+0,0,-89),Angle(0,0,0),false,"717")
|
||||
self.FrontCouple = self:CreateCouple(Vector( 419.5+3.5,0,-75),Angle(0,0,0),true,"717")
|
||||
self.RearCouple = self:CreateCouple(Vector(-421.5-3.5,0,-75),Angle(0,180,0),false,"717")
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
-- Initialize key mapping
|
||||
self.KeyMap = {
|
||||
[KEY_1] = "KVSetX1",
|
||||
[KEY_2] = "KVSetX2",
|
||||
[KEY_3] = "KVSetX3",
|
||||
[KEY_4] = "KVSet0",
|
||||
[KEY_5] = "KVSetT1",
|
||||
[KEY_6] = "KVSetT1AB",
|
||||
[KEY_7] = "KVSetT2",
|
||||
[KEY_8] = "KRP",
|
||||
|
||||
[KEY_EQUAL] = "R_Program1Set",
|
||||
[KEY_MINUS] = "R_Program2Set",
|
||||
|
||||
[KEY_G] = "VozvratRPSet",
|
||||
|
||||
[KEY_0] = "KVReverserUp",
|
||||
[KEY_9] = "KVReverserDown",
|
||||
[KEY_PAD_PLUS] = "KVReverserUp",
|
||||
[KEY_PAD_MINUS] = "KVReverserDown",
|
||||
[KEY_W] = "KVUp",
|
||||
[KEY_S] = "KVDown",
|
||||
[KEY_F] = "PneumaticBrakeUp",
|
||||
[KEY_R] = "PneumaticBrakeDown",
|
||||
|
||||
[KEY_A] = "KDL",
|
||||
[KEY_D] = "KDP",
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "HornEngage",
|
||||
[KEY_N] = "VZ1Set",
|
||||
[KEY_PAD_1] = "PneumaticBrakeSet1",
|
||||
[KEY_PAD_2] = "PneumaticBrakeSet2",
|
||||
[KEY_PAD_3] = "PneumaticBrakeSet3",
|
||||
[KEY_PAD_4] = "PneumaticBrakeSet4",
|
||||
[KEY_PAD_5] = "PneumaticBrakeSet5",
|
||||
[KEY_PAD_6] = "PneumaticBrakeSet6",
|
||||
[KEY_PAD_7] = "PneumaticBrakeSet7",
|
||||
[KEY_PAD_DIVIDE] = "KRPSet",
|
||||
[KEY_PAD_MULTIPLY] = "KAHSet",
|
||||
--[KEY_J] = "KVWrenchKRU",
|
||||
|
||||
--[KEY_SPACE] = "PBSet",
|
||||
[KEY_BACKSPACE] = "EmergencyBrake",
|
||||
|
||||
[KEY_PAD_0] = "DriverValveDisconnect",
|
||||
[KEY_LSHIFT] = {
|
||||
[KEY_W] = "KVUp_Unlocked",
|
||||
[KEY_SPACE] = "KVTSet",
|
||||
|
||||
[KEY_A] = "DURASelectAlternate",
|
||||
[KEY_D] = "DURASelectMain",
|
||||
[KEY_V] = "DURAToggleChannel",
|
||||
[KEY_1] = "DIPonSet",
|
||||
[KEY_2] = "DIPoffSet",
|
||||
[KEY_4] = "KVSet0Fast",
|
||||
--[KEY_L] = "DriverValveDisconnect",
|
||||
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_6] = "KVSetT1A",
|
||||
},
|
||||
|
||||
[KEY_RSHIFT] = {
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
--[KEY_L] = "DriverValveDisconnect",
|
||||
[KEY_F] = "BCCDSet",
|
||||
[KEY_R] = "VZPSet",
|
||||
},
|
||||
[KEY_LALT] = {
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
},
|
||||
--[KEY_RALT] = {
|
||||
--[KEY_L] = "EPKToggle",
|
||||
--},
|
||||
}
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(-471,-30,0),
|
||||
Radius = 28,
|
||||
ID = "RearDoor"
|
||||
},
|
||||
{ Pos = Vector(473,32,28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor1"
|
||||
},
|
||||
{ Pos = Vector(473,32,-28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor2"
|
||||
},
|
||||
{ Pos = Vector(383.02,31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor1"
|
||||
},
|
||||
{ Pos = Vector(383.02,-31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor1"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor3"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor4"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor5"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor6"
|
||||
},
|
||||
}
|
||||
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[2] = { "glow", Vector(469.4, 45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[4] = { "glow", Vector(458+9,-14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[5] = { "glow", Vector(458+9,0, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[6] = { "glow", Vector(458+9, 14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
|
||||
-- Emergency lit
|
||||
[9] = { "headlight", Vector(412,0,51), Angle(80,0,0), Color(255,255,255), brightness = 1, farz = 117, nearz = 0.01, shadows = 0, fov = 120 },
|
||||
-- Cabin
|
||||
[22] = { "light", Vector(432+5.9,-54.5,42.2), Angle(90,0,0), Color(255,180,128), brightness = 0.75, scale = 0.4, texture = "sprites/light_glow03.vmt" },
|
||||
[23] = { "dynamiclight", Vector(432,-10.0,20), Angle(0,0,0), Color(255,130,88), brightness = 0.001, distance = 500},
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, -5), Angle(180,0,0), Color(255, 176, 59), brightness = 2, distance = 400 , fov=180 },
|
||||
[12] = { "dynamiclight", Vector( 0, 0, -5), Angle(180,0,0), Color(255, 176, 59), brightness = 2, distance = 400, fov=180 },
|
||||
[13] = { "dynamiclight", Vector(-300, 0, -5), Angle(180,0,0), Color(255, 176, 59), brightness = 2, distance = 400 , fov=180 },
|
||||
|
||||
[15] = { "light", Vector(402.202942,69.270073,44.79285), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[16] = { "light", Vector(402.202942,69.270073,41.509621), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[17] = { "light", Vector(402.202942,69.270073,37.3862), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
|
||||
[70 ] = { "headlight", Vector( 450, -60, -47), Angle(45,-90,0), Color(255,255,255), brightness = 0.5, distance = 400 , fov=120, shadows = 1 },
|
||||
|
||||
}
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- KV wrench mode
|
||||
self.KVWrenchMode = 0
|
||||
|
||||
-- Parking brake ratio
|
||||
self.ManualBrake = 0.0
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self.CabinDoor = false
|
||||
self.PassengerDoor = false
|
||||
|
||||
-- self.A5:TriggerInput("Set",0)
|
||||
self:TrainSpawnerUpdate()
|
||||
end
|
||||
|
||||
function ENT:TrainSpawnerUpdate()
|
||||
self.Texture = self:GetNW2String("Texture")
|
||||
self.PassTexture = self:GetNW2String("PassTexture")
|
||||
self.CabTexture = self:GetNW2String("CabTexture")
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self.CabTexture]
|
||||
|
||||
for k in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
elseif v == "models/metrostroi_train/81/tabl" then
|
||||
if not self.SignsList then
|
||||
self:PrepareSigns()
|
||||
end
|
||||
if self.SignsList[self.SignsIndex] then self:SetSubMaterial(k-1,self.SignsList[self.SignsIndex][1]) end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
local RetVal = self.BaseClass.Think(self)
|
||||
|
||||
-- Check if wrench was pulled out
|
||||
if self.DriversWrenchPresent then
|
||||
self.KV:TriggerInput("Enabled",self:IsWrenchPresent() and 1 or 0)
|
||||
end
|
||||
self:SetPackedBool("RedLight",(self.Panel["RedLightLeft"] > 0.5 or self.Panel["RedLightRight"] > 0.5 ) and not IsValid(self.FrontTrain))
|
||||
|
||||
-- Emergency Ezh cabin lights
|
||||
self:SetLightPower(9, self.AV8B.Value < 0.5 and self.VU2.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
|
||||
-- Cabin lights
|
||||
--self:SetLightPower(22, self.L_2.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
self:SetLightPower(23, self.VU3.Value > 0.5)
|
||||
|
||||
--Gauges lights
|
||||
self:SetPackedBool("PanelLights",self.L_3.Value > 0.5 and self.Panel["V1"] > 0.5)
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = (self.VU2.Value > 0.5 and self.Panel["V1"] > 0.5) or lightsActive2
|
||||
self:SetPackedBool("Lamps_emer",lightsActive1)
|
||||
self:SetPackedBool("Lamps_full",lightsActive2)
|
||||
local Light
|
||||
if self.Pneumatic.Compressor == 1 then
|
||||
Light = (lightsActive2 and 0.6 or 0.3)
|
||||
else
|
||||
Light = (lightsActive2 and 0.8 or 0.4)
|
||||
end
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
self:SetPackedRatio("LampsI",math.Round((self.Electric.I24-150)/1000.0,1.5))
|
||||
|
||||
-- Total temperature
|
||||
local IGLA_Temperature = math.max(self.Electric.T1,self.Electric.T2)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:WriteTrainWire(35,(self.Pneumatic.BrakeCylinderPressure > 0.1) and 1 or 0)
|
||||
|
||||
-- DIP/power
|
||||
self:SetPackedBool(32,self.Panel["V1"] > 0.5)
|
||||
-- Red RP
|
||||
local TW18 = self:GetTrainWire18()
|
||||
if self:ReadTrainWire(20) == 0 or (self.Panel["V1"] < 0.5) then TW18 = 0 end
|
||||
self:SetPackedBool(131,TW18 > 0)
|
||||
self:SetPackedRatio("LRP",TW18)
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle or 0
|
||||
if self.ManualBrake < 0.001 and self.ManualBrake > self.TrueBrakeAngle then self.TrueBrakeAngle = self.ManualBrake end
|
||||
if self.ManualBrake > 0.999 and self.ManualBrake < self.TrueBrakeAngle then self.TrueBrakeAngle = self.ManualBrake end
|
||||
self.TrueBrakeAngle = self.TrueBrakeAngle + (self.ManualBrake - self.TrueBrakeAngle)*2.0*(self.DeltaTime or 0)
|
||||
self:SetPackedRatio("ManualBrake",self.TrueBrakeAngle)
|
||||
-- Green RP
|
||||
self:SetPackedBool(36,self.Panel["GreenRP"] > 0.5)
|
||||
-- Cabin heating
|
||||
self:SetPackedBool(37,self.Panel["KUP"] > 0.5)
|
||||
-- AVU
|
||||
self:SetPackedBool(38,self.Panel["AVU"] > 0.5)
|
||||
-- Ring
|
||||
self:SetPackedBool(39,self.Panel["Ring"] > 0.5)
|
||||
-- SD
|
||||
self:SetPackedBool(40,self.Panel["V1"] > 0.5 and self.Panel["SD"] < 0.5)
|
||||
-- KSD
|
||||
self:SetPackedBool("KSD",self.KSD.Value == 0.00)
|
||||
-- KRP
|
||||
self:SetPackedBool(113,self.KRP.Value == 1.0)
|
||||
|
||||
|
||||
self:SetPackedBool("DriverValveBLDisconnect",self.DriverValveBLDisconnect.Value == 1.0)
|
||||
self:SetPackedBool("DriverValveTLDisconnect",self.DriverValveTLDisconnect.Value == 1.0)
|
||||
if self.DriverValveDisconnect.Blocked > 0 and self.Pneumatic.ValveType == 2 then
|
||||
self.DriverValveDisconnect:TriggerInput("Block",0)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Block",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Block",1)
|
||||
end
|
||||
if self.DriverValveDisconnect.Blocked == 0 and self.Pneumatic.ValveType == 1 then
|
||||
self.DriverValveDisconnect:TriggerInput("Block",1)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Block",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Block",0)
|
||||
end
|
||||
self:SetPackedBool("EPK",self.EPK.Value == 1.0)
|
||||
self:SetPackedBool("VPR",self.RST.Value > 0 and self.Panel["V1"] > 0)
|
||||
self:SetPackedBool("LST",self:ReadTrainWire(6) > 0.5)
|
||||
self:SetPackedBool("LVD",self:ReadTrainWire(1) > 0.5)
|
||||
self:SetPackedBool("RK",self:ReadTrainWire(2) > 0.5)
|
||||
self:SetPackedBool(19,self.OtklAVU.Value == 1.0)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(55,(self.DoorSelect.Value == 1.0))
|
||||
self:SetPackedBool("VZ1",(self.VZ1.Value == 1))
|
||||
|
||||
self:SetPackedBool(17,self.KRZD.Value == 1.0)
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
self:SetPackedBool(158,self.PassengerDoor)
|
||||
self:SetPackedBool(159,self.CabinDoor)
|
||||
|
||||
self:SetNW2Bool("ASNPPlay",self.VB.Value > 0 and self:ReadTrainWire(47) > 0)
|
||||
--KRR
|
||||
self:SetPackedBool("KRR",self.KRR.Value > 0.5)
|
||||
|
||||
--Radiostation
|
||||
self:SetPackedBool(125,self.R_G.Value == 1.0)
|
||||
self:SetPackedBool(127,self.R_ZS.Value == 1.0)
|
||||
self:SetPackedBool(126,self.R_Radio.Value == 1.0)
|
||||
self:SetPackedBool(128,self.R_Program1.Value == 1.0)
|
||||
self:SetPackedBool(129,self.R_Program2.Value == 1.0)
|
||||
|
||||
--[[
|
||||
-- LST
|
||||
self:SetPackedBool(49,self:ReadTrainWire(6) > 0.5)
|
||||
-- LVD
|
||||
self:SetPackedBool(50,self:ReadTrainWire(1) > 0.5)
|
||||
|
||||
self:SetPackedBool(165,self.PB.Value > 0)
|
||||
|
||||
-- AV states
|
||||
-- for i,v in ipairs(self.Panel.AVMap) do
|
||||
-- if tonumber(v)
|
||||
-- then self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
-- elseif self[v] then self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
self:SetPackedBool(62,self.L_3.Value > 0.5)
|
||||
self:SetPackedBool(64+19,self.VU1.Value > 0.5)
|
||||
self:SetPackedBool(64+12,self.VU.Value > 0.5)
|
||||
self:SetPackedBool(64+24,self.RST.Value > 0.5)
|
||||
self:SetPackedBool(64+7 ,self.AV8B.Value > 0.5)
|
||||
self:SetPackedBool(64+36,self.VU2.Value > 0.5)
|
||||
self:SetPackedBool(64+13,self.VU3.Value > 0.5)
|
||||
self:SetPackedBool("VPR",self.RST.Value == 1.0 and self.Panel["V1"])
|
||||
]]
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/7)
|
||||
self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.ReservoirPressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, math.min(2.7,self.Pneumatic.BrakeCylinderPressure)/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, 0.5 + 0.5*(self.Electric.I24/500.0))
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 82.0)
|
||||
self:SetPackedRatio(11,IGLA_Temperature)
|
||||
self:SetPackedBool("EmergencyBrakeValve",self.EmergencyBrakeValve.Value > 0)
|
||||
self:SetPackedBool(152,self.UAVA.Value == 1.0)
|
||||
|
||||
self:SetPackedBool(128,self.R_Program1.Value == 1.0)
|
||||
self:SetPackedBool(129,self.R_Program2.Value == 1.0)
|
||||
self:SetPackedBool(22,self.Pneumatic.ValveType == 2)
|
||||
|
||||
-- Update ARS system (no ars on E)
|
||||
self:SetPackedRatio(3, self.ALS_ARS.Speed/100.0)
|
||||
self:SetPackedRatio("Speed", self.Speed/100)
|
||||
---print (self.Speed)
|
||||
if (self.ALS_ARS.Ring == true) then
|
||||
self:SetPackedBool(39,true)
|
||||
end
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 27000+13000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 27000+13000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
local add = 1
|
||||
if math.abs(self:GetAngles().pitch) > 4 then
|
||||
add = math.min((math.abs(self:GetAngles().pitch)-4)/2,1)*2
|
||||
end
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure*add
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = self.ParkingBrake.Value > 0.5
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure*add
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
end
|
||||
|
||||
-- Generate bogey sounds
|
||||
local jerk = math.abs((self.Acceleration - (self.PrevAcceleration or 0)) / self.DeltaTime)
|
||||
self.PrevAcceleration = self.Acceleration
|
||||
|
||||
if jerk > (2.0 + self.Speed/15.0) then
|
||||
self.PrevTriggerTime1 = self.PrevTriggerTime1 or CurTime()
|
||||
self.PrevTriggerTime2 = self.PrevTriggerTime2 or CurTime()
|
||||
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime1 > 1.5) then
|
||||
self.PrevTriggerTime1 = CurTime()
|
||||
self.FrontBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 85, math.random(96,110))
|
||||
end
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime2 > 1.5) then
|
||||
self.PrevTriggerTime2 = CurTime()
|
||||
self.RearBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 85, math.random(96,110))
|
||||
end
|
||||
end
|
||||
|
||||
-- Temporary hacks
|
||||
--self:SetNW2Float("V",self.Speed)
|
||||
--self:SetNW2Float("A",self.Acceleration)
|
||||
|
||||
return RetVal
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
-- Parking brake
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,(self.ManualBrake or 0) - 0.05)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,(self.ManualBrake or 0) + 0.05)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
end
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",tonumber(button:sub(-1,-1)))
|
||||
return
|
||||
end
|
||||
if button:find("FrontDoor") then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("RearDoor") then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button:find("PassengerDoor") then
|
||||
self.PassengerDoor = not self.PassengerDoor
|
||||
if self.PassengerDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("CabinDoor") then
|
||||
self.CabinDoor = not self.CabinDoor
|
||||
if self.CabinDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button == "NextSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex + 1
|
||||
if self.SignsIndex > #self.SignsList then self.SignsIndex = 1 end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
if button == "PrevSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex - 1
|
||||
if self.SignsIndex < 1 then self.SignsIndex = #self.SignsList end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
|
||||
if button == "Num1P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num1M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
|
||||
-- Parking brake
|
||||
if button == "ManualBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,self.ManualBrake - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ManualBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,self.ManualBrake + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
|
||||
if button == "KVUp" then
|
||||
if self.KV.ControllerPosition ~= -1 then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
end
|
||||
if button == "KVUp_Unlocked" then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
if button == "KVDown" then
|
||||
self.KV:TriggerInput("ControllerDown",1.0)
|
||||
end
|
||||
|
||||
-- KRU
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserUp") then
|
||||
self.KRU:TriggerInput("Up",1)
|
||||
self:OnButtonPress("KRUUp")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserDown") then
|
||||
self.KRU:TriggerInput("Down",1)
|
||||
self:OnButtonPress("KRUDown")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX1") then
|
||||
self.KRU:TriggerInput("SetX1",1)
|
||||
self:OnButtonPress("KRUSetX1")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX2") then
|
||||
self.KRU:TriggerInput("SetX2",1)
|
||||
self:OnButtonPress("KRUSetX2")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX3") then
|
||||
self.KRU:TriggerInput("SetX3",1)
|
||||
self:OnButtonPress("KRUSetX3")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSet0") then
|
||||
self.KRU:TriggerInput("Set0",1)
|
||||
self:OnButtonPress("KRUSet0")
|
||||
end
|
||||
|
||||
if button == "KVSetT1AB" then
|
||||
if self.KV.ControllerPosition == -2 then
|
||||
self.KV:TriggerInput("ControllerSet",-1)
|
||||
timer.Simple(0.20,function()
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end)
|
||||
else
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end
|
||||
end
|
||||
if button == "KVWrench0" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 1 then
|
||||
if self.KVWrenchMode ~= 1 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 0
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
if button == "KVWrenchKV" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 0 then
|
||||
if self.KVWrenchMode ~= 0 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 1
|
||||
self.DriversWrenchPresent = true
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--THERE IS NO KRU IN THIS EZH MODEL
|
||||
--[[
|
||||
if button == "KVWrenchKRU" then
|
||||
if self.KVWrenchMode == 3 then
|
||||
self:PlayOnce("kru_in","cabin",0.7)
|
||||
self.KVWrenchMode = 2
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("LockX3",1)
|
||||
end
|
||||
end]]
|
||||
if button == "KVWrenchNone" then
|
||||
if self.KVWrenchMode ~= 3 and self.KV.ReverserPosition == 0 then
|
||||
if self.KVWrenchMode == 2 then
|
||||
self:PlayOnce("kru_out","cabin",0.7)
|
||||
else
|
||||
self:PlayOnce("revers_out","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 3
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Close",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Close",1) self:OnButtonPress("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Close",1) self:OnButtonPress("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Close",1) self:OnButtonPress("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",1)
|
||||
self:OnButtonPress("KRPSet")
|
||||
end
|
||||
if button == "EmergencyBrake" then
|
||||
self.KV:TriggerInput("ControllerSet",-3)
|
||||
self.Pneumatic:TriggerInput("BrakeSet",7)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
return
|
||||
end
|
||||
if button == "DriverValveDisconnect" then
|
||||
if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",1)
|
||||
else
|
||||
--self:PlayOnce("pneumo_disconnect1","cabin",0.9)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",0)
|
||||
end
|
||||
if self.DriverValveBLDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_on","cabin",0.9) end
|
||||
else
|
||||
--self:PlayOnce("pneumo_disconnect2","cabin",0.9)
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_off","cabin",0.9) end
|
||||
end
|
||||
return
|
||||
end
|
||||
-- Special logic
|
||||
if (button == "VDL") or (button == "KDL") or (button == "KDP") then
|
||||
--self.VUD1:TriggerInput("Open",1)
|
||||
end
|
||||
if (button == "KDP") then
|
||||
--self.DoorSelect:TriggerInput("Close",1)
|
||||
end
|
||||
if (button == "VUD1Set") or (button == "VUD1Toggle") or
|
||||
(button == "VUD2Set") or (button == "VUD2Toggle") then
|
||||
self.VDL:TriggerInput("Open",1)
|
||||
self.KDL:TriggerInput("Open",1)
|
||||
self.KDP:TriggerInput("Open",1)
|
||||
end
|
||||
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
--[[if (button == "UAVAToggle") then
|
||||
if self.UAVA then
|
||||
if self.UAVA.Value > 0.5 then
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
else
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
end
|
||||
end
|
||||
return
|
||||
end]]
|
||||
end
|
||||
|
||||
function ENT:OnButtonRelease(button)
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
return
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Open",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Open",1) self:OnButtonRelease("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Open",1) self:OnButtonRelease("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Open",1) self:OnButtonRelease("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",0)
|
||||
self:OnButtonRelease("KRPSet")
|
||||
end
|
||||
|
||||
--[[
|
||||
if (button == "PneumaticBrakeDown") and (self.Pneumatic.DriverValvePosition == 1) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",2)
|
||||
end
|
||||
if self.Pneumatic.ValveType == 1 then
|
||||
if (button == "PneumaticBrakeUp") and (self.Pneumatic.DriverValvePosition == 5) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",4)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
if (not string.find(button,"KVT")) and string.find(button,"KV") then return end
|
||||
if string.find(button,"KRU") then return end
|
||||
end
|
||||
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
|
||||
function ENT:TriggerTurbostroiInput(sys,name,val)
|
||||
self.BaseClass.TriggerTurbostroiInput(self,sys,name,val)
|
||||
if sys == "Panel" and name:find("HeadLights") or sys == "L_4" then
|
||||
local brightness = math.min(1,self.Panel["HeadLights1"])*0.50 +
|
||||
math.min(1,self.Panel["HeadLights2"])*0.25 +
|
||||
math.min(1,self.Panel["HeadLights3"])*0.25
|
||||
if (self.Panel["HeadLights3"] > 0.5 or self.Panel["HeadLights1"] > 0.5) then-- and (self.L_4.Value > 0.5) then
|
||||
self:SetPackedRatio("Headlight",brightness)
|
||||
else
|
||||
self:SetPackedRatio("Headlight",0)
|
||||
end
|
||||
self:SetPackedBool("HeadLights1",self.Panel["HeadLights1"] > 0)
|
||||
self:SetPackedBool("HeadLights2",self.Panel["HeadLights2"] > 0)
|
||||
end
|
||||
end
|
||||
@@ -1,538 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintName = "Entities.Em508_int"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = true
|
||||
ENT.AdminSpawnable = false
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
local function GetDoorPosition(i,k)
|
||||
return Vector(359.0 - 35/2 - 229.5*i,-65*(1-2*k),7.5)
|
||||
end
|
||||
ENT.AnnouncerPositions = {
|
||||
{Vector(412,-49 ,61),80,1},
|
||||
{Vector(-3,-60, 62),300,1},
|
||||
{Vector(-3,60 ,62),300,1},
|
||||
}
|
||||
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["rolling_10"] = {loop=true,"subway_trains/717/rolling/10_rolling.wav"}
|
||||
self.SoundNames["rolling_40"] = {loop=true,"subway_trains/717/rolling/40_rolling.wav"}
|
||||
self.SoundNames["rolling_70"] = {loop=true,"subway_trains/717/rolling/70_rolling.wav"}
|
||||
self.SoundNames["rolling_80"] = {loop=true,"subway_trains/717/rolling/80_rolling.wav"}
|
||||
self.SoundPositions["rolling_10"] = {1200,1e9,Vector(0,0,0),1}
|
||||
self.SoundPositions["rolling_40"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundPositions["rolling_70"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundPositions["rolling_80"] = self.SoundPositions["rolling_10"]
|
||||
self.SoundNames["pneumo_disconnect2"] = "subway_trains/common/pneumatic/pneumo_close.mp3"
|
||||
self.SoundNames["pneumo_disconnect1"] = {
|
||||
"subway_trains/common/pneumatic/pneumo_open.mp3",
|
||||
"subway_trains/common/pneumatic/pneumo_open2.mp3",
|
||||
}
|
||||
self.SoundPositions["pneumo_disconnect2"] = {60,1e9,Vector(431.8,-50.1+1.5,-33.7),1}
|
||||
self.SoundPositions["pneumo_disconnect1"] = {60,1e9,Vector(431.8,-50.1+1.5,-33.7),1}
|
||||
self.SoundNames["epv_on"] = "subway_trains/common/pneumatic/epv_on.mp3"
|
||||
self.SoundNames["epv_off"] = "subway_trains/common/pneumatic/epv_off.mp3"
|
||||
self.SoundPositions["epv_on"] = {100,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
self.SoundPositions["epv_off"] = {100,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
self.SoundPositions["epv_off"] = {60,1e9,Vector(437.2,-53.1,-32.0),1}
|
||||
-- Релюшки
|
||||
self.SoundNames["rpb_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["rpb_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["rpb_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["rpb_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["rvt_on"] = {
|
||||
"subway_trains/717/relays/brake_on1.mp3",
|
||||
}
|
||||
self.SoundNames["rvt_off"] = {
|
||||
"subway_trains/717/relays/brake_off1.mp3",
|
||||
"subway_trains/717/relays/brake_off2.mp3",
|
||||
"subway_trains/717/relays/brake_off3.mp3",
|
||||
}
|
||||
self.SoundPositions["rvt_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["rvt_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
if self.Breakers then
|
||||
self.SoundNames["r1_5_on"] = "subway_trains/717/relays/drive_on1.mp3"
|
||||
else
|
||||
self.SoundNames["r1_5_on"] = "subway_trains/717/relays/drive2_on.mp3"
|
||||
end
|
||||
self.SoundNames["r1_5_off"] = "subway_trains/717/relays/drive_off.mp3"
|
||||
self.SoundPositions["r1_5_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["r1_5_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
|
||||
self.SoundNames["kd_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["kd_on"] = "subway_trains/717/relays/lsd_1.mp3"
|
||||
self.SoundPositions["kd_on"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["kd_off"] = {100,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["k25_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["k25_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["k25_on"] = {120,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["k25_off"] = {120,1e9,Vector(400,25,-35),1}
|
||||
self.SoundNames["ro_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["ro_on"] = "subway_trains/717/relays/RO_on.mp3"
|
||||
self.SoundPositions["ro_on"] = {140,1e9,Vector(400,25,-35),1}
|
||||
self.SoundPositions["ro_off"] = {140,1e9,Vector(400,25,-35),1}
|
||||
|
||||
|
||||
self.SoundNames["avu_off"] = "subway_trains/717/relays/lsd_2.mp3"
|
||||
self.SoundNames["avu_on"] = "subway_trains/717/relays/relay_on.mp3"
|
||||
self.SoundPositions["avu_on"] = {60,1e9, Vector(400,-40,-45),1}
|
||||
self.SoundPositions["avu_off"] = {60,1e9, Vector(400,-40,-45),1}
|
||||
--Подвагонка
|
||||
self.SoundNames["lk2_on"] = "subway_trains/717/pneumatic/lk/lk2_on.mp3"
|
||||
self.SoundNames["lk2_off"] = "subway_trains/717/pneumatic/lk/lk2_off.mp3"
|
||||
self.SoundNames["lk3_on"] = "subway_trains/717/pneumatic/lk/lk3_on.mp3"
|
||||
self.SoundNames["lk3_off"] = "subway_trains/717/pneumatic/lk/lk3_off.mp3"
|
||||
self.SoundPositions["lk2_on"] = {440,1e9,Vector(-60,-40,-66),0.2}
|
||||
self.SoundPositions["lk2_off"] = {400,1e9,Vector(-60,-40,-66),0.6}
|
||||
self.SoundPositions["lk3_on"] = {440,1e9,Vector(-60,-40,-66),0.2}
|
||||
self.SoundPositions["lk3_off"] = {400,1e9,Vector(-60,-40,-66),0.6}
|
||||
|
||||
self.SoundNames["compressor"] = {loop=2.0,"subway_trains/ezh/compressor/ezh_compressor_start.mp3","subway_trains/ezh/compressor/ezh_compressor_loop.mp3", "subway_trains/ezh/compressor/ezh_compressor_end.mp3"}
|
||||
self.SoundPositions["compressor"] = {700,1e9,Vector(-118,-40,-66)}
|
||||
self.SoundNames["rk"] = {"subway_trains/717/rk/rk_start.wav","subway_trains/717/rk/rk_spin.wav","subway_trains/717/rk/rk_stop.mp3"}
|
||||
self.SoundPositions["rk"] = {70,1e3,Vector(110,-40,-75)}
|
||||
|
||||
self.SoundNames["ezh3_revers_0-f"] = {"subway_trains/717/kv70/reverser_0-f_1.mp3","subway_trains/717/kv70/reverser_0-f_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_f-0"] = {"subway_trains/717/kv70/reverser_f-0_1.mp3","subway_trains/717/kv70/reverser_f-0_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_0-b"] = {"subway_trains/717/kv70/reverser_0-b_1.mp3","subway_trains/717/kv70/reverser_0-b_2.mp3"}
|
||||
self.SoundNames["ezh3_revers_b-0"] = {"subway_trains/717/kv70/reverser_b-0_1.mp3","subway_trains/717/kv70/reverser_b-0_2.mp3"}
|
||||
self.SoundNames["revers_in"] = {"subway_trains/ezh3/kv66/revers_in.wav"}
|
||||
self.SoundNames["revers_out"] = {"subway_trains/ezh3/kv66/revers_out.wav"}
|
||||
self.SoundPositions["ezh3_revers_0-f"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_f-0"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_0-b"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_b-0"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_in"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
self.SoundPositions["ezh3_revers_out"] = {80,1e9,Vector(445.5,-32+1.7,-7.5)}
|
||||
|
||||
self.SoundNames["kru_in"] = {
|
||||
"subway_trains/717/kru/kru_insert1.mp3",
|
||||
"subway_trains/717/kru/kru_insert2.mp3"
|
||||
}
|
||||
self.SoundPositions["kru_in"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundNames["kru_out"] = {
|
||||
"subway_trains/717/kru/kru_eject1.mp3",
|
||||
"subway_trains/717/kru/kru_eject2.mp3",
|
||||
"subway_trains/717/kru/kru_eject3.mp3",
|
||||
}
|
||||
self.SoundPositions["kru_out"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
|
||||
self.SoundNames["kru_0_1"] = {
|
||||
"subway_trains/717/kru/kru0-1_1.mp3",
|
||||
"subway_trains/717/kru/kru0-1_2.mp3",
|
||||
"subway_trains/717/kru/kru0-1_3.mp3",
|
||||
"subway_trains/717/kru/kru0-1_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_1_2"] = {
|
||||
"subway_trains/717/kru/kru1-2_1.mp3",
|
||||
"subway_trains/717/kru/kru1-2_2.mp3",
|
||||
"subway_trains/717/kru/kru1-2_3.mp3",
|
||||
"subway_trains/717/kru/kru1-2_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_2_1"] = {
|
||||
"subway_trains/717/kru/kru2-1_1.mp3",
|
||||
"subway_trains/717/kru/kru2-1_2.mp3",
|
||||
"subway_trains/717/kru/kru2-1_3.mp3",
|
||||
"subway_trains/717/kru/kru2-1_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_1_0"] = {
|
||||
"subway_trains/717/kru/kru1-0_1.mp3",
|
||||
"subway_trains/717/kru/kru1-0_2.mp3",
|
||||
"subway_trains/717/kru/kru1-0_3.mp3",
|
||||
"subway_trains/717/kru/kru1-0_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_2_3"] = {
|
||||
"subway_trains/717/kru/kru2-3_1.mp3",
|
||||
"subway_trains/717/kru/kru2-3_2.mp3",
|
||||
"subway_trains/717/kru/kru2-3_3.mp3",
|
||||
"subway_trains/717/kru/kru2-3_4.mp3",
|
||||
}
|
||||
self.SoundNames["kru_3_2"] = {
|
||||
"subway_trains/717/kru/kru3-2_1.mp3",
|
||||
"subway_trains/717/kru/kru3-2_2.mp3",
|
||||
"subway_trains/717/kru/kru3-2_3.mp3",
|
||||
"subway_trains/717/kru/kru3-2_4.mp3",
|
||||
}
|
||||
self.SoundPositions["kru_0_1"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_1_2"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_2_1"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_1_0"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_2_3"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
self.SoundPositions["kru_3_2"] = {80,1e9,Vector(452.3,-24.0,4.0)}
|
||||
|
||||
self.SoundNames["kr_open"] = {
|
||||
"subway_trains/717/cover/cover_open1.mp3",
|
||||
"subway_trains/717/cover/cover_open2.mp3",
|
||||
"subway_trains/717/cover/cover_open3.mp3",
|
||||
}
|
||||
self.SoundNames["kr_close"] = {
|
||||
"subway_trains/717/cover/cover_close1.mp3",
|
||||
"subway_trains/717/cover/cover_close2.mp3",
|
||||
"subway_trains/717/cover/cover_close3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["switch_off"] = {
|
||||
"subway_trains/717/switches/tumbler_slim_off1.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off2.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off3.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_off4.mp3",
|
||||
}
|
||||
self.SoundNames["switch_on"] = {
|
||||
"subway_trains/717/switches/tumbler_slim_on1.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on2.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on3.mp3",
|
||||
"subway_trains/717/switches/tumbler_slim_on4.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["switchbl_off"] = {
|
||||
"subway_trains/717/switches/tumbler_fatb_off1.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_off2.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_off3.mp3",
|
||||
}
|
||||
self.SoundNames["switchbl_on"] = {
|
||||
"subway_trains/717/switches/tumbler_fatb_on1.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_on2.mp3",
|
||||
"subway_trains/717/switches/tumbler_fatb_on3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["triple_down-0"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_down-0_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_down-0_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_0-up"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_0-up_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_0-up_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_up-0"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_up-0_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_up-0_2.mp3",
|
||||
}
|
||||
self.SoundNames["triple_0-down"] = {
|
||||
"subway_trains/717/switches/tumbler_triple_0-down_1.mp3",
|
||||
"subway_trains/717/switches/tumbler_triple_0-down_2.mp3",
|
||||
}
|
||||
self.SoundNames["button1_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off1.mp3",
|
||||
"subway_trains/ezh3/switches/button_off2.mp3",
|
||||
}
|
||||
self.SoundNames["button1_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on1.mp3",
|
||||
"subway_trains/ezh3/switches/button_on2.mp3",
|
||||
}
|
||||
self.SoundNames["button2_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off3.mp3",
|
||||
"subway_trains/ezh3/switches/button_off4.mp3",
|
||||
}
|
||||
self.SoundNames["button2_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on3.mp3",
|
||||
"subway_trains/ezh3/switches/button_on4.mp3",
|
||||
}
|
||||
self.SoundNames["button3_off"] = {
|
||||
"subway_trains/ezh3/switches/button_off6.mp3",
|
||||
"subway_trains/ezh3/switches/button_off5.mp3",
|
||||
}
|
||||
self.SoundNames["button3_on"] = {
|
||||
"subway_trains/ezh3/switches/button_on5.mp3",
|
||||
"subway_trains/ezh3/switches/button_on6.mp3",
|
||||
}
|
||||
self.SoundNames["button4_off"] = {
|
||||
"subway_trains/ezh3/switches/button_on1.mp3",
|
||||
"subway_trains/ezh3/switches/button_on2.mp3",
|
||||
}
|
||||
self.SoundNames["button4_on"] = {
|
||||
"subway_trains/717/switches/button4_on1.mp3",
|
||||
"subway_trains/717/switches/button4_on2.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["uava_reset"] = {
|
||||
"subway_trains/common/uava/uava_reset1.mp3",
|
||||
"subway_trains/common/uava/uava_reset2.mp3",
|
||||
"subway_trains/common/uava/uava_reset4.mp3",
|
||||
}
|
||||
self.SoundPositions["uava_reset"] = {80,1e9,Vector(449+7.7,56.0,-10.24349),0.6}
|
||||
self.SoundNames["gv_f"] = self.SoundNames["revers_0-b"]
|
||||
self.SoundNames["gv_b"] = self.SoundNames["revers_b-0"]
|
||||
self.SoundPositions["gv_f"] = {80,1e2,Vector(120,62.0+0.0,-60),0.5}
|
||||
self.SoundPositions["gv_b"] = {80,1e2,Vector(120,62.0+0.0,-60),0.5}
|
||||
|
||||
--Краны
|
||||
self.SoundNames["brake"] = {"subway_trains/common/pneumatic/vz_brake_on1.mp3","subway_trains/common/pneumatic/vz_brake_on2.mp3"}
|
||||
self.SoundPositions["brake"] = {600,1e9,Vector(0,0,0),0.5}
|
||||
self.SoundNames["release1"] = {loop=true,"subway_trains/common/pneumatic/release.wav"} --TODO разделение отпуска и срыва по позициям в кабине\вне
|
||||
self.SoundPositions["release1"] = {1200,1e9,Vector(-183,0,-70)}
|
||||
self.SoundNames["crane334_brake"] = {loop=true,"subway_trains/common/pneumatic/334_brake.wav"} --TODO добавить жужжащий звук
|
||||
self.SoundPositions["crane334_brake"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
self.SoundNames["crane334_brake_slow"] = {loop=true,"subway_trains/common/pneumatic/334_brake_slow.wav"} --TODO добавить жужжащий звук
|
||||
self.SoundPositions["crane334_brake_slow"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
self.SoundNames["crane334_release"] = {loop=true,"subway_trains/common/pneumatic/334_release.wav"}
|
||||
self.SoundPositions["crane334_release"] = {180,1e9,Vector(440,-55.75,-10)}
|
||||
|
||||
self.SoundNames["epk_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["epk_brake"] = {200,1e9,Vector(437.2,-53.1,-50.0)}
|
||||
self.SoundNames["epk_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["epk_brake_start"] = self.SoundPositions["epk_brake"]
|
||||
|
||||
self.SoundNames["valve_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["valve_brake"] = {200,1e9,Vector(402,-63,-50)}
|
||||
self.SoundNames["valve_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["valve_brake_start"] = self.SoundPositions["valve_brake"]
|
||||
|
||||
self.SoundNames["emer_brake"] = {loop=true,"subway_trains/common/pneumatic/epv_loop.wav"}
|
||||
self.SoundPositions["emer_brake"] = {200,1e9,Vector(380,-45,-75)}
|
||||
self.SoundNames["emer_brake_start"] = "subway_trains/common/pneumatic/epv_start.mp3"
|
||||
self.SoundPositions["emer_brake_start"] = self.SoundPositions["emer_brake"]
|
||||
|
||||
self.SoundNames["pneumo_TL_open"] = {
|
||||
"subway_trains/common/334/334_open.mp3",
|
||||
}
|
||||
self.SoundNames["pneumo_TL_disconnect"] = {
|
||||
"subway_trains/common/334/334_close.mp3",
|
||||
}
|
||||
self.SoundNames["pneumo_BL_disconnect"] = {
|
||||
"subway_trains/common/334/334_close.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pak_on"] = "subway_trains/717/switches/rc_on.mp3"
|
||||
self.SoundNames["pak_off"] = "subway_trains/717/switches/rc_off.mp3"
|
||||
|
||||
--self.SoundNames["kv70_fix_on"] = {"subway_trains/717/kv70/kv70_fix_on1.mp3","subway_trains/717/kv70/kv70_fix_on2.mp3"}
|
||||
-- self.SoundNames["kv70_fix_off"] = {"subway_trains/717/kv70/kv70_fix_off1.mp3","subway_trains/717/kv70/kv70_fix_off2.mp3"}
|
||||
self.SoundNames["kv40_0_t1"] = {"subway_trains/ezh/kv40/kv40_0_T1.mp3"}
|
||||
self.SoundNames["kv40_t1_0"] = {"subway_trains/ezh/kv40/kv40_T1_0.mp3"}
|
||||
self.SoundNames["kv40_t1_t1a"] = {"subway_trains/ezh/kv40/kv40_T1_T1A.mp3"}
|
||||
self.SoundNames["kv40_t1a_t1"] = {"subway_trains/ezh/kv40/kv40_T1A_T1.mp3"}
|
||||
self.SoundNames["kv40_t1a_t2"] = {"subway_trains/ezh/kv40/kv40_T1A_T2.mp3"}
|
||||
self.SoundNames["kv40_t2_t1a"] = {"subway_trains/ezh/kv40/kv40_T2_T1A.mp3"}
|
||||
self.SoundNames["kv40_0_x1"] = {"subway_trains/ezh/kv40/kv40_0_X1.mp3"}
|
||||
self.SoundNames["kv40_x1_0"] = {"subway_trains/ezh/kv40/kv40_X1_0.mp3"}
|
||||
self.SoundNames["kv40_x1_x2"] = {"subway_trains/ezh/kv40/kv40_X1_X2.mp3"}
|
||||
self.SoundNames["kv40_x2_x1"] = {"subway_trains/ezh/kv40/kv40_X2_X1.mp3"}
|
||||
self.SoundNames["kv40_x2_x3"] = {"subway_trains/ezh/kv40/kv40_X2_X3.mp3"}
|
||||
self.SoundNames["kv40_x3_x2"] = {"subway_trains/ezh/kv40/kv40_X3_X2.mp3"}
|
||||
--self.SoundPositions["kv70_fix_on"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
--self.SoundPositions["kv70_fix_off"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
self.SoundPositions["kv40_0_t1"] = {100,1e9,Vector(442.2,-40,-16.2),2}
|
||||
self.SoundPositions["kv40_t1_0"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1_t1a"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1a_t1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t1a_t2"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_t2_t1a"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_0_x1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x1_0"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x1_x2"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x2_x1"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x2_x3"] = self.SoundPositions["kv40_0_t1"]
|
||||
self.SoundPositions["kv40_x3_x2"] = self.SoundPositions["kv40_0_t1"]
|
||||
|
||||
self.SoundNames["ring"] = {"subway_trains/717/ring/ring_start.wav","subway_trains/717/ring/ring_loop.wav","subway_trains/717/ring/ring_end.wav"}
|
||||
self.SoundPositions["ring"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["ring2"] = {loop=0.1,"subway_trains/717/ring/ringc_start.wav","subway_trains/717/ring/ringc_loop.wav","subway_trains/717/ring/ringc_end.mp3"}
|
||||
self.SoundPositions["ring2"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["ring_old"] = {loop=0.15,"subway_trains/717/ring/ringo_start.wav","subway_trains/717/ring/ringo_loop.wav","subway_trains/717/ring/ringo_end.mp3"}
|
||||
self.SoundPositions["ring_old"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["cab_door_open"] = {
|
||||
"subway_trains/common/door/cab/cab_door_open2.mp3",
|
||||
"subway_trains/common/door/cab/cab_door_open.mp3",
|
||||
}
|
||||
self.SoundPositions["cab_door_open"] = {100,1e9,Vector(400,-40,50)}
|
||||
|
||||
self.SoundNames["cab_door_close"] = {
|
||||
"subway_trains/common/door/cab/cab_door_close2.mp3",
|
||||
"subway_trains/common/door/cab/cab_door_close.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["parking_brake_rolling"] = {"subway_trains/ezh3/parking_brake_rolling1.mp3","subway_trains/ezh3/parking_brake_rolling2.mp3","subway_trains/ezh3/parking_brake_rolling3.mp3","subway_trains/ezh3/parking_brake_rolling4.mp3"}
|
||||
self.SoundPositions["parking_brake_rolling"] = {120,1e9,Vector(449.118378+7.6,33.493385,-14.713276)}
|
||||
self.SoundNames["av8_on"] = {"subway_trains/common/switches/av8/av8_on.mp3","subway_trains/common/switches/av8/av8_on2.mp3"}
|
||||
self.SoundNames["av8_off"] = {"subway_trains/common/switches/av8/av8_off.mp3","subway_trains/common/switches/av8/av8_off2.mp3"}
|
||||
self.SoundPositions["av8_on"] = {100,1e9,Vector(405,40,30)}
|
||||
self.SoundPositions["av8_off"] = {100,1e9,Vector(405,40,30)}
|
||||
|
||||
self.SoundNames["vu22_on"] = {"subway_trains/ezh3/vu/vu22_on1.mp3", "subway_trains/ezh3/vu/vu22_on2.mp3", "subway_trains/ezh3/vu/vu22_on3.mp3"}
|
||||
self.SoundNames["vu22_off"] = {"subway_trains/ezh3/vu/vu22_off1.mp3", "subway_trains/ezh3/vu/vu22_off2.mp3", "subway_trains/ezh3/vu/vu22_off3.mp3"}
|
||||
self.SoundNames["vu223_on"] = {"subway_trains/common/switches/vu22/vu22_3_on.mp3"}
|
||||
self.SoundNames["vu223_off"] = {"subway_trains/common/switches/vu22/vu22_3_off.mp3"}
|
||||
|
||||
self.SoundNames["igla_on"] = "subway_trains/common/other/igla/igla_on1.mp3"
|
||||
self.SoundNames["igla_off"] = "subway_trains/common/other/igla/igla_off2.mp3"
|
||||
self.SoundNames["igla_start1"] = "subway_trains/common/other/igla/igla2_start1.mp3"
|
||||
self.SoundNames["igla_start2"] = "subway_trains/common/other/igla/igla2_start2.mp3"
|
||||
self.SoundPositions["igla_on"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_off"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_start1"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.3}
|
||||
self.SoundPositions["igla_start2"] = {50,1e9,Vector(420.4-0.6,-56.1-0.15,9.87-1.15),0.2}
|
||||
|
||||
self.SoundNames["upps"] = {"subway_trains/common/other/upps/upps1.mp3","subway_trains/common/other/upps/upps2.mp3"}
|
||||
self.SoundPositions["upps"] = {60,1e9,Vector(443,-64,4),0.5}
|
||||
|
||||
self.SoundNames["pnm_on"] = {"subway_trains/common/pnm/pnm_switch_on.mp3","subway_trains/common/pnm/pnm_switch_on2.mp3"}
|
||||
self.SoundNames["pnm_off"] = {"subway_trains/common/pnm/pnm_switch_off.mp3","subway_trains/common/pnm/pnm_switch_off2.mp3"}
|
||||
self.SoundNames["pnm_button1_on"] = {
|
||||
"subway_trains/common/pnm/pnm_button_push.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push2.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button2_on"] = {
|
||||
"subway_trains/common/pnm/pnm_button_push4.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push5.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_push6.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button1_off"] = {
|
||||
"subway_trains/common/pnm/pnm_button_release.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release2.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release3.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["pnm_button2_off"] = {
|
||||
"subway_trains/common/pnm/pnm_button_release4.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release5.mp3",
|
||||
"subway_trains/common/pnm/pnm_button_release6.mp3",
|
||||
}
|
||||
|
||||
self.SoundNames["horn1"] = {loop=0.6,"subway_trains/common/pneumatic/horn/horn1_start.wav","subway_trains/common/pneumatic/horn/horn1_loop.wav", "subway_trains/common/pneumatic/horn/horn1_end.mp3"}
|
||||
self.SoundNames["horn2"] = {loop=0.8,"subway_trains/common/pneumatic/horn/horn3_start.wav","subway_trains/common/pneumatic/horn/horn3_loop.wav", "subway_trains/common/pneumatic/horn/horn3_end.wav"}
|
||||
self.SoundPositions["horn1"] = {1100,1e9,Vector(450,0,-55)}
|
||||
self.SoundPositions["horn2"] = self.SoundPositions["horn1"]
|
||||
|
||||
--DOORS
|
||||
self.SoundNames["vdol_on"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDO_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDO2_on.mp3",
|
||||
}
|
||||
self.SoundNames["vdol_off"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDO_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDO2_off.mp3",
|
||||
}
|
||||
self.SoundPositions["vdol_on"] = {100,1e9,Vector(410,20,-45)}
|
||||
self.SoundPositions["vdol_off"] = self.SoundPositions["vdol_on"]
|
||||
self.SoundNames["vdor_on"] = self.SoundNames["vdol_on"]
|
||||
self.SoundNames["vdor_off"] = self.SoundNames["vdol_off"]
|
||||
self.SoundPositions["vdor_on"] = self.SoundPositions["vdol_on"]
|
||||
self.SoundPositions["vdor_off"] = self.SoundPositions["vdol_off"]
|
||||
self.SoundNames["vdz_on"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ2_on.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ3_on.mp3",
|
||||
}
|
||||
self.SoundNames["vdz_off"] = {
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ2_off.mp3",
|
||||
"subway_trains/common/pneumatic/door_valve/VDZ3_off.mp3",
|
||||
}
|
||||
self.SoundPositions["vdz_on"] = {100,1e9,Vector(410,20,-45)}
|
||||
self.SoundPositions["vdz_off"] = {100,1e9,Vector(410,20,-45)}
|
||||
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
self.SoundNames["door"..i.."x"..k.."r"] = {"subway_trains/common/door/door_roll.wav",loop=true}
|
||||
self.SoundPositions["door"..i.."x"..k.."r"] = {150,1e9,GetDoorPosition(i,k),0.2}
|
||||
self.SoundNames["door"..i.."x"..k.."o"] = {"subway_trains/common/door/door_open_end1.mp3","subway_trains/common/door/door_open_end2.mp3","subway_trains/common/door/door_open_end3.mp3","subway_trains/common/door/door_open_end4.mp3"}
|
||||
self.SoundPositions["door"..i.."x"..k.."o"] = {300,1e9,GetDoorPosition(i,k),1}
|
||||
self.SoundNames["door"..i.."x"..k.."c"] = {"subway_trains/common/door/door_close_end.mp3","subway_trains/common/door/door_close_end2.mp3","subway_trains/common/door/door_close_end3.mp3"}
|
||||
self.SoundPositions["door"..i.."x"..k.."c"] = self.SoundPositions["door"..i.."x"..k.."o"]
|
||||
end
|
||||
end
|
||||
self.SoundNames["PN2end"] = "subway_trains/common/pneumatic/vz2_end.mp3"
|
||||
self.SoundPositions["PN2end"] = {600,1e9,Vector(-183,0,-70),0.5}
|
||||
|
||||
for k,v in ipairs(self.AnnouncerPositions) do
|
||||
self.SoundNames["announcer_noise1_"..k] = {loop=true,"subway_announcers/upo/noiseS1.wav"}
|
||||
self.SoundPositions["announcer_noise1_"..k] = {v[2] or 300,1e9,v[1],v[3]*0.5}
|
||||
self.SoundNames["announcer_noise2_"..k] = {loop=true,"subway_announcers/upo/noiseS2.wav"}
|
||||
self.SoundPositions["announcer_noise2_"..k] = {v[2] or 300,1e9,v[1],v[3]*0.5}
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема Е (АРС)
|
||||
self:LoadSystem("Electric","81_701_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_108D")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A","KF_47A6")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_40")
|
||||
-- Контроллер резервного управления (KRP)
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A","YAR_15A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
self.Pneumatic.ValveType = 1
|
||||
-- Панель управления Еж АРС МП
|
||||
self:LoadSystem("Panel","81_508_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
--self:LoadSystem("DURA")
|
||||
self:LoadSystem("ALS_ARS","NoARS")
|
||||
|
||||
self:LoadSystem("ASNP31","Relay","Switch")
|
||||
self:LoadSystem("ASNP32","Relay","Switch")
|
||||
self:LoadSystem("Horn")
|
||||
|
||||
self:LoadSystem("Announcer","81_722_Announcer", "AnnouncementsASNP")
|
||||
self:LoadSystem("ASNP","81_71_ASNP")
|
||||
self:LoadSystem("IGLA_CBKI","IGLA_CBKI2")
|
||||
self:LoadSystem("IGLA_PCBK")
|
||||
end
|
||||
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Em508",
|
||||
WagType = 1,
|
||||
ARS = {
|
||||
NoEPK = true,
|
||||
NoUAVA = true,
|
||||
},
|
||||
EKKType = 703,
|
||||
NoFrontEKK=true,
|
||||
}
|
||||
|
||||
ENT.NumberRanges = {{3955,3999},{6101,6200}}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,958 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Ema",
|
||||
WagType = 0,
|
||||
ARS = {
|
||||
HaveASNP = false,
|
||||
}
|
||||
}
|
||||
function ENT:Initialize()
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi_train/em/ema.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(430,-39,-21.5),Angle(0,0,0))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(430,40,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat1 = self:CreateSeat("instructor",Vector(443,0,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat2 = self:CreateSeat("instructor",Vector(420,-20,-48+6),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.InstructorsSeat:SetColor(Color(0,0,0,0))
|
||||
self.InstructorsSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
self.ExtraSeat1:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat1:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.ExtraSeat2:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat2:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 320,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-320,0,-80),Angle(0,0,0),false)
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
-- Initialize key mapping
|
||||
self.KeyMap = {
|
||||
[KEY_1] = "KVSetX1",
|
||||
[KEY_2] = "KVSetX2",
|
||||
[KEY_3] = "KVSetX3",
|
||||
[KEY_4] = "KVSet0",
|
||||
[KEY_5] = "KVSetT1",
|
||||
[KEY_6] = "KVSetT1AB",
|
||||
[KEY_7] = "KVSetT2",
|
||||
[KEY_8] = "KRP",
|
||||
|
||||
[KEY_EQUAL] = "R_Program1Set",
|
||||
[KEY_MINUS] = "R_Program2Set",
|
||||
|
||||
[KEY_G] = "VozvratRPSet",
|
||||
|
||||
[KEY_0] = "KVReverserUp",
|
||||
[KEY_9] = "KVReverserDown",
|
||||
[KEY_PAD_PLUS] = "KVReverserUp",
|
||||
[KEY_PAD_MINUS] = "KVReverserDown",
|
||||
[KEY_W] = "KVUp",
|
||||
[KEY_S] = "KVDown",
|
||||
[KEY_F] = "PneumaticBrakeUp",
|
||||
[KEY_R] = "PneumaticBrakeDown",
|
||||
|
||||
[KEY_A] = "KDL",
|
||||
[KEY_D] = "KDP",
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "HornEngage",
|
||||
[KEY_N] = "VZ1Set",
|
||||
[KEY_PAD_1] = "PneumaticBrakeSet1",
|
||||
[KEY_PAD_2] = "PneumaticBrakeSet2",
|
||||
[KEY_PAD_3] = "PneumaticBrakeSet3",
|
||||
[KEY_PAD_4] = "PneumaticBrakeSet4",
|
||||
[KEY_PAD_5] = "PneumaticBrakeSet5",
|
||||
[KEY_PAD_6] = "PneumaticBrakeSet6",
|
||||
[KEY_PAD_7] = "PneumaticBrakeSet7",
|
||||
[KEY_PAD_DIVIDE] = "KRPSet",
|
||||
[KEY_PAD_MULTIPLY] = "KAHSet",
|
||||
|
||||
[KEY_SPACE] = "PBSet",
|
||||
[KEY_BACKSPACE] = "EmergencyBrake",
|
||||
|
||||
[KEY_PAD_0] = "DriverValveDisconnect",
|
||||
[KEY_PAD_DECIMAL] = "EPKToggle",
|
||||
[KEY_LSHIFT] = {
|
||||
[KEY_W] = "KVUp_Unlocked",
|
||||
[KEY_SPACE] = "KVTSet",
|
||||
|
||||
[KEY_A] = "DURASelectAlternate",
|
||||
[KEY_D] = "DURASelectMain",
|
||||
[KEY_V] = "DURAToggleChannel",
|
||||
[KEY_1] = "DIPonSet",
|
||||
[KEY_2] = "DIPoffSet",
|
||||
[KEY_4] = "KVSet0Fast",
|
||||
[KEY_L] = "DriverValveDisconnect",
|
||||
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_6] = "KVSetT1A",
|
||||
},
|
||||
|
||||
[KEY_RSHIFT] = {
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_L] = "DriverValveDisconnect",
|
||||
[KEY_F] = "BCCDSet",
|
||||
[KEY_R] = "VZPSet",
|
||||
},
|
||||
[KEY_LALT] = {
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "EPKToggle",
|
||||
},
|
||||
[KEY_RALT] = {
|
||||
[KEY_L] = "EPKToggle",
|
||||
},
|
||||
}
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(-471,-30,0),
|
||||
Radius = 28,
|
||||
ID = "RearDoor"
|
||||
},
|
||||
{ Pos = Vector(473,32,28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor1"
|
||||
},
|
||||
{ Pos = Vector(473,32,-28),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor2"
|
||||
},
|
||||
{ Pos = Vector(383.02,31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor1"
|
||||
},
|
||||
{ Pos = Vector(383.02,-31.85,2),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor1"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor2"
|
||||
},
|
||||
{ Pos = Vector(408.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor3"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,-26),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor4"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,6),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor5"
|
||||
},
|
||||
{ Pos = Vector(458.18,63.59,38),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor6"
|
||||
},
|
||||
}
|
||||
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[1] = { "headlight", Vector(475,0,-20), Angle(0,0,0), Color(216,161,92), fov = 100 },
|
||||
[2] = { "glow", Vector(469.4, 45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[3] = { "glow", Vector(469.4,-45.43,-30.7), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[4] = { "glow", Vector(458+9,-14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[5] = { "glow", Vector(458+9,0, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[6] = { "glow", Vector(458+9, 14.86, 58), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
|
||||
-- Reverse
|
||||
--[8] = { "light", Vector(458+11,-30.7, 54.2), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
--[9] = { "light", Vector(458+11, 30.7, 54.2), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
|
||||
-- Cabin
|
||||
[10] = { "dynamiclight", Vector(435,0,20), Angle(0,-0,0), Color(255,107,50), brightness = 0.004, distance = 600, shadows = 1},
|
||||
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 300 , fov=180,farz = 128 },
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 400, fov=180,farz = 128 },
|
||||
[13] = { "dynamiclight", Vector(-300, 0, 0), Angle(0,0,0), Color(255,95,10), brightness = 5, distance = 400 , fov=180,farz = 128 },
|
||||
|
||||
-- Side lights
|
||||
--//[14] = { "light", Vector(390+12.15, 69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[15] = { "light", Vector(390+12.15, 69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[16] = { "light", Vector(390+12.15, 69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[17] = { "light", Vector(390+12.15, 69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
--[18] = { "light", Vector(390+12.15, -69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[19] = { "light", Vector(390+12.15, -69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[20] = { "light", Vector(390+12.15, -69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
--[21] = { "light", Vector(390+12.15, -69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[15] = { "light", Vector(402.202942,69.270073,44.79285), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[16] = { "light", Vector(402.202942,69.270073,41.509621), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[17] = { "light", Vector(402.202942,69.270073,37.3862), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
|
||||
--[19] = { "light", Vector(15, -69, 58.3), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
--[20] = { "light", Vector(12, -69, 58.3), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
--[21] = { "light", Vector(9, -69, 58.3), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "sprites/light_glow02.vmt" },
|
||||
[32] = { "headlight", Vector(450.70,-56.3,28), Angle(-90,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 77 },
|
||||
[33] = { "headlight", Vector(450.70,-56.3,32), Angle(-90,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 77 },
|
||||
|
||||
[34] = { "headlight", Vector(448.65,-56.40,22.60), Angle(-30,0,-45), Color(216,161,92), farz = 6, nearz = 4, shadows = 0, brightness = 2, fov = 140 },
|
||||
|
||||
[35] = { "headlight", Vector(450.6,-55.84,12.73), Angle(-90,-90,-180), Color(216,161,92), farz = 7, nearz = 4, shadows = 0, brightness = 2, fov = 130 },
|
||||
|
||||
[36] = { "headlight", Vector(455.2,-53.2,5.35), Angle(-90,-90,-180), Color(216,161,92), farz = 4, nearz = 4, shadows = 0, brightness = 2, fov = 130 },
|
||||
|
||||
[37] = { "headlight", Vector(458.3,-20.32,19.6), Angle(-90,-120,-180), Color(216,161,92), farz = 4, nearz = 4, shadows = 0, brightness = 3, fov = 160 },
|
||||
|
||||
[38] = { "headlight", Vector( -20, 0, 30), Angle(90,0,90), Color(255,95,10), brightness = 1, distance = 999,fov=179, shadows = 0, farz = 500},
|
||||
[39] = { "headlight", Vector( -20, 0, 10), Angle(-90,0,90), Color(255,95,10), brightness = 1, distance = 999,fov=179, shadows = 0, farz = 500},
|
||||
[70 ] = { "headlight", Vector( 450, -60, -47), Angle(45,-90,0), Color(255,255,255), brightness = 0.5, distance = 400 , fov=120, shadows = 1 },
|
||||
|
||||
}
|
||||
self.NetworkSwitches = {
|
||||
"VB","VBA",
|
||||
|
||||
"KVT","VZP","VZD","KRZD",
|
||||
|
||||
"KDL","DIPon","DIPoff","VozvratRP","KSN","KDP",
|
||||
|
||||
"KU1","Ring","VUS","KAK","VAutodrive","VUD1",
|
||||
|
||||
"RezMK",
|
||||
|
||||
"VUD2","VUD2L","VDL",
|
||||
|
||||
"VRU","VAH","VAD","OVT","KSD","DP","VKF",
|
||||
|
||||
"OtklAVU","KRP",
|
||||
|
||||
"RC1","RC2","VRD",
|
||||
|
||||
"PB","VU3","VU1","VU2","AV8B","VU","KDLK","VDLK","KDPK","KAHK","L_3","RST","VSOSD",
|
||||
}
|
||||
self.Plombs = {
|
||||
RST = true,
|
||||
VAH = true,
|
||||
VAD = true,
|
||||
OVT = true,
|
||||
RC1 = true,
|
||||
RC2 = true,
|
||||
Init = true,
|
||||
}
|
||||
-- Lights
|
||||
--[[
|
||||
for i = 1,23 do
|
||||
self.Lights[69+i] = { "light", Vector(-470 + 35*i, 0, 65), Angle(180,0,0), Color(255,220,180), brightness = 0.25, scale = 0.75}
|
||||
--self:SetLightPower(69+i,RealTime()%1*2>1)
|
||||
end]]
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- KV wrench mode
|
||||
self.KVWrenchMode = 0
|
||||
|
||||
-- Parking brake ratio
|
||||
self.ManualBrake = 0.0
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self.CabinDoor = false
|
||||
self.PassengerDoor = false
|
||||
|
||||
-- self.A5:TriggerInput("Set",0)
|
||||
self:UpdateTextures()
|
||||
end
|
||||
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self.CabTexture]
|
||||
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
--self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
self:SetNW2String("texture",self.Texture)
|
||||
self:SetNW2String("passtexture",self.PassTexture)
|
||||
self:SetNW2String("cabtexture",self.CabTexture)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
self.RetVal = self.BaseClass.Think(self)
|
||||
|
||||
-- Check if wrench was pulled out
|
||||
if self.DriversWrenchPresent then
|
||||
self.KV:TriggerInput("Enabled",self:IsWrenchPresent() and 1 or 0)
|
||||
end
|
||||
self:SetLightPower(1, self.Panel["HeadLights3"] > 0.5,(math.min(1,self.Panel["HeadLights1"])*0.50 +
|
||||
math.min(1,self.Panel["HeadLights2"])*0.25 +
|
||||
math.min(1,self.Panel["HeadLights3"])*0.25)
|
||||
)
|
||||
--self:SetLightPower(2, self.Panel["HeadLights2"] > 0.5)
|
||||
--self:SetLightPower(3, self.Panel["HeadLights2"] > 0.5)
|
||||
--self:SetLightPower(4, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(5, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(6, self.Panel["HeadLights1"] > 0.5)
|
||||
--self:SetLightPower(7, self.Panel["HeadLights2"] > 0.5)
|
||||
-- Reverser lights
|
||||
--self:SetLightPower(8, self.Panel["RedLightRight"] > 0.5)
|
||||
--self:SetLightPower(9, self.Panel["RedLightLeft"] > 0.5)
|
||||
self:SetPackedBool("HeadLights1",self.Panel["HeadLights1"] > 0.5)
|
||||
self:SetPackedBool("HeadLights2",self.Panel["HeadLights2"] > 0.5)
|
||||
self:SetPackedBool("RedLight",self.Panel["RedLightLeft"] > 0.5 or self.Panel["RedLightRight"] > 0.5)
|
||||
-- Interior/cabin lights
|
||||
self:SetLightPower(10, self.Panel["CabinLight"] > 0.5)
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = self.Panel["EmergencyLight"] > 0.5 or lightsActive2
|
||||
self:SetPackedBool("Lamps_emer",lightsActive1)
|
||||
self:SetPackedBool("Lamps_full",lightsActive2)
|
||||
--local I = math.Round((self.Electric.I24-150)/1000.0,1.5)
|
||||
local Light
|
||||
if self.Pneumatic.Compressor == 1 then
|
||||
Light = (lightsActive2 and 0.6 or 0.3)
|
||||
--[[
|
||||
if I > 0 then
|
||||
Light = Light*(1-math.abs(I*0.1))
|
||||
end
|
||||
]]
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
else
|
||||
Light = (lightsActive2 and 0.8 or 0.4)
|
||||
--[[
|
||||
if I > 0 then
|
||||
Light = Light*(1-math.abs(I*0.1))
|
||||
end
|
||||
]]
|
||||
self:SetLightPower(11, lightsActive1, Light)
|
||||
self:SetLightPower(12, lightsActive1, Light)
|
||||
self:SetLightPower(13, lightsActive1, Light)
|
||||
end
|
||||
self:SetPackedRatio("LampsI",math.Round((self.Electric.I24-150)/1000.0,1.5))
|
||||
self.SOSD = self.Panel["SD"] <= 0 and self.Panel["V1"] > 0 and self.KV.ReverserPosition ~= 0 and self.VSOSD.Value > 0.5
|
||||
self:SetLightPower(70,self.SOSD)
|
||||
--self:SetLightPower(12, lightsActive1,0.1 + ((self.PowerSupply.XT3_4 > 65.0) and 0.7 or 0))
|
||||
--self:SetLightPower(13, lightsActive2, 0.8)
|
||||
--for i = 1,23 do
|
||||
--self:SetLightPower(69+i,lightsActive2 and true or lightsActive1 and i%5==1 or false)
|
||||
--end
|
||||
--self:SetLightPower(12, self.Panel["EmergencyLight"] > 0.5)
|
||||
--self:SetLightPower(13, self.PowerSupply.XT3_4 > 65.0)
|
||||
|
||||
-- Side lights
|
||||
--self:SetLightPower(15, self.Panel["TrainDoors"] > 0.5)
|
||||
--self:SetLightPower(19, self.Panel["TrainDoors"] > 0.5)
|
||||
|
||||
--self:SetLightPower(16, self.Panel["GreenRP"] > 0.5)
|
||||
--self:SetLightPower(20, self.Panel["GreenRP"] > 0.5)
|
||||
|
||||
--self:SetLightPower(17, self.Panel["TrainBrakes"] > 0.5)
|
||||
--self:SetLightPower(21, self.Panel["TrainBrakes"] > 0.5)
|
||||
|
||||
self:SetLightPower(32,self.L_3.Value > 0.5)
|
||||
self:SetLightPower(33,self.L_3.Value > 0.5)
|
||||
self:SetLightPower(34,self.L_3.Value > 0.5)
|
||||
self:SetLightPower(35,self.L_3.Value > 0.5)
|
||||
self:SetLightPower(36,self.L_3.Value > 0.5)
|
||||
self:SetLightPower(37,self.L_3.Value > 0.5)
|
||||
-- Total temperature
|
||||
local IGLA_Temperature = math.max(self.Electric.T1,self.Electric.T2)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:WriteTrainWire(35,(self.Pneumatic.BrakeCylinderPressure > 0.1) and 1 or 0)
|
||||
|
||||
-- DIP/power
|
||||
self:SetPackedBool(32,self.Panel["V1"] > 0.5)
|
||||
-- Red RP
|
||||
local TW18 = self:GetTrainWire18()
|
||||
if self:ReadTrainWire(20) == 0 or (self.Panel["V1"] < 0.5) then TW18 = 0 end--(self.KV.ControllerPositionAutodrive == 0 and self.KV.ControllerPosition == 0)
|
||||
self:SetPackedBool(35,TW18 > 0.5)
|
||||
self:SetPackedBool(131,TW18 > 0)
|
||||
-- Green RP
|
||||
self:SetPackedBool(36,self.Panel["GreenRP"] > 0.5)
|
||||
-- Cabin heating
|
||||
--self:SetPackedBool(37,self.Panel["KUP"] > 0.5)
|
||||
-- AVU
|
||||
--self:SetPackedBool(38,self.Panel["AVU"] > 0.5)
|
||||
-- Ring
|
||||
self:SetPackedBool(39,self.Panel["Ring"] > 0.5)
|
||||
-- SD
|
||||
self:SetPackedBool(40,self.Panel["SD"] > 0.5)
|
||||
-- OCh
|
||||
self:SetPackedBool(41,self.ALS_ARS.NoFreq)
|
||||
-- 0
|
||||
self:SetPackedBool(42,self.ALS_ARS.Signal0)
|
||||
-- 40
|
||||
self:SetPackedBool(43,self.ALS_ARS.Signal40)
|
||||
-- 60
|
||||
self:SetPackedBool(44,self.ALS_ARS.Signal60)
|
||||
-- 75
|
||||
self:SetPackedBool(45,self.ALS_ARS.Signal70)
|
||||
-- 80
|
||||
self:SetPackedBool(46,self.ALS_ARS.Signal80)
|
||||
-- KT
|
||||
self:SetPackedBool(47,self.ALS_ARS.LKT and self.Panel["V1"] > 0.5)
|
||||
-- KVD
|
||||
self:SetPackedBool(48,self.ALS_ARS.LVD)
|
||||
self:SetPackedBool("DriverValveBLDisconnect",self.DriverValveBLDisconnect.Value == 1.0)
|
||||
self:SetPackedBool("DriverValveTLDisconnect",self.DriverValveTLDisconnect.Value == 1.0)
|
||||
self:SetPackedBool("EPK",self.EPK.Value == 1.0)
|
||||
for i=1,#self.NetworkSwitches do
|
||||
local switch = self.NetworkSwitches[i]
|
||||
self:SetPackedBool(switch,self[switch].Value == 1.0)
|
||||
end
|
||||
self:SetPackedBool("VPR",self.RST.Value > 0 and self.Panel["V1"] > 0)
|
||||
self:SetPackedBool("Lamp6",self:ReadTrainWire(6) > 0.5)
|
||||
self:SetPackedBool("Lamp1",self:ReadTrainWire(1) > 0.5)
|
||||
self:SetPackedBool("Lamp2",self:ReadTrainWire(2) > 0.5)
|
||||
self:SetPackedBool("DoorsWag",self.BD.Value == 0.0 and self.Panel["V1"] > 0.5 and self.KSD.Value > 0.5)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
self:SetPackedBool(158,self.PassengerDoor)
|
||||
self:SetPackedBool(159,self.CabinDoor)
|
||||
|
||||
if self.VUD2.Blocked > 0 and self.VUD2L.Value > 0.5 then
|
||||
self.VUD2:TriggerInput("Block",0)
|
||||
end
|
||||
if self.VUD2.Blocked == 0 and self.VUD2L.Value == 0 then
|
||||
self.VUD2:TriggerInput("Block",1)
|
||||
end
|
||||
if self.VUD2L.Blocked > 0 and self.VUD2.Value > 0 then
|
||||
self.VUD2L:TriggerInput("Block",0)
|
||||
end
|
||||
if self.VUD2L.Blocked == 0 and self.VUD2.Value == 0 then
|
||||
self.VUD2L:TriggerInput("Block",1)
|
||||
end
|
||||
self:SetPackedBool("VUD2Bl",self.VUD2.Blocked > 0)
|
||||
self:SetPackedBool("VUD2LBl",self.VUD2L.Blocked > 0)
|
||||
--[[
|
||||
-- LST
|
||||
self:SetPackedBool(49,self:ReadTrainWire(6) > 0.5)
|
||||
-- LVD
|
||||
self:SetPackedBool(50,self:ReadTrainWire(1) > 0.5)
|
||||
|
||||
self:SetPackedBool(165,self.PB.Value > 0)
|
||||
|
||||
-- AV states
|
||||
-- for i,v in ipairs(self.Panel.AVMap) do
|
||||
-- if tonumber(v)
|
||||
-- then self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
-- elseif self[v] then self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
self:SetPackedBool(62,self.L_3.Value > 0.5)
|
||||
self:SetPackedBool(64+19,self.VU1.Value > 0.5)
|
||||
self:SetPackedBool(64+12,self.VU.Value > 0.5)
|
||||
self:SetPackedBool(64+24,self.RST.Value > 0.5)
|
||||
self:SetPackedBool(64+7 ,self.AV8B.Value > 0.5)
|
||||
self:SetPackedBool(64+36,self.VU2.Value > 0.5)
|
||||
self:SetPackedBool(64+13,self.VU3.Value > 0.5)
|
||||
self:SetPackedBool("VPR",self.RST.Value == 1.0 and self.Panel["V1"])
|
||||
]]
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/7)
|
||||
self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.ReservoirPressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, math.min(2.7,self.Pneumatic.BrakeCylinderPressure + 4.0*self.ManualBrake)/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, math.abs(self.Electric.I24)/1000.0)
|
||||
--self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 82.0)
|
||||
self:SetPackedRatio(11,IGLA_Temperature)
|
||||
|
||||
-- Update ARS system
|
||||
self:SetPackedRatio(3, self.ALS_ARS.Speed/100.0)
|
||||
self:SetPackedRatio("Speed", self.Speed/120)
|
||||
if (self.ALS_ARS.Ring == true) then
|
||||
self:SetPackedBool(39,true)
|
||||
end
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = false
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
--self.RearBogey.ParkingBrake = self.ManualBrake.Value > 0.5
|
||||
end
|
||||
|
||||
-- Generate bogey sounds
|
||||
local jerk = math.abs((self.Acceleration - (self.PrevAcceleration or 0)) / self.DeltaTime)
|
||||
self.PrevAcceleration = self.Acceleration
|
||||
|
||||
if jerk > (2.0 + self.Speed/15.0) then
|
||||
self.PrevTriggerTime1 = self.PrevTriggerTime1 or CurTime()
|
||||
self.PrevTriggerTime2 = self.PrevTriggerTime2 or CurTime()
|
||||
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime1 > 1.5) then
|
||||
self.PrevTriggerTime1 = CurTime()
|
||||
self.FrontBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 70, math.random(96,110))
|
||||
end
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime2 > 1.5) then
|
||||
self.PrevTriggerTime2 = CurTime()
|
||||
self.RearBogey:EmitSound("subway_trains/bogey/chassis_"..math.random(1,5)..".wav", 70, math.random(96,110))
|
||||
end
|
||||
end
|
||||
|
||||
-- Temporary hacks
|
||||
--self:SetNW2Float("V",self.Speed)
|
||||
--self:SetNW2Float("A",self.Acceleration)
|
||||
|
||||
return self.RetVal
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
-- Parking brake
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,(self.ManualBrake or 0) - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,(self.ManualBrake or 0) + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",tonumber(button:sub(-1,-1)))
|
||||
return
|
||||
end
|
||||
if button:find("FrontDoor") then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("RearDoor") then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button:find("PassengerDoor") then
|
||||
self.PassengerDoor = not self.PassengerDoor
|
||||
if self.PassengerDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("CabinDoor") then
|
||||
self.CabinDoor = not self.CabinDoor
|
||||
if self.CabinDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button == "UAVAToggle" then
|
||||
local state = self.UAVA.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." UAVA!")
|
||||
end
|
||||
if button == "VRDToggle" then
|
||||
local state = self.VRD.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." VRD!")
|
||||
end
|
||||
if button == "NextSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex + 1
|
||||
if self.SignsIndex > #self.SignsList then self.SignsIndex = 1 end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
if button == "PrevSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex - 1
|
||||
if self.SignsIndex < 1 then self.SignsIndex = #self.SignsList end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
|
||||
if button == "Num1P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num1M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
|
||||
-- Parking brake
|
||||
if button == "ManualBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,self.ManualBrake - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ManualBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,self.ManualBrake + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
|
||||
if button == "KVUp" then
|
||||
if self.KV.ControllerPosition ~= -1 then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
end
|
||||
if button == "KVUp_Unlocked" then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
if button == "KVDown" then
|
||||
self.KV:TriggerInput("ControllerDown",1.0)
|
||||
end
|
||||
|
||||
-- KRU
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserUp") then
|
||||
self.KRU:TriggerInput("Up",1)
|
||||
self:OnButtonPress("KRUUp")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserDown") then
|
||||
self.KRU:TriggerInput("Down",1)
|
||||
self:OnButtonPress("KRUDown")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX1") then
|
||||
self.KRU:TriggerInput("SetX1",1)
|
||||
self:OnButtonPress("KRUSetX1")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX2") then
|
||||
self.KRU:TriggerInput("SetX2",1)
|
||||
self:OnButtonPress("KRUSetX2")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX3") then
|
||||
self.KRU:TriggerInput("SetX3",1)
|
||||
self:OnButtonPress("KRUSetX3")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSet0") then
|
||||
self.KRU:TriggerInput("Set0",1)
|
||||
self:OnButtonPress("KRUSet0")
|
||||
end
|
||||
|
||||
if button == "KVSetT1AB" then
|
||||
if self.KV.ControllerPosition == -2 then
|
||||
self.KV:TriggerInput("ControllerSet",-1)
|
||||
timer.Simple(0.20,function()
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end)
|
||||
else
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end
|
||||
end
|
||||
if button == "KVWrench0" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 1 then
|
||||
if self.KVWrenchMode ~= 1 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 0
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
if button == "KVWrenchKV" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 0 then
|
||||
if self.KVWrenchMode ~= 0 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 1
|
||||
self.DriversWrenchPresent = true
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--THERE IS NO KRU IN THIS EZH MODEL
|
||||
--[[
|
||||
if button == "KVWrenchKRU" then
|
||||
if self.KVWrenchMode == 3 then
|
||||
self:PlayOnce("kru_in","cabin",0.7)
|
||||
self.KVWrenchMode = 2
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("LockX3",1)
|
||||
end
|
||||
end]]
|
||||
if button == "KVWrenchNone" then
|
||||
if self.KVWrenchMode ~= 3 and self.KV.ReverserPosition == 0 then
|
||||
if self.KVWrenchMode == 2 then
|
||||
self:PlayOnce("kru_out","cabin",0.7)
|
||||
else
|
||||
self:PlayOnce("revers_out","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 3
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Close",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Close",1) self:OnButtonPress("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Close",1) self:OnButtonPress("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Close",1) self:OnButtonPress("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",1)
|
||||
self:OnButtonPress("KRPSet")
|
||||
end
|
||||
if button == "EmergencyBrake" then
|
||||
self.KV:TriggerInput("ControllerSet",-3)
|
||||
self.Pneumatic:TriggerInput("BrakeSet",7)
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
return
|
||||
end
|
||||
if button == "DriverValveDisconnect" then
|
||||
if self.DriverValveBLDisconnect.Value == 0 or self.DriverValveTLDisconnect.Value == 0 then
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",1)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",1)
|
||||
else
|
||||
self.DriverValveBLDisconnect:TriggerInput("Set",0)
|
||||
self.DriverValveTLDisconnect:TriggerInput("Set",0)
|
||||
end
|
||||
if self.DriverValveBLDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_off","cabin",0.9) end
|
||||
else
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_on","cabin",0.9) end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if button == "DriverValveBLDisconnectToggle" then
|
||||
if self.DriverValveBLDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_off","cabin",0.9) end
|
||||
else
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_on","cabin",0.9) end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Special logic
|
||||
if (button == "VDL") or (button == "KDL") or (button == "KDP") then
|
||||
--self.VUD1:TriggerInput("Open",1)
|
||||
end
|
||||
if (button == "KDP") then
|
||||
--self.DoorSelect:TriggerInput("Close",1)
|
||||
end
|
||||
if (button == "VUD1Set") or (button == "VUD1Toggle") or
|
||||
(button == "VUD2Set") or (button == "VUD2Toggle") then
|
||||
self.VDL:TriggerInput("Open",1)
|
||||
self.KDL:TriggerInput("Open",1)
|
||||
self.KDP:TriggerInput("Open",1)
|
||||
end
|
||||
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if (button == "UAVAToggle") then
|
||||
if self.UAVA then
|
||||
if self.UAVA.Value > 0.5 then
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
else
|
||||
self:PlayOnce("uava_off","cabin")
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if button == "EPKToggle" and self.DriverValveBLDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 0.0 then
|
||||
self:PlayOnce("epv_off","cabin",0.9)
|
||||
else
|
||||
self:PlayOnce("epv_on","cabin",0.9)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnButtonRelease(button)
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
return
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Open",1) end
|
||||
if button == "KDL" and self.VUD1.Value < 1 then self.KDL:TriggerInput("Open",1) self:OnButtonRelease("KDLSet") end
|
||||
if button == "KDP" and self.VUD1.Value < 1 then self.KDP:TriggerInput("Open",1) self:OnButtonRelease("KDPSet") end
|
||||
if button == "VDL" and self.VUD1.Value < 1 then self.VDL:TriggerInput("Open",1) self:OnButtonRelease("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",0)
|
||||
self:OnButtonRelease("KRPSet")
|
||||
end
|
||||
|
||||
--[[
|
||||
if (button == "PneumaticBrakeDown") and (self.Pneumatic.DriverValvePosition == 1) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",2)
|
||||
end
|
||||
if self.Pneumatic.ValveType == 1 then
|
||||
if (button == "PneumaticBrakeUp") and (self.Pneumatic.DriverValvePosition == 5) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",4)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
if (not string.find(button,"KVT")) and string.find(button,"KV") then return end
|
||||
if string.find(button,"KRU") then return end
|
||||
end
|
||||
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
@@ -1,106 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.Ema"
|
||||
ENT.Author = "Oldy"
|
||||
ENT.Contact = "oldy702@gmail.com"
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["relay_close2"] = nil
|
||||
self.SoundNames["rvt_close"] = nil
|
||||
self.SoundNames["r1_5_close"] = nil
|
||||
self.SoundNames["rvt_open"] = nil
|
||||
self.SoundNames["r1_5_open"] = nil
|
||||
--[[self.SoundNames["relay_close4"] = {"subway_trains/new/relay_7.wav","subway_trains/new/lsd_4.wav"}
|
||||
self.SoundNames["pneumo_switch"] = {
|
||||
"subway_trains/pneumo_8.wav",
|
||||
"subway_trains/pneumo_9.wav",
|
||||
}
|
||||
self.SoundNames["rk_spin"] = "subway_trains/rk_3.wav"
|
||||
self.SoundNames["rk_stop"] = "subway_trains/rk_4.wav"
|
||||
]]
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема 81-710
|
||||
self:LoadSystem("Electric","81_704_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_117DM")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A","KF_47A")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_70")
|
||||
-- Контроллер резервного управления
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
self.Pneumatic.ValveType = 1
|
||||
-- Панель управления Е
|
||||
self:LoadSystem("Panel","81_705_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
self:LoadSystem("DURA")
|
||||
self:LoadSystem("ALS_ARS","BARS_Em")
|
||||
self:LoadSystem("Horn")
|
||||
self:LoadSystem("Announcer")
|
||||
|
||||
|
||||
self:LoadSystem("UPO")
|
||||
self:LoadSystem("Autodrive")
|
||||
self:LoadSystem("KSAUP")
|
||||
self:LoadSystem("ADoorDisable","Relay")
|
||||
|
||||
--self:LoadSystem("Custom1","Relay","Switch")
|
||||
--self:LoadSystem("Custom2","Relay","Switch")
|
||||
--self:LoadSystem("Custom3","Relay","Switch")
|
||||
--self:LoadSystem("CustomC","Relay","Switch")
|
||||
--self:LoadSystem("CustomD","Relay","Switch")
|
||||
--self:LoadSystem("CustomE","Relay","Switch")
|
||||
--self:LoadSystem("CustomF","Relay","Switch")
|
||||
--self:LoadSystem("CustomG","Relay","Switch")
|
||||
|
||||
|
||||
end
|
||||
@@ -1,353 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
ENT.ButtonMap["FrontPneumatic"] = {
|
||||
pos = Vector(460.0,-45.0,-50.0),
|
||||
ang = Angle(0,90,90),
|
||||
width = 900,
|
||||
height = 100,
|
||||
scale = 0.1,
|
||||
}
|
||||
ENT.ButtonMap["RearPneumatic"] = {
|
||||
pos = Vector(-483.0,45.0,-50.0),
|
||||
ang = Angle(0,270,90),
|
||||
width = 900,
|
||||
height = 100,
|
||||
scale = 0.1,
|
||||
}
|
||||
ENT.ButtonMap["Test1"] = {
|
||||
pos = Vector(460.0,-15,46.5),
|
||||
ang = Angle(0,90,90),
|
||||
width = 32,
|
||||
height = 96,
|
||||
scale = 1,
|
||||
}
|
||||
ENT.ButtonMap["AirDistributor"] = {
|
||||
pos = Vector(-180,70,-50),
|
||||
ang = Angle(0,180,90),
|
||||
width = 80,
|
||||
height = 40,
|
||||
scale = 0.1,
|
||||
}
|
||||
|
||||
-- Wagon numbers
|
||||
ENT.ButtonMap["TrainNumber1"] = {
|
||||
pos = Vector(30,-67.6,-12),
|
||||
ang = Angle(0,0,90),
|
||||
width = 130,
|
||||
height = 55,
|
||||
scale = 0.20,
|
||||
}
|
||||
ENT.ButtonMap["TrainNumber2"] = {
|
||||
pos = Vector(30+28,67.7,-12),
|
||||
ang = Angle(0,180,90),
|
||||
width = 130,
|
||||
height = 55,
|
||||
scale = 0.20,
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientPropsInitialized = false
|
||||
ENT.ClientProps["train_line"] = {
|
||||
model = "models/metrostroi/81-717/black_arrow.mdl",
|
||||
pos = Vector(447.10,-14.4,58),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
ENT.ClientProps["brake_line"] = {
|
||||
model = "models/metrostroi/81-717/red_arrow.mdl",
|
||||
pos = Vector(447.00,-14.4,58),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
ENT.ClientProps["brake_cylinder"] = {
|
||||
model = "models/metrostroi/81-717/black_arrow.mdl",
|
||||
pos =Vector(447.10,-18.8,57.9),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps["ampermeter"] = {
|
||||
model = "models/metrostroi/81-717/black_arrow.mdl",
|
||||
pos = Vector(447.00,11.0,57.3),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
ENT.ClientProps["voltmeter"] = {
|
||||
model = "models/metrostroi/81-717/black_arrow.mdl",
|
||||
pos = Vector(447.00,15.5,57.3),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
ENT.ClientProps["volt1"] = {
|
||||
model = "models/metrostroi/81-717/black_arrow.mdl",
|
||||
pos = Vector(447.00,-9.7,58),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps["battery"] = {
|
||||
model = "models/metrostroi/81-717/switch01.mdl",
|
||||
pos = Vector(446.0,0.0,55),
|
||||
ang = Angle(90,0,180)
|
||||
}
|
||||
ENT.ClientProps["gv"] = {
|
||||
model = "models/metrostroi/81-717/gv.mdl",
|
||||
pos = Vector(154,62.5+1.5,-65),
|
||||
ang = Angle(-90,0,-90)
|
||||
}
|
||||
ENT.ClientProps["gv_wrench"] = {
|
||||
model = "models/metrostroi/81-717/reverser.mdl",
|
||||
pos = Vector(154,62.5+1.5,-65),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
--[[for x=0,11 do
|
||||
for y=0,3 do
|
||||
ENT.ClientProps["a"..(x+12*y)] = {
|
||||
model = "models/metrostroi/81-717/circuit_breaker.mdl",
|
||||
pos = Vector(393.8,-52.5+x*2.75,37.5-y*8),
|
||||
ang = Angle(90,0,0)
|
||||
}
|
||||
end
|
||||
end]]--
|
||||
--[[Metrostroi.ClientPropForButton("battery",{
|
||||
panel = "Battery",
|
||||
button = "VBToggle",
|
||||
model = "models/metrostroi/81-717/switch01.mdl",
|
||||
z = -10.7,
|
||||
})]]--
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Add doors
|
||||
local function GetDoorPosition(i,k,j)
|
||||
if j == 0
|
||||
then return Vector(351.0 - 34*k - 231*i,-65*(1-2*k),-2.8)
|
||||
else return Vector(351.0 - 34*(1-k) - 231*i,-65*(1-2*k),-2.8)
|
||||
end
|
||||
end
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
ENT.ClientProps["door"..i.."x"..k.."a"] = {
|
||||
model = "models/metrostroi/e/em508_door1.mdl",
|
||||
pos = GetDoorPosition(i,k,0),
|
||||
ang = Angle(0,180*k,0)
|
||||
}
|
||||
ENT.ClientProps["door"..i.."x"..k.."b"] = {
|
||||
model = "models/metrostroi/e/em508_door2.mdl",
|
||||
pos = GetDoorPosition(i,k,1),
|
||||
ang = Angle(0,180*k,0)
|
||||
}
|
||||
end
|
||||
end
|
||||
ENT.ClientProps["door1"] = {
|
||||
model = "models/metrostroi/e/em508_door5.mdl",
|
||||
pos = Vector(455.5,0.5,-5),
|
||||
ang = Angle(0,0,0)
|
||||
}
|
||||
ENT.ClientProps["door2"] = {
|
||||
model = "models/metrostroi/e/em508_door5.mdl",
|
||||
pos = Vector(-479.5,.0,-5),
|
||||
ang = Angle(0,180,0)
|
||||
}
|
||||
|
||||
|
||||
ENT.FrontDoor = 0
|
||||
ENT.RearDoor = 0
|
||||
ENT.PassengerDoor = 0
|
||||
ENT.CabinDoor = 0
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self:GetNW2String("texture")]
|
||||
local passtexture = Metrostroi.Skins["pass"][self:GetNW2String("passtexture")]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self:GetNW2String("cabtexture")]
|
||||
for _,ent in pairs(self.ClientEnts) do
|
||||
if not IsValid(ent) then continue end
|
||||
for k,v in pairs(ent:GetMaterials()) do
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
ent:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
ent:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
ent:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
if self.Texture ~= self:GetNW2String("texture") then
|
||||
self.Texture = self:GetNW2String("texture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
if self.PassTexture ~= self:GetNW2String("passtexture") then
|
||||
self.PassTexture = self:GetNW2String("passtexture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
if self.CabinTexture ~= self:GetNW2String("cabtexture") then
|
||||
self.CabinTexture = self:GetNW2String("cabtexture")
|
||||
self:UpdateTextures()
|
||||
end
|
||||
|
||||
if self.RearDoor < 90 and self:GetPackedBool(156) or self.RearDoor > 0 and not self:GetPackedBool(156) then
|
||||
local RearDoorData = self.ClientProps["door2"]
|
||||
--RearDoor:SetLocalPos(RearDoorData.pos + Vector(-2,-0,0))
|
||||
self.RearDoor = math.max(0,math.min(90,self.RearDoor + (self:GetPackedBool(156) and 1 or -1)*self.DeltaTime*180))
|
||||
end
|
||||
if not self.ClientPropsMatrix["door2"] or self.ClientPropsMatrix["door2"]:GetAngles().yaw ~= self.RearDoor then
|
||||
self:ApplyMatrix("door2",Vector(0,-16,0),Angle(0,self.RearDoor,0))
|
||||
end
|
||||
if self.FrontDoor < 90 and self:GetPackedBool(157) or self.FrontDoor > 0 and not self:GetPackedBool(157) then
|
||||
local FrontDoorData = self.ClientProps["door1"]
|
||||
--FrontDoor:SetLocalPos(FrontDoorData.pos + Vector(-2,-0,0))
|
||||
self.FrontDoor = math.max(0,math.min(90,self.FrontDoor + (self:GetPackedBool(157) and 1 or -1)*self.DeltaTime*180))
|
||||
self:ApplyMatrix("door1",Vector(0,-16,0),Angle(0,self.FrontDoor,0))
|
||||
end
|
||||
if not self.ClientPropsMatrix["door1"] or self.ClientPropsMatrix["door1"]:GetAngles().yaw ~= self.FrontDoor then
|
||||
self:ApplyMatrix("door1",Vector(0,-16,0),Angle(0,self.FrontDoor,0))
|
||||
end
|
||||
local transient = (self.Transient or 0)*0.05
|
||||
if (self.Transient or 0) ~= 0.0 then self.Transient = 0.0 end
|
||||
|
||||
-- Simulate pressure gauges getting stuck a little
|
||||
--self:Animate("brake", self:GetPackedRatio(0)^0.5, 0.00, 0.65, 256,24)
|
||||
--self:Animate("controller", self:GetPackedRatio(1), 0.30, 0.70, 384,24)
|
||||
--self:Animate("reverser", 1-self:GetPackedRatio(2), 0.25, 0.75, 4,false)
|
||||
self:Animate("volt1", self:GetPackedRatio(10), 0.38,0.64)
|
||||
--self:ShowHide("reverser", self:GetPackedBool(0))
|
||||
|
||||
self:Animate("brake_line", self:GetPackedRatio(4), 0.16, 0.84, 256)--,,2,0.01)
|
||||
self:Animate("train_line", self:GetPackedRatio(5)-transient, 0.16, 0.84, 256)--,,2,0.01)
|
||||
self:Animate("brake_cylinder", self:GetPackedRatio(6), 0.17, 0.86, 256)--,,2,0.03)
|
||||
self:Animate("voltmeter", self:GetPackedRatio(7), 0.38, 0.63)
|
||||
self:Animate("ampermeter", self:GetPackedRatio(8), 0.38, 0.63)
|
||||
--self:Animate("volt2", 0, 0.38, 0.63)
|
||||
|
||||
self:Animate("battery", self:GetPackedBool(7) and 1 or 0, 0,1, 16, false)
|
||||
|
||||
-- Animate AV switches
|
||||
for i,v in ipairs(self.Panel.AVMap) do
|
||||
local value = self:GetPackedBool(64+(i-1)) and 1 or 0
|
||||
self:Animate("a"..(i-1),value,0,1,8,false)
|
||||
end
|
||||
|
||||
-- Main switch
|
||||
if self.LastValue ~= self:GetPackedBool(5) then
|
||||
self.ResetTime = CurTime()+2.0
|
||||
self.LastValue = self:GetPackedBool(5)
|
||||
end
|
||||
self:Animate("gv_wrench", (self:GetPackedBool(5) and 1 or 0), 0,0.51, 128, 1,false)
|
||||
self:ShowHide("gv_wrench", CurTime() < self.ResetTime)
|
||||
|
||||
-- Animate doors
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
local n_l = "door"..i.."x"..k.."a"
|
||||
local n_r = "door"..i.."x"..k.."b"
|
||||
local animation = self:Animate(n_l,self:GetPackedBool(21+i+4-k*4) and 1 or 0,0,1, 0.8 + (-0.2+0.4*math.random()),0)
|
||||
local offset_l = Vector(math.abs(31*animation),0,0)
|
||||
local offset_r = Vector(math.abs(32*animation),0,0)
|
||||
if self.ClientEnts[n_l] then
|
||||
self.ClientEnts[n_l]:SetPos(self:LocalToWorld(self.ClientProps[n_l].pos + (1.0 - 2.0*k)*offset_l))
|
||||
self.ClientEnts[n_l]:SetSkin(self:GetSkin())
|
||||
end
|
||||
if self.ClientEnts[n_r] then
|
||||
self.ClientEnts[n_r]:SetPos(self:LocalToWorld(self.ClientProps[n_r].pos - (1.0 - 2.0*k)*offset_r))
|
||||
self.ClientEnts[n_r]:SetSkin(self:GetSkin())
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.ClientEnts["door1"] then self.ClientEnts["door1"]:SetSkin(self:GetSkin()) end
|
||||
if self.ClientEnts["door2"] then self.ClientEnts["door2"]:SetSkin(self:GetSkin()) end
|
||||
|
||||
|
||||
-- Brake-related sounds
|
||||
local brakeLinedPdT = self:GetPackedRatio(9)
|
||||
local dT = self.DeltaTime
|
||||
self.BrakeLineRamp1 = self.BrakeLineRamp1 or 0
|
||||
|
||||
if (brakeLinedPdT > -0.001)
|
||||
then self.BrakeLineRamp1 = self.BrakeLineRamp1 + 4.0*(0-self.BrakeLineRamp1)*dT
|
||||
else self.BrakeLineRamp1 = self.BrakeLineRamp1 + 4.0*((-0.6*brakeLinedPdT)-self.BrakeLineRamp1)*dT
|
||||
end
|
||||
self.BrakeLineRamp1 = math.Clamp(self.BrakeLineRamp1,0,1)
|
||||
self:SetSoundState("release2_w",self.BrakeLineRamp1^1.65,1.0)
|
||||
|
||||
self.BrakeLineRamp2 = self.BrakeLineRamp2 or 0
|
||||
if (brakeLinedPdT < 0.001)
|
||||
then self.BrakeLineRamp2 = self.BrakeLineRamp2 + 4.0*(0-self.BrakeLineRamp2)*dT
|
||||
else self.BrakeLineRamp2 = self.BrakeLineRamp2 + 8.0*(0.1*brakeLinedPdT-self.BrakeLineRamp2)*dT
|
||||
end
|
||||
self.BrakeLineRamp2 = math.Clamp(self.BrakeLineRamp2,0,1)
|
||||
self:SetSoundState("release3_w",self.BrakeLineRamp2 + math.max(0,self.BrakeLineRamp1/2-0.15),1.0)
|
||||
|
||||
self:SetSoundState("cran1_w",math.min(1,self:GetPackedRatio(4)/50*(self:GetPackedBool(6) and 1 or 0)),1.0)
|
||||
|
||||
-- Compressor
|
||||
local state = self:GetPackedBool(20)
|
||||
self.PreviousCompressorState = self.PreviousCompressorState or false
|
||||
if self.PreviousCompressorState ~= state then
|
||||
self.PreviousCompressorState = state
|
||||
if state then
|
||||
self:SetSoundState("compressor_ezh",1,1)
|
||||
else
|
||||
self:SetSoundState("compressor_ezh",0,1)
|
||||
self:SetSoundState("compressor_ezh_end",0,1)
|
||||
self:SetSoundState("compressor_ezh_end",1,1)
|
||||
--self:PlayOnce("compressor_e_end",nil,1,nil,true)
|
||||
end
|
||||
end
|
||||
|
||||
-- RK rotation
|
||||
if self:GetPackedBool(112) then self.RKTimer = CurTime() end
|
||||
local state = (CurTime() - (self.RKTimer or 0)) < 0.2
|
||||
self.PreviousRKState = self.PreviousRKState or false
|
||||
if self.PreviousRKState ~= state then
|
||||
self.PreviousRKState = state
|
||||
if state then
|
||||
self:SetSoundState("rk_spin",0.7,1,nil,0.75)
|
||||
else
|
||||
self:SetSoundState("rk_spin",0,0,nil,0.75)
|
||||
self:SetSoundState("rk_stop",0,1,nil,0.75)
|
||||
self:SetSoundState("rk_stop",0.7,1,nil,0.75)
|
||||
end
|
||||
end
|
||||
|
||||
-- DIP sound
|
||||
--self:SetSoundState("bpsn1",self:GetPackedBool(52) and 1 or 0,1.0)
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
|
||||
function ENT:DrawPost()
|
||||
self:DrawOnPanel("FrontPneumatic",function()
|
||||
draw.DrawText(self:GetNW2Bool("FbI") and "Isolated" or "Open","Trebuchet24",150,30,Color(0,0,0,255))
|
||||
draw.DrawText(self:GetNW2Bool("FtI") and "Isolated" or "Open","Trebuchet24",650,30,Color(0,0,0,255))
|
||||
draw.DrawText(self:GetPackedBool(160) and "Brake" or "Released","Trebuchet24",950,30,Color(0,0,0,255))
|
||||
end)
|
||||
self:DrawOnPanel("RearPneumatic",function()
|
||||
draw.DrawText(self:GetNW2Bool("RbI") and "Isolated" or "Open","Trebuchet24",150,30,Color(0,0,0,255))
|
||||
draw.DrawText(self:GetNW2Bool("RtI") and "Isolated" or "Open","Trebuchet24",650,30,Color(0,0,0,255))
|
||||
end)
|
||||
self:DrawOnPanel("AirDistributor",function()
|
||||
draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255))
|
||||
end)
|
||||
|
||||
self:DrawOnPanel("AirDistributor",function()
|
||||
draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255))
|
||||
end)
|
||||
-- Draw train numbers
|
||||
local dc = render.GetLightColor(self:GetPos())
|
||||
self:DrawOnPanel("TrainNumber1",function()
|
||||
draw.DrawText(Format("%04d",self:EntIndex()),"MetrostroiSubway_LargeText3",0,0,Color(255*dc.x,255*dc.y,255*dc.z,255))
|
||||
end)
|
||||
self:DrawOnPanel("TrainNumber2",function()
|
||||
draw.DrawText(Format("%04d",self:EntIndex()),"MetrostroiSubway_LargeText3",0,0,Color(255*dc.x,255*dc.y,255*dc.z,255))
|
||||
end)
|
||||
--render.DrawLine( self:LocalToWorld(self.ClientProps["door1"].pos - Vector(0,16,0)), self:LocalToWorld(self.ClientProps["door1"].pos + Vector(0,16,0)), Color(0,0,255), false)
|
||||
end
|
||||
@@ -1,347 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Em508T",
|
||||
Manufacturer = "MVM",
|
||||
WagType = 2,
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi/81/ema508t.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 325-20,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-325-10,0,-80),Angle(0,0,0),false)
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(458,-30,-55),
|
||||
Radius = 16,
|
||||
ID = "FrontBrakeLineIsolationToggle" },
|
||||
{ Pos = Vector(458, 30,-55),
|
||||
Radius = 16,
|
||||
ID = "FrontTrainLineIsolationToggle" },
|
||||
{ Pos = Vector(458, 60,-55),
|
||||
Radius = 16,
|
||||
ID = "ParkingBrakeToggle" },
|
||||
{ Pos = Vector(-482,30,-55),
|
||||
Radius = 16,
|
||||
ID = "RearBrakeLineIsolationToggle" },
|
||||
{ Pos = Vector(-482, -30,-55),
|
||||
Radius = 16,
|
||||
ID = "RearTrainLineIsolationToggle" },
|
||||
{ Pos = Vector(154,62.5,-65),
|
||||
Radius = 16,
|
||||
ID = "GVToggle" },
|
||||
{ Pos = Vector(446.0,0.0,50),
|
||||
Radius = 16,
|
||||
ID = "VBToggle" },
|
||||
{ Pos = Vector(-180,68.5,-50),
|
||||
Radius = 20,
|
||||
ID = "AirDistributorDisconnectToggle" },
|
||||
{ Pos = Vector(-482,-38,-1),
|
||||
Radius = 24,
|
||||
ID = "RearDoor" },
|
||||
{ Pos = Vector(458,38,-1),
|
||||
Radius = 24,
|
||||
ID = "FrontDoor" },
|
||||
}
|
||||
|
||||
-- Lights
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[1] = { "headlight", Vector(465,0,-20), Angle(0,0,0), Color(176,161,132), fov = 100 },
|
||||
[2] = { "glow", Vector(460, 51,-23), Angle(0,0,0), Color(255,255,255), brightness = 2 },
|
||||
[3] = { "glow", Vector(460,-51,-23), Angle(0,0,0), Color(255,255,255), brightness = 2 },
|
||||
[4] = { "glow", Vector(460,-8, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[5] = { "glow", Vector(460,-8, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[6] = { "glow", Vector(460, 2, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
[7] = { "glow", Vector(460, 2, 55), Angle(0,0,0), Color(255,255,255), brightness = 0.3 },
|
||||
|
||||
-- Reverse
|
||||
[8] = { "light", Vector(458,-45, 55), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
[9] = { "light", Vector(458, 45, 55), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
|
||||
-- Cabin
|
||||
[10] = { "dynamiclight", Vector( 420, 0, 35), Angle(0,0,0), Color(255,255,255), brightness = 0.1, distance = 550 },
|
||||
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
[13] = { "dynamiclight", Vector(-250, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
|
||||
-- Side lights
|
||||
[14] = { "light", Vector(-50, 68, 51.9), Angle(0,0,0), Color(255,0,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[15] = { "light", Vector(6, 68, 51.9), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[16] = { "light", Vector(3, 68, 51.9), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[17] = { "light", Vector(-0, 68, 51.9), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[18] = { "light", Vector(-50, -69, 51.9), Angle(0,0,0), Color(255,0,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[19] = { "light", Vector(6, -69, 51.9), Angle(0,0,0), Color(150,255,255), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[20] = { "light", Vector(3, -69, 51.9), Angle(0,0,0), Color(50,255,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[21] = { "light", Vector(-0, -69, 51.9), Angle(0,0,0), Color(255,255,0), brightness = 0.9, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
-- Green RP
|
||||
[22] = { "light", Vector(439.4,12.5-9.6,-5.7), Angle(0,0,0), Color(100,255,0), brightness = 1.0, scale = 0.020 },
|
||||
-- AVU
|
||||
[23] = { "light", Vector(441.2,12.5-20.3,-3.7), Angle(0,0,0), Color(255,40,0), brightness = 1.0, scale = 0.020 },
|
||||
-- LKTP
|
||||
[24] = { "light", Vector(441.2,12.5-23.0,-3.7), Angle(0,0,0), Color(255,40,0), brightness = 1.0, scale = 0.020 },
|
||||
}
|
||||
|
||||
for i = 1,23 do
|
||||
self.Lights[69+i] = { "light", Vector(-470 + 35*i, 0, 65), Angle(180,0,0), Color(255,220,180), brightness = 0.25, scale = 0.75}
|
||||
--self:SetLightPower(69+i,RealTime()%1*2>1)
|
||||
end
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self:UpdateTextures()
|
||||
end
|
||||
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
|
||||
end
|
||||
self:SetNW2String("texture",self.Texture)
|
||||
self:SetNW2String("passtexture",self.PassTexture)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
local retVal = self.BaseClass.Think(self)
|
||||
|
||||
self.Electric:TriggerInput("TrainMode",1)
|
||||
|
||||
-- Interior/cabin lights
|
||||
-- self:SetLightPower(10, (self.Panel["CabinLight"] > 0.5))
|
||||
--self:SetLightPower(12, self.PowerSupply.XT3_4 > 65.0)
|
||||
-- self:SetLightPower(13, self.PowerSupply.XT3_4 > 65.0)
|
||||
self:SetLightPower(11, self.PowerSupply.XT3_4 > 65.0, 0.8)
|
||||
self:SetLightPower(12, self.Panel["EmergencyLight"] > 0.5,0.1 + ((self.PowerSupply.XT3_4 > 65.0) and 0.7 or 0))
|
||||
self:SetLightPower(13, self.PowerSupply.XT3_4 > 65.0, 0.8)
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = self.Panel["EmergencyLight"] > 0.5
|
||||
self:SetLightPower(11, lightsActive2, 0.8)
|
||||
self:SetLightPower(12, lightsActive1,0.1 + ((self.PowerSupply.XT3_4 > 65.0) and 0.7 or 0))
|
||||
self:SetLightPower(13, lightsActive2, 0.8)
|
||||
for i = 1,23 do
|
||||
self:SetLightPower(69+i,lightsActive2 and true or lightsActive1 and i%5==1 or false)
|
||||
end
|
||||
|
||||
-- Side lights
|
||||
self:SetLightPower(15, self.Panel["TrainDoors"] > 0.5)
|
||||
self:SetLightPower(19, self.Panel["TrainDoors"] > 0.5)
|
||||
self:SetLightPower(16, (self.Panel["GreenRP"] or 0) > 0.5)
|
||||
self:SetLightPower(20, (self.Panel["GreenRP"] or 0) > 0.5)
|
||||
self:SetLightPower(17, self.Panel["TrainBrakes"] > 0.5)
|
||||
self:SetLightPower(21, self.Panel["TrainBrakes"] > 0.5)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
self:SetPackedBool(5,self.GV.Value == 1.0)
|
||||
self:SetPackedBool(7,self.VB.Value == 1.0)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
self:SetPackedBool(22,self.Pneumatic.LeftDoorState[2] > 0.5)
|
||||
self:SetPackedBool(23,self.Pneumatic.LeftDoorState[3] > 0.5)
|
||||
self:SetPackedBool(24,self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
self:SetPackedBool(26,self.Pneumatic.RightDoorState[2] > 0.5)
|
||||
self:SetPackedBool(27,self.Pneumatic.RightDoorState[3] > 0.5)
|
||||
self:SetPackedBool(28,self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
|
||||
self:SetPackedBool(160,self.ParkingBrake)
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
|
||||
-- BPSN
|
||||
self:SetPackedBool(52,self.PowerSupply.XT3_1 > 0)
|
||||
|
||||
-- AV states
|
||||
for i,v in ipairs(self.Panel.AVMap) do
|
||||
if tonumber(v) then
|
||||
if self["A"..v].Value < 1 then
|
||||
self["A"..v]:TriggerInput("Set",1)
|
||||
end
|
||||
self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
elseif self[v] then
|
||||
if self[v].Value < 1 then
|
||||
self[v]:TriggerInput("Set",1)
|
||||
end
|
||||
self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
end
|
||||
end
|
||||
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/5)
|
||||
--self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
--self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.ReservoirPressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, self.Pneumatic.BrakeCylinderPressure/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, math.abs(self.Electric.I24)/1000.0)
|
||||
--self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
--self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 100.0)
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = self.ParkingBrake.Value > 0.5
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
--self.RearBogey.ParkingBrake = self.ParkingBrake.Value > 0.5
|
||||
end
|
||||
|
||||
return retVal
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
if button == "AirDistributorDisconnectToggle" then return end
|
||||
if button == "VBToggle" then
|
||||
if self.VB.Value == 1 then
|
||||
self:PlayOnce("vu22_on",nil)
|
||||
else
|
||||
self:PlayOnce("vu22_off",nil)
|
||||
end
|
||||
return
|
||||
end
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Generic button or switch sound
|
||||
if string.find(button,"Set") then
|
||||
self:PlayOnce("switch")
|
||||
end
|
||||
if string.find(button,"Toggle") then
|
||||
self:PlayOnce("switch2")
|
||||
end
|
||||
if button == "FrontDoor" then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button == "RearDoor" then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
end
|
||||
@@ -1,82 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.Em508T"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["rvt_close"] = "subway_trains/sbor.wav"
|
||||
self.SoundNames["r1_5_close"] = "subway_trains/sbor_hod.wav"
|
||||
self.SoundNames["rvt_open"] = "subway_trains/rasbor_t.wav"
|
||||
self.SoundNames["r1_5_open"] = "subway_trains/razbor_hod.wav"
|
||||
self.SoundNames["rk_spin"] = "subway_trains/rk_3.wav"
|
||||
self.SoundNames["rk_stop"] = "subway_trains/rk_4.wav"
|
||||
self.SoundNames["switch_off"] = {"subway_trains/tumbler_1_off.wav","subway_trains/tumbler_2_off.wav","subway_trains/tumbler_3_off.wav"}
|
||||
self.SoundNames["switch_on"] = {"subway_trains/tumbler_1_on.wav","subway_trains/tumbler_2_on.wav","subway_trains/tumbler_3_on.wav"}
|
||||
self.SoundNames["av_on"] = {
|
||||
"subway_trains/va21_2_1_on.wav",
|
||||
"subway_trains/va21_2_2_on.wav",
|
||||
}
|
||||
self.SoundNames["av_off"] = {
|
||||
"subway_trains/va21_2_1_off.wav",
|
||||
"subway_trains/va21_2_2_off.wav",
|
||||
}
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема 81-710
|
||||
self:LoadSystem("Electric","81_705_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_117DM")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
-- Пульт маневрнового передвижения
|
||||
self:LoadSystem("PMP","PMP")
|
||||
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
|
||||
-- Панель управления 81-710
|
||||
self:LoadSystem("Panel","81_710_Panel")
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
self:LoadSystem("Announcer")
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,979 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "E",
|
||||
Name = "Ezh3",
|
||||
Manufacturer = "MVM",
|
||||
WagType = 0,
|
||||
ARS = {
|
||||
HaveASNP = true,
|
||||
}
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi/e/em508.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(418,-45,-28+4))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(430,40,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat1 = self:CreateSeat("instructor",Vector(443,0,-48+6+2.5),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
self.ExtraSeat2 = self:CreateSeat("instructor",Vector(420,-20,-48+6),Angle(0,90,0),"models/vehicles/prisoner_pod_inner.mdl")
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.InstructorsSeat:SetColor(Color(0,0,0,0))
|
||||
self.InstructorsSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
self.ExtraSeat1:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat1:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.ExtraSeat2:SetColor(Color(0,0,0,0))
|
||||
self.ExtraSeat2:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 325-10,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-325-10,0,-80),Angle(0,0,0),false)
|
||||
local pneumoPow = 0.8+(math.random()^0.4)*0.3
|
||||
self.FrontBogey.PneumaticPow = pneumoPow
|
||||
self.RearBogey.PneumaticPow = pneumoPow
|
||||
|
||||
-- Initialize key mapping
|
||||
self.KeyMap = {
|
||||
[KEY_1] = "KVSetX1",
|
||||
[KEY_2] = "KVSetX2",
|
||||
[KEY_3] = "KVSetX3",
|
||||
[KEY_4] = "KVSet0",
|
||||
[KEY_5] = "KVSetT1",
|
||||
[KEY_6] = "KVSetT1AB",
|
||||
[KEY_7] = "KVSetT2",
|
||||
[KEY_8] = "KRP",
|
||||
|
||||
[KEY_EQUAL] = "R_Program1Set",
|
||||
[KEY_MINUS] = "R_Program2Set",
|
||||
|
||||
[KEY_G] = "VozvratRPSet",
|
||||
|
||||
[KEY_0] = "KVReverserUp",
|
||||
[KEY_9] = "KVReverserDown",
|
||||
[KEY_PAD_PLUS] = "KVReverserUp",
|
||||
[KEY_PAD_MINUS] = "KVReverserDown",
|
||||
[KEY_W] = "KVUp",
|
||||
[KEY_S] = "KVDown",
|
||||
[KEY_F] = "PneumaticBrakeUp",
|
||||
[KEY_R] = "PneumaticBrakeDown",
|
||||
|
||||
[KEY_A] = "KDL",
|
||||
[KEY_D] = "KDP",
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "HornEngage",
|
||||
[KEY_N] = "VZ1Set",
|
||||
[KEY_PAD_1] = "PneumaticBrakeSet1",
|
||||
[KEY_PAD_2] = "PneumaticBrakeSet2",
|
||||
[KEY_PAD_3] = "PneumaticBrakeSet3",
|
||||
[KEY_PAD_4] = "PneumaticBrakeSet4",
|
||||
[KEY_PAD_5] = "PneumaticBrakeSet5",
|
||||
[KEY_PAD_6] = "PneumaticBrakeSet6",
|
||||
[KEY_PAD_7] = "PneumaticBrakeSet7",
|
||||
[KEY_PAD_DIVIDE] = "KRPSet",
|
||||
[KEY_PAD_MULTIPLY] = "KAHSet",
|
||||
|
||||
[KEY_SPACE] = "PBSet",
|
||||
[KEY_BACKSPACE] = "EmergencyBrake",
|
||||
|
||||
[KEY_PAD_0] = "DriverValveDisconnectToggle",
|
||||
[KEY_PAD_DECIMAL] = "EPKToggle",
|
||||
[KEY_LSHIFT] = {
|
||||
[KEY_W] = "KVUp_Unlocked",
|
||||
[KEY_SPACE] = "KVTSet",
|
||||
[KEY_F] = "BCCDSet",
|
||||
[KEY_R] = "VZPSet",
|
||||
|
||||
[KEY_A] = "DURASelectAlternate",
|
||||
[KEY_D] = "DURASelectMain",
|
||||
[KEY_V] = "DURAToggleChannel",
|
||||
[KEY_1] = "DIPonSet",
|
||||
[KEY_2] = "DIPoffSet",
|
||||
[KEY_4] = "KVSet0Fast",
|
||||
[KEY_L] = "DriverValveDisconnectToggle",
|
||||
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_6] = "KVSetT1A",
|
||||
|
||||
[KEY_PAD_7] = "BFSet",
|
||||
[KEY_PAD_8] = "BUpSet",
|
||||
[KEY_PAD_9] = "BMSet",
|
||||
[KEY_PAD_4] = "BLeftSet",
|
||||
[KEY_PAD_5] = "BDownSet",
|
||||
[KEY_PAD_6] = "BRightSet",
|
||||
[KEY_PAD_ENTER] = "BPSet",
|
||||
},
|
||||
|
||||
[KEY_RSHIFT] = {
|
||||
[KEY_7] = "KVWrenchNone",
|
||||
[KEY_8] = "KVWrenchKRU",
|
||||
[KEY_9] = "KVWrenchKV",
|
||||
[KEY_0] = "KVWrench0",
|
||||
[KEY_L] = "DriverValveDisconnectToggle",
|
||||
|
||||
},
|
||||
[KEY_LALT] = {
|
||||
[KEY_V] = "VUD1Toggle",
|
||||
[KEY_L] = "EPKToggle",
|
||||
[KEY_PAD_PLUS] = "Custom2Set",
|
||||
[KEY_PAD_MINUS] = "Custom1Set",
|
||||
[KEY_PAD_ENTER] = "Custom3Set",
|
||||
[KEY_PAD_ENTER] = "Custom3Set",
|
||||
[KEY_PAD_MULTIPLY] = "CustomCToggle",
|
||||
},
|
||||
[KEY_RALT] = {
|
||||
[KEY_L] = "EPKToggle",
|
||||
},
|
||||
}
|
||||
|
||||
self.InteractionZones = {
|
||||
{ Pos = Vector(458,-30,-55),
|
||||
Radius = 32,
|
||||
ID = "FrontBrakeLineIsolationToggle" },
|
||||
{ Pos = Vector(458, 30,-55),
|
||||
Radius = 32,
|
||||
ID = "FrontTrainLineIsolationToggle" },
|
||||
{ Pos = Vector(-482,30,-55),
|
||||
Radius = 32,
|
||||
ID = "RearBrakeLineIsolationToggle" },
|
||||
{ Pos = Vector(-482, -30,-55),
|
||||
Radius = 32,
|
||||
ID = "RearTrainLineIsolationToggle" },
|
||||
{ Pos = Vector(154,62.5,-65),
|
||||
Radius = 32,
|
||||
ID = "GVToggle" },
|
||||
{ Pos = Vector(393.6,26.0+4.6*1,24.9),
|
||||
Radius = 8,
|
||||
ID = "VBToggle" },
|
||||
{ Pos = Vector(-180,68.5,-50),
|
||||
Radius = 20,
|
||||
ID = "AirDistributorDisconnectToggle" },
|
||||
{ Pos = Vector(-470,-38,9),
|
||||
Radius = 28,
|
||||
ID = "RearDoor" },
|
||||
{ Pos = Vector(450,38,9),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor1" },
|
||||
{ Pos = Vector(450,38,-16),
|
||||
Radius = 28,
|
||||
ID = "FrontDoor2" },
|
||||
{ Pos = Vector(382,38,9),
|
||||
Radius = 28,
|
||||
ID = "PassengerDoor" },
|
||||
{ Pos = Vector(445,61,25),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor1" },
|
||||
{ Pos = Vector(445,61,-25),
|
||||
Radius = 16,
|
||||
ID = "CabinDoor2" },
|
||||
{ Pos = Vector(380,67,25),
|
||||
Radius = 28,
|
||||
ID = "CabinDoor3" },
|
||||
{ Pos = Vector(380,67,-25),
|
||||
Radius = 28,
|
||||
ID = "CabinDoor4" },
|
||||
}
|
||||
|
||||
-- Lights
|
||||
self.Lights = {
|
||||
-- Head
|
||||
[1] = { "headlight", Vector(465,0,-20), Angle(0,0,0), Color(216,161,92), fov = 100 },
|
||||
[2] = { "glow", Vector(460, 49,-28), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[3] = { "glow", Vector(460,-49,-28), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 1.0 },
|
||||
[4] = { "glow", Vector(458,-15, 57), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[5] = { "glow", Vector(458,-5, 57), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[6] = { "glow", Vector(458, 5, 57), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
[7] = { "glow", Vector(458, 15, 57), Angle(0,0,0), Color(255,220,180), brightness = 1, scale = 0.5 },
|
||||
|
||||
-- Reverse
|
||||
[8] = { "light", Vector(458,-31, 58), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
[9] = { "light", Vector(458, 31, 58), Angle(0,0,0), Color(255,0,0), brightness = 10, scale = 1.0 },
|
||||
|
||||
-- Cabin
|
||||
[10] = { "dynamiclight", Vector( 420, -40, 35), Angle(0,0,0), Color(255,255,255), brightness = 0.1, distance = 550 },
|
||||
|
||||
-- Interior
|
||||
[11] = { "dynamiclight", Vector( 250, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
[12] = { "dynamiclight", Vector( 0, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
[13] = { "dynamiclight", Vector(-250, 0, 5), Angle(0,0,0), Color(255,255,255), brightness = 3, distance = 400 },
|
||||
|
||||
-- Side lights
|
||||
[14] = { "light", Vector(390, 69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[15] = { "light", Vector(390, 69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[16] = { "light", Vector(390, 69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[17] = { "light", Vector(390, 69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[18] = { "light", Vector(390, -69, 54), Angle(0,0,0), Color(255,0,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[19] = { "light", Vector(390, -69, 51), Angle(0,0,0), Color(150,255,255), brightness = 0.6, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[20] = { "light", Vector(390, -69, 48), Angle(0,0,0), Color(50,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
[21] = { "light", Vector(390, -69, 45), Angle(0,0,0), Color(255,255,0), brightness = 0.5, scale = 0.10, texture = "models/metrostroi_signals/signal_sprite_002.vmt" },
|
||||
|
||||
[30] = { "headlight", Vector(447.8,-34.6,9.6), Angle(0,0,0), Color(255,161,40), farz = 3, nearz = 1, shadows = 0, brightness = 2, fov = 124 },
|
||||
[31] = { "headlight", Vector(449,-32.9,13.5), Angle(0,4,0), Color(237,161,73), farz = 3, nearz = 1, shadows = 0, brightness = 2, fov = 120 },
|
||||
[32] = { "headlight", Vector(445.6,-38.4,0.1), Angle(-65,-5,0), Color(20,161,20), farz = 5, nearz = 1, shadows = 0, brightness = 2, fov = 140 },
|
||||
[33] = { "headlight", Vector(446.5,-57.2,20.4), Angle(-90,0,0), Color(216,161,92), farz = 7.2, nearz = 1, shadows = 0, brightness = 2, fov = 120 },
|
||||
|
||||
-- Custom D
|
||||
[35] = { "light", Vector(447.7,-54.5,17.4-4.4), Angle(0,-0,0), Color(255,0,0), brightness = 1.0, scale = 0.020 },
|
||||
-- Custom E
|
||||
[36] = { "light", Vector(447,-55.5,17.4-4.4), Angle(0,0,0), Color(255,255,255), brightness = 1.0, scale = 0.020 },
|
||||
-- Custom F
|
||||
[37] = { "light", Vector(444.7,-58.5,17.4-4.4), Angle(0,0,0), Color(255,160,0), brightness = 1.0, scale = 0.020 },
|
||||
-- Custom G
|
||||
[38] = { "light", Vector(444,-59.5,17.4-4.4), Angle(0,0,0), Color(100,255,0), brightness = 1.0, scale = 0.020 },
|
||||
[70 ] = { "headlight", Vector( 430, -60, -47), Angle(45,-90,0), Color(255,255,255), brightness = 0.5, distance = 400 , fov=120, shadows = 1 },
|
||||
}
|
||||
|
||||
for i = 1,23 do
|
||||
self.Lights[69+i] = { "light", Vector(-470 + 35*i, 0, 65), Angle(180,0,0), Color(255,220,180), brightness = 0.25, scale = 0.75}
|
||||
--self:SetLightPower(69+i,RealTime()%1*2>1)
|
||||
end
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
[18] = true,
|
||||
[34] = true,
|
||||
}
|
||||
self.TrainWireCrossConnections = {
|
||||
[5] = 4, -- Reverser F<->B
|
||||
[31] = 32, -- Doors L<->R
|
||||
}
|
||||
|
||||
-- Setup door positions
|
||||
self.LeftDoorPositions = {}
|
||||
self.RightDoorPositions = {}
|
||||
for i=0,3 do
|
||||
table.insert(self.LeftDoorPositions,Vector(353.0 - 35*0.5 - 231*i,65,-1.8))
|
||||
table.insert(self.RightDoorPositions,Vector(353.0 - 35*0.5 - 231*i,-65,-1.8))
|
||||
end
|
||||
|
||||
-- KV wrench mode
|
||||
self.KVWrenchMode = 0
|
||||
|
||||
-- Parking brake ratio
|
||||
self.ManualBrake = 0.0
|
||||
self.RearDoor = false
|
||||
self.FrontDoor = false
|
||||
self.CabinDoor = false
|
||||
self.PassengerDoor = false
|
||||
|
||||
self.A5:TriggerInput("Set",0)
|
||||
self:UpdateTextures()
|
||||
end
|
||||
function ENT:UpdateTextures()
|
||||
local texture = Metrostroi.Skins["train"][self.Texture]
|
||||
local passtexture = Metrostroi.Skins["pass"][self.PassTexture]
|
||||
local cabintexture = Metrostroi.Skins["cab"][self.CabTexture]
|
||||
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
self:SetSubMaterial(k-1,"")
|
||||
end
|
||||
for k,v in pairs(self:GetMaterials()) do
|
||||
if v == "models/metrostroi_train/81/int02" then
|
||||
if not Metrostroi.Skins["717_schemes"] or not Metrostroi.Skins["717_schemes"]["m"] then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"][""])
|
||||
else
|
||||
if not self.Adverts or self.Adverts ~= 4 then
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].adv)
|
||||
else
|
||||
self:SetSubMaterial(k-1,Metrostroi.Skins["717_schemes"]["m"].clean)
|
||||
end
|
||||
end
|
||||
end
|
||||
local tex = string.Explode("/",v)
|
||||
tex = tex[#tex]
|
||||
if cabintexture and cabintexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,cabintexture.textures[tex])
|
||||
end
|
||||
if passtexture and passtexture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,passtexture.textures[tex])
|
||||
end
|
||||
if texture and texture.textures[tex] then
|
||||
self:SetSubMaterial(k-1,texture.textures[tex])
|
||||
end
|
||||
end
|
||||
self:SetNW2String("texture",self.Texture)
|
||||
self:SetNW2String("passtexture",self.PassTexture)
|
||||
self:SetNW2String("cabtexture",self.CabTexture)
|
||||
end
|
||||
|
||||
local LK = {}
|
||||
local PKG = 0
|
||||
local RK = 0
|
||||
local KV = 0
|
||||
local OldTime
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
--[[
|
||||
if self.KV.ControllerPosition ~= KV then
|
||||
if KV == 0 then OldTime = nil end
|
||||
if self.KV.ControllerPosition == 0 then OldTime = nil end
|
||||
if not OldTime then print("") end
|
||||
KV = self.KV.ControllerPosition
|
||||
print(Format("Controller moved:%d",KV))
|
||||
end
|
||||
for i=1,5 do
|
||||
if LK[i] ~= self["LK"..i].Value then
|
||||
if not OldTime then OldTime = CurTime() end
|
||||
print(Format("%.2f:LK%d = %d",CurTime()-OldTime,i,self["LK"..i].Value))
|
||||
LK[i] = self["LK"..i].Value
|
||||
end
|
||||
end
|
||||
if RK ~= math.floor(self.RheostatController.Position+0.5) then
|
||||
if not OldTime then OldTime = CurTime() end
|
||||
RK = math.floor(self.RheostatController.Position+0.5)
|
||||
print(Format("%.2f:RK = %d",CurTime()-OldTime,RK))
|
||||
end
|
||||
if PKG ~= math.floor(self.PositionSwitch.Position+0.5) then
|
||||
if not OldTime then OldTime = CurTime() end
|
||||
local nPKG = math.floor(self.PositionSwitch.Position+0.5)
|
||||
print(Format("%.2f:PK = %d->%d",CurTime()-OldTime,PKG,nPKG))
|
||||
PKG = nPKG
|
||||
end
|
||||
]]
|
||||
self.RetVal = self.BaseClass.Think(self)
|
||||
-- Check if wrench was pulled out
|
||||
if self.DriversWrenchPresent then
|
||||
self.KV:TriggerInput("Enabled",self:IsWrenchPresent() and 1 or 0)
|
||||
end
|
||||
self:SetLightPower(1, self.Panel["HeadLights3"] > 0.5,(math.min(1,self.Panel["HeadLights1"])*0.50 +
|
||||
math.min(1,self.Panel["HeadLights2"])*0.25 +
|
||||
math.min(1,self.Panel["HeadLights3"])*0.25)
|
||||
)
|
||||
self:SetLightPower(2, self.Panel["HeadLights3"] > 0.5)
|
||||
self:SetLightPower(3, self.Panel["HeadLights3"] > 0.5)
|
||||
self:SetLightPower(4, self.Panel["HeadLights2"] > 0.5)
|
||||
self:SetLightPower(5, self.Panel["HeadLights1"] > 0.5)
|
||||
self:SetLightPower(6, self.Panel["HeadLights1"] > 0.5)
|
||||
self:SetLightPower(7, self.Panel["HeadLights2"] > 0.5)
|
||||
-- Reverser lights
|
||||
self:SetLightPower(8, self.Panel["RedLightRight"] > 0.5)
|
||||
self:SetLightPower(9, self.Panel["RedLightLeft"] > 0.5)
|
||||
|
||||
-- Interior/cabin lights
|
||||
self:SetLightPower(10, self.Panel["CabinLight"] > 0.5)
|
||||
|
||||
local lightsActive2 = self.PowerSupply.XT3_4 > 65.0
|
||||
local lightsActive1 = self.Panel["EmergencyLight"] > 0.5
|
||||
self:SetLightPower(11, lightsActive2, 0.8)
|
||||
self:SetLightPower(12, lightsActive1,0.1 + ((self.PowerSupply.XT3_4 > 65.0) and 0.7 or 0))
|
||||
self:SetLightPower(13, lightsActive2, 0.8)
|
||||
for i = 1,23 do
|
||||
self:SetLightPower(69+i,lightsActive2 and true or lightsActive1 and i%5==1 or false)
|
||||
end
|
||||
self:SetLightPower(30, (self.L_3.Value > 0.5))
|
||||
self:SetLightPower(31, (self.L_3.Value > 0.5))
|
||||
self:SetLightPower(32, (self.L_3.Value > 0.5))
|
||||
self:SetLightPower(33, (self.L_3.Value > 0.5))
|
||||
--self:SetLightPower(12, self.Panel["EmergencyLight"] > 0.5)
|
||||
--self:SetLightPower(13, self.PowerSupply.XT3_4 > 65.0)
|
||||
|
||||
-- Side lights
|
||||
self:SetLightPower(14, false)
|
||||
self:SetLightPower(18, false)
|
||||
|
||||
self:SetLightPower(15, self.Panel["TrainDoors"] > 0.5)
|
||||
self:SetLightPower(19, self.Panel["TrainDoors"] > 0.5)
|
||||
|
||||
self:SetLightPower(16, self.Panel["GreenRP"] > 0.5)
|
||||
self:SetLightPower(20, self.Panel["GreenRP"] > 0.5)
|
||||
|
||||
self:SetLightPower(17, self.Panel["TrainBrakes"] > 0.5)
|
||||
self:SetLightPower(21, self.Panel["TrainBrakes"] > 0.5)
|
||||
|
||||
-- Total temperature
|
||||
local IGLA_Temperature = math.max(self.Electric.T1,self.Electric.T2)
|
||||
|
||||
-- Switch and button states
|
||||
self:SetPackedBool(0,self:IsWrenchPresent())
|
||||
self:SetPackedBool(1,self.VUS.Value == 1.0)
|
||||
self:SetPackedBool("L_3",self.L_3.Value == 1.0)
|
||||
self:SetPackedBool(2,self.VozvratRP.Value == 1.0)
|
||||
self:SetPackedBool(3,self.DIPon.Value == 1.0)
|
||||
self:SetPackedBool(4,self.DIPoff.Value == 1.0)
|
||||
self:SetPackedBool(5,self.GV.Value == 1.0)
|
||||
self:SetPackedBool(6,self.DriverValveDisconnect.Value == 1.0)
|
||||
self:SetPackedBool(7,self.VB.Value == 1.0)
|
||||
self:SetPackedBool(8,self.RezMK.Value == 1.0)
|
||||
self:SetPackedBool(9,self.VMK.Value == 1.0)
|
||||
self:SetPackedBool(10,self.VAH.Value == 1.0)
|
||||
self:SetPackedBool(11,self.VAD.Value == 1.0)
|
||||
self:SetPackedBool(12,self.VUD1.Value == 0.0)
|
||||
self:SetPackedBool(13,self.VUD2.Value == 1.0)
|
||||
self:SetPackedBool(14,self.VDL.Value == 1.0)
|
||||
self:SetPackedBool(15,self.KDL.Value == 1.0)
|
||||
self:SetPackedBool(16,self.KDP.Value == 1.0)
|
||||
self:SetPackedBool(17,self.KRZD.Value == 1.0)
|
||||
self:SetPackedBool(18,self.KSN.Value == 1.0)
|
||||
self:SetPackedBool(19,self.OtklAVU.Value == 1.0)
|
||||
self:SetPackedBool(20,self.Pneumatic.Compressor == 1.0)
|
||||
self:SetPackedBool(21,self.Pneumatic.LeftDoorState[1] > 0.5)
|
||||
--self:SetPackedBool(22,self.Pneumatic.LeftDoorState[2] > 0.5)
|
||||
--self:SetPackedBool(23,self.Pneumatic.LeftDoorState[3] > 0.5)
|
||||
--self:SetPackedBool(24,self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self:SetPackedBool(24,self.DURA.Power)
|
||||
self:SetPackedBool(25,self.Pneumatic.RightDoorState[1] > 0.5)
|
||||
--self:SetPackedBool(26,self.Pneumatic.RightDoorState[2] > 0.5)
|
||||
--self:SetPackedBool(27,self.Pneumatic.RightDoorState[3] > 0.5)
|
||||
self:SetPackedBool(27,self.KVWrenchMode == 2)
|
||||
--self:SetPackedBool(28,self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:SetPackedBool(28,self.KVT.Value == 1.0)
|
||||
--self:SetPackedBool(156,self.KB.Value == 1.0)
|
||||
self:SetPackedBool(29,self.DURA.SelectAlternate == false)
|
||||
self:SetPackedBool(30,self.DURA.SelectAlternate == true)
|
||||
self:SetPackedBool(31,self.DURA.Channel == 2)
|
||||
self:SetPackedBool(56,self.ARS.Value == 1.0)
|
||||
self:SetPackedBool(57,self.ALS.Value == 1.0)
|
||||
self:SetPackedBool(58,self.Panel["CabinLight"] > 0.5)
|
||||
self:SetPackedBool(112,(self.RheostatController.Velocity ~= 0.0))
|
||||
self:SetPackedBool(114,self.Custom1.Value == 1.0)
|
||||
self:SetPackedBool(115,self.Custom2.Value == 1.0)
|
||||
self:SetPackedBool(116,self.Custom3.Value == 1.0)
|
||||
self:SetPackedBool(124,self.CustomC.Value == 1.0)
|
||||
--[[self:SetPackedBool(117,self.Custom4.Value == 1.0)
|
||||
self:SetPackedBool(118,self.Custom5.Value == 1.0)
|
||||
self:SetPackedBool(119,self.Custom6.Value == 1.0)
|
||||
self:SetPackedBool(120,self.Custom7.Value == 1.0)
|
||||
self:SetPackedBool(121,self.Custom8.Value == 1.0)
|
||||
self:SetPackedBool(122,self.CustomA.Value == 1.0)
|
||||
self:SetPackedBool(124,self.CustomC.Value == 1.0)]]--
|
||||
self:SetLightPower(35,self.CustomD.Value == 1.0)
|
||||
self:SetLightPower(36,self.CustomE.Value == 1.0)
|
||||
self:SetLightPower(37,self.CustomF.Value == 1.0)
|
||||
self:SetLightPower(38,self.CustomG.Value == 1.0)
|
||||
self:SetPackedBool(125,self.R_G.Value == 1.0)
|
||||
self:SetPackedBool(126,self.R_Radio.Value == 1.0)
|
||||
self:SetPackedBool(127,self.R_ZS.Value == 1.0)
|
||||
self:SetPackedBool("R_VPR",self.R_VPR.Value == 1.0)
|
||||
self:SetPackedBool("VPR",self.R_VPR.Value == 1.0 and self.A29.Value == 1.0 and self.Panel["V1"])
|
||||
self:SetPackedBool(128,self.R_Program1.Value == 1.0)
|
||||
self:SetPackedBool(129,self.R_Program2.Value == 1.0)
|
||||
self:SetPackedBool(130,self.RC1.Value == 1.0)
|
||||
self:SetPackedBool(132,self.ManualBrake <= 0.001)
|
||||
self:SetPackedBool(133,self.ManualBrake >= 0.999)
|
||||
self:SetPackedBool(134,self.UOS.Value == 1.0)
|
||||
self:SetPackedBool(135,self.BPS.Value == 1.0)
|
||||
self:SetPackedBool(152,self.UAVA.Value == 1.0)
|
||||
self:SetPackedBool(153,self.DURA.Channel1Alternate)
|
||||
self:SetPackedBool(154,self.DURA.Channel2Alternate)
|
||||
self:SetPackedBool(155,self.EPK.Value == 1.0)
|
||||
self:SetPackedBool(156,self.RearDoor)
|
||||
self:SetPackedBool(157,self.FrontDoor)
|
||||
self:SetPackedBool(158,self.PassengerDoor)
|
||||
self:SetPackedBool(159,self.CabinDoor)
|
||||
|
||||
-- Signal if doors are open or no to platform simulation
|
||||
self.LeftDoorsOpen =
|
||||
(self.Pneumatic.LeftDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.LeftDoorState[4] > 0.5)
|
||||
self.RightDoorsOpen =
|
||||
(self.Pneumatic.RightDoorState[1] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[2] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[3] > 0.5) or
|
||||
(self.Pneumatic.RightDoorState[4] > 0.5)
|
||||
self:WriteTrainWire(35,(self.Pneumatic.BrakeCylinderPressure > 0.1) and 1 or 0)
|
||||
|
||||
-- DIP/power
|
||||
self:SetPackedBool(32,self.Panel["V1"] > 0.5)
|
||||
-- LxRK
|
||||
self:SetPackedBool(33,false)--self.RheostatController.MotorCoilState ~= 0.0)
|
||||
-- NR1
|
||||
self:SetPackedBool(34,(self.NR.Value == 1.0) or (self.RPU.Value == 1.0))
|
||||
-- Red RP
|
||||
local TW18 = self:GetTrainWire18()
|
||||
if self:ReadTrainWire(20) == 0 or (self.Panel["V1"] < 0.5) then TW18 = 0 end--(self.KV.ControllerPositionAutodrive == 0 and self.KV.ControllerPosition == 0)
|
||||
self:SetPackedBool(35,TW18 > 0.5)
|
||||
self:SetPackedBool(131,TW18 > 0)
|
||||
-- Green RP
|
||||
self:SetPackedBool(36,self.Panel["GreenRP"] > 0.5)
|
||||
-- Cabin heating
|
||||
self:SetPackedBool(37,self.Panel["KUP"] > 0.5)
|
||||
-- AVU
|
||||
self:SetPackedBool(38,self.Panel["AVU"] > 0.5)
|
||||
-- Ring
|
||||
self:SetPackedBool(39,self.Panel["Ring"] > 0.5)
|
||||
-- SD
|
||||
self:SetPackedBool(40,self.Panel["SD"] > 0.5)
|
||||
-- OCh
|
||||
self:SetPackedBool(41,self.ALS_ARS.NoFreq)
|
||||
-- 0
|
||||
self:SetPackedBool(42,self.ALS_ARS.Signal0)
|
||||
-- 40
|
||||
self:SetPackedBool(43,self.ALS_ARS.Signal40)
|
||||
-- 60
|
||||
self:SetPackedBool(44,self.ALS_ARS.Signal60)
|
||||
-- 75
|
||||
self:SetPackedBool(45,self.ALS_ARS.Signal70)
|
||||
-- 80
|
||||
self:SetPackedBool(46,self.ALS_ARS.Signal80)
|
||||
-- KT
|
||||
self:SetPackedBool(47,self.ALS_ARS.LKT)
|
||||
-- KVD
|
||||
self:SetPackedBool(48,self.ALS_ARS.LVD)
|
||||
-- LVD
|
||||
self:SetPackedBool(50,self:ReadTrainWire(1) > 0.5)
|
||||
|
||||
-- AV states
|
||||
for i,v in ipairs(self.Panel.AVMap) do
|
||||
if tonumber(v)
|
||||
then self:SetPackedBool(64+(i-1),self["A"..v].Value == 1.0)
|
||||
elseif self[v] then self:SetPackedBool(64+(i-1),self[v].Value == 1.0)
|
||||
end
|
||||
end
|
||||
self.SOSD = self.Panel["SD"] <= 0 and self.Panel["V1"] > 0 and self.KV.ReverserPosition ~= 0
|
||||
self:SetLightPower(70,self.SOSD)
|
||||
|
||||
-- Feed packed floats
|
||||
self:SetPackedRatio(0, 1-self.Pneumatic.DriverValvePosition/7)
|
||||
self:SetPackedRatio(1, (self.KV.ControllerPosition+3)/7)
|
||||
self:SetPackedRatio(2, 1-(self.KV.ReverserPosition+1)/2)
|
||||
self:SetPackedRatio(4, self.Pneumatic.BrakeLinePressure/16.0)
|
||||
self:SetPackedRatio(5, self.Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio(6, (self.Pneumatic.BrakeCylinderPressure + 4.0*self.ManualBrake)/6.0)
|
||||
self:SetPackedRatio(7, self.Electric.Power750V/1000.0)
|
||||
self:SetPackedRatio(8, math.abs(self.Electric.I24)/1000.0)
|
||||
--self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
if self.Pneumatic.TrainLineOpen then
|
||||
self:SetPackedRatio(9, (-self.Pneumatic.TrainLinePressure_dPdT or 0)*6)
|
||||
else
|
||||
self:SetPackedRatio(9, self.Pneumatic.BrakeLinePressure_dPdT or 0)
|
||||
end
|
||||
self:SetPackedRatio(10,(self.Panel["V1"] * self.Battery.Voltage) / 100.0)
|
||||
self:SetPackedRatio(11,IGLA_Temperature)
|
||||
|
||||
-- Update ARS system
|
||||
self:SetPackedRatio(3, self.ALS_ARS.Speed/100.0)
|
||||
if (self.ALS_ARS.Ring == true) then
|
||||
self:SetPackedBool(39,true)
|
||||
end
|
||||
|
||||
-- RUT test
|
||||
local weightRatio = math.max(0,math.min(1,(self:GetNW2Float("PassengerCount")/300)))
|
||||
if math.abs(self:GetAngles().pitch) > 2.5 then weightRatio = weightRatio + 1.00 end
|
||||
self.YAR_13A:TriggerInput("WeightLoadRatio",math.max(0,math.min(1.00,weightRatio)))
|
||||
|
||||
-- Exchange some parameters between engines, pneumatic system, and real world
|
||||
self.Engines:TriggerInput("Speed",self.Speed)
|
||||
if IsValid(self.FrontBogey) and IsValid(self.RearBogey) and not self.IgnoreEngine then
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
self.FrontBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.FrontBogey.Reversed = (self.RKR.Value > 0.5)
|
||||
self.RearBogey.MotorForce = 30300+25000*(A < 0 and 1 or 0)
|
||||
self.RearBogey.Reversed = (self.RKR.Value < 0.5)
|
||||
|
||||
-- These corrections are required to beat source engine friction at very low values of motor power
|
||||
local A = 2*self.Engines.BogeyMoment
|
||||
local P = math.max(0,0.04449 + 1.06879*math.abs(A) - 0.465729*A^2)
|
||||
if math.abs(A) > 0.4 then P = math.abs(A) end
|
||||
if math.abs(A) < 0.05 then P = 0 end
|
||||
if self.Speed < 10 then P = P*(1.0 + 0.5*(10.0-self.Speed)/10.0) end
|
||||
self.RearBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
self.FrontBogey.MotorPower = P*0.5*((A > 0) and 1 or -1)
|
||||
|
||||
-- Apply brakes
|
||||
self.FrontBogey.PneumaticBrakeForce = 50000.0
|
||||
self.FrontBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.FrontBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
self.FrontBogey.ParkingBrake = false
|
||||
self.RearBogey.PneumaticBrakeForce = 50000.0
|
||||
self.RearBogey.BrakeCylinderPressure = self.Pneumatic.BrakeCylinderPressure + 7.0*self.ManualBrake
|
||||
self.RearBogey.BrakeCylinderPressure_dPdT = -self.Pneumatic.BrakeCylinderPressure_dPdT
|
||||
--self.RearBogey.ParkingBrake = self.ManualBrake.Value > 0.5
|
||||
end
|
||||
|
||||
-- Generate bogey sounds
|
||||
local jerk = math.abs((self.Acceleration - (self.PrevAcceleration or 0)) / self.DeltaTime)
|
||||
self.PrevAcceleration = self.Acceleration
|
||||
|
||||
if jerk > (2.0 + self.Speed/15.0) then
|
||||
self.PrevTriggerTime1 = self.PrevTriggerTime1 or CurTime()
|
||||
self.PrevTriggerTime2 = self.PrevTriggerTime2 or CurTime()
|
||||
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime1 > 1.5) then
|
||||
self.PrevTriggerTime1 = CurTime()
|
||||
self.FrontBogey:EmitSound("subway_trains/chassis_"..math.random(1,3)..".wav", 70, math.random(90,110))
|
||||
end
|
||||
if ((math.random() > 0.00) or (jerk > 10)) and (CurTime() - self.PrevTriggerTime2 > 1.5) then
|
||||
self.PrevTriggerTime2 = CurTime()
|
||||
self.RearBogey:EmitSound("subway_trains/chassis_"..math.random(1,3)..".wav", 70, math.random(90,110))
|
||||
end
|
||||
end
|
||||
|
||||
-- Temporary hacks
|
||||
--self:SetNW2Float("V",self.Speed)
|
||||
--self:SetNW2Float("A",self.Acceleration)
|
||||
|
||||
if self:ReadTrainWire(5)*self:ReadTrainWire(4) > 0 and not self.RevCheck then
|
||||
self.RevCheck = CurTime()+0.25
|
||||
end
|
||||
if self.RevCheck and CurTime() - self.RevCheck > 0 then
|
||||
if self:ReadTrainWire(5)*self:ReadTrainWire(4) > 0 then
|
||||
self:TriggerInput("VUOpenBypass")
|
||||
if self.VU.TargetValue == 0 then
|
||||
--self:PlayOnce("av_off","cabin")
|
||||
end
|
||||
end
|
||||
self.RevCheck = nil
|
||||
end
|
||||
return self.RetVal
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:OnButtonPress(button,ply)
|
||||
-- Parking brake
|
||||
if button == "ParkingBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,(self.ManualBrake or 0) - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ParkingBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,(self.ManualBrake or 0) + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",tonumber(button:sub(-1,-1)))
|
||||
return
|
||||
end
|
||||
if button:find("FrontDoor") then
|
||||
self.FrontDoor = not self.FrontDoor
|
||||
if self.FrontDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("RearDoor") then
|
||||
self.RearDoor = not self.RearDoor
|
||||
if self.RearDoor then self:PlayOnce("door_open_tor") else self:PlayOnce("door_close_tor") end
|
||||
end
|
||||
if button:find("PassengerDoor") then
|
||||
self.PassengerDoor = not self.PassengerDoor
|
||||
if self.PassengerDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button:find("CabinDoor") then
|
||||
self.CabinDoor = not self.CabinDoor
|
||||
if self.CabinDoor then self:PlayOnce("door_open_tor","cabin") else self:PlayOnce("door_close_tor","cabin") end
|
||||
end
|
||||
if button == "VAHToggle" then
|
||||
local state = self.VAH.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." VAH!")
|
||||
end
|
||||
if button == "OtklAVUToggle" then
|
||||
local state = self.OtklAVU.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." OtklAVU!")
|
||||
end
|
||||
if button == "VADToggle" then
|
||||
local state = self.VAD.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." VAD!")
|
||||
end
|
||||
if button == "RC1Toggle" then
|
||||
local state = self.RC1.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." RC1!")
|
||||
end
|
||||
if button == "UOSToggle" then
|
||||
local state = self.UOS.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." UOS!")
|
||||
end
|
||||
if button == "UAVAToggle" then
|
||||
local state = self.UAVA.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." UAVA!")
|
||||
end
|
||||
if button == "BPSToggle" then
|
||||
local state = self.BPS.TargetValue < 0.5 and "enabled" or "disabled"
|
||||
RunConsoleCommand("say",ply:GetName().." "..state.." BPS!")
|
||||
end
|
||||
if button == "AirDistributorDisconnectToggle" then return end
|
||||
if button == "NextSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex + 1
|
||||
if self.SignsIndex > #self.SignsList then self.SignsIndex = 1 end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
if button == "PrevSign" then
|
||||
self:PrepareSigns()
|
||||
self.SignsIndex = self.SignsIndex - 1
|
||||
if self.SignsIndex < 1 then self.SignsIndex = #self.SignsList end
|
||||
|
||||
self:SetNW2String("FrontText",self.SignsList[self.SignsIndex][2])
|
||||
end
|
||||
|
||||
if button == "Num1P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num1M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[2])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,2, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2P" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num + 1
|
||||
if num > 9 then num = 0 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
if button == "Num2M" then
|
||||
if not self.RouteNumber then self.RouteNumber = "00" end
|
||||
local num = tonumber(self.RouteNumber[1])
|
||||
num = num - 1
|
||||
if num < 0 then num = 9 end
|
||||
self.RouteNumber = string.SetChar(self.RouteNumber,1, num)
|
||||
self:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
local trn = self.WagonList[#self.WagonList]
|
||||
if IsValid(trn) and trn ~= self then
|
||||
trn.RouteNumber = self.RouteNumber
|
||||
trn:SetNW2String("RouteNumber",self.RouteNumber)
|
||||
end
|
||||
end
|
||||
|
||||
-- Parking brake
|
||||
if button == "ManualBrakeLeft" then
|
||||
self.ManualBrake = math.max(0.0,self.ManualBrake - 0.008)
|
||||
if self.ManualBrake == 0.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
if button == "ManualBrakeRight" then
|
||||
self.ManualBrake = math.min(1.0,self.ManualBrake + 0.008)
|
||||
if self.ManualBrake == 1.0 then return end
|
||||
--print(self.ManualBrake)
|
||||
end
|
||||
|
||||
if button == "KVUp" then
|
||||
if self.KV.ControllerPosition ~= -1 then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
end
|
||||
if button == "KVUp_Unlocked" then
|
||||
self.KV:TriggerInput("ControllerUp",1.0)
|
||||
end
|
||||
if button == "KVDown" then
|
||||
self.KV:TriggerInput("ControllerDown",1.0)
|
||||
end
|
||||
-- KRU
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserUp") then
|
||||
self.KRU:TriggerInput("Up",1)
|
||||
self:OnButtonPress("KRUUp")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVReverserDown") then
|
||||
self.KRU:TriggerInput("Down",1)
|
||||
self:OnButtonPress("KRUDown")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX1") then
|
||||
self.KRU:TriggerInput("SetX1",1)
|
||||
self:OnButtonPress("KRUSetX1")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX2") then
|
||||
self.KRU:TriggerInput("SetX2",1)
|
||||
self:OnButtonPress("KRUSetX2")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSetX3") then
|
||||
self.KRU:TriggerInput("SetX3",1)
|
||||
self:OnButtonPress("KRUSetX3")
|
||||
end
|
||||
if (self.KVWrenchMode == 2) and (button == "KVSet0") then
|
||||
self.KRU:TriggerInput("Set0",1)
|
||||
self:OnButtonPress("KRUSet0")
|
||||
end
|
||||
|
||||
if button == "KVSetT1AB" then
|
||||
if self.KV.ControllerPosition == -2 then
|
||||
self.KV:TriggerInput("ControllerSet",-1)
|
||||
timer.Simple(0.20,function()
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end)
|
||||
else
|
||||
self.KV:TriggerInput("ControllerSet",-2)
|
||||
end
|
||||
end
|
||||
if button == "KVWrench0" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 1 then
|
||||
if self.KVWrenchMode ~= 1 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 0
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
if button == "KVWrenchKV" then
|
||||
if self.KVWrenchMode == 3 or self.KVWrenchMode == 0 then
|
||||
if self.KVWrenchMode ~= 0 then
|
||||
self:PlayOnce("revers_in","cabin",0.7)
|
||||
end
|
||||
self.KVWrenchMode = 1
|
||||
self.DriversWrenchPresent = true
|
||||
self.DriversWrenchMissing = false
|
||||
self.KV:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--THERE IS NO KRU IN THIS EZH MODEL
|
||||
--[[
|
||||
if button == "KVWrenchKRU" then
|
||||
if self.KVWrenchMode == 3 then
|
||||
self:PlayOnce("kru_in","cabin",0.7)
|
||||
self.KVWrenchMode = 2
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",1)
|
||||
self.KRU:TriggerInput("LockX3",1)
|
||||
end
|
||||
end]]
|
||||
if button == "KVWrenchNone" then
|
||||
if self.KVWrenchMode ~= 3 and self.KV.ReverserPosition == 0 then
|
||||
if self.KVWrenchMode == 2 then
|
||||
self:PlayOnce("kru_out","cabin",0.7,120.0)
|
||||
else
|
||||
self:PlayOnce("revers_out","cabin",0.7,120.0)
|
||||
end
|
||||
self.KVWrenchMode = 3
|
||||
self.DriversWrenchPresent = false
|
||||
self.DriversWrenchMissing = true
|
||||
self.KV:TriggerInput("Enabled",0)
|
||||
self.KRU:TriggerInput("Enabled",0)
|
||||
end
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Close",1) end
|
||||
if button == "KDL" then self.KDL:TriggerInput("Close",1) self:OnButtonPress("KDLSet") end
|
||||
if button == "KDP" then self.KDP:TriggerInput("Close",1) self:OnButtonPress("KDPSet") end
|
||||
if button == "VDL" then self.VDL:TriggerInput("Close",1) self:OnButtonPress("VDLSet") end
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",1)
|
||||
self:OnButtonPress("KRPSet")
|
||||
end
|
||||
if button == "EmergencyBrake" then
|
||||
self.KV:TriggerInput("ControllerSet",-3)
|
||||
self.Pneumatic:TriggerInput("BrakeSet",7)
|
||||
self.DriverValveDisconnect:TriggerInput("Set",1)
|
||||
return
|
||||
end
|
||||
-- Special logic
|
||||
if (button == "VDL") or (button == "KDL") or (button == "KDP") then
|
||||
--self.VUD1:TriggerInput("Open",1)
|
||||
end
|
||||
if (button == "KDP") then
|
||||
--self.DoorSelect:TriggerInput("Close",1)
|
||||
end
|
||||
if (button == "VUD1Set") or (button == "VUD1Toggle") or
|
||||
(button == "VUD2Set") or (button == "VUD2Toggle") then
|
||||
self.VDL:TriggerInput("Open",1)
|
||||
self.KDL:TriggerInput("Open",1)
|
||||
self.KDP:TriggerInput("Open",1)
|
||||
end
|
||||
|
||||
if button == "GVToggle" then
|
||||
if self.GV.Value > 0.5 then
|
||||
self:PlayOnce("revers_f",nil,0.7)
|
||||
else
|
||||
self:PlayOnce("revers_b",nil,0.7)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if button == "DriverValveDisconnectToggle" then
|
||||
if self.DriverValveDisconnect.Value == 1.0 then
|
||||
self:PlayOnce("pneumo_disconnect2","cabin",0.9)
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_on","cabin",0.9) end
|
||||
else
|
||||
self:PlayOnce("pneumo_disconnect1","cabin",0.9)
|
||||
if self.EPK.Value == 1 then self:PlayOnce("epv_off","cabin",0.9) end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if button == "EPKToggle" and self.DriverValveDisconnect.Value == 1.0 then
|
||||
if self.EPK.Value == 1.0 then
|
||||
self:PlayOnce("epv_off","cabin",0.9)
|
||||
else
|
||||
self:PlayOnce("epv_on","cabin",0.9)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:OnButtonRelease(button)
|
||||
if string.find(button,"PneumaticBrakeSet") then
|
||||
return
|
||||
end
|
||||
--if button == "KVT2Set" then self.KVT:TriggerInput("Open",1) end
|
||||
if button == "KDL" then self.KDL:TriggerInput("Open",1) self:OnButtonRelease("KDLSet") end
|
||||
if button == "KDP" then self.KDP:TriggerInput("Open",1) self:OnButtonRelease("KDPSet") end
|
||||
if button == "VDL" then self.VDL:TriggerInput("Open",1) self:OnButtonRelease("VDLSet") end
|
||||
|
||||
if button == "KRP" then
|
||||
self.KRP:TriggerInput("Set",0)
|
||||
self:OnButtonRelease("KRPSet")
|
||||
end
|
||||
--[[
|
||||
if (button == "PneumaticBrakeDown") and (self.Pneumatic.DriverValvePosition == 1) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",2)
|
||||
end
|
||||
if self.Pneumatic.ValveType == 1 then
|
||||
if (button == "PneumaticBrakeUp") and (self.Pneumatic.DriverValvePosition == 5) then
|
||||
self.Pneumatic:TriggerInput("BrakeSet",4)
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
end
|
||||
|
||||
function ENT:OnCouple(train,isfront)
|
||||
if isfront and self.FrontAutoCouple then
|
||||
self.FrontBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.FrontAutoCouple = false
|
||||
elseif not isfront and self.RearAutoCouple then
|
||||
self.RearBrakeLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearTrainLineIsolation:TriggerInput("Open",1.0)
|
||||
self.RearAutoCouple = false
|
||||
end
|
||||
self.BaseClass.OnCouple(self,train,isfront)
|
||||
end
|
||||
@@ -1,116 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.Ezh3"
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSounds()
|
||||
self.BaseClass.InitializeSounds(self)
|
||||
self.SoundNames["relay_close2"] = nil
|
||||
self.SoundNames["relay_close3"] = nil
|
||||
--[[self.SoundNames["relay_close4"] = {"subway_trains/new/relay_7.wav","subway_trains/new/lsd_4.wav"}
|
||||
self.SoundNames["pneumo_switch"] = {
|
||||
"subway_trains/pneumo_8.wav",
|
||||
"subway_trains/pneumo_9.wav",
|
||||
}]]
|
||||
self.SoundNames["rvt_close"] = "subway_trains/sbor.wav"
|
||||
self.SoundNames["r1_5_close"] = "subway_trains/sbor_hod.wav"
|
||||
self.SoundNames["rvt_open"] = "subway_trains/rasbor_t.wav"
|
||||
self.SoundNames["r1_5_open"] = "subway_trains/razbor_hod.wav"
|
||||
self.SoundNames["rk_spin"] = "subway_trains/rk_3.wav"
|
||||
self.SoundNames["rk_stop"] = "subway_trains/rk_4.wav"
|
||||
self.SoundNames["switch_off"] = {"subway_trains/tumbler_1_off.wav","subway_trains/tumbler_2_off.wav","subway_trains/tumbler_3_off.wav"}
|
||||
self.SoundNames["switch_on"] = {"subway_trains/tumbler_1_on.wav","subway_trains/tumbler_2_on.wav","subway_trains/tumbler_3_on.wav"}
|
||||
self.SoundNames["av_on"] = {
|
||||
"subway_trains/va21_2_1_on.wav",
|
||||
"subway_trains/va21_2_2_on.wav",
|
||||
}
|
||||
self.SoundNames["av_off"] = {
|
||||
"subway_trains/va21_2_1_off.wav",
|
||||
"subway_trains/va21_2_2_off.wav",
|
||||
}
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
-- Электросистема 81-710
|
||||
self:LoadSystem("Electric","81_710RU1_Electric")
|
||||
|
||||
-- Токоприёмник
|
||||
self:LoadSystem("TR","TR_3B")
|
||||
-- Электротяговые двигатели
|
||||
self:LoadSystem("Engines","DK_117DM")
|
||||
|
||||
-- Резисторы для реостата/пусковых сопротивлений
|
||||
self:LoadSystem("KF_47A")
|
||||
-- Резисторы для ослабления возбуждения
|
||||
self:LoadSystem("KF_50A")
|
||||
-- Ящик с предохранителями
|
||||
self:LoadSystem("YAP_57")
|
||||
|
||||
-- Резисторы для цепей управления
|
||||
--self:LoadSystem("YAS_44V")
|
||||
-- Реостатный контроллер для управления пусковыми сопротивления
|
||||
self:LoadSystem("RheostatController","EKG_17B")
|
||||
-- Групповой переключатель положений
|
||||
self:LoadSystem("PositionSwitch","EKG_18B")
|
||||
-- Кулачковый контроллер
|
||||
self:LoadSystem("KV","KV_70")
|
||||
-- Контроллер резервного управления
|
||||
self:LoadSystem("KRU")
|
||||
|
||||
|
||||
-- Ящики с реле и контакторами
|
||||
self:LoadSystem("LK_755A")
|
||||
self:LoadSystem("YAR_13A")
|
||||
self:LoadSystem("YAR_27")
|
||||
self:LoadSystem("YAK_36")
|
||||
self:LoadSystem("YAK_37E")
|
||||
self:LoadSystem("YAS_44V")
|
||||
self:LoadSystem("YARD_2")
|
||||
self:LoadSystem("PR_14X_Panels")
|
||||
|
||||
-- Пневмосистема 81-710
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
self.Pneumatic.ValveType = 2
|
||||
-- Панель управления 81-710
|
||||
self:LoadSystem("Panel","81_710RU1_Panel")
|
||||
-- Everything else
|
||||
self:LoadSystem("Battery")
|
||||
self:LoadSystem("PowerSupply","DIP_01K")
|
||||
self:LoadSystem("DURA")
|
||||
self:LoadSystem("ALS_ARS")
|
||||
self:LoadSystem("Horn")
|
||||
self:LoadSystem("Announcer")
|
||||
self:LoadSystem("ASNP")
|
||||
|
||||
self:LoadSystem("IGLA")
|
||||
|
||||
self:LoadSystem("ASNP31","Relay","Switch")
|
||||
self:LoadSystem("ASNP32","Relay","Switch")
|
||||
|
||||
self:LoadSystem("Custom1","Relay","Switch")
|
||||
self:LoadSystem("Custom2","Relay","Switch")
|
||||
self:LoadSystem("Custom3","Relay","Switch")
|
||||
self:LoadSystem("CustomC","Relay","Switch")
|
||||
self:LoadSystem("CustomD","Relay","Switch")
|
||||
self:LoadSystem("CustomE","Relay","Switch")
|
||||
self:LoadSystem("CustomF","Relay","Switch")
|
||||
self:LoadSystem("CustomG","Relay","Switch")
|
||||
|
||||
|
||||
end
|
||||
@@ -1,700 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
ENT.AutoAnims = {}
|
||||
ENT.AutoAnimNames = {}
|
||||
ENT.ClientSounds = {}
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
|
||||
ENT.ButtonMap["ARM"] = {
|
||||
pos = Vector(-4.9,9.1,50.3),
|
||||
ang = Angle(0,-90-1,90),
|
||||
width = 800,
|
||||
height = 600,
|
||||
scale = 0.02*1.2,
|
||||
mouse = true
|
||||
}
|
||||
ENT.ClientProps["ARMPK"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_screen.mdl",
|
||||
pos = Vector(-5,0,31.2),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMMonitor"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_body.mdl",
|
||||
pos = Vector(-5,15,0),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMKeyboard"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_keyboard.mdl",
|
||||
pos = Vector(-15,-2,31),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMMouse"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_mouse.mdl",
|
||||
pos = Vector(-18,-20,32),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMBreen"] = {
|
||||
model = "models/props_combine/breenglobe.mdl",
|
||||
pos = Vector(-11,30,39.5),
|
||||
ang = Angle(0,-180+45,0),
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self.BaseClass.Initialize(self)
|
||||
self.ARM = self:CreateRT("ARM",1024,1024)
|
||||
for k,v in pairs(self.Types) do
|
||||
for i,tex in pairs(v) do
|
||||
if type(tex) == "table" and type(tex[1]) == "string" then
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CamMoved()
|
||||
self:HandleMouse(false)
|
||||
gui.EnableScreenClicker(self.CurrentCamera ~= 0)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
if not self.RenderClientEnts or self.CreatingCSEnts then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.ARM then return end
|
||||
--self.MouseX = 0
|
||||
--self.MouseY = 0
|
||||
self.MouseX = self:GetNW2Int("CursorX",0)
|
||||
self.MouseY = self:GetNW2Int("CursorY",0)
|
||||
render.PushRenderTarget(self.ARM,0,0,1024, 1024)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
render.OverrideAlphaWriteEnable(true, true)
|
||||
surface.SetDrawColor(0,0,0)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
self:ARMMonitor()
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
|
||||
|
||||
function ENT:DrawPost()
|
||||
self.RTMaterial:SetTexture("$basetexture", self.ARM)
|
||||
self:DrawOnPanel("ARM",function(...)
|
||||
surface.SetMaterial(self.RTMaterial)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRectRotated(512,512,1024,1024,0)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local gray = Color(100,100,100)
|
||||
local black = Color(0,0,0)
|
||||
local white = Color(150,150,150)
|
||||
local green = Color(0,50,0)
|
||||
|
||||
local function GetTextures(segm,typ)
|
||||
return segm[typ],segm.maintex or segm[typ]
|
||||
end
|
||||
--Get texture Width and Height
|
||||
local function GetWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.w or dtex.w,tex.h or dtex.h
|
||||
end
|
||||
--Get real(original) texture Width and Height
|
||||
local function GetRWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
end
|
||||
--Get X and Y adds
|
||||
local function GetXYA(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
local function drawSegment(w,h,u0,v0,u1,v1,segm,typ,align)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
if dtex.mat then
|
||||
local sx,sy = GetXY(w,h)
|
||||
local sw,sh = GetWH(segm,typ)
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = GetXYA(segm,typ)
|
||||
local rw,rh = GetRWH(segm,typ)
|
||||
surface.SetDrawColor(tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
end
|
||||
local function drawElement(sx,sy,u0,v0,u1,v1,segm,typ,col)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex = segm[typ]
|
||||
local dtex = segm.maintex or tex
|
||||
--local sx,sy = 100+w*36,100+h*70
|
||||
local sw,sh = tex.w or dtex.w,tex.h or dtex.h
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
local rw,rh = tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
surface.SetDrawColor(col or tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0 ,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
|
||||
local mouse = surface.GetTextureID("gui/info")
|
||||
|
||||
local function createFont(name,font,size,weight)
|
||||
surface.CreateFont("Metrostroi_"..name, {
|
||||
font = font,
|
||||
size = size,
|
||||
weight = weight or 400,
|
||||
blursize = 0,
|
||||
antialias = true,
|
||||
underline = false,
|
||||
italic = false,
|
||||
strikeout = false,
|
||||
symbol = false,
|
||||
rotary = false,
|
||||
shadow = false,
|
||||
additive = false,
|
||||
outline = false,
|
||||
extended = true,
|
||||
})
|
||||
end
|
||||
createFont("Arial10","Arial",10,400)
|
||||
createFont("Arial20","Arial",20,800)
|
||||
|
||||
local colorConverter = {
|
||||
r = Color(0,0,0),
|
||||
y = Color(240,240,71),
|
||||
g = Color(41,202,26),
|
||||
b = Color(26,84,202),
|
||||
w = Color(255,255,255),
|
||||
}
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMFindNextSegm(station,csegm,alt,dir,deb)
|
||||
if dir then
|
||||
if alt and not csegm.segm.next_a then return end
|
||||
if not alt and not csegm.segm.next_m then return end
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x <= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(csegm,alt)
|
||||
local tx,ty = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
|
||||
if not txa then continue end
|
||||
--if tx then print(1,segm.x,segm.y,GetSegmPos2(csegm,alt),csegm.invertX,csegm.invertY) end
|
||||
local sx,sy = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
--if not alt then print(2,x,y,sx,sy,tx,ty,txa,tya) end
|
||||
if sx == tx and sy == ty then return segm,sx,sy end
|
||||
if sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(segm,false)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
--if deb then print(sx,x) end
|
||||
if sx and sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(segm,true)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm,sx,sy end
|
||||
end
|
||||
else
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x >= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(segm,alt)
|
||||
local tx,ty = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
|
||||
if not txa then continue end
|
||||
|
||||
local sx,sy = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
if sx == tx and sy == ty then return segm,sx,sy end
|
||||
if sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(csegm,false)
|
||||
|
||||
if sx and sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(csegm,true)
|
||||
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm,sx,sy end
|
||||
end
|
||||
--[[ for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x >= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(segm,alt)
|
||||
local tx,ty = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
if not txa then continue end
|
||||
--if tx then print(1,segm.x,segm.y,GetSegmPos2(csegm,alt),csegm.invertX,csegm.invertY) end
|
||||
local sx,sy = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
--if not alt then print(2,x,y,sx,sy,tx,ty,txa,tya) end
|
||||
if sx == tx and sy == ty then return segm end
|
||||
if sx == txa and sy == tya then return segm end
|
||||
sx,sy = GetSegmPos(csegm,false)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
--if deb then print(sx,x) end
|
||||
if sx and sx == txa and sy == tya then return segm end
|
||||
sx,sy = GetSegmPos(csegm,true)
|
||||
--if alt then print(3,x,y,sx,sy,tx,ty) end
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm end
|
||||
end--]]
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNextCompare(posX,posY,segm,nsegm)
|
||||
local xp,yp = GetSegmPos(segm)
|
||||
local x,y = GetSegmPos(nsegm)
|
||||
if sx and posX == x and posY == y then
|
||||
nsegm.prev = segm
|
||||
return true
|
||||
end
|
||||
|
||||
sx,sy = GetSegmPos(nsegm,false)
|
||||
if sx and posX == sx and posY == sy then
|
||||
nsegm.next_m = segm
|
||||
return true
|
||||
end
|
||||
if not nsegm.segm.next_a then return end
|
||||
sx,sy = GetSegmPos(nsegm,true)
|
||||
if x ~= xp and y ~= yp and sx and posX == sx and posY == sy then
|
||||
nsegm.next_a = segm
|
||||
if segm.id == 29 then
|
||||
local x1,y1 = GetSegmPos(nsegm)
|
||||
local x2,y2 = GetSegmPos(segm)
|
||||
print(-2,x1,y1,x2,y2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNext(station)
|
||||
for csegmid,csegm in ipairs(station) do
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
|
||||
local posX,posY = GetSegmPos(csegm)
|
||||
if ARMSetNextCompare(posX,posY,csegm,segm) then
|
||||
csegm.prev = segm
|
||||
--break
|
||||
end
|
||||
local posOX,posOY = GetSegmPos(csegm,false)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_m = segm
|
||||
--break
|
||||
end
|
||||
local posAЧ,posAY = GetSegmPos(segm)
|
||||
if not csegm.segm.next_a or posX == posAX or posY == posAY then continue end
|
||||
posOX,posOY = GetSegmPos(csegm,true)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_a = segm
|
||||
--break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function ENT:ARMMonitor()
|
||||
if self.FilterMag then
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
end
|
||||
|
||||
render.PushFilterMag( TEXFILTER.POINT )
|
||||
render.PushFilterMin( TEXFILTER.POINT )
|
||||
self.FilterMag = true
|
||||
surface.SetDrawColor(gray)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
local station = self:GetNW2Int("ARM:Station",0)
|
||||
--draw.SimpleText("АРМ ДЫЫСЦЫПЫ","Metrostroi_BUKPSpeed",400, 300,Color(220,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
if station > 0 and Metrostroi.ARMConfigGenerated and Metrostroi.ARMConfigGenerated[station] then
|
||||
local armTable = Metrostroi.ARMConfigGenerated[station]
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"maintex")
|
||||
|
||||
--[[
|
||||
local w,h = GetXY(segm.x+segm.width*u0,segm.y)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(w+5*u1-5*u0,h,w,h)
|
||||
surface.DrawLine(w,h+5,w,h)
|
||||
local w,h = GetSegmPos(segm,false)
|
||||
surface.SetDrawColor(Color(255,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6,w,h)
|
||||
local w,h = GetSegmPos(segm,true)
|
||||
if w then
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6*v1+6*v0,w,h)
|
||||
end--]]
|
||||
end
|
||||
local w,h = 0,0
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if Metrostroi.GetARMInfo(station,id,"occup2") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_x")
|
||||
end
|
||||
if Metrostroi.GetARMInfo(station,id,"switch_m") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_a") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_a") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_na") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_an")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_mn")
|
||||
else
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
end
|
||||
if segm.signal1 then
|
||||
local sig = segm.signal1
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local x,y = 100+(segm.x+segm.width)*36,100+segm.y*70-(sig.top and -26 or 15)
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local sx,sy = x-rw-2,y-rh-2
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y-(sig.top and -7 or 15),Color(0,0,0),TEXT_ALIGN_RIGHT,TEXT_ALIGN_BOTTOM)
|
||||
drawElement(sx,sy,0,0,1,1,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal1") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal1I") then
|
||||
drawElement(sx+13*(sig.type-1),sy,0,0,1,1,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal1Y") then
|
||||
drawElement(sx+13*(sig.type-2),sy,0,0,1,1,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
if segm.signal2 then
|
||||
local sig = segm.signal2
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local x,y = 100+(segm.x)*36+2,100+segm.y*70+(sig.top and -38 or 3)
|
||||
local sx,sy = x-1,y+rh
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y+(sig.top and -2 or 20),Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_TOP)
|
||||
drawElement(sx,sy,1,1,0,0,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal2") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal2I") then
|
||||
drawElement(sx+rw-12-13*(sig.type-1),sy,1,1,0,0,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal2Y") then
|
||||
drawElement(sx+rw-12-13*(sig.type-2),sy,1,1,0,0,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
end
|
||||
for id,button in ipairs(armTable.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
if button.type=="r" then
|
||||
sw,sh = 15,25
|
||||
xa,ya = 3,12
|
||||
end
|
||||
local x,y = sx+xa,sy+ya
|
||||
if Metrostroi.GetARMInfo(station,1000+id,"buttonSelected") then
|
||||
surface.SetDrawColor(Color(80,80,180))
|
||||
elseif Metrostroi.GetARMInfo(station,1000+id,"buttonPressable") then
|
||||
surface.SetDrawColor(Color(220,220,220))
|
||||
else
|
||||
surface.SetDrawColor(Color(120,120,120))
|
||||
end
|
||||
surface.DrawRect(x,y,sw,sh)
|
||||
Metrostroi.DrawLine(x,y,x,y+sh,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x-1,y,x+sw,y,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x+sw,y,x+sw,y+sh,Color(60,60,60),2)
|
||||
Metrostroi.DrawLine(x,y+sh,x+sw+1,y+sh,Color(60,60,60),2)
|
||||
end
|
||||
end
|
||||
for i,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
if i == station then
|
||||
surface.SetDrawColor(Color(110,140,170))
|
||||
elseif math.InRangeXYR(self.MouseX,self.MouseY,20+(i-1)*30,20,30,20) then
|
||||
surface.SetDrawColor(Color(80,110,140))
|
||||
else
|
||||
surface.SetDrawColor(Color(100,130,160))
|
||||
end
|
||||
|
||||
surface.DrawRect(20+(i-1)*31,20,30,20)
|
||||
draw.SimpleText(v.shortname or v.id,"Metrostroi_Arial20",35+(i-1)*31, 30,Color(40,60,170),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end
|
||||
--if self.CurrentCamera == 0 then
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.SetTexture(mouse)
|
||||
surface.DrawTexturedRectRotated(self.MouseX,self.MouseY,8,8,0)
|
||||
--end
|
||||
surface.SetDrawColor(0,0,0,200)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
self.FilterMag = false
|
||||
--[=[
|
||||
local iter = 0
|
||||
local function ARMFindSegmSignals(station,segm,dir,signals,checked,restbl,trace,NextAlt)
|
||||
if not restbl then restbl = {} end
|
||||
if not checked then checked = {} end
|
||||
if not trace then trace = {} end
|
||||
if checked[segm] then return end
|
||||
checked[segm] = true
|
||||
local segmIndex = table.insert(trace,{segm.id})
|
||||
--trace[segm] = true
|
||||
|
||||
iter = iter + 1
|
||||
if iter > 10000 then ARMGenError(Format("Routes generation error. Max iter reached!"),true) return false end
|
||||
local segmt = segm.segm
|
||||
local segmM,segmA = segmt.next_m,segmt.next_a
|
||||
if not segmM then return end
|
||||
|
||||
local NextM = ARMFindNextSegm(station,segm,not NextAlt,dir)
|
||||
local NextA = ARMFindNextSegm(station,segm,NextAlt,dir)
|
||||
|
||||
|
||||
local xp,yp = GetXY(segm.x,segm.y)
|
||||
if NextA then
|
||||
local trace= table.Copy(trace)
|
||||
trace[segmIndex][2] = true
|
||||
local xn,yn = GetXY(NextA.x,NextA.y)
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
local xa2,ya2 = GetSegmPos(NextA,true)
|
||||
--trace[segmIndex][2] = true
|
||||
local nxt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
--MsgN(Format("->A\n",segm.x,segm.y))
|
||||
local signal = dir and NextA.signal2 or NextA.signal1
|
||||
--print("A",segm.x,segm.y,NextA.x,NextA.y,signal and signal.name,dir)
|
||||
if signal and table.HasValue(signals,signal.name) then--and not segmOnA.invertX then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,NextA,dir,signals,checked,restbl,trace,true)
|
||||
end
|
||||
if NextM then
|
||||
local xn,yn = GetXY(NextM.x,NextM.y)
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
local xa2,ya2 = GetSegmPos(NextM,true)
|
||||
local nxt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
local signal = dir and NextM.signal2 or NextM.signal1
|
||||
--print("M",segm.x,segm.y,NextM.x,NextM.y,signal and signal.name,dir)
|
||||
if signal and table.HasValue(signals,signal.name) then--and not segmOnA.invertX then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,NextM,dir,signals,checked,restbl,table.Copy(trace))
|
||||
end
|
||||
return restbl
|
||||
end
|
||||
local station = Metrostroi.ARMConfigGenerated[station]
|
||||
for _,button in pairs(station.buttons,station.routes["PT64"]) do
|
||||
if button.type == "r" and station.routes[button.signal] then
|
||||
--button.pressable = true
|
||||
local results = ARMFindSegmSignals(station,button.segm,false,station.routes[button.signal])
|
||||
if #results == 0 then
|
||||
results = ARMFindSegmSignals(station,button.segm,true,station.routes[button.signal])
|
||||
end
|
||||
for k,v in pairs(results) do
|
||||
local i = 0
|
||||
for k,v in pairs(v[2]) do
|
||||
print(v[2])
|
||||
end
|
||||
end
|
||||
--print(results[1][1].name,results[1][1].segm)--]]
|
||||
--button.routes = results
|
||||
end
|
||||
end--]=]
|
||||
--[=[
|
||||
local x = 0
|
||||
local founded = true
|
||||
local stat = Metrostroi.ARMConfigGenerated[station]
|
||||
local maxd = 3
|
||||
local x = 26-- or math.ceil((CurTime()%10)/10*#stat)
|
||||
local dir = true-- or CurTime()%20 > 10
|
||||
local function findt(station,segm,dir,i,depth,px,py )
|
||||
depth = depth or 0
|
||||
i = i or 0
|
||||
local segmt = segm.segm
|
||||
local segmM,segmA = segmt.next_m,segmt.next_a
|
||||
local NextM,NextMX,NextMY = ARMFindNextSegm(station,segm,false,dir)
|
||||
local NextA,NextAX,NextAY = ARMFindNextSegm(station,segm,true,dir)
|
||||
local xp,yp = GetXY(segm.x,segm.y)
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",xp,yp,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
draw.SimpleText(Format("%.1f:%.1f",segm.x,segm.y),"Metrostroi_Arial10",xp,yp-20,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
if i==4 then print(xa1,ya1,px,py,xa1 == px and ya1 == py) end
|
||||
local alt = px and py ~= yp and xa1 == px and ya1 == py
|
||||
if NextA and depth+1 < maxd then
|
||||
--if i==3 then print(1) end
|
||||
local xn,yn = GetXY(NextA.x,NextA.y)
|
||||
local xa2,ya2 = GetSegmPos(NextA,true)
|
||||
local nalt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
if nalt or alt then surface.SetDrawColor(Color(255,0,0))
|
||||
else surface.SetDrawColor(Color(0,255,0)) end
|
||||
surface.DrawLine(px or xp,py or yp,NextAX or xn,NextAY or yn)
|
||||
if findt(station,NextA,dir,i+1,depth+1,NextAX,NextAY) then return end
|
||||
--return true
|
||||
--if i==5 then print("RES",segm.x,segm.y,NextA.x,NextA.y) end
|
||||
end
|
||||
if NextM and depth < maxd then
|
||||
local xn,yn = GetXY(NextM.x,NextM.y)
|
||||
local xa2,ya2 = GetSegmPos(NextM,true)
|
||||
local nalt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
if alt then surface.SetDrawColor(Color(255,255,0))
|
||||
else surface.SetDrawColor(Color(0,255,0)) end
|
||||
surface.DrawLine(px or xp,py or yp,NextMX or xn,NextMY or yn)
|
||||
if findt(station,NextM,dir,i+1,depth,NextMX,NextMY) then return end
|
||||
end
|
||||
end
|
||||
--findt(stat,stat[x],dir)--]=]
|
||||
---[==[
|
||||
if Metrostroi.ARMConfigGenerated[station] then
|
||||
ARMSetNext(Metrostroi.ARMConfigGenerated[station])
|
||||
--[=[ for id,segm in ipairs(Metrostroi.ARMConfigGenerated[station]) do
|
||||
local ws,hs = GetSegmPos(segm)
|
||||
draw.SimpleText(segm.id,"Metrostroi_Arial20",ws,hs-15--[[ *(math.random()*5)--]] ,Color(0,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
if segm.next_m then
|
||||
local w,h = GetSegmPos(segm.next_m)
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(ws,hs,w,h)
|
||||
surface.DrawLine(ws-6,hs-6,ws+6,hs+6)
|
||||
surface.DrawLine(ws-6,hs+6,ws+6,hs-6)
|
||||
surface.DrawLine(w-6,h-2,w+6,h+2)
|
||||
surface.DrawLine(w-6,h+2,w+6,h-2)
|
||||
else
|
||||
local w,h = GetSegmPos(segm)
|
||||
w = w+segm.width*36/2
|
||||
surface.SetDrawColor(Color(255,0,255))
|
||||
surface.DrawLine(w-4,h-4,w+4,h+4)
|
||||
surface.DrawLine(w-4,h+4,w+4,h-4)
|
||||
continue
|
||||
end
|
||||
if segm.next_a then
|
||||
local w,h = GetSegmPos(segm.next_a)
|
||||
draw.SimpleText(segm.id,"Metrostroi_Arial20",w,h+15,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(ws,hs,w,h)
|
||||
surface.DrawLine(ws-7,hs-4,ws+7,hs+4)
|
||||
surface.DrawLine(ws-7,hs+4,ws+7,hs-4)
|
||||
surface.DrawLine(w-7,h-2,w+7,h+2)
|
||||
surface.DrawLine(w-7,h+2,w+7,h-2)
|
||||
end
|
||||
end--]=]
|
||||
local x = 0
|
||||
local founded = true
|
||||
local stat = Metrostroi.ARMConfigGenerated[station]
|
||||
local maxd = 2
|
||||
local x = 21-- or math.ceil((CurTime()%10)/10*#stat)
|
||||
local dir = true-- or CurTime()%20 > 10
|
||||
local function findt(station,segm,dir,i,depth,last )
|
||||
depth = depth or 0
|
||||
i = i or 0
|
||||
local segmP = segm.prev
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local x,y = GetXY(segm.x,segm.y)
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",x,y,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
draw.SimpleText(Format("%.1f:%.1f",segm.x,segm.y),"Metrostroi_Arial10",x,y-20,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
|
||||
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if i==7 and last.next_a then
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",x,y,Color(0,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
local x,y = GetXY(last.x,last.y)
|
||||
draw.SimpleText(i-1,"Metrostroi_Arial20",x,y,Color(255,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
--print(last.next_a,segm)
|
||||
end
|
||||
|
||||
if segmA and mainM and depth+1 < maxd then
|
||||
--if i==3 then print(1) end
|
||||
local xn,yn = GetXY(segmA.x,segmA.y)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmA,dir,i+1,depth+1,segm) then return end
|
||||
return true
|
||||
--if i==5 then print("RES",segm.x,segm.y,NextA.x,NextA.y) end
|
||||
end
|
||||
if segmM and mainM and depth < maxd then
|
||||
local xn,yn = GetXY(segmM.x,segmM.y)
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmM,dir,i+1,depth,segm) then return end
|
||||
end
|
||||
if segmP and mainP and depth < maxd then
|
||||
local xn,yn = GetXY(segmP.x,segmP.y)
|
||||
local alt = last and segm.next_a == last or segmP.next_a == segm
|
||||
if alt then surface.SetDrawColor(Color(255,255,0))
|
||||
else surface.SetDrawColor(Color(0,255,255)) end
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmP,dir,i+1,depth,segm) then return end
|
||||
end
|
||||
end
|
||||
findt(stat,stat[x],dir)
|
||||
end--]==]
|
||||
--findt(stat,stat[6],false)
|
||||
end
|
||||
Metrostroi.GenerateClientProps()
|
||||
@@ -1,169 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_combine/breendesk.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self.DriverSeat = self:CreateSeat("driver", Vector(-40, 0, 0), Angle(0, 0, 0), "models//nova/chair_office02.mdl")
|
||||
self.CursorX = 0
|
||||
self.CursorY = 0
|
||||
self:CursorMove(0, 0)
|
||||
self.Station = 0
|
||||
end
|
||||
|
||||
hook.Add("AcceptInput", "metrostroi_arm_trigger_check", function(ent, inputName, activator, called, data)
|
||||
if inputName == "ARMStartTouch" then
|
||||
called.ARMTriggered = true
|
||||
print(called, called:GetName(), activator, "Enable")
|
||||
end
|
||||
|
||||
if inputName == "ARMEndTouch" then
|
||||
called.ARMTriggered = false
|
||||
print(called, called:GetName(), activator, "Disable")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
local function GetOccupation(tbl)
|
||||
for sID,signame in ipairs(tbl) do
|
||||
if signame[1] == "@" then
|
||||
local trigger = Metrostroi.ARMGet(signame:sub(2,-1), "trigger")
|
||||
if not trigger or trigger.ARMTriggered then
|
||||
return true
|
||||
end
|
||||
elseif signame ~= "" then
|
||||
local signal = Metrostroi.ARMGet(signame, "signal")
|
||||
if not signal or signal.OccupiedBy and signal.OccupiedBy ~= signal then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local armTbl = Metrostroi.ARMTable
|
||||
local armConf = Metrostroi.ARMConfigGenerated
|
||||
local station = armConf[self.Station]
|
||||
local armTblStation = armTbl[self.Station]
|
||||
if not station then return end
|
||||
if not armTblStation or (IsValid(armTblStation.Controller) and armTblStation.Controller ~= self) then return end
|
||||
armTblStation.Controller = self
|
||||
for buttonID,button in ipairs(station.buttons) do
|
||||
--print(button,button.selected)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonPressable",button.pressable)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonSelected",button.selected)
|
||||
end
|
||||
for segmID, segm in ipairs(station) do
|
||||
if type(segm) == "table" then
|
||||
if segm.occup then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup", GetOccupation(segm.occup) or segm.occupAlt and GetOccupation(segm.occupAlt))
|
||||
end
|
||||
|
||||
if segm.occup2 then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup2", GetOccupation(segm.occup2))
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "route", segm.route and true)
|
||||
|
||||
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
local alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_m", main)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_a", alt)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_na", not main and not alt)
|
||||
end
|
||||
if segm.signal1 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal1.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal1.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal1I", signal and signal.InvationSignal) end
|
||||
if segm.signal1.type > 2 then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1", colors)
|
||||
end
|
||||
if segm.signal2 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal2.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal2.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal2I", signal and signal.InvationSignal) end
|
||||
if segm.signal2.type > 2 then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2", colors)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:NextThink(CurTime() + 0.5)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
function ENT:CursorMove(sys, dX, dY)
|
||||
self.CursorX = sys == "" and math.Clamp(self.CursorX + dX * 200, 0, 800) or dX
|
||||
self.CursorY = sys == "" and math.Clamp(self.CursorY + dY * 200, 0, 600) or dY
|
||||
self:SetNW2Int("CursorX", math.floor(self.CursorX))
|
||||
self:SetNW2Int("CursorY", math.floor(self.CursorY))
|
||||
end
|
||||
|
||||
function ENT:PanelTouch(state, x, y)
|
||||
for i, v in ipairs(Metrostroi.ARMConfig) do
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, 20 + (i - 1) * 30, 20, 30, 20) then
|
||||
self.Station = i
|
||||
self:SetNW2Int("ARM:Station", i)
|
||||
end
|
||||
end
|
||||
if not state then return end
|
||||
local RouteChoosing = self.RouteChoosing
|
||||
self.RouteChoosing = nil
|
||||
if RouteChoosing then
|
||||
print("DISABLE")
|
||||
for k,v in pairs(RouteChoosing.routes) do
|
||||
if v[1].button then
|
||||
v[1].button.selected = false
|
||||
elseif v[1].isbutton then
|
||||
v[1].selected = false
|
||||
end
|
||||
end
|
||||
end
|
||||
local confGenStation = Metrostroi.ARMConfigGenerated[self.Station]
|
||||
for k,button in pairs(confGenStation.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
if button.type == "r" then
|
||||
local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
local x,y = sx+xa,sy+ya
|
||||
if RouteChoosing then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
for k,v in ipairs(RouteChoosing.routes) do
|
||||
if v[1].button and button == v[1].button or v[1].isbutton and button==v[1] then
|
||||
Metrostroi.CentralisationPrepareRoute(self.Station,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif not self.RouteChoosing and button.pressable then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
self.RouteChoosing = button
|
||||
for k,v in ipairs(button.routes) do
|
||||
print(v[1],v[1].name,v[1].button)
|
||||
if v[1].button then
|
||||
v[1].button.selected = true
|
||||
elseif v[1].isbutton then
|
||||
v[1].selected = true
|
||||
print(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,656 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
--Inherit subway base for some need functions
|
||||
ENT.Base = "gmod_subway_base"
|
||||
ENT.NoTrain = true
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.ARM"
|
||||
ENT.Category = "Metrostroi"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = true
|
||||
|
||||
ENT.Cameras = {
|
||||
{Vector(-18+3,0,43+2),Angle(0,0,0),"ARM.Monitor1",true},
|
||||
}
|
||||
ENT.Types = {
|
||||
--Main segments
|
||||
[0.25]={
|
||||
maintex = {"metrostroi_arm/sec025",w=8,h=8,rw=7,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec025_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec025_m",col=Color(39,103,63)},
|
||||
width = 0.25,
|
||||
next_m = {x=0.25,y=0}
|
||||
},
|
||||
[0.5]={
|
||||
maintex = {"metrostroi_arm/sec05",w=16,h=8,rw=16,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec05_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec05_m",col=Color(39,103,63)},
|
||||
width = 0.5,
|
||||
next_m = {x=0.5,y=0}
|
||||
},
|
||||
[1]={
|
||||
maintex = {"metrostroi_arm/sec1",w=64,h=8,rw=34,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec1_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec1_m",col=Color(39,103,63)},
|
||||
width = 1,
|
||||
next_m = {x=1,y=0}
|
||||
},
|
||||
[2]={
|
||||
maintex = {"metrostroi_arm/sec2",w=128,h=8,rw=70,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec2_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec2_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0}
|
||||
},
|
||||
[3]={
|
||||
maintex = {"metrostroi_arm/sec3",w=128,h=8,rw=106,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec3_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec3_m",col=Color(39,103,63)},
|
||||
width = 3,
|
||||
next_m = {x=3,y=0}
|
||||
},
|
||||
[4]={
|
||||
maintex = {"metrostroi_arm/sec4",w=256,h=8,rw=142,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec4_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec4_m",col=Color(39,103,63)},
|
||||
width = 4,
|
||||
next_m = {x=4,y=0}
|
||||
},
|
||||
[5]={
|
||||
maintex = {"metrostroi_arm/sec5",w=256,h=8,rw=178,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec5_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec5_m",col=Color(39,103,63)},
|
||||
width = 5,
|
||||
next_m = {x=5,y=0}
|
||||
},
|
||||
--Switches and helpers
|
||||
sw = {
|
||||
maintex = {"metrostroi_arm/switch",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/switch_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/switch_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/switch_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/switch_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/switch_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/switch_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/switch_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/switch_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
["2sw"] = {
|
||||
maintex = {"metrostroi_arm/2-switch_half",w=128,h=256,rw=70,rh=143,},
|
||||
occup_m = {"metrostroi_arm/2-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch_half_as",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch_half_ms",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
},
|
||||
["2swm"] = {
|
||||
maintex = {"metrostroi_arm/2-switch-middle_half",w=128,h=128,rw=70,rh=73,},
|
||||
occup_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch-middle_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch-middle_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
},
|
||||
["4sw"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter",w=128,h=256,rw=73,rh=143,x=-3,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(39,103,63)},
|
||||
occup_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(255,255,255)},
|
||||
route_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
["4sws"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter_small",w=64,h=128,rw=53,rh=78,x=-1,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(255,255,255),x=-1,},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(39,103,63),x=-1,},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(255,255,255),x=-1,},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(39,103,63),x=-1,},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(200,50,50)},
|
||||
width = 1.5,
|
||||
next_m = {x=1.5,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
ofd = {
|
||||
maintex = {"metrostroi_arm/offset_down",w=64,h=256,rw=57,rh=143,},
|
||||
occup_m = {"metrostroi_arm/offset_down_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offset_down_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=2},
|
||||
},
|
||||
ofds = {
|
||||
maintex = {"metrostroi_arm/offsed_down_small",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/offsed_down_small_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offsed_down_small_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=1},
|
||||
},
|
||||
ysw = {
|
||||
maintex = {"metrostroi_arm/Y-switch_half",w=128,h=128,rw=70,rh=108,},
|
||||
occup_m = {"metrostroi_arm/Y-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/Y-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/Y-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/Y-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/Y-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/Y-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/Y-switch_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/Y-switch_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
--Signals
|
||||
tl_1 = {
|
||||
maintex = {"metrostroi_arm/tl_1",w=32,h=16,rw=21,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_2 = {
|
||||
maintex = {"metrostroi_arm/tl_2",w=64,h=16,rw=34,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_3 = {
|
||||
maintex = {"metrostroi_arm/tl_3",w=64,h=16,rw=47,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
}
|
||||
if CLIENT then
|
||||
for i,segm in pairs(ENT.Types) do
|
||||
for k,tex in pairs(segm) do
|
||||
if type(tex) ~= "table" or type(tex[1]) ~= "string" then continue end
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
segm.id = i
|
||||
end
|
||||
end
|
||||
|
||||
--------------
|
||||
-- Syntax of table
|
||||
-- {
|
||||
-- station = "ID,abbreviation,full name"
|
||||
-- First line of segments
|
||||
-- {"segment type:occupation checkers,...,occupation checkers:lights:...:lights"},
|
||||
-- Second line of segments
|
||||
-- {x=x indent,skip=y indent(skips y segments vertically),"segment type:occupation checkers main,...,occupation checkers main:occupation checkers alt,...,occupation checkers alt:lights:...:lights"},
|
||||
-- }
|
||||
-- segment type can have > or ! on start, when we want mirror it vertically or horisontally
|
||||
-- Occupation checkers can be triggers(have @ in start of trigger name) or signals
|
||||
-- Lights can be empty, if we want take light name from occupation checkers
|
||||
-- Lights can have ! when stay in right direction or !! when stay in opposite direction
|
||||
-- Lights can have > when we want switch light location from bottom to top
|
||||
-- Examples
|
||||
--{
|
||||
-- station = "001,ST,Station name",
|
||||
-- {
|
||||
-- {"1:L1:!","1:L3:!","sw:@sw1trigger:@sw3trigger"}
|
||||
-- {x=1,"1:L2",">sw:@sw2trigger:@sw3rigger"},
|
||||
-- }
|
||||
--}
|
||||
--------------
|
||||
Metrostroi.ARMConfig = {
|
||||
{
|
||||
station = "451,ВБ,Уоллеса брина",
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","sw:1","3:1","3:1"},
|
||||
{x=7,"0.5:1","4sws:1",">4sws:1","1:1","1:1"},{skip=1},
|
||||
{x=7,"0.5:1","!4sws:1",">!4sws:1","1:1","1:1"},
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","!sw:1","3:1","3:1"},
|
||||
},{
|
||||
station="915,РЧ,Речная",
|
||||
{x=3.5,"0.5:RX22","1:RX22","1:RX20","0.5:RX98","4sw:::RX1:0",">4sw:::RX3:","1","2","2","1","1"},{skip=3},
|
||||
{"1:201","0.5:203","0.5:205","0.5:207","0.5:209","0.5:211","0.5:213","1:215","1:217","0.5:219","!4sw:::RX2::!!2RX95",">!4sw:::RX4:","1","2","2","1","1"},
|
||||
},{
|
||||
station="110,МД,Международная",
|
||||
{"1:19:!1","1:17:!1","1:15:!1","1:13:!1","3:11:!>1","sw:@wt_md_s1_1,@wt_md_s1_2:@wt_md_s1_3:MD1:!!>2D:!>2G","5:@wt_md_t1"},
|
||||
{x=9,"4sws:@wt_md_s3::MD3",">4sws:@wt_md_s5::MD5:!2MD1","2:@wt_md_t3"},{skip=1},
|
||||
{x=9,"!4sws:@wt_md_s4::MD4",">!4sws:@wt_md_s6::MD6:!>2MD2","2:@wt_md_t4"},
|
||||
{"1:MD16:!!2","1:MD14:!!2","1:MD12:!!2","1:MD10:!!2:!1 OP","1:MD8:!!2","1:MD8A","1:MD8B","!sw:@wt_md_s2_1,@wt_md_s2_2:@wt_md_s2_3:MD2:!!2MD6:!2E","5:@wt_md_t2"},
|
||||
buttons = {
|
||||
{type="r",y=4-0.6 ,x=4, signal=" OP"},
|
||||
{type="r",y=4 ,x=6+0.4, signal="MD6"},
|
||||
{type="r",y=4-0.6 ,x=9, signal="E"},
|
||||
{type="r",y=3 ,x=14, signal="4I",target={12,3}},
|
||||
{type="r",y=1-0.6 ,x=14, signal="3I",target={12,1}},
|
||||
{type="r",y=3 ,x=12, signal="MD2"},
|
||||
{type="r",y=1-0.6 ,x=12, signal="MD1"},
|
||||
--{type="r",y=0-0.6 ,x=4, signal="13"},
|
||||
{type="r",y=0-0.6 ,x=6+0.4, signal="D",target={4,0}},
|
||||
{type="r",y=0 ,x=9, signal="G"},
|
||||
},
|
||||
routes = {
|
||||
MD6={"4I","3I"},
|
||||
E={" OP"},
|
||||
MD2={" OP","D"},
|
||||
MD1={" OP","13"},
|
||||
D={"4I","3I"},
|
||||
G={"13"},
|
||||
}
|
||||
},{
|
||||
station="112,ПТ,Политехническая",
|
||||
{x=1,"1:PT2TB","2:PT2TA","2:PT2T:!!2PT2","2:PT4SA:!!2PT4",">2swm:@wt_pt_s4_1,@wt_pt_s4_2,@wt_pt_s4_3::PT4:!3PT968M:!!2G ","1:PT966A","2:PT966:!>2","sw:@wt_pt_s6_2,@wt_pt_s6_3::PT6:!>2PT964:!!>3A","1:962"},
|
||||
{x=15,"1:PT6SS","1:963"},
|
||||
{x=1,"1:77:!1","1:75:!1","1:73:!1","1:71:!>1",">2swm:@wt_pt_s1_1::PT1:!!>2B","!2swm:@wt_pt_s3_1:@wt_pt_s3_2:PT3:!>2PT69","1:PT67M:!2","1:PT65B","1:PT65A","1:PT65:!2","1:PT63:!2:!!1 OP ","1:PT61:!2","1:PT59:!2","1:PT57:!2"},{skip=1},
|
||||
{"1:PT70:!!2:!1 OP2 ","1:PT68:!!2","2:@wt_pt_s2_3:!!2PT66","!2swm:@wt_pt_s2_1:@wt_pt_s2_2:PT2:!!3PT64","2","2:62:!!1","1:60:!!1","2:60A","1:58M:!!1","1:56:!!1","1:54:!!1","1: 52:!!1"},
|
||||
{},
|
||||
labels = {
|
||||
|
||||
},
|
||||
buttons = {
|
||||
{type="r",y=0-0.6 ,x=1, signal="3T",target={1,0},flip=true},
|
||||
{type="r",y=0 ,x=3+0.4,signal="PT2",target={1,0},flip=true},
|
||||
|
||||
{type="r",y=4-0.6 ,x=1, signal=" OP2 "},
|
||||
{type="r",y=4 ,x=-1+0.4, signal="PT70"},
|
||||
{type="r",y=4 ,x=3+0.4, signal="2P",target={6,4}},
|
||||
--{type="r",y=4 ,x=7+0.4, signal="62"},
|
||||
{type="r",y=2 ,x=5, signal="71"},
|
||||
{type="r",y=2-0.6 ,x=4+0.4, signal="B",target={5,2}},
|
||||
{type="r",y=2-0.6 ,x=17, signal="PT57"},
|
||||
{type="r",y=2-0.6 ,x=10, signal="PT67M"},
|
||||
{type="r",y=2 ,x=12+0.4,signal=" OP "},
|
||||
{type="r",y=0-0.6 ,x=10, signal="PT968M",flip=true},
|
||||
{type="r",y=0 ,x=15, signal="PT964",flip=true},
|
||||
{type="r",y=1-0.6 ,x=15, signal="4O",target={15,1},flip=true},
|
||||
{type="r",y=0-0.6 ,x=12+0.4,signal="A",flip=true},
|
||||
},
|
||||
routes = {
|
||||
PT2 = {"A"},
|
||||
PT70 = {" OP ","A","2P"},
|
||||
--PT64 = {" OP ","A","PT64"},
|
||||
B = {" OP ","A"},
|
||||
PT57 = {"PT67M"},
|
||||
PT964 = {"PT968M"},
|
||||
PT67M = {"71"," OP2 "},
|
||||
PT968M = {"3T","71"," OP2 "},
|
||||
A={"4O"}
|
||||
}
|
||||
},{
|
||||
station="115,ОК,Октябрьская",
|
||||
{"1","1","1","1","3","sw:::OK1","1"},
|
||||
{x=9,"4sws:::OK3",">4sws:::OK5","1"},{skip=1},
|
||||
{x=9,"!4sws:::OK4",">!4sws:::OK6","1"},
|
||||
{"1","1","1","1","3","!sw:::OK2","5"},
|
||||
}
|
||||
}
|
||||
|
||||
print("MetrostroiARM:Generating ARM table...")
|
||||
local errors,warnings = 0,0
|
||||
local function ARMGenError(text,err)
|
||||
MsgC(Color(255,err and 0 or 255,0),"MetrostroiARM:"..text.."\n")
|
||||
ErrorNoHalt()
|
||||
if err then errors = errors + 1 else warnings = warnings + 1 end
|
||||
end
|
||||
|
||||
local function ParseARMTable(text,station,line,segm)
|
||||
local resultTbl = {}
|
||||
|
||||
local tbl = string.Explode(":",text)
|
||||
|
||||
local typ = tbl[1]
|
||||
if typ:find("^[>!]") then
|
||||
resultTbl.invertX = typ:find(">")
|
||||
resultTbl.invertY = typ:find("!")
|
||||
typ = typ:gsub("^[>!]+","")
|
||||
end
|
||||
local segmTyp = ENT.Types[tonumber(typ) or typ]
|
||||
if not segmTyp then return {error = 1,type = tbl[1]} end
|
||||
table.remove(tbl,1)
|
||||
|
||||
for i,str in ipairs(tbl) do
|
||||
if str:find(",") then
|
||||
tbl[i] = string.Explode(",",str)
|
||||
end
|
||||
if str:sub(1,2) == "!!" then
|
||||
resultTbl.signal2 = str:sub(3,-1)
|
||||
elseif str[1] == "!" then
|
||||
resultTbl.signal1 = str:sub(2,-1)
|
||||
end
|
||||
end
|
||||
resultTbl.occup = type(tbl[1]) == "table" and tbl[1] or {tbl[1]}
|
||||
if segmTyp.occup_a then
|
||||
resultTbl.occupAlt = type(tbl[2]) == "table" and tbl[2] or {tbl[2]}
|
||||
resultTbl.switch = tbl[3]
|
||||
if segmTyp.occup_x then
|
||||
resultTbl.occup2 = type(tbl[4]) == "table" and tbl[4] or {tbl[4]}
|
||||
end
|
||||
end
|
||||
|
||||
if resultTbl.signal1 then
|
||||
local signal = resultTbl.signal1:gsub("^[>]+","")
|
||||
local top = resultTbl.signal1:find("^>")
|
||||
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal1 = {name=name,type=typ or 1,top = top,segm=resultTbl}
|
||||
end
|
||||
if resultTbl.signal2 then
|
||||
local signal = resultTbl.signal2:gsub("^[>]+","")
|
||||
local top = resultTbl.signal2:find("^>")
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal2 = {name=name,type=typ or 1,top = top,segm=resultTbl}
|
||||
end
|
||||
resultTbl.type = typ
|
||||
resultTbl.width = segmTyp.width or 1
|
||||
resultTbl.segm = segmTyp
|
||||
return resultTbl
|
||||
end
|
||||
|
||||
|
||||
Metrostroi.ARMConfigGenerated = {}
|
||||
local id = 0
|
||||
for i,station in ipairs(Metrostroi.ARMConfig) do
|
||||
if not Metrostroi.ARMConfigGenerated[i] then Metrostroi.ARMConfigGenerated[i] = {} end
|
||||
local genStation = Metrostroi.ARMConfigGenerated[i]
|
||||
local y = 0
|
||||
|
||||
MsgC(Color(0, 222, 255),"MetrostroiARM:Solving station ",i,"\n")
|
||||
if #station == 0 then ARMGenError(Format("Parser warning. Empty station %d! Skipping...",i),false) continue end
|
||||
if not station.station then ARMGenError(Format("Parser error. Can't find station name in station %d! Skipping...",i),true) continue end
|
||||
|
||||
local stationTbl = string.Explode(",",station.station)
|
||||
if not stationTbl or #stationTbl < 3 or not tonumber(stationTbl[1]) then ARMGenError(Format("Parser error. Malformed station data in station %d! Skipping...",i),true) continue end
|
||||
|
||||
genStation.id = stationTbl[1]
|
||||
genStation.shortname = stationTbl[2]
|
||||
genStation.name = stationTbl[3]
|
||||
genStation.buttons = {}
|
||||
genStation.routes = station.routes or {}
|
||||
for lineID,line in ipairs(station) do
|
||||
local x = line.x or 0
|
||||
for segmID,segm in ipairs(line) do
|
||||
if type(segm) ~= "string" then
|
||||
ARMGenError(Format("Parser error on station %d line %d segm %d, excepted string,got %s. Skipping segment...",i,lineID,segmID,type(segm)),true)
|
||||
continue
|
||||
end
|
||||
local segmTbl= ParseARMTable(segm,i,lineID,segmID)
|
||||
if segmTbl.error then
|
||||
ARMGenError(Format("Parser warning. Skipping station %d line %d segm %d segment, type error(type '%s' not found)",i,lineID,segmID,segmTbl.type),false)
|
||||
continue
|
||||
end
|
||||
segmTbl.x = x
|
||||
segmTbl.y = y
|
||||
segmTbl.id = table.insert(genStation,segmTbl)
|
||||
x = x + (segmTbl.width or 1)
|
||||
end
|
||||
y = y + (line.skip or 1)
|
||||
end
|
||||
if station.buttons then
|
||||
for _,button in pairs(station.buttons) do
|
||||
button.pressable = false
|
||||
button.selected = false
|
||||
button.isbutton = true
|
||||
if button.type == "r" then
|
||||
button.segm = ENT.Types.button_normal
|
||||
for k,v in ipairs(genStation) do
|
||||
if v.signal1 and v.signal1.name == button.signal then
|
||||
button.segm = v
|
||||
v.signal1.button = button
|
||||
break
|
||||
end
|
||||
if v.signal2 and v.signal2.name == button.signal then
|
||||
button.segm = v
|
||||
v.signal2.button = button
|
||||
break
|
||||
end
|
||||
if button.target and button.target[1] == v.x and button.target[2] == v.y then
|
||||
button.segm = v
|
||||
v.button = button
|
||||
if v.button then
|
||||
v.button = nil
|
||||
v.buttons = {v.button,button}
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(genStation.buttons,button)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function ARMSetNextCompare(posX,posY,segm,nsegm)
|
||||
local xp,yp = GetSegmPos(segm)
|
||||
local x,y = GetSegmPos(nsegm)
|
||||
if sx and posX == x and posY == y then
|
||||
nsegm.prev = segm
|
||||
return true
|
||||
end
|
||||
|
||||
sx,sy = GetSegmPos(nsegm,false)
|
||||
if sx and posX == sx and posY == sy then
|
||||
nsegm.next_m = segm
|
||||
return true
|
||||
end
|
||||
if not nsegm.segm.next_a then return end
|
||||
sx,sy = GetSegmPos(nsegm,true)
|
||||
if x ~= xp and y ~= yp and sx and posX == sx and posY == sy then
|
||||
nsegm.next_a = segm
|
||||
if segm.id == 29 then
|
||||
local x1,y1 = GetSegmPos(nsegm)
|
||||
local x2,y2 = GetSegmPos(segm)
|
||||
print(-2,x1,y1,x2,y2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNext(station)
|
||||
for csegmid,csegm in ipairs(station) do
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
|
||||
local posX,posY = GetSegmPos(csegm)
|
||||
if ARMSetNextCompare(posX,posY,csegm,segm) then
|
||||
csegm.prev = segm
|
||||
--break
|
||||
end
|
||||
local posOX,posOY = GetSegmPos(csegm,false)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_m = segm
|
||||
--break
|
||||
end
|
||||
local posAX,posAY = GetSegmPos(segm)
|
||||
if not csegm.segm.next_a or posX == posAX or posY == posAY then continue end
|
||||
posOX,posOY = GetSegmPos(csegm,true)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_a = segm
|
||||
--break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,st in ipairs(Metrostroi.ARMConfigGenerated) do ARMSetNext(st) end
|
||||
|
||||
|
||||
local function tcopy(from)
|
||||
local t = {}
|
||||
for k,v in pairs(from) do
|
||||
t[k] = v
|
||||
end
|
||||
return t
|
||||
end
|
||||
local iter = 1
|
||||
local function ARMFindSegmSignals(station,segm,dir,signals,last,checked,restbl,trace)
|
||||
if not restbl then restbl = {} end
|
||||
if not checked then checked = {} end
|
||||
if not trace then trace = {} end
|
||||
if checked[segm] then return end
|
||||
checked[segm] = true
|
||||
local segmIndex = table.insert(trace,{segm.id})
|
||||
--trace[segm] = true
|
||||
|
||||
iter = iter + 1
|
||||
if iter > 10000 then ARMGenError(Format("Routes generation error. Max iter reached!"),true) return false end
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local segmP = segm.prev
|
||||
|
||||
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if segmA and mainM then
|
||||
local trace= table.Copy(trace)
|
||||
|
||||
trace[segmIndex][2] = true
|
||||
local signal = dir and segmA.signal2 or segmA.signal1
|
||||
local button = segmA.button
|
||||
|
||||
if signal and table.HasValue(signals,signal.name) then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
elseif button and table.HasValue(signals,button.signal) then
|
||||
table.insert(trace,{segmA.id})
|
||||
table.insert(restbl,{button,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,segmA,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
if segmM and mainM then
|
||||
local signal = dir and segmM.signal2 or segmM.signal1
|
||||
local button = segmM.button
|
||||
if signal and table.HasValue(signals,signal.name) then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
elseif button and table.HasValue(signals,button.signal) then
|
||||
table.insert(trace,{segmM.id})
|
||||
table.insert(restbl,{button,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,segmM,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
if segmP and mainP then
|
||||
trace[segmIndex][2] = last and segm.next_a == last or nil-- or segmP.next_a == segm or nil
|
||||
local signal = dir and segmP.signal2 or segmP.signal1
|
||||
local button = segmP.button
|
||||
if signal and table.HasValue(signals,signal.name) then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
elseif button and table.HasValue(signals,button.signal) then
|
||||
table.insert(trace,{segmP.id})
|
||||
table.insert(restbl,{button,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,segmP,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
return restbl
|
||||
end
|
||||
|
||||
for i,station in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
print("STATION",i)
|
||||
for _,button in pairs(station.buttons) do
|
||||
if button.type == "r" and station.routes[button.signal] then
|
||||
print(button.signal,button.segm)
|
||||
button.pressable = true
|
||||
local results = ARMFindSegmSignals(station,button.segm,false,station.routes[button.signal])
|
||||
if #results == 0 then
|
||||
results = ARMFindSegmSignals(station,button.segm,true,station.routes[button.signal])
|
||||
end
|
||||
for k,v in pairs(results) do
|
||||
local i = 0
|
||||
for k,v in pairs(v[2]) do i = i + 1 end
|
||||
print("--",k,v,v[1],v[2],i)
|
||||
end
|
||||
--print(results[1][1].name,results[1][1].segm)--]]
|
||||
button.routes = results
|
||||
end
|
||||
--[[ if segm.signal2 then
|
||||
local result = ARMFindNextSegm(station,segm,true,nil,nil,segm.signal2.name=="PT640")
|
||||
if result and #result > 0 then
|
||||
print(segm.signal2.name.."->")
|
||||
for k,v in ipairs(result) do print(" "..v.name) end
|
||||
end
|
||||
end
|
||||
if segm.signal1 then
|
||||
local result = ARMFindNextSegm(station,segm,false,nil,nil,segm.signal1.name=="MD01")
|
||||
if result and #result > 0 then
|
||||
print(segm.signal1.name.."->")
|
||||
for k,v in ipairs(result) do print(" "..v.name) end
|
||||
end
|
||||
end--]]
|
||||
end
|
||||
|
||||
end
|
||||
if errors == 0 and warnings == 0 then
|
||||
MsgC(Color(0,255,0),"MetrostroiARM:Generate finished without errors and warnings.\n")
|
||||
elseif errors == 0 then
|
||||
MsgC(Color(255,255,0),"MetrostroiARM:Generate finished with "..warnings.." warnings.\n")
|
||||
else
|
||||
MsgC(Color(255,0,0),"MetrostroiARM:Generate finished with "..errors.." errors and "..warnings.." warnings!\n")
|
||||
end
|
||||
--PrintTable(Metrostroi.ARMConfigGenerated)
|
||||
|
||||
for k,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
Metrostroi.ARMTable[k] = {
|
||||
occChecks = {},
|
||||
net = {},
|
||||
signal = {},
|
||||
switch = {},
|
||||
routes = {},
|
||||
}
|
||||
end
|
||||
@@ -1,700 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
ENT.AutoAnims = {}
|
||||
ENT.AutoAnimNames = {}
|
||||
ENT.ClientSounds = {}
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
|
||||
ENT.ButtonMap["ARM"] = {
|
||||
pos = Vector(-4.9,9.1,50.3),
|
||||
ang = Angle(0,-90-1,90),
|
||||
width = 800,
|
||||
height = 600,
|
||||
scale = 0.02*1.2,
|
||||
mouse = true
|
||||
}
|
||||
ENT.ClientProps["ARMPK"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_screen.mdl",
|
||||
pos = Vector(-5,0,31.2),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMMonitor"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_body.mdl",
|
||||
pos = Vector(-5,15,0),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMKeyboard"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_keyboard.mdl",
|
||||
pos = Vector(-15,-2,31),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMMouse"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_mouse.mdl",
|
||||
pos = Vector(-18,-20,32),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMBreen"] = {
|
||||
model = "models/props_combine/breenglobe.mdl",
|
||||
pos = Vector(-11,30,39.5),
|
||||
ang = Angle(0,-180+45,0),
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self.BaseClass.Initialize(self)
|
||||
self.ARM = self:CreateRT("ARM",1024,1024)
|
||||
for k,v in pairs(self.Types) do
|
||||
for i,tex in pairs(v) do
|
||||
if type(tex) == "table" and type(tex[1]) == "string" then
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CamMoved()
|
||||
self:HandleMouse(false)
|
||||
gui.EnableScreenClicker(self.CurrentCamera ~= 0)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
if not self.RenderClientEnts or self.CreatingCSEnts then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.ARM then return end
|
||||
--self.MouseX = 0
|
||||
--self.MouseY = 0
|
||||
self.MouseX = self:GetNW2Int("CursorX",0)
|
||||
self.MouseY = self:GetNW2Int("CursorY",0)
|
||||
render.PushRenderTarget(self.ARM,0,0,1024, 1024)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
render.OverrideAlphaWriteEnable(true, true)
|
||||
surface.SetDrawColor(0,0,0)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
self:ARMMonitor()
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
|
||||
|
||||
function ENT:DrawPost()
|
||||
self.RTMaterial:SetTexture("$basetexture", self.ARM)
|
||||
self:DrawOnPanel("ARM",function(...)
|
||||
surface.SetMaterial(self.RTMaterial)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRectRotated(512,512,1024,1024,0)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local gray = Color(100,100,100)
|
||||
local black = Color(0,0,0)
|
||||
local white = Color(150,150,150)
|
||||
local green = Color(0,50,0)
|
||||
|
||||
local function GetTextures(segm,typ)
|
||||
return segm[typ],segm.maintex or segm[typ]
|
||||
end
|
||||
--Get texture Width and Height
|
||||
local function GetWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.w or dtex.w,tex.h or dtex.h
|
||||
end
|
||||
--Get real(original) texture Width and Height
|
||||
local function GetRWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
end
|
||||
--Get X and Y adds
|
||||
local function GetXYA(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
local function drawSegment(w,h,u0,v0,u1,v1,segm,typ,align)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
if dtex.mat then
|
||||
local sx,sy = GetXY(w,h)
|
||||
local sw,sh = GetWH(segm,typ)
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = GetXYA(segm,typ)
|
||||
local rw,rh = GetRWH(segm,typ)
|
||||
surface.SetDrawColor(tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
end
|
||||
local function drawElement(sx,sy,u0,v0,u1,v1,segm,typ,col)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex = segm[typ]
|
||||
local dtex = segm.maintex or tex
|
||||
--local sx,sy = 100+w*36,100+h*70
|
||||
local sw,sh = tex.w or dtex.w,tex.h or dtex.h
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
local rw,rh = tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
surface.SetDrawColor(col or tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0 ,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
|
||||
local mouse = surface.GetTextureID("gui/info")
|
||||
|
||||
local function createFont(name,font,size,weight)
|
||||
surface.CreateFont("Metrostroi_"..name, {
|
||||
font = font,
|
||||
size = size,
|
||||
weight = weight or 400,
|
||||
blursize = 0,
|
||||
antialias = true,
|
||||
underline = false,
|
||||
italic = false,
|
||||
strikeout = false,
|
||||
symbol = false,
|
||||
rotary = false,
|
||||
shadow = false,
|
||||
additive = false,
|
||||
outline = false,
|
||||
extended = true,
|
||||
})
|
||||
end
|
||||
createFont("Arial10","Arial",10,400)
|
||||
createFont("Arial20","Arial",20,800)
|
||||
|
||||
local colorConverter = {
|
||||
r = Color(0,0,0),
|
||||
y = Color(240,240,71),
|
||||
g = Color(41,202,26),
|
||||
b = Color(26,84,202),
|
||||
w = Color(255,255,255),
|
||||
}
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMFindNextSegm(station,csegm,alt,dir,deb)
|
||||
if dir then
|
||||
if alt and not csegm.segm.next_a then return end
|
||||
if not alt and not csegm.segm.next_m then return end
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x <= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(csegm,alt)
|
||||
local tx,ty = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
|
||||
if not txa then continue end
|
||||
--if tx then print(1,segm.x,segm.y,GetSegmPos2(csegm,alt),csegm.invertX,csegm.invertY) end
|
||||
local sx,sy = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
--if not alt then print(2,x,y,sx,sy,tx,ty,txa,tya) end
|
||||
if sx == tx and sy == ty then return segm,sx,sy end
|
||||
if sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(segm,false)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
--if deb then print(sx,x) end
|
||||
if sx and sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(segm,true)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm,sx,sy end
|
||||
end
|
||||
else
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x >= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(segm,alt)
|
||||
local tx,ty = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
|
||||
if not txa then continue end
|
||||
|
||||
local sx,sy = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
if sx == tx and sy == ty then return segm,sx,sy end
|
||||
if sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(csegm,false)
|
||||
|
||||
if sx and sx == txa and sy == tya then return segm,sx,sy end
|
||||
sx,sy = GetSegmPos(csegm,true)
|
||||
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm,sx,sy end
|
||||
end
|
||||
--[[ for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
if segm.x >= csegm.x then continue end
|
||||
local txa,tya = GetSegmPos(segm,alt)
|
||||
local tx,ty = GetXY(segm.x+segm.width*(segm.invertX or 0),segm.y)
|
||||
if not txa then continue end
|
||||
--if tx then print(1,segm.x,segm.y,GetSegmPos2(csegm,alt),csegm.invertX,csegm.invertY) end
|
||||
local sx,sy = GetXY(csegm.x+csegm.width*(csegm.invertX or 0),csegm.y)
|
||||
--if not alt then print(2,x,y,sx,sy,tx,ty,txa,tya) end
|
||||
if sx == tx and sy == ty then return segm end
|
||||
if sx == txa and sy == tya then return segm end
|
||||
sx,sy = GetSegmPos(csegm,false)
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
--if deb then print(sx,x) end
|
||||
if sx and sx == txa and sy == tya then return segm end
|
||||
sx,sy = GetSegmPos(csegm,true)
|
||||
--if alt then print(3,x,y,sx,sy,tx,ty) end
|
||||
--if sx and sx == tx and sy == ty then return segm,false end
|
||||
if sx and sx == txa and sy == tya and (not alt or segm.y ~= csegm.y) then return segm end
|
||||
end--]]
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNextCompare(posX,posY,segm,nsegm)
|
||||
local xp,yp = GetSegmPos(segm)
|
||||
local x,y = GetSegmPos(nsegm)
|
||||
if sx and posX == x and posY == y then
|
||||
nsegm.prev = segm
|
||||
return true
|
||||
end
|
||||
|
||||
sx,sy = GetSegmPos(nsegm,false)
|
||||
if sx and posX == sx and posY == sy then
|
||||
nsegm.next_m = segm
|
||||
return true
|
||||
end
|
||||
if not nsegm.segm.next_a then return end
|
||||
sx,sy = GetSegmPos(nsegm,true)
|
||||
if x ~= xp and y ~= yp and sx and posX == sx and posY == sy then
|
||||
nsegm.next_a = segm
|
||||
if segm.id == 29 then
|
||||
local x1,y1 = GetSegmPos(nsegm)
|
||||
local x2,y2 = GetSegmPos(segm)
|
||||
print(-2,x1,y1,x2,y2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNext(station)
|
||||
for csegmid,csegm in ipairs(station) do
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
|
||||
local posX,posY = GetSegmPos(csegm)
|
||||
if ARMSetNextCompare(posX,posY,csegm,segm) then
|
||||
csegm.prev = segm
|
||||
--break
|
||||
end
|
||||
local posOX,posOY = GetSegmPos(csegm,false)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_m = segm
|
||||
--break
|
||||
end
|
||||
local _,posAY = GetSegmPos(segm)
|
||||
if not csegm.segm.next_a or posX == posAX or posY == posAY then continue end
|
||||
posOX,posOY = GetSegmPos(csegm,true)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_a = segm
|
||||
--break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function ENT:ARMMonitor()
|
||||
if self.FilterMag then
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
end
|
||||
|
||||
render.PushFilterMag( TEXFILTER.POINT )
|
||||
render.PushFilterMin( TEXFILTER.POINT )
|
||||
self.FilterMag = true
|
||||
surface.SetDrawColor(gray)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
local station = self:GetNW2Int("ARM:Station",0)
|
||||
--draw.SimpleText("АРМ ДЫЫСЦЫПЫ","Metrostroi_BUKPSpeed",400, 300,Color(220,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
if station > 0 and Metrostroi.ARMConfigGenerated and Metrostroi.ARMConfigGenerated[station] then
|
||||
local armTable = Metrostroi.ARMConfigGenerated[station]
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"maintex")
|
||||
|
||||
--[[
|
||||
local w,h = GetXY(segm.x+segm.width*u0,segm.y)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(w+5*u1-5*u0,h,w,h)
|
||||
surface.DrawLine(w,h+5,w,h)
|
||||
local w,h = GetSegmPos(segm,false)
|
||||
surface.SetDrawColor(Color(255,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6,w,h)
|
||||
local w,h = GetSegmPos(segm,true)
|
||||
if w then
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6*v1+6*v0,w,h)
|
||||
end--]]
|
||||
end
|
||||
local w,h = 0,0
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if Metrostroi.GetARMInfo(station,id,"occup2") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_x")
|
||||
end
|
||||
if Metrostroi.GetARMInfo(station,id,"switch_m") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_a") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_a") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_na") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_an")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_mn")
|
||||
else
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
end
|
||||
if segm.signal1 then
|
||||
local sig = segm.signal1
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local x,y = 100+(segm.x+segm.width)*36,100+segm.y*70-(sig.top and -26 or 15)
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local sx,sy = x-rw-2,y-rh-2
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y-(sig.top and -7 or 15),Color(0,0,0),TEXT_ALIGN_RIGHT,TEXT_ALIGN_BOTTOM)
|
||||
drawElement(sx,sy,0,0,1,1,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal1") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal1I") then
|
||||
drawElement(sx+13*(sig.type-1),sy,0,0,1,1,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal1Y") then
|
||||
drawElement(sx+13*(sig.type-2),sy,0,0,1,1,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
if segm.signal2 then
|
||||
local sig = segm.signal2
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local x,y = 100+(segm.x)*36+2,100+segm.y*70+(sig.top and -38 or 3)
|
||||
local sx,sy = x-1,y+rh
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y+(sig.top and -2 or 20),Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_TOP)
|
||||
drawElement(sx,sy,1,1,0,0,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal2") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal2I") then
|
||||
drawElement(sx+rw-12-13*(sig.type-1),sy,1,1,0,0,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal2Y") then
|
||||
drawElement(sx+rw-12-13*(sig.type-2),sy,1,1,0,0,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
end
|
||||
for id,button in ipairs(armTable.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
if button.type=="r" then
|
||||
sw,sh = 15,25
|
||||
xa,ya = 3,12
|
||||
end
|
||||
local x,y = sx+xa,sy+ya
|
||||
if Metrostroi.GetARMInfo(station,1000+id,"buttonSelected") then
|
||||
surface.SetDrawColor(Color(80,80,180))
|
||||
elseif Metrostroi.GetARMInfo(station,1000+id,"buttonPressable") then
|
||||
surface.SetDrawColor(Color(220,220,220))
|
||||
else
|
||||
surface.SetDrawColor(Color(120,120,120))
|
||||
end
|
||||
surface.DrawRect(x,y,sw,sh)
|
||||
Metrostroi.DrawLine(x,y,x,y+sh,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x-1,y,x+sw,y,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x+sw,y,x+sw,y+sh,Color(60,60,60),2)
|
||||
Metrostroi.DrawLine(x,y+sh,x+sw+1,y+sh,Color(60,60,60),2)
|
||||
end
|
||||
end
|
||||
for i,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
if i == station then
|
||||
surface.SetDrawColor(Color(110,140,170))
|
||||
elseif math.InRangeXYR(self.MouseX,self.MouseY,20+(i-1)*30,20,30,20) then
|
||||
surface.SetDrawColor(Color(80,110,140))
|
||||
else
|
||||
surface.SetDrawColor(Color(100,130,160))
|
||||
end
|
||||
|
||||
surface.DrawRect(20+(i-1)*31,20,30,20)
|
||||
draw.SimpleText(v.shortname or v.id,"Metrostroi_Arial20",35+(i-1)*31, 30,Color(40,60,170),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end
|
||||
--if self.CurrentCamera == 0 then
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.SetTexture(mouse)
|
||||
surface.DrawTexturedRectRotated(self.MouseX,self.MouseY,8,8,0)
|
||||
--end
|
||||
surface.SetDrawColor(0,0,0,200)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
self.FilterMag = false
|
||||
--[=[
|
||||
local iter = 0
|
||||
local function ARMFindSegmSignals(station,segm,dir,signals,checked,restbl,trace,NextAlt)
|
||||
if not restbl then restbl = {} end
|
||||
if not checked then checked = {} end
|
||||
if not trace then trace = {} end
|
||||
if checked[segm] then return end
|
||||
checked[segm] = true
|
||||
local segmIndex = table.insert(trace,{segm.id})
|
||||
--trace[segm] = true
|
||||
|
||||
iter = iter + 1
|
||||
if iter > 10000 then ARMGenError(Format("Routes generation error. Max iter reached!"),true) return false end
|
||||
local segmt = segm.segm
|
||||
local segmM,segmA = segmt.next_m,segmt.next_a
|
||||
if not segmM then return end
|
||||
|
||||
local NextM = ARMFindNextSegm(station,segm,not NextAlt,dir)
|
||||
local NextA = ARMFindNextSegm(station,segm,NextAlt,dir)
|
||||
|
||||
|
||||
local xp,yp = GetXY(segm.x,segm.y)
|
||||
if NextA then
|
||||
local trace= table.Copy(trace)
|
||||
trace[segmIndex][2] = true
|
||||
local xn,yn = GetXY(NextA.x,NextA.y)
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
local xa2,ya2 = GetSegmPos(NextA,true)
|
||||
--trace[segmIndex][2] = true
|
||||
local nxt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
--MsgN(Format("->A\n",segm.x,segm.y))
|
||||
local signal = dir and NextA.signal2 or NextA.signal1
|
||||
--print("A",segm.x,segm.y,NextA.x,NextA.y,signal and signal.name,dir)
|
||||
if signal and table.HasValue(signals,signal.name) then--and not segmOnA.invertX then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,NextA,dir,signals,checked,restbl,trace,true)
|
||||
end
|
||||
if NextM then
|
||||
local xn,yn = GetXY(NextM.x,NextM.y)
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
local xa2,ya2 = GetSegmPos(NextM,true)
|
||||
local nxt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
local signal = dir and NextM.signal2 or NextM.signal1
|
||||
--print("M",segm.x,segm.y,NextM.x,NextM.y,signal and signal.name,dir)
|
||||
if signal and table.HasValue(signals,signal.name) then--and not segmOnA.invertX then
|
||||
table.insert(restbl,{signal,table.Copy(trace)})
|
||||
end
|
||||
ARMFindSegmSignals(station,NextM,dir,signals,checked,restbl,table.Copy(trace))
|
||||
end
|
||||
return restbl
|
||||
end
|
||||
local station = Metrostroi.ARMConfigGenerated[station]
|
||||
for _,button in pairs(station.buttons,station.routes["PT64"]) do
|
||||
if button.type == "r" and station.routes[button.signal] then
|
||||
--button.pressable = true
|
||||
local results = ARMFindSegmSignals(station,button.segm,false,station.routes[button.signal])
|
||||
if #results == 0 then
|
||||
results = ARMFindSegmSignals(station,button.segm,true,station.routes[button.signal])
|
||||
end
|
||||
for k,v in pairs(results) do
|
||||
local i = 0
|
||||
for k,v in pairs(v[2]) do
|
||||
print(v[2])
|
||||
end
|
||||
end
|
||||
--print(results[1][1].name,results[1][1].segm)--]]
|
||||
--button.routes = results
|
||||
end
|
||||
end--]=]
|
||||
--[=[
|
||||
local x = 0
|
||||
local founded = true
|
||||
local stat = Metrostroi.ARMConfigGenerated[station]
|
||||
local maxd = 3
|
||||
local x = 26-- or math.ceil((CurTime()%10)/10*#stat)
|
||||
local dir = true-- or CurTime()%20 > 10
|
||||
local function findt(station,segm,dir,i,depth,px,py )
|
||||
depth = depth or 0
|
||||
i = i or 0
|
||||
local segmt = segm.segm
|
||||
local segmM,segmA = segmt.next_m,segmt.next_a
|
||||
local NextM,NextMX,NextMY = ARMFindNextSegm(station,segm,false,dir)
|
||||
local NextA,NextAX,NextAY = ARMFindNextSegm(station,segm,true,dir)
|
||||
local xp,yp = GetXY(segm.x,segm.y)
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",xp,yp,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
draw.SimpleText(Format("%.1f:%.1f",segm.x,segm.y),"Metrostroi_Arial10",xp,yp-20,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
|
||||
local xa1,ya1 = GetSegmPos(segm,true)
|
||||
if i==4 then print(xa1,ya1,px,py,xa1 == px and ya1 == py) end
|
||||
local alt = px and py ~= yp and xa1 == px and ya1 == py
|
||||
if NextA and depth+1 < maxd then
|
||||
--if i==3 then print(1) end
|
||||
local xn,yn = GetXY(NextA.x,NextA.y)
|
||||
local xa2,ya2 = GetSegmPos(NextA,true)
|
||||
local nalt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
if nalt or alt then surface.SetDrawColor(Color(255,0,0))
|
||||
else surface.SetDrawColor(Color(0,255,0)) end
|
||||
surface.DrawLine(px or xp,py or yp,NextAX or xn,NextAY or yn)
|
||||
if findt(station,NextA,dir,i+1,depth+1,NextAX,NextAY) then return end
|
||||
--return true
|
||||
--if i==5 then print("RES",segm.x,segm.y,NextA.x,NextA.y) end
|
||||
end
|
||||
if NextM and depth < maxd then
|
||||
local xn,yn = GetXY(NextM.x,NextM.y)
|
||||
local xa2,ya2 = GetSegmPos(NextM,true)
|
||||
local nalt = xa1==xn and ya1==yn or
|
||||
xa2==xn and ya2==yn or
|
||||
xa1==xp and ya1==yp or
|
||||
xa2==xp and ya2==yp or
|
||||
xa1 and xa2 and xa1==xa2 and ya1==ya2
|
||||
if alt then surface.SetDrawColor(Color(255,255,0))
|
||||
else surface.SetDrawColor(Color(0,255,0)) end
|
||||
surface.DrawLine(px or xp,py or yp,NextMX or xn,NextMY or yn)
|
||||
if findt(station,NextM,dir,i+1,depth,NextMX,NextMY) then return end
|
||||
end
|
||||
end
|
||||
--findt(stat,stat[x],dir)--]=]
|
||||
--[==[
|
||||
if Metrostroi.ARMConfigGenerated[station] then
|
||||
ARMSetNext(Metrostroi.ARMConfigGenerated[station])
|
||||
--[=[ for id,segm in ipairs(Metrostroi.ARMConfigGenerated[station]) do
|
||||
local ws,hs = GetSegmPos(segm)
|
||||
draw.SimpleText(segm.id,"Metrostroi_Arial20",ws,hs-15--[[ *(math.random()*5)--]] ,Color(0,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
if segm.next_m then
|
||||
local w,h = GetSegmPos(segm.next_m)
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(ws,hs,w,h)
|
||||
surface.DrawLine(ws-6,hs-6,ws+6,hs+6)
|
||||
surface.DrawLine(ws-6,hs+6,ws+6,hs-6)
|
||||
surface.DrawLine(w-6,h-2,w+6,h+2)
|
||||
surface.DrawLine(w-6,h+2,w+6,h-2)
|
||||
else
|
||||
local w,h = GetSegmPos(segm)
|
||||
w = w+segm.width*36/2
|
||||
surface.SetDrawColor(Color(255,0,255))
|
||||
surface.DrawLine(w-4,h-4,w+4,h+4)
|
||||
surface.DrawLine(w-4,h+4,w+4,h-4)
|
||||
continue
|
||||
end
|
||||
if segm.next_a then
|
||||
local w,h = GetSegmPos(segm.next_a)
|
||||
draw.SimpleText(segm.id,"Metrostroi_Arial20",w,h+15,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(ws,hs,w,h)
|
||||
surface.DrawLine(ws-7,hs-4,ws+7,hs+4)
|
||||
surface.DrawLine(ws-7,hs+4,ws+7,hs-4)
|
||||
surface.DrawLine(w-7,h-2,w+7,h+2)
|
||||
surface.DrawLine(w-7,h+2,w+7,h-2)
|
||||
end
|
||||
end--]=]
|
||||
local x = 0
|
||||
local founded = true
|
||||
local stat = Metrostroi.ARMConfigGenerated[station]
|
||||
local maxd = 2
|
||||
local x = 21-- or math.ceil((CurTime()%10)/10*#stat)
|
||||
local dir = true-- or CurTime()%20 > 10
|
||||
local function findt(station,segm,dir,i,depth,last )
|
||||
depth = depth or 0
|
||||
i = i or 0
|
||||
local segmP = segm.prev
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local x,y = GetXY(segm.x,segm.y)
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",x,y,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
draw.SimpleText(Format("%.1f:%.1f",segm.x,segm.y),"Metrostroi_Arial10",x,y-20,Color(255,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
|
||||
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if i==7 and last.next_a then
|
||||
draw.SimpleText(i,"Metrostroi_Arial20",x,y,Color(0,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
local x,y = GetXY(last.x,last.y)
|
||||
draw.SimpleText(i-1,"Metrostroi_Arial20",x,y,Color(255,255,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
--print(last.next_a,segm)
|
||||
end
|
||||
|
||||
if segmA and mainM and depth+1 < maxd then
|
||||
--if i==3 then print(1) end
|
||||
local xn,yn = GetXY(segmA.x,segmA.y)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmA,dir,i+1,depth+1,segm) then return end
|
||||
return true
|
||||
--if i==5 then print("RES",segm.x,segm.y,NextA.x,NextA.y) end
|
||||
end
|
||||
if segmM and mainM and depth < maxd then
|
||||
local xn,yn = GetXY(segmM.x,segmM.y)
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmM,dir,i+1,depth,segm) then return end
|
||||
end
|
||||
if segmP and mainP and depth < maxd then
|
||||
local xn,yn = GetXY(segmP.x,segmP.y)
|
||||
local alt = last and segm.next_a == last or segmP.next_a == segm
|
||||
if alt then surface.SetDrawColor(Color(255,255,0))
|
||||
else surface.SetDrawColor(Color(0,255,255)) end
|
||||
surface.DrawLine(x,y,xn,yn)
|
||||
if findt(station,segmP,dir,i+1,depth,segm) then return end
|
||||
end
|
||||
end
|
||||
findt(stat,stat[x],dir)
|
||||
end--]==]
|
||||
--findt(stat,stat[6],false)
|
||||
end
|
||||
Metrostroi.GenerateClientProps()
|
||||
@@ -1,189 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_combine/breendesk.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self.DriverSeat = self:CreateSeat("driver", Vector(-40, 0, 0), Angle(0, 0, 0), "models//nova/chair_office02.mdl")
|
||||
self.CursorX = 0
|
||||
self.CursorY = 0
|
||||
self:CursorMove(0, 0)
|
||||
self.Station = 0
|
||||
end
|
||||
|
||||
hook.Add("AcceptInput", "metrostroi_arm_trigger_check", function(ent, inputName, activator, called, data)
|
||||
if inputName == "ARMStartTouch" then
|
||||
called.ARMTriggered = true
|
||||
print(called, called:GetName(), activator, "Enable")
|
||||
end
|
||||
|
||||
if inputName == "ARMEndTouch" then
|
||||
called.ARMTriggered = false
|
||||
print(called, called:GetName(), activator, "Disable")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
local function GetOccupation(tbl)
|
||||
for sID,signame in ipairs(tbl) do
|
||||
if signame[1] == "@" then
|
||||
local trigger = Metrostroi.ARMGet(signame:sub(2,-1), "trigger")
|
||||
if not trigger or trigger.ARMTriggered then
|
||||
return true
|
||||
end
|
||||
elseif signame ~= "" then
|
||||
local signal = Metrostroi.ARMGet(signame, "signal")
|
||||
if not signal or signal.OccupiedBy and signal.OccupiedBy ~= signal then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local armTbl = Metrostroi.ARMTable
|
||||
local armConf = Metrostroi.ARMConfigGenerated
|
||||
local station = armConf[self.Station]
|
||||
local armTblStation = armTbl[self.Station]
|
||||
if not station then return end
|
||||
if not armTblStation or (IsValid(armTblStation.Controller) and armTblStation.Controller ~= self) then return end
|
||||
armTblStation.Controller = self
|
||||
for buttonID,button in ipairs(station.buttons) do
|
||||
--print(button,button.selected)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonPressable",button.pressable)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonSelected",button.selected)
|
||||
end
|
||||
for segmID, segm in ipairs(station) do
|
||||
if type(segm) == "table" then
|
||||
if segm.occup then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup", segm.occupied)
|
||||
end
|
||||
|
||||
if segm.occup2 then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup2", segm._occup or GetOccupation(segm.occup2))
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "route", segm.route and true)
|
||||
|
||||
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
local alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_m", main)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_a", alt)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_na", not main and not alt)
|
||||
end
|
||||
if segm.signal1 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal1.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal1.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal1I", signal and signal.InvationSignal) end
|
||||
if segm.signal1.type > 2 and colors then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1", colors)
|
||||
end
|
||||
if segm.signal2 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal2.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal2.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal2I", signal and signal.InvationSignal) end
|
||||
if segm.signal2.type > 2 and colors then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2", colors)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:NextThink(CurTime() + 0.5)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
function ENT:CursorMove(sys, dX, dY)
|
||||
self.CursorX = sys == "" and math.Clamp(self.CursorX + dX * 200, 0, 800) or dX
|
||||
self.CursorY = sys == "" and math.Clamp(self.CursorY + dY * 200, 0, 600) or dY
|
||||
self:SetNW2Int("CursorX", math.floor(self.CursorX))
|
||||
self:SetNW2Int("CursorY", math.floor(self.CursorY))
|
||||
end
|
||||
|
||||
local function GetTextures(segm,typ)
|
||||
return segm[typ],segm.maintex or segm[typ]
|
||||
end
|
||||
--Get real(original) texture Width and Height
|
||||
local function GetRWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
end
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
function ENT:PanelTouch(state, x, y)
|
||||
for i, v in ipairs(Metrostroi.ARMConfig) do
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, 20 + (i - 1) * 30, 20, 30, 20) then
|
||||
self.Station = i
|
||||
self:SetNW2Int("ARM:Station", i)
|
||||
end
|
||||
end
|
||||
if not state then return end
|
||||
local RouteChoosing = self.RouteChoosing
|
||||
self.RouteChoosing = nil
|
||||
if RouteChoosing then
|
||||
print("DISABLE")
|
||||
for k,v in pairs(RouteChoosing.routes) do
|
||||
if v[1].button then
|
||||
v[1].button.selected = false
|
||||
elseif v[1].isbutton then
|
||||
v[1].selected = false
|
||||
end
|
||||
end
|
||||
end
|
||||
local confGenStation = Metrostroi.ARMConfigGenerated[self.Station]
|
||||
for k,button in pairs(confGenStation.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
if button.type == "r" then
|
||||
local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
local x,y = sx+xa,sy+ya
|
||||
if RouteChoosing then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
for k,v in ipairs(RouteChoosing.routes) do
|
||||
if v[1].button and button == v[1].button or v[1].isbutton and button==v[1] then
|
||||
Metrostroi.CentralisationPrepareRoute(self.Station,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif not self.RouteChoosing and button.pressable then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
self.RouteChoosing = button
|
||||
for k,v in ipairs(button.routes) do
|
||||
if v[1].button then
|
||||
v[1].button.selected = true
|
||||
elseif v[1].isbutton then
|
||||
v[1].selected = true
|
||||
print(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not self.RouteChoosing and not RouteChoosing then
|
||||
for k,segm in ipairs(confGenStation) do
|
||||
local x,y = GetXY(segm.x,segm.y)
|
||||
local w,h = GetRWH(segm.segm,"maintex")
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,w,h) then
|
||||
segm._occup = not segm._occup
|
||||
print(segm)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,753 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
--Inherit subway base for some need functions
|
||||
ENT.Base = "gmod_subway_base"
|
||||
ENT.NoTrain = true
|
||||
|
||||
ENT.PrintNameTranslated = "Entities.ARM"
|
||||
ENT.Category = "Metrostroi"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = true
|
||||
|
||||
ENT.Cameras = {
|
||||
{Vector(-18+3,0,43+2),Angle(0,0,0),"ARM.Monitor1",true},
|
||||
}
|
||||
ENT.Types = {
|
||||
--Main segments
|
||||
[0.25]={
|
||||
maintex = {"metrostroi_arm/sec025",w=8,h=8,rw=7,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec025_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec025_m",col=Color(39,103,63)},
|
||||
width = 0.25,
|
||||
next_m = {x=0.25,y=0}
|
||||
},
|
||||
[0.5]={
|
||||
maintex = {"metrostroi_arm/sec05",w=16,h=8,rw=16,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec05_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec05_m",col=Color(39,103,63)},
|
||||
width = 0.5,
|
||||
next_m = {x=0.5,y=0}
|
||||
},
|
||||
[1]={
|
||||
maintex = {"metrostroi_arm/sec1",w=64,h=8,rw=34,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec1_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec1_m",col=Color(39,103,63)},
|
||||
width = 1,
|
||||
next_m = {x=1,y=0}
|
||||
},
|
||||
[2]={
|
||||
maintex = {"metrostroi_arm/sec2",w=128,h=8,rw=70,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec2_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec2_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0}
|
||||
},
|
||||
[3]={
|
||||
maintex = {"metrostroi_arm/sec3",w=128,h=8,rw=106,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec3_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec3_m",col=Color(39,103,63)},
|
||||
width = 3,
|
||||
next_m = {x=3,y=0}
|
||||
},
|
||||
[4]={
|
||||
maintex = {"metrostroi_arm/sec4",w=256,h=8,rw=142,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec4_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec4_m",col=Color(39,103,63)},
|
||||
width = 4,
|
||||
next_m = {x=4,y=0}
|
||||
},
|
||||
[5]={
|
||||
maintex = {"metrostroi_arm/sec5",w=256,h=8,rw=178,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec5_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec5_m",col=Color(39,103,63)},
|
||||
width = 5,
|
||||
next_m = {x=5,y=0}
|
||||
},
|
||||
--Switches and helpers
|
||||
sw = {
|
||||
maintex = {"metrostroi_arm/switch",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/switch_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/switch_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/switch_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/switch_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/switch_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/switch_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/switch_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/switch_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
["2sw"] = {
|
||||
maintex = {"metrostroi_arm/2-switch_half",w=128,h=256,rw=70,rh=143,},
|
||||
occup_m = {"metrostroi_arm/2-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch_half_as",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch_half_ms",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
},
|
||||
["2swm"] = {
|
||||
maintex = {"metrostroi_arm/2-switch-middle_half",w=128,h=128,rw=70,rh=73,},
|
||||
occup_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch-middle_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch-middle_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
},
|
||||
["4sw"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter",w=128,h=256,rw=73,rh=143,x=-3,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(39,103,63)},
|
||||
occup_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(255,255,255)},
|
||||
route_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
["4sws"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter_small",w=64,h=128,rw=53,rh=78,x=-1,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(255,255,255),x=-1,},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(39,103,63),x=-1,},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(255,255,255),x=-1,},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(39,103,63),x=-1,},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(200,50,50)},
|
||||
width = 1.5,
|
||||
next_m = {x=1.5,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
ofd = {
|
||||
maintex = {"metrostroi_arm/offset_down",w=64,h=256,rw=57,rh=143,},
|
||||
occup_m = {"metrostroi_arm/offset_down_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offset_down_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=2},
|
||||
},
|
||||
ofds = {
|
||||
maintex = {"metrostroi_arm/offsed_down_small",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/offsed_down_small_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offsed_down_small_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=1},
|
||||
},
|
||||
ysw = {
|
||||
maintex = {"metrostroi_arm/Y-switch_half",w=128,h=128,rw=70,rh=108,},
|
||||
occup_m = {"metrostroi_arm/Y-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/Y-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/Y-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/Y-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/Y-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/Y-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/Y-switch_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/Y-switch_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
--Signals
|
||||
tl_1 = {
|
||||
maintex = {"metrostroi_arm/tl_1",w=32,h=16,rw=21,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_2 = {
|
||||
maintex = {"metrostroi_arm/tl_2",w=64,h=16,rw=34,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_3 = {
|
||||
maintex = {"metrostroi_arm/tl_3",w=64,h=16,rw=47,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
}
|
||||
if CLIENT then
|
||||
for i,segm in pairs(ENT.Types) do
|
||||
for k,tex in pairs(segm) do
|
||||
if type(tex) ~= "table" or type(tex[1]) ~= "string" then continue end
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
segm.id = i
|
||||
end
|
||||
end
|
||||
|
||||
--------------
|
||||
-- Syntax of table
|
||||
-- {
|
||||
-- station = "ID,abbreviation,full name"
|
||||
-- First line of segments
|
||||
-- {"segment type:occupation checkers,...,occupation checkers:lights:...:lights"},
|
||||
-- Second line of segments
|
||||
-- {x=x indent,skip=y indent(skips y segments vertically),"segment type:occupation checkers main,...,occupation checkers main:occupation checkers alt,...,occupation checkers alt:lights:...:lights"},
|
||||
-- }
|
||||
-- segment type can have > or ! on start, when we want mirror it vertically or horisontally
|
||||
-- Occupation checkers can be triggers(have @ in start of trigger name) or signals
|
||||
-- Lights can be empty, if we want take light name from occupation checkers
|
||||
-- Lights can have ! when stay in right direction or !! when stay in opposite direction
|
||||
-- Lights can have > when we want switch light location from bottom to top
|
||||
-- Examples
|
||||
--{
|
||||
-- station = "001,ST,Station name",
|
||||
-- {
|
||||
-- {"1:L1:!","1:L3:!","sw:@sw1trigger:@sw3trigger"}
|
||||
-- {x=1,"1:L2",">sw:@sw2trigger:@sw3rigger"},
|
||||
-- }
|
||||
--}
|
||||
--------------
|
||||
Metrostroi.ARMConfig = {
|
||||
---[=[
|
||||
{
|
||||
station = "451,ВБ,Уоллеса брина",
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","sw:1","3:1","3:1"},
|
||||
{x=7,"0.5:1","4sws:1",">4sws:1","1:1","1:1"},{skip=1},
|
||||
{x=7,"0.5:1","!4sws:1",">!4sws:1","1:1","1:1"},
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","!sw:1","3:1","3:1"},
|
||||
},{
|
||||
station="915,РЧ,Речная",
|
||||
{x=3.5,"0.5:RX22","1:RX22","1:RX20","0.5:RX98","4sw:::RX1:0",">4sw:::RX3:","1","2","2","1","1"},{skip=3},
|
||||
{"1:201","0.5:203","0.5:205","0.5:207","0.5:209","0.5:211","0.5:213","1:215","1:217","0.5:219","!4sw:::RX2::!!2RX95",">!4sw:::RX4:","1","2","2","1","1"},
|
||||
},{
|
||||
station="110,МД,Международная",
|
||||
{"1:145//:!1","1:143:!1","1:141//:!1","0.5:RC137","0.5:139M:!1","3:137:!>1","sw:@wt_md_s1:@wt_md_s1:MD1:!!>2D:!>2G","3:@wt_md_t1_1::!2MD3","2:@wt_md_t1_2"},
|
||||
{x=9,"4sws:@wt_md_s3::MD3",">4sws:@wt_md_s5::MD5:!2MD1","2:@wt_md_t3"},{skip=1},
|
||||
{x=9,"!4sws:@wt_md_s4::MD4",">!4sws:@wt_md_s6::MD6:!>2MD2","2:@wt_md_t4"},
|
||||
{"1:MD148:!!2","1:MD146:!!2","1:MD144:!!2","1:MD142:!!2:!1 OP","1:MD140:!!2","1:RC144A","1:RC142","!sw:@wt_md_s2:@wt_md_s2:MD2:!!2MD138G:!1E","3:@wt_md_t2_1::!>2MD4","2:@wt_md_t2_2"},
|
||||
buttons = {
|
||||
{type="r",y=4-0.6 ,x=4, signal=" OP",target={3,4}},
|
||||
{type="r",y=4 ,x=-1+0.4, signal="MD148"},
|
||||
{type="r",y=4 ,x=6+0.4, signal="MD138G"},
|
||||
{type="r",y=4-0.6 ,x=9, signal="E"},
|
||||
{type="r",y=3 ,x=14, signal="4I",target={12,3}},
|
||||
{type="r",y=1-0.6 ,x=14, signal="3I",target={12,1}},
|
||||
{type="r",y=3 ,x=12, signal="MD2"},
|
||||
{type="r",y=1-0.6 ,x=12, signal="MD1"},
|
||||
--{type="r",y=0-0.6 ,x=4, signal="13"},
|
||||
{type="r",y=0-0.6 ,x=6+0.4, signal="D",target={4,0}},
|
||||
{type="r",y=0 ,x=9, signal="G"},
|
||||
},
|
||||
routes = {
|
||||
MD148={" OP"},
|
||||
[" OP"]={"MD138G"},
|
||||
MD138G={"4I","3I"},
|
||||
E={" OP"},
|
||||
MD2={" OP","D"},
|
||||
MD1={" OP","D"},
|
||||
D={"4I","3I"},
|
||||
G={"D"},
|
||||
},
|
||||
signals = {
|
||||
--"LensesStr": "YYG-RW",
|
||||
MD148={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD146={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD144={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD142={
|
||||
Mode=1, --AB 1/5
|
||||
R="3",RY="31",Y="1",G="2",IS="4", --Lenses ID
|
||||
Autostop = true,AO = false,bs=4,
|
||||
},
|
||||
MD140={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",--[[ Y="1",--]] YG="13",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD138G={
|
||||
Mode=1, --AB 1/5
|
||||
R="3",RY="32",W="1",IS="4", --Lenses ID
|
||||
Autostop = true,AO = false,bs=1,
|
||||
},
|
||||
MD3={
|
||||
Mode=1, --AB 1/5
|
||||
R="1",IS="2",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD4={
|
||||
Mode=1, --AB 1/5
|
||||
R="1",IS="2",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD1={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD2={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
E={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
G={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
D={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
}
|
||||
},{
|
||||
station="112,ПТ,Политехническая",
|
||||
{x=1,"1:PT2TB","2:PT2TA","2:PT2T:!!2PT2","2:PT4SA:!!2PT4",">2swm:@wt_pt_t4::PT4:!3PT968M:!!2G ","1:PT966A","2:PT966:!>2","sw:@wt_pt_t6::PT6:!>2PT964:!!>3A","1:962"},
|
||||
{x=15,"1:PT6SS","1:963"},
|
||||
{x=1,"1:77:!1","1:75:!1","1:73:!1","1:71:!>1",">2swm:@wt_pt_t1::PT1:!!>2B","!2swm:@wt_pt_t3::PT3:!>2PT69","1:PT67M:!2","1:PT65B","1:PT65A","1:PT65:!2","1:PT63:!2:!!1 OP ","1:PT61:!2","1:PT59:!2","1:PT57:!2"},{skip=1},
|
||||
{"1:PT70:!!2:!1 OP2 ","1:PT68:!!2","2:@wt_pt_t2:!!2PT66","!2swm:@wt_pt_t4::PT2:!!3PT64","2","2:62:!!1","1:60:!!1","2:60A","1:58M:!!1","1:56:!!1","1:54:!!1","1: 52:!!1"},
|
||||
{},
|
||||
labels = {
|
||||
|
||||
},
|
||||
buttons = {
|
||||
{type="r",y=0-0.6 ,x=1, signal="3T",target={1,0},flip=true},
|
||||
{type="r",y=0 ,x=3+0.4,signal="PT2",target={1,0},flip=true},
|
||||
|
||||
{type="r",y=4-0.6 ,x=1, signal=" OP2 "},
|
||||
{type="r",y=4 ,x=-1+0.4, signal="PT70"},
|
||||
{type="r",y=4 ,x=3+0.4, signal="2P",target={8,4}},
|
||||
--{type="r",y=4 ,x=7+0.4, signal="62"},
|
||||
{type="r",y=2 ,x=5, signal="71"},
|
||||
{type="r",y=2-0.6 ,x=4+0.4, signal="B",target={5,2}},
|
||||
{type="r",y=2-0.6 ,x=17, signal="PT57"},
|
||||
{type="r",y=2-0.6 ,x=10, signal="PT67M"},
|
||||
{type="r",y=2 ,x=12+0.4,signal=" OP "},
|
||||
{type="r",y=0-0.6 ,x=10, signal="PT968M",flip=true},
|
||||
{type="r",y=0 ,x=15, signal="PT964",flip=true},
|
||||
{type="r",y=1-0.6 ,x=15, signal="4O",target={15,1},flip=true},
|
||||
{type="r",y=0-0.6 ,x=12+0.4,signal="A",flip=true},
|
||||
},
|
||||
routes = {
|
||||
PT2 = {"A"},
|
||||
PT70 = {" OP ","A","2P"},
|
||||
--PT64 = {" OP ","A","PT64"},
|
||||
B = {" OP ","A"},
|
||||
PT57 = {"PT67M"},
|
||||
PT964 = {"PT968M"},
|
||||
PT67M = {"71"," OP2 "},
|
||||
PT968M = {"3T","71"," OP2 "},
|
||||
A={"4O"}
|
||||
},
|
||||
signals = {
|
||||
--"LensesStr": "YYG-RW",
|
||||
PT70={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT68={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT66={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT64={ --"YWY-GRW
|
||||
Mode=1, --AB 1/5
|
||||
R="5",RY="51",Y="3",YG="34",G="4",IS="6",W="2",YY="13",YbY="1b3", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
routes = {
|
||||
[" OP "]={path=2,mode=3},--Path-2, Mode: W
|
||||
A={path=3,mode=2},--Path-2, Mode: YY
|
||||
}
|
||||
}
|
||||
}
|
||||
},{
|
||||
station="115,ОК,Октябрьская",
|
||||
{"1","1","1","1","3","sw:::OK1","1"},
|
||||
{x=9,"4sws:::OK3",">4sws:::OK5","1"},{skip=1},
|
||||
{x=9,"!4sws:::OK4",">!4sws:::OK6","1"},
|
||||
{"1","1","1","1","3","!sw:::OK2","5"},
|
||||
}--]=]
|
||||
}
|
||||
|
||||
print("MetrostroiARM:Generating ARM table...")
|
||||
local errors,warnings = 0,0
|
||||
local function ARMGenError(text,err)
|
||||
MsgC(Color(255,err and 0 or 255,0),"MetrostroiARM:"..text.."\n")
|
||||
ErrorNoHalt()
|
||||
if err then errors = errors + 1 else warnings = warnings + 1 end
|
||||
end
|
||||
|
||||
local function ParseARMTable(text,station,line,segm)
|
||||
local resultTbl = {}
|
||||
|
||||
local tbl = string.Explode(":",text)
|
||||
|
||||
local typ = tbl[1]
|
||||
if typ:find("^[>!]") then
|
||||
resultTbl.invertX = typ:find(">")
|
||||
resultTbl.invertY = typ:find("!")
|
||||
typ = typ:gsub("^[>!]+","")
|
||||
end
|
||||
local segmTyp = ENT.Types[tonumber(typ) or typ]
|
||||
if not segmTyp then return {error = 1,type = tbl[1]} end
|
||||
table.remove(tbl,1)
|
||||
|
||||
for i,str in ipairs(tbl) do
|
||||
if str:find(",") then
|
||||
tbl[i] = string.Explode(",",str)
|
||||
end
|
||||
if str:sub(1,2) == "!!" then
|
||||
resultTbl.signal2 = str:sub(3,-1)
|
||||
elseif str[1] == "!" then
|
||||
resultTbl.signal1 = str:sub(2,-1)
|
||||
end
|
||||
end
|
||||
resultTbl.occup = type(tbl[1]) == "table" and tbl[1] or {tbl[1]}
|
||||
if segmTyp.occup_a then
|
||||
resultTbl.occupAlt = type(tbl[2]) == "table" and tbl[2] or {tbl[2]}
|
||||
resultTbl.switch = tbl[3]
|
||||
if segmTyp.occup_x then
|
||||
resultTbl.occup2 = type(tbl[4]) == "table" and tbl[4] or {tbl[4]}
|
||||
end
|
||||
end
|
||||
|
||||
if resultTbl.signal1 then
|
||||
local signal = resultTbl.signal1:gsub("^[>]+","")
|
||||
local top = resultTbl.signal1:find("^>")
|
||||
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal1 = {name=name,type=typ or 1,top = top,segm=resultTbl}
|
||||
end
|
||||
if resultTbl.signal2 then
|
||||
local signal = resultTbl.signal2:gsub("^[>]+","")
|
||||
local top = resultTbl.signal2:find("^>")
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal2 = {name=name,type=typ or 1,top = top,segm=resultTbl}
|
||||
end
|
||||
resultTbl.type = typ
|
||||
resultTbl.width = segmTyp.width or 1
|
||||
resultTbl.segm = segmTyp
|
||||
return resultTbl
|
||||
end
|
||||
|
||||
|
||||
Metrostroi.ARMConfigGenerated = {}
|
||||
local id = 0
|
||||
for i,station in ipairs(Metrostroi.ARMConfig) do
|
||||
if not Metrostroi.ARMConfigGenerated[i] then Metrostroi.ARMConfigGenerated[i] = {} end
|
||||
local genStation = Metrostroi.ARMConfigGenerated[i]
|
||||
local y = 0
|
||||
|
||||
MsgC(Color(0, 222, 255),"MetrostroiARM:Solving station ",i,"\n")
|
||||
if #station == 0 then ARMGenError(Format("Parser warning. Empty station %d! Skipping...",i),false) continue end
|
||||
if not station.station then ARMGenError(Format("Parser error. Can't find station name in station %d! Skipping...",i),true) continue end
|
||||
|
||||
local stationTbl = string.Explode(",",station.station)
|
||||
if not stationTbl or #stationTbl < 3 or not tonumber(stationTbl[1]) then ARMGenError(Format("Parser error. Malformed station data in station %d! Skipping...",i),true) continue end
|
||||
|
||||
genStation.id = stationTbl[1]
|
||||
genStation.shortname = stationTbl[2]
|
||||
genStation.name = stationTbl[3]
|
||||
genStation.buttons = {}
|
||||
genStation.routes = station.routes or {}
|
||||
genStation.signals = station.signals or {}
|
||||
for lineID,line in ipairs(station) do
|
||||
local x = line.x or 0
|
||||
for segmID,segm in ipairs(line) do
|
||||
if type(segm) ~= "string" then
|
||||
ARMGenError(Format("Parser error on station %d line %d segm %d, excepted string,got %s. Skipping segment...",i,lineID,segmID,type(segm)),true)
|
||||
continue
|
||||
end
|
||||
local segmTbl= ParseARMTable(segm,i,lineID,segmID)
|
||||
if segmTbl.error then
|
||||
ARMGenError(Format("Parser warning. Skipping station %d line %d segm %d segment, type error(type '%s' not found)",i,lineID,segmID,segmTbl.type),false)
|
||||
continue
|
||||
end
|
||||
segmTbl.x = x
|
||||
segmTbl.y = y
|
||||
segmTbl.id = table.insert(genStation,segmTbl)
|
||||
x = x + (segmTbl.width or 1)
|
||||
end
|
||||
y = y + (line.skip or 1)
|
||||
end
|
||||
if station.buttons then
|
||||
for _,button in pairs(station.buttons) do
|
||||
button.pressable = false
|
||||
button.selected = false
|
||||
button.isbutton = true
|
||||
if button.type == "r" then
|
||||
button.segm = ENT.Types.button_normal
|
||||
for k,v in ipairs(genStation) do
|
||||
if button.target and button.target[1] == v.x and button.target[2] == v.y then
|
||||
button.segm = v
|
||||
if v.button and not v.buttons then
|
||||
v.buttons = {v.button,button}
|
||||
v.button = nil
|
||||
elseif v.buttons then
|
||||
table.insert(v.buttons,button)
|
||||
else
|
||||
v.button = button
|
||||
end
|
||||
break
|
||||
end
|
||||
if not button.segm and v.signal1 and v.signal1.name == button.signal then
|
||||
button.segm = v
|
||||
v.signal1.button = button
|
||||
end
|
||||
if not button.segm and v.signal2 and v.signal2.name == button.signal then
|
||||
button.segm = v
|
||||
v.signal2.button = button
|
||||
end
|
||||
end
|
||||
end
|
||||
table.insert(genStation.buttons,button)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function ARMSetNextCompare(posX,posY,segm,nsegm)
|
||||
local xp,yp = GetSegmPos(segm)
|
||||
local x,y = GetSegmPos(nsegm)
|
||||
if sx and posX == x and posY == y then
|
||||
nsegm.prev = segm
|
||||
return true
|
||||
end
|
||||
|
||||
sx,sy = GetSegmPos(nsegm,false)
|
||||
if sx and posX == sx and posY == sy then
|
||||
nsegm.next_m = segm
|
||||
return true
|
||||
end
|
||||
if not nsegm.segm.next_a then return end
|
||||
sx,sy = GetSegmPos(nsegm,true)
|
||||
if x ~= xp and y ~= yp and sx and posX == sx and posY == sy then
|
||||
nsegm.next_a = segm
|
||||
if segm.id == 29 then
|
||||
local x1,y1 = GetSegmPos(nsegm)
|
||||
local x2,y2 = GetSegmPos(segm)
|
||||
print(-2,x1,y1,x2,y2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNext(station)
|
||||
for csegmid,csegm in ipairs(station) do
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
|
||||
local posX,posY = GetSegmPos(csegm)
|
||||
if ARMSetNextCompare(posX,posY,csegm,segm) then
|
||||
csegm.prev = segm
|
||||
--break
|
||||
end
|
||||
local posOX,posOY = GetSegmPos(csegm,false)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_m = segm
|
||||
--break
|
||||
end
|
||||
local posAX,posAY = GetSegmPos(segm)
|
||||
if not csegm.segm.next_a or posX == posAX or posY == posAY then continue end
|
||||
posOX,posOY = GetSegmPos(csegm,true)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_a = segm
|
||||
--break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,st in ipairs(Metrostroi.ARMConfigGenerated) do ARMSetNext(st) end
|
||||
|
||||
|
||||
local function tcopy(from)
|
||||
local t = {}
|
||||
for k,v in pairs(from) do
|
||||
t[k] = v
|
||||
end
|
||||
return t
|
||||
end
|
||||
local iter = 1
|
||||
local function ARMAddSignal(segm,dir,signals,trace,restbl)
|
||||
local signal = dir and segm.signal2 or not dir and segm.signal1
|
||||
local button,buttons = segm.button,segm.buttons
|
||||
if button then print(bitton,button.signal) end
|
||||
if signal and table.HasValue(signals,signal.name) then
|
||||
table.insert(restbl,{signal,table.Copy(trace),dir})
|
||||
elseif button and table.HasValue(signals,button.signal) then
|
||||
table.insert(trace,{segm.id})
|
||||
table.insert(restbl,{button,table.Copy(trace),dir})
|
||||
elseif buttons then
|
||||
for k,button in pairs(buttons) do
|
||||
if table.HasValue(signals,button.signal) then
|
||||
table.insert(trace,{segm.id})
|
||||
table.insert(restbl,{button,table.Copy(trace),dir})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local function ARMFindSegmSignals(station,segm,dir,signals,last,checked,restbl,trace)
|
||||
if not restbl then restbl = {} end
|
||||
if not checked then checked = {} end
|
||||
if not trace then trace = {} end
|
||||
if not segm or checked[segm] then return restbl end
|
||||
checked[segm] = true
|
||||
local segmIndex = table.insert(trace,{segm.id})
|
||||
--trace[segm] = true
|
||||
|
||||
iter = iter + 1
|
||||
if iter > 10000 then ARMGenError(Format("Routes generation error. Max iter reached!"),true) return false end
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local segmP = segm.prev
|
||||
|
||||
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if segmA and mainM then
|
||||
local trace= table.Copy(trace)
|
||||
|
||||
trace[segmIndex][2] = true
|
||||
ARMAddSignal(segmA,dir,signals,trace,restbl)
|
||||
ARMFindSegmSignals(station,segmA,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
if segmM and mainM then
|
||||
ARMAddSignal(segmM,dir,signals,trace,restbl)
|
||||
ARMFindSegmSignals(station,segmM,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
if segmP and mainP then
|
||||
trace[segmIndex][2] = last and segm.next_a == last or nil-- or segmP.next_a == segm or nil
|
||||
ARMAddSignal(segmP,dir,signals,trace,restbl)
|
||||
ARMFindSegmSignals(station,segmP,dir,signals,segm,checked,restbl,trace)
|
||||
end
|
||||
return restbl
|
||||
end
|
||||
|
||||
for i,station in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
print("STATION",i)
|
||||
for _,button in pairs(station.buttons) do
|
||||
if button.type == "r" and station.routes[button.signal] then
|
||||
print(button.signal,button.segm)
|
||||
button.pressable = true
|
||||
local results1 = ARMFindSegmSignals(station,button.segm,false,station.routes[button.signal])
|
||||
local results2 = ARMFindSegmSignals(station,button.segm,true,station.routes[button.signal])
|
||||
|
||||
table.Add( results2, results1 )
|
||||
--print(results[1][1].name,results[1][1].segm)--]]
|
||||
for k,v in pairs(results1) do
|
||||
local i = 0
|
||||
for k,v in pairs(v[2]) do i = i + 1 end
|
||||
print("--",k,v,v[1],v[2],i)
|
||||
end
|
||||
button.routes = results2
|
||||
end
|
||||
--[[ if segm.signal2 then
|
||||
local result = ARMFindNextSegm(station,segm,true,nil,nil,segm.signal2.name=="PT640")
|
||||
if result and #result > 0 then
|
||||
print(segm.signal2.name.."->")
|
||||
for k,v in ipairs(result) do print(" "..v.name) end
|
||||
end
|
||||
end
|
||||
if segm.signal1 then
|
||||
local result = ARMFindNextSegm(station,segm,false,nil,nil,segm.signal1.name=="MD01")
|
||||
if result and #result > 0 then
|
||||
print(segm.signal1.name.."->")
|
||||
for k,v in ipairs(result) do print(" "..v.name) end
|
||||
end
|
||||
end--]]
|
||||
end
|
||||
|
||||
end
|
||||
if errors == 0 and warnings == 0 then
|
||||
MsgC(Color(0,255,0),"MetrostroiARM:Generate finished without errors and warnings.\n")
|
||||
elseif errors == 0 then
|
||||
MsgC(Color(255,255,0),"MetrostroiARM:Generate finished with "..warnings.." warnings.\n")
|
||||
else
|
||||
MsgC(Color(255,0,0),"MetrostroiARM:Generate finished with "..errors.." errors and "..warnings.." warnings!\n")
|
||||
end
|
||||
--PrintTable(Metrostroi.ARMConfigGenerated)
|
||||
|
||||
for k,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
Metrostroi.ARMTable[k] = {
|
||||
occChecks = {},
|
||||
net = {},
|
||||
signal = {},
|
||||
switch = {},
|
||||
routes = {},
|
||||
}
|
||||
end
|
||||
@@ -1,181 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
--[[
|
||||
ENT.ButtonMap["TestDraw"] = {
|
||||
pos = Vector(455,5,7),
|
||||
ang = Angle(0,-90,80),
|
||||
width = 512,
|
||||
height = 512,
|
||||
scale = 0.024,
|
||||
}]]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
ENT.ClientProps["door1"] = {
|
||||
model = "models/props_junk/PopCan01a.mdl",
|
||||
pos = Vector(410,71.1,55.2),
|
||||
ang = Angle(90,-0,0)
|
||||
}
|
||||
--------------------------------------------------------------------------------
|
||||
-- Add doors
|
||||
local function GetDoorPosition(i,k,j)
|
||||
if j == 0
|
||||
then return Vector(349.0 - 32*k - 230*i,-65*(1-2*k),-2.8)
|
||||
else return Vector(349.0 - 32*(1-k) - 230*i,-65*(1-2*k),-2.8)
|
||||
end
|
||||
end
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
ENT.ClientProps["door"..i.."x"..k.."a"] = {
|
||||
model = "models/metrostroi/81/81-7036_door1.mdl",
|
||||
pos = GetDoorPosition(i,k,0),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
ENT.ClientProps["door"..i.."x"..k.."b"] = {
|
||||
model = "models/metrostroi/81/81-7036_door2.mdl",
|
||||
pos = GetDoorPosition(i,k,1),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
end
|
||||
end
|
||||
table.insert(ENT.ClientProps,{
|
||||
model = "models/metrostroi/81/81-7036_door4.mdl",
|
||||
pos = Vector(-487.0,-2.2,-4.5),
|
||||
ang = Angle(0,0,0)
|
||||
})
|
||||
table.insert(ENT.ClientProps,{
|
||||
model = "models/metrostroi/81/81-7036_door3.mdl",
|
||||
pos = Vector(414.0,65.0,-1.8),
|
||||
ang = Angle(0,0,0)
|
||||
})
|
||||
table.insert(ENT.ClientProps,{
|
||||
model = "models/metrostroi/81/81-7036_door5.mdl",
|
||||
pos = Vector(414.3,-65.0,-1.8),
|
||||
ang = Angle(0,0,0)
|
||||
})
|
||||
|
||||
|
||||
Metrostroi.RTQuele = {
|
||||
entries = {}
|
||||
}
|
||||
Metrostroi.RTQueleFrame = 0
|
||||
Metrostroi.PixVisHandle = util.GetPixelVisibleHandle()
|
||||
local drawn = true
|
||||
hook.Add("RenderScene","MetrostroiParallelView",function()
|
||||
Metrostroi.RTQueleFrame = Metrostroi.RTQueleFrame + 1
|
||||
if #Metrostroi.RTQuele > 0 and Metrostroi.RTQueleFrame > 1/FrameTime()/20*#Metrostroi.RTQuele then
|
||||
local id = table.remove(Metrostroi.RTQuele,1)
|
||||
Metrostroi.RTQuele.entries[id]()
|
||||
Metrostroi.RTQuele.entries[id] = nil
|
||||
Metrostroi.RTQueleFrame = 0
|
||||
--print("draw",1/FrameTime())
|
||||
drawn = false
|
||||
else
|
||||
--print("nodraw",1/FrameTime())
|
||||
end
|
||||
end)
|
||||
function Metrostroi.CanRenderCam(RT,func,draw)
|
||||
if not Metrostroi.RTQuele.entries[RT] and draw then
|
||||
table.insert(Metrostroi.RTQuele,RT)
|
||||
Metrostroi.RTQuele.entries[RT] = func
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Initialize()
|
||||
self.BaseClass.Initialize(self)
|
||||
--[[
|
||||
self.Cams = {}
|
||||
for i=1,3 do
|
||||
self.Cams[i] = self:CreateRT("cam"..i,false,128,128)
|
||||
end
|
||||
self.Test = self:CreateRT("cam",true)]]
|
||||
end
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
--[[
|
||||
Metrostroi.CanRenderCam("7036cam1", function()
|
||||
if not IsValid(self) then return end
|
||||
render.PushRenderTarget(self.Cams[1].rt,0,0,128, 128)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
surface.SetDrawColor(200,0,0)
|
||||
surface.DrawRect(0,0,64,64)
|
||||
render.RenderView({
|
||||
origin = self:LocalToWorld(Vector(410,73.1,55.2)), -- change to your liking
|
||||
angles = self:LocalToWorldAngles(Angle( 0, 180+10, 0 )), -- change to your liking
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 128,
|
||||
h = 128,
|
||||
fov = 70,
|
||||
} )
|
||||
surface.SetDrawColor(255,0,0)
|
||||
surface.DrawRect(0,0,64,64)
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end,self)
|
||||
Metrostroi.CanRenderCam("7036cam2", function()
|
||||
if not IsValid(self) then return end
|
||||
render.PushRenderTarget(self.Cams[2].rt,0,0,128, 128)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
render.RenderView({
|
||||
origin = self:LocalToWorld(Vector(410,-73.1,55.2)), -- change to your liking
|
||||
angles = self:LocalToWorldAngles(Angle( 0, 180-10, 0 )), -- change to your liking
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 128,
|
||||
h = 128,
|
||||
fov = 70,
|
||||
} )
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end,self)
|
||||
Metrostroi.CanRenderCam("7036cam3", function()
|
||||
if not IsValid(self) then return end
|
||||
render.PushRenderTarget(self.Cams[3].rt,0,0,128, 128)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
render.RenderView( {
|
||||
origin = self:LocalToWorld(Vector(410,0,55.2)), -- change to your liking
|
||||
angles = self:LocalToWorldAngles(Angle( 0, 180-10, 0 )), -- change to your liking
|
||||
x = 0,
|
||||
y = 0,
|
||||
w = 128,
|
||||
h = 128,
|
||||
fov = 70,
|
||||
} )
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end)]]
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
function ENT:DrawPost(special)
|
||||
--[[self:DrawOnPanel("TestDraw",function(...)
|
||||
surface.SetMaterial(self.Cams[1].mat)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRect(0,0,256,256,0)
|
||||
surface.SetMaterial(self.Cams[2].mat)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRect(256,0,256,256,0)
|
||||
surface.SetMaterial(self.Cams[3].mat)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRect(0,256,256,256,0)
|
||||
end)]]
|
||||
end
|
||||
|
||||
function ENT:OnButtonPressed(button)
|
||||
if button == "ShowHelp" then
|
||||
RunConsoleCommand("metrostroi_train_manual")
|
||||
end
|
||||
end
|
||||
@@ -1,46 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "81",
|
||||
Name = "81-7036",
|
||||
WagType = 1,
|
||||
Manufacturer = "KVZ",
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi/81/81-7036.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create seat entities
|
||||
self.DriverSeat = self:CreateSeat("driver",Vector(420,-2,-22))
|
||||
self.InstructorsSeat = self:CreateSeat("instructor",Vector(410,35,-20))
|
||||
|
||||
-- Hide seats
|
||||
self.DriverSeat:SetColor(Color(0,0,0,0))
|
||||
self.DriverSeat:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 325-20,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-325-10,0,-80),Angle(0,0,0),false)
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
local retVal = self.BaseClass.Think(self)
|
||||
return retVal
|
||||
end
|
||||
@@ -1,24 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
self:LoadSystem("KK","Relay","Switch")
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
end
|
||||
@@ -1,53 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Add doors
|
||||
local function GetDoorPosition(i,k,j)
|
||||
if j == 0
|
||||
then return Vector(347.5 - 32*k - 230*i,-65*(1-2*k),-2.8)
|
||||
else return Vector(347.5 - 32*(1-k) - 230*i,-65*(1-2*k),-2.8)
|
||||
end
|
||||
end
|
||||
for i=0,3 do
|
||||
for k=0,1 do
|
||||
ENT.ClientProps["door"..i.."x"..k.."a"] = {
|
||||
model = "models/metrostroi/81/81-7036_door1.mdl",
|
||||
pos = GetDoorPosition(i,k,0),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
ENT.ClientProps["door"..i.."x"..k.."b"] = {
|
||||
model = "models/metrostroi/81/81-7036_door2.mdl",
|
||||
pos = GetDoorPosition(i,k,1),
|
||||
ang = Angle(0,180*(1-k),0)
|
||||
}
|
||||
end
|
||||
end
|
||||
table.insert(ENT.ClientProps,{
|
||||
model = "models/metrostroi/81/81-7036_door4.mdl",
|
||||
pos = Vector(-487.0,-2.2,-4.5),
|
||||
ang = Angle(0,0,0)
|
||||
})
|
||||
table.insert(ENT.ClientProps,{
|
||||
model = "models/metrostroi/81/81-7036_door4.mdl",
|
||||
pos = Vector(461.0,1.2,-4.5),
|
||||
ang = Angle(0,180,0)
|
||||
})
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
@@ -1,38 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
ENT.BogeyDistance = 650 -- Needed for gm trainspawner
|
||||
|
||||
---------------------------------------------------
|
||||
-- Defined train information
|
||||
-- Types of wagon(for wagon limit system):
|
||||
-- 0 = Head or intherim
|
||||
-- 1 = Only head
|
||||
-- 2 = Only intherim
|
||||
---------------------------------------------------
|
||||
ENT.SubwayTrain = {
|
||||
Type = "81",
|
||||
Name = "81-7037",
|
||||
WagType = 2,
|
||||
Manufacturer = "KVZ",
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
|
||||
-- Set model and initialize
|
||||
self:SetModel("models/metrostroi/81/81-7037.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self:SetPos(self:GetPos() + Vector(0,0,140))
|
||||
|
||||
-- Create bogeys
|
||||
self.FrontBogey = self:CreateBogey(Vector( 325-20,0,-80),Angle(0,180,0),true)
|
||||
self.RearBogey = self:CreateBogey(Vector(-325-10,0,-80),Angle(0,0,0),false)
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
function ENT:Think()
|
||||
local retVal = self.BaseClass.Think(self)
|
||||
return retVal
|
||||
end
|
||||
@@ -1,24 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
ENT.Base = "gmod_subway_base"
|
||||
|
||||
ENT.Author = ""
|
||||
ENT.Contact = ""
|
||||
ENT.Purpose = ""
|
||||
ENT.Instructions = ""
|
||||
ENT.Category = "Metrostroi (trains)"
|
||||
|
||||
ENT.Spawnable = false --NOT FINISHED
|
||||
ENT.AdminSpawnable = false --NOT FINISHED
|
||||
|
||||
function ENT:PassengerCapacity()
|
||||
return 300
|
||||
end
|
||||
|
||||
function ENT:GetStandingArea()
|
||||
return Vector(-450,-30,-45),Vector(380,30,-45)
|
||||
end
|
||||
|
||||
function ENT:InitializeSystems()
|
||||
self:LoadSystem("KK","Relay","Switch")
|
||||
self:LoadSystem("Pneumatic","81_717_Pneumatic")
|
||||
end
|
||||
@@ -1,458 +0,0 @@
|
||||
include("shared.lua")
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
ENT.ClientProps = {}
|
||||
ENT.ButtonMap = {}
|
||||
ENT.AutoAnims = {}
|
||||
ENT.AutoAnimNames = {}
|
||||
ENT.ClientSounds = {}
|
||||
ENT.ClientPropsInitialized = false
|
||||
|
||||
|
||||
ENT.ButtonMap["ARM"] = {
|
||||
pos = Vector(-4.9,9.1,50.3),
|
||||
ang = Angle(0,-90-1,90),
|
||||
width = 800,
|
||||
height = 600,
|
||||
scale = 0.02*1.2,
|
||||
mouse = true
|
||||
}
|
||||
ENT.ClientProps["ARMPK"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_screen.mdl",
|
||||
pos = Vector(-5,0,31.2),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMMonitor"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_body.mdl",
|
||||
pos = Vector(-5,15,0),
|
||||
ang = Angle(0,180,0),
|
||||
bscale = Vector(4/3,1,1),
|
||||
}
|
||||
ENT.ClientProps["ARMKeyboard"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_keyboard.mdl",
|
||||
pos = Vector(-15,-2,31),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMMouse"] = {
|
||||
model = "models/cyber_metrostroi/pc_arm/pc_mouse.mdl",
|
||||
pos = Vector(-18,-20,32),
|
||||
ang = Angle(0,180,0),
|
||||
}
|
||||
ENT.ClientProps["ARMBreen"] = {
|
||||
model = "models/props_combine/breenglobe.mdl",
|
||||
pos = Vector(-11,30,39.5),
|
||||
ang = Angle(0,-180+45,0),
|
||||
}
|
||||
|
||||
function ENT:Initialize()
|
||||
self.BaseClass.Initialize(self)
|
||||
self.ARM = self:CreateRT("ARM",1024,1024)
|
||||
for k,v in pairs(self.Types) do
|
||||
for i,tex in pairs(v) do
|
||||
if type(tex) == "table" and type(tex[1]) == "string" then
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:CamMoved()
|
||||
self:HandleMouse(false)
|
||||
gui.EnableScreenClicker(self.CurrentCamera ~= 0)
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
self.BaseClass.Think(self)
|
||||
if not self.RenderClientEnts or self.CreatingCSEnts then
|
||||
return
|
||||
end
|
||||
|
||||
if not self.ARM then return end
|
||||
--self.MouseX = 0
|
||||
--self.MouseY = 0
|
||||
self.MouseX = self:GetNW2Int("CursorX",0)
|
||||
self.MouseY = self:GetNW2Int("CursorY",0)
|
||||
render.PushRenderTarget(self.ARM,0,0,1024, 1024)
|
||||
render.Clear(0, 0, 0, 0)
|
||||
cam.Start2D()
|
||||
render.OverrideAlphaWriteEnable(true, true)
|
||||
surface.SetDrawColor(0,0,0)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
self:ARMMonitor()
|
||||
cam.End2D()
|
||||
render.PopRenderTarget()
|
||||
end
|
||||
|
||||
function ENT:Draw()
|
||||
self.BaseClass.Draw(self)
|
||||
end
|
||||
|
||||
|
||||
function ENT:DrawPost()
|
||||
self.RTMaterial:SetTexture("$basetexture", self.ARM)
|
||||
self:DrawOnPanel("ARM",function(...)
|
||||
surface.SetMaterial(self.RTMaterial)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawTexturedRectRotated(512,512,1024,1024,0)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local gray = Color(100,100,100)
|
||||
local black = Color(0,0,0)
|
||||
local white = Color(150,150,150)
|
||||
local green = Color(0,50,0)
|
||||
|
||||
local function GetTextures(segm,typ)
|
||||
return segm[typ],segm.maintex or segm[typ]
|
||||
end
|
||||
--Get texture Width and Height
|
||||
local function GetWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.w or dtex.w,tex.h or dtex.h
|
||||
end
|
||||
--Get real(original) texture Width and Height
|
||||
local function GetRWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
end
|
||||
--Get X and Y adds
|
||||
local function GetXYA(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
local function drawSegment(w,h,u0,v0,u1,v1,segm,typ,align)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
if dtex.mat then
|
||||
local sx,sy = GetXY(w,h)
|
||||
local sw,sh = GetWH(segm,typ)
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = GetXYA(segm,typ)
|
||||
local rw,rh = GetRWH(segm,typ)
|
||||
surface.SetDrawColor(tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
end
|
||||
local function drawElement(sx,sy,u0,v0,u1,v1,segm,typ,col)
|
||||
--local segm = self.Types[typ]
|
||||
if not segm or not segm[typ] then return end
|
||||
local tex = segm[typ]
|
||||
local dtex = segm.maintex or tex
|
||||
--local sx,sy = 100+w*36,100+h*70
|
||||
local sw,sh = tex.w or dtex.w,tex.h or dtex.h
|
||||
local sxa = tex.x or dtex.x or 0
|
||||
local xa,ya = tex.xa or dtex.xa or 0,tex.ya or dtex.ya or 0
|
||||
local rw,rh = tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
surface.SetDrawColor(col or tex.col or dtex.col or white)
|
||||
surface.SetTexture(tex.mat or dtex.mat)
|
||||
surface.DrawTexturedRectUV(sx+xa+sxa*u0,sy+ya-(rh-8)*v0 ,rw,rh,(rw/sw)*u0,(rh/sh)*v0,(rw/sw)*u1,(rh/sh)*v1)
|
||||
end
|
||||
|
||||
local mouse = surface.GetTextureID("gui/info")
|
||||
|
||||
local function createFont(name,font,size,weight)
|
||||
surface.CreateFont("Metrostroi_"..name, {
|
||||
font = font,
|
||||
size = size,
|
||||
weight = weight or 400,
|
||||
blursize = 0,
|
||||
antialias = true,
|
||||
underline = false,
|
||||
italic = false,
|
||||
strikeout = false,
|
||||
symbol = false,
|
||||
rotary = false,
|
||||
shadow = false,
|
||||
additive = false,
|
||||
outline = false,
|
||||
extended = true,
|
||||
})
|
||||
end
|
||||
createFont("Arial10","Arial",10,400)
|
||||
createFont("Arial11","Arial",11,400)
|
||||
createFont("Arial13","Arial",13,400)
|
||||
createFont("Arial15","Arial",15,400)
|
||||
createFont("Arial15B","Arial",15,800)
|
||||
createFont("Arial20","Arial",20,800)
|
||||
|
||||
local colorConverter = {
|
||||
r = Color(0,0,0),
|
||||
y = Color(240,240,71),
|
||||
g = Color(41,202,26),
|
||||
b = Color(26,84,202),
|
||||
w = Color(255,255,255),
|
||||
}
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function ENT:ARMMonitor()
|
||||
if self.FilterMag then
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
end
|
||||
|
||||
render.PushFilterMag( TEXFILTER.POINT )
|
||||
render.PushFilterMin( TEXFILTER.POINT )
|
||||
self.FilterMag = true
|
||||
surface.SetDrawColor(gray)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
local station = self:GetNW2Int("ARM:Station",0)
|
||||
--draw.SimpleText("АРМ ДЫЫСЦЫПЫ","Metrostroi_BUKPSpeed",400, 300,Color(220,0,0),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
if station > 0 and Metrostroi.ARMConfigGenerated and Metrostroi.ARMConfigGenerated[station] then
|
||||
local armTable = Metrostroi.ARMConfigGenerated[station]
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"maintex")
|
||||
end
|
||||
local w,h = 0,0
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if Metrostroi.GetARMInfo(station,id,"occup2") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_x")
|
||||
end
|
||||
if Metrostroi.GetARMInfo(station,id,"switch_m") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_a") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_a") end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_a")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"switch_na") then
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_a")
|
||||
end
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_an")
|
||||
drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"switch_mn")
|
||||
else
|
||||
if Metrostroi.GetARMInfo(station,id,"occup") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"occup_m")
|
||||
elseif Metrostroi.GetARMInfo(station,id,"route") then drawSegment(segm.x,segm.y,u0,v0,u1,v1,segm.segm,"route_m") end
|
||||
end
|
||||
if segm.signal1 then
|
||||
local sig = segm.signal1
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local x,y = 100+(segm.x+segm.width)*36,100+segm.y*70-(sig.top and -26 or 15)
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local sx,sy = x-rw-2,y-rh-2
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y-(sig.top and -7 or 15),Color(0,0,0),TEXT_ALIGN_RIGHT,TEXT_ALIGN_BOTTOM)
|
||||
drawElement(sx,sy,0,0,1,1,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal1") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal1I") then
|
||||
drawElement(sx+13*(sig.type-1),sy,0,0,1,1,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal1Y") then
|
||||
drawElement(sx+13*(sig.type-2),sy,0,0,1,1,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx,sy,0,0,1,1,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
if segm.signal2 then
|
||||
local sig = segm.signal2
|
||||
local typ = self.Types["tl_"..sig.type]
|
||||
|
||||
local rw,rh = GetRWH(typ,"maintex")
|
||||
local x,y = 100+(segm.x)*36+2,100+segm.y*70+(sig.top and -38 or 3)
|
||||
local sx,sy = x-1,y+rh
|
||||
|
||||
draw.SimpleText(sig.name,"Metrostroi_Arial10",x, y+(sig.top and -2 or 20),Color(0,0,0),TEXT_ALIGN_LEFT,TEXT_ALIGN_TOP)
|
||||
drawElement(sx,sy,1,1,0,0,typ,"maintex")
|
||||
local colors = Metrostroi.GetARMInfo(station,id,"signal2") or ""
|
||||
if sig.type > 1 and Metrostroi.GetARMInfo(station,id,"signal2I") then
|
||||
drawElement(sx+rw-12-13*(sig.type-1),sy,1,1,0,0,typ,"full",colorConverter.w)
|
||||
end
|
||||
if sig.type > 2 and Metrostroi.GetARMInfo(station,id,"signal2Y") then
|
||||
drawElement(sx+rw-12-13*(sig.type-2),sy,1,1,0,0,typ,"full",colorConverter.y)
|
||||
end
|
||||
if colors ~= "" and #colors == 1 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"full",colorConverter[color] or Color(0,0,0))
|
||||
elseif colors ~= "" and #colors == 2 then
|
||||
local color = colors:lower()
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h1",colorConverter[color[1]] or Color(0,0,0))
|
||||
drawElement(sx+rw-12,sy,1,1,0,0,typ,"h2",colorConverter[color[2]] or Color(0,0,0))
|
||||
end
|
||||
end
|
||||
end
|
||||
for id,obj in ipairs(armTable.objects) do
|
||||
if obj.type=="b" then
|
||||
local x1,y1 = GetXY(obj.x1,obj.y1)
|
||||
local x2,y2 = GetXY(obj.x2,obj.y2)
|
||||
local w,h = x2-x1,y2-y1
|
||||
--Metrostroi.DrawRectOL(x1,y1,x2-x1,y2-y1,Color(255,255,255),2,Color(200,200,200))
|
||||
surface.SetDrawColor(200,200,200)
|
||||
surface.DrawRect(x1,y1,w,h)
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.DrawOutlinedRect(x1,y1,w,h)
|
||||
surface.SetFont("Metrostroi_Arial20")
|
||||
local fw,fh = 0,0
|
||||
local rows = string.Explode("\n",obj.name)
|
||||
for _,text in ipairs(rows) do
|
||||
local w,h = surface.GetTextSize(text)
|
||||
fw,fh = math.max(w,fw),math.max(h,fh)
|
||||
end
|
||||
for i=#rows,1,-1 do
|
||||
local x,y = x1+w/2,y1+h/2+(i-1)*20-(#rows-1)*20/2
|
||||
surface.SetDrawColor(150,150,150)
|
||||
surface.DrawRect(x-fw/2-5,y-fh/2-5,fw+10,fh+10)
|
||||
draw.SimpleText(rows[i],"Metrostroi_Arial20",x, y,Color(40,40,40),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end
|
||||
end
|
||||
if obj.type=="cl" then
|
||||
local x,y = GetXY(obj.x,obj.y)
|
||||
if obj.right then x = x-50 y = y-30 end
|
||||
--Metrostroi.DrawRectOL(x1,y1,x2-x1,y2-y1,Color(255,255,255),2,Color(200,200,200))
|
||||
surface.SetDrawColor(60,60,60)
|
||||
surface.DrawRect(x,y,50,30)
|
||||
draw.SimpleText(Format("%02d:%02d",23,30),"Metrostroi_Arial15",x+4, y+4,Color(150,255,50),TEXT_ALIGN_LEFT,TEXT_ALIGN_TOP)
|
||||
end
|
||||
end
|
||||
for id,button in ipairs(armTable.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
if button.type=="r" then
|
||||
sw,sh = 15,25
|
||||
xa,ya = 3,12
|
||||
end
|
||||
if button.type=="pn" then
|
||||
sw,sh = 15,15
|
||||
xa,ya = -sw/2,-sh/2
|
||||
end
|
||||
if button.type=="rn" then
|
||||
surface.SetFont("Metrostroi_Arial15")
|
||||
local w,h = surface.GetTextSize(button.name)
|
||||
sw,sh = w+9,15
|
||||
xa,ya = -sw/2,-sh/2
|
||||
end
|
||||
local x,y = sx+xa,sy+ya
|
||||
if Metrostroi.GetARMInfo(station,1000+id,"buttonSelected") then
|
||||
surface.SetDrawColor(Color(80,80,180))
|
||||
elseif Metrostroi.GetARMInfo(station,1000+id,"buttonPressable") then
|
||||
surface.SetDrawColor(Color(220,220,220))
|
||||
else
|
||||
if button.type=="pn" then
|
||||
surface.SetDrawColor(Color(20,20,20))
|
||||
else
|
||||
surface.SetDrawColor(Color(120,120,120))
|
||||
end
|
||||
end
|
||||
surface.DrawRect(x,y,sw,sh)
|
||||
Metrostroi.DrawLine(x,y,x,y+sh,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x-1,y,x+sw,y,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x+sw,y,x+sw,y+sh,Color(60,60,60),2)
|
||||
Metrostroi.DrawLine(x,y+sh,x+sw+1,y+sh,Color(60,60,60),2)
|
||||
|
||||
if button.type=="rn" then
|
||||
draw.SimpleText(button.name,"Metrostroi_Arial15B",x+sw/2, y+sh/2,Color(50,50,50),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end
|
||||
end
|
||||
for id,text in ipairs(armTable.info) do
|
||||
local x,y = 100+text.x*36,100+text.y*70
|
||||
local w,h = 45,13
|
||||
if text.col then
|
||||
surface.SetDrawColor(text.col)
|
||||
surface.DrawRect(x,y,w,h)
|
||||
end
|
||||
draw.SimpleText(text.text,"Metrostroi_Arial13",x+2, y+h/2,Color(50,50,50),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||||
Metrostroi.DrawLine(x,y,x,y+h,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x-1,y,x+w,y,Color(240,240,240),2)
|
||||
Metrostroi.DrawLine(x+w,y,x+w,y+h,Color(60,60,60),2)
|
||||
Metrostroi.DrawLine(x,y+h,x+w+1,y+h,Color(60,60,60),2)
|
||||
|
||||
--[[ if button.type=="rn" then
|
||||
draw.SimpleText(button.name,"Metrostroi_Arial15B",x+sw/2, y+sh/2,Color(50,50,50),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end--]]
|
||||
end
|
||||
end
|
||||
for i,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
if i == station then
|
||||
surface.SetDrawColor(Color(110,140,170))
|
||||
elseif math.InRangeXYR(self.MouseX,self.MouseY,20+(i-1)*30,20,30,20) then
|
||||
surface.SetDrawColor(Color(80,110,140))
|
||||
else
|
||||
surface.SetDrawColor(Color(100,130,160))
|
||||
end
|
||||
|
||||
surface.DrawRect(20+(i-1)*31,20,30,20)
|
||||
draw.SimpleText(v.shortname or v.id,"Metrostroi_Arial20",35+(i-1)*31, 30,Color(40,60,170),TEXT_ALIGN_CENTER,TEXT_ALIGN_CENTER)
|
||||
end
|
||||
if station > 0 and Metrostroi.ARMConfigGenerated and Metrostroi.ARMConfigGenerated[station] then
|
||||
local armTable = Metrostroi.ARMConfigGenerated[station]
|
||||
for id,segm in ipairs(armTable) do
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
|
||||
---[[ DEBUG
|
||||
local w,h = GetXY(segm.x+segm.width*u0,segm.y)
|
||||
surface.SetDrawColor(Color(255,0,0))
|
||||
surface.DrawLine(w+5*u1-5*u0,h,w,h)
|
||||
surface.DrawLine(w,h+5,w,h)
|
||||
local w,h = GetSegmPos(segm,false)
|
||||
surface.SetDrawColor(Color(255,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6,w,h)
|
||||
local w,h = GetSegmPos(segm,true)
|
||||
if w then
|
||||
surface.SetDrawColor(Color(0,255,0))
|
||||
surface.DrawLine(w-6*u1+6*u0,h,w,h)
|
||||
surface.DrawLine(w,h-6*v1+6*v0,w,h)
|
||||
end
|
||||
local x,y = 100+(segm.x+segm.width)*36,100+segm.y*70-4
|
||||
local rw,rh = GetRWH(segm.segm,"maintex")
|
||||
local sx,sy = x-rw-2,y-rh-2
|
||||
|
||||
surface.SetDrawColor(Color(0,0,0,150))
|
||||
surface.DrawRect(sx,y-7,30,10)
|
||||
draw.SimpleText(Format("%.1f:%.1f",segm.x,segm.y),"Metrostroi_Arial11",sx, y-2,Color(255,255,50),TEXT_ALIGN_LEFT,TEXT_ALIGN_CENTER)
|
||||
--]]
|
||||
end
|
||||
end
|
||||
--if self.CurrentCamera == 0 then
|
||||
surface.SetDrawColor(255,255,255)
|
||||
surface.SetTexture(mouse)
|
||||
surface.DrawTexturedRectRotated(self.MouseX,self.MouseY,8,8,0)
|
||||
--end
|
||||
|
||||
surface.SetDrawColor(0,0,0,200)
|
||||
surface.DrawRect(0,0,800,600)
|
||||
render.PopFilterMag()
|
||||
render.PopFilterMin()
|
||||
self.FilterMag = false
|
||||
end
|
||||
Metrostroi.GenerateClientProps()
|
||||
@@ -1,207 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/props_combine/breendesk.mdl")
|
||||
self.BaseClass.Initialize(self)
|
||||
self.DriverSeat = self:CreateSeat("driver", Vector(-40, 0, 0), Angle(0, 0, 0), "models//nova/chair_office02.mdl")
|
||||
self.CursorX = 0
|
||||
self.CursorY = 0
|
||||
self:CursorMove(0, 0)
|
||||
self.Station = 0
|
||||
end
|
||||
|
||||
hook.Add("AcceptInput", "metrostroi_arm_trigger_check", function(ent, inputName, activator, called, data)
|
||||
if inputName == "ARMStartTouch" then
|
||||
called.ARMTriggered = true
|
||||
print(called, called:GetName(), activator, "Enable")
|
||||
end
|
||||
|
||||
if inputName == "ARMEndTouch" then
|
||||
called.ARMTriggered = false
|
||||
print(called, called:GetName(), activator, "Disable")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
local function GetOccupation(tbl)
|
||||
for sID,signame in ipairs(tbl) do
|
||||
if signame[1] == "@" then
|
||||
local trigger = Metrostroi.ARMGet(signame:sub(2,-1), "trigger")
|
||||
if not trigger or trigger.ARMTriggered then
|
||||
return true
|
||||
end
|
||||
elseif signame ~= "" then
|
||||
local signal = Metrostroi.ARMGet(signame, "signal")
|
||||
if not signal or signal.OccupiedBy and signal.OccupiedBy ~= signal then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
local armTbl = Metrostroi.ARMTable
|
||||
local armConf = Metrostroi.ARMConfigGenerated
|
||||
local station = armConf[self.Station]
|
||||
local armTblStation = armTbl[self.Station]
|
||||
if not station then return end
|
||||
if not armTblStation or (IsValid(armTblStation.Controller) and armTblStation.Controller ~= self) then return end
|
||||
armTblStation.Controller = self
|
||||
for buttonID,button in ipairs(station.buttons) do
|
||||
--print(button,button.selected)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonPressable",button.pressable)
|
||||
Metrostroi.ARMSync(self.Station, 1000+buttonID, "buttonSelected",button.selected)
|
||||
end
|
||||
for segmID, segm in ipairs(station) do
|
||||
if type(segm) == "table" then
|
||||
if segm.occup then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup", segm.occupied)
|
||||
end
|
||||
|
||||
if segm.occup2 then
|
||||
Metrostroi.ARMSync(self.Station, segmID, "occup2", segm._occup or GetOccupation(segm.occup2))
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "route", segm.route and true)
|
||||
|
||||
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
local alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_m", main)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_a", alt)
|
||||
Metrostroi.ARMSync(self.Station, segmID, "switch_na", not main and not alt)
|
||||
end
|
||||
if segm.signal1 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal1.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal1.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal1I", signal and signal.InvationSignal) end
|
||||
if segm.signal1.type > 2 and colors then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal1", colors)
|
||||
end
|
||||
if segm.signal2 then
|
||||
local signal = Metrostroi.ARMGet(segm.signal2.name, "signal")
|
||||
local colors = signal and signal.Colors
|
||||
if segm.signal2.type > 1 then Metrostroi.ARMSync(self.Station, segmID, "signal2I", signal and signal.InvationSignal) end
|
||||
if segm.signal2.type > 2 and colors then
|
||||
local Y = #colors:gsub("[^yY]","") > 1
|
||||
if Y then colors = colors:SetChar(colors:find("[yY]"),"") end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2Y", Y)
|
||||
end
|
||||
Metrostroi.ARMSync(self.Station, segmID, "signal2", colors)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:NextThink(CurTime() + 0.5)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function ENT:OnRemove()
|
||||
end
|
||||
|
||||
function ENT:CursorMove(sys, dX, dY)
|
||||
self.CursorX = sys == "" and math.Clamp(self.CursorX + dX * 200, 0, 800) or dX
|
||||
self.CursorY = sys == "" and math.Clamp(self.CursorY + dY * 200, 0, 600) or dY
|
||||
self:SetNW2Int("CursorX", math.floor(self.CursorX or 0))
|
||||
self:SetNW2Int("CursorY", math.floor(self.CursorY or 0))
|
||||
end
|
||||
|
||||
local function GetTextures(segm,typ)
|
||||
return segm[typ],segm.maintex or segm[typ]
|
||||
end
|
||||
--Get real(original) texture Width and Height
|
||||
local function GetRWH(segm,typ)
|
||||
local tex,dtex = GetTextures(segm,typ)
|
||||
return tex.rw or dtex.rw,tex.rh or dtex.rh
|
||||
end
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
|
||||
|
||||
function ENT:RouteButtonPressed(button)
|
||||
--if not button.routes then return end
|
||||
if self.RouteChoosing then
|
||||
for k,v in ipairs(self.RouteChoosing.routes) do
|
||||
if v.endButtons and table.HasValue(v.endButtons,button) then
|
||||
Metrostroi.CentralisationPrepareRoute(self.Station,v)
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif button.routes and not self.RouteChoosing and button.pressable then
|
||||
self.RouteChoosing = button
|
||||
for _,route in ipairs(self.RouteChoosing.routes) do
|
||||
print(route.endButtons)
|
||||
if not route.endButtons then continue end
|
||||
for _,b in ipairs(route.endButtons) do b.selected = true end
|
||||
end
|
||||
end
|
||||
end
|
||||
function ENT:PanelTouch(state--[[ , x, y--]] )
|
||||
for i, v in ipairs(Metrostroi.ARMConfig) do
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, 20 + (i - 1) * 30, 20, 30, 20) then
|
||||
self.Station = i
|
||||
self:SetNW2Int("ARM:Station", i)
|
||||
end
|
||||
end
|
||||
if not state then return end
|
||||
local ResetRoute = false
|
||||
if self.RouteChoosing then
|
||||
for _,route in ipairs(self.RouteChoosing.routes) do
|
||||
if not route.endButtons then continue end
|
||||
for _,b in ipairs(route.endButtons) do b.selected = false end
|
||||
end
|
||||
ResetRoute = true
|
||||
end
|
||||
--[[ local RouteChoosing = self.RouteChoosing
|
||||
self.RouteChoosing = nil--]]
|
||||
local confGenStation = Metrostroi.ARMConfigGenerated[self.Station]
|
||||
if not confGenStation then return end
|
||||
for k,button in pairs(confGenStation.buttons) do
|
||||
local sx,sy = 100+button.x*36,100+button.y*70
|
||||
if button.type == "r" and math.InRangeXYR(self.CursorX, self.CursorY, sx+3,sy+12,15,25) then
|
||||
self:RouteButtonPressed(button)
|
||||
--[[ local sw,sh = 15,25
|
||||
local xa,ya = 3,12
|
||||
local x,y = sx+xa,sy+ya math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh)
|
||||
if RouteChoosing then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
for k,v in ipairs(RouteChoosing.routes) do
|
||||
if k == Format("%s-%s",button.name,v.name) then
|
||||
Metrostroi.CentralisationPrepareRoute(self.Station,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif not self.RouteChoosing and button.pressable then
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,sw,sh) then
|
||||
self.RouteChoosing = button
|
||||
for k,v in ipairs(button.routes) do
|
||||
if v.buttonend then
|
||||
v.buttonend.selected = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end--]]
|
||||
end
|
||||
end
|
||||
if not self.RouteChoosing then
|
||||
for k,segm in ipairs(confGenStation) do
|
||||
local x,y = GetXY(segm.x,segm.y)
|
||||
local w,h = GetRWH(segm.segm,"maintex")
|
||||
if math.InRangeXYR(self.CursorX, self.CursorY, x,y,w,h) then
|
||||
segm._occup = not segm._occup
|
||||
print(segm)
|
||||
end
|
||||
end
|
||||
end
|
||||
if ResetRoute then self.RouteChoosing = nil end
|
||||
end
|
||||
@@ -1,836 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
--Inherit subway base for some need functions
|
||||
ENT.Base = "gmod_subway_base"
|
||||
ENT.NoTrain = true
|
||||
|
||||
ENT.Category = "Metrostroi"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = true
|
||||
|
||||
ENT.Cameras = {
|
||||
{Vector(-18+3,0,43+2),Angle(0,0,0),"Common.ARM.Monitor1",true},
|
||||
}
|
||||
ENT.Types = {
|
||||
--Main segments
|
||||
[0.25]={
|
||||
maintex = {"metrostroi_arm/sec025",w=8,h=8,rw=7,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec025_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec025_m",col=Color(39,103,63)},
|
||||
width = 0.25,
|
||||
next_m = {x=0.25,y=0}
|
||||
},
|
||||
[0.5]={
|
||||
maintex = {"metrostroi_arm/sec05",w=16,h=8,rw=16,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec05_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec05_m",col=Color(39,103,63)},
|
||||
width = 0.5,
|
||||
next_m = {x=0.5,y=0}
|
||||
},
|
||||
[1]={
|
||||
maintex = {"metrostroi_arm/sec1",w=64,h=8,rw=34,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec1_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec1_m",col=Color(39,103,63)},
|
||||
width = 1,
|
||||
next_m = {x=1,y=0}
|
||||
},
|
||||
[2]={
|
||||
maintex = {"metrostroi_arm/sec2",w=128,h=8,rw=70,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec2_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec2_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0}
|
||||
},
|
||||
[3]={
|
||||
maintex = {"metrostroi_arm/sec3",w=128,h=8,rw=106,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec3_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec3_m",col=Color(39,103,63)},
|
||||
width = 3,
|
||||
next_m = {x=3,y=0}
|
||||
},
|
||||
[4]={
|
||||
maintex = {"metrostroi_arm/sec4",w=256,h=8,rw=142,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec4_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec4_m",col=Color(39,103,63)},
|
||||
width = 4,
|
||||
next_m = {x=4,y=0}
|
||||
},
|
||||
[5]={
|
||||
maintex = {"metrostroi_arm/sec5",w=256,h=8,rw=178,rh=8,},
|
||||
occup_m = {"metrostroi_arm/sec5_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/sec5_m",col=Color(39,103,63)},
|
||||
width = 5,
|
||||
next_m = {x=5,y=0}
|
||||
},
|
||||
--Switches and helpers
|
||||
sw = {
|
||||
maintex = {"metrostroi_arm/switch",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/switch_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/switch_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/switch_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/switch_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/switch_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/switch_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/switch_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/switch_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
["2sw"] = {
|
||||
maintex = {"metrostroi_arm/2-switch_half",w=128,h=256,rw=70,rh=143,},
|
||||
occup_m = {"metrostroi_arm/2-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch_half_as",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch_half_ms",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
},
|
||||
["2swm"] = {
|
||||
maintex = {"metrostroi_arm/2-switch-middle_half",w=128,h=128,rw=70,rh=73,},
|
||||
occup_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/2-switch-middle_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/2-switch-middle_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/2-switch-middle_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/2-switch-middle_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/2-switch-middle_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
},
|
||||
["4sw"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter",w=128,h=256,rw=73,rh=143,x=-3,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_a1",col=Color(39,103,63)},
|
||||
occup_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(255,255,255)},
|
||||
route_x = {"metrostroi_arm/4-switch_quarter_a2",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=2},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
["4sws"] = {
|
||||
maintex = {"metrostroi_arm/4-switch_quarter_small",w=64,h=128,rw=53,rh=78,x=-1,},
|
||||
occup_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(255,255,255),x=-1,},
|
||||
route_m = {"metrostroi_arm/4-switch_quarter_small_m",col=Color(39,103,63),x=-1,},
|
||||
occup_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(255,255,255),x=-1,},
|
||||
route_a = {"metrostroi_arm/4-switch_quarter_small_a",col=Color(39,103,63),x=-1,},
|
||||
switch_m = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/4-switch_quarter_small_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/4-switch_quarter_small_as",col=Color(200,50,50)},
|
||||
width = 1.5,
|
||||
next_m = {x=1.5,y=0},
|
||||
next_a = {x=1.5,y=1},
|
||||
acc_x = ">",
|
||||
acc_y = "!",
|
||||
},
|
||||
ofd = {
|
||||
maintex = {"metrostroi_arm/offset_down",w=64,h=256,rw=57,rh=143,},
|
||||
occup_m = {"metrostroi_arm/offset_down_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offset_down_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=2},
|
||||
},
|
||||
ofds = {
|
||||
maintex = {"metrostroi_arm/offsed_down_small",w=128,h=128,rw=70,rh=78,},
|
||||
occup_m = {"metrostroi_arm/offsed_down_small_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/offsed_down_small_m",col=Color(39,103,63)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=1},
|
||||
},
|
||||
ysw = {
|
||||
maintex = {"metrostroi_arm/y-switch_half",w=128,h=128,rw=70,rh=108,},
|
||||
occup_m = {"metrostroi_arm/y-switch_half_m",col=Color(255,255,255)},
|
||||
route_m = {"metrostroi_arm/y-switch_half_m",col=Color(39,103,63)},
|
||||
occup_a = {"metrostroi_arm/y-switch_half_a",col=Color(255,255,255)},
|
||||
route_a = {"metrostroi_arm/y-switch_half_a",col=Color(39,103,63)},
|
||||
switch_m = {"metrostroi_arm/y-switch_half_ms",col=Color(41,202,26)},
|
||||
switch_a = {"metrostroi_arm/y-switch_half_as",col=Color(240,240,71)},
|
||||
switch_mn = {"metrostroi_arm/y-switch_half_ms",col=Color(200,50,50)},
|
||||
switch_an = {"metrostroi_arm/y-switch_half_as",col=Color(200,50,50)},
|
||||
width = 2,
|
||||
next_m = {x=2,y=0},
|
||||
next_a = {x=2,y=1},
|
||||
},
|
||||
--Signals
|
||||
tl_1 = {
|
||||
maintex = {"metrostroi_arm/tl_1",w=32,h=16,rw=21,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_2 = {
|
||||
maintex = {"metrostroi_arm/tl_2",w=64,h=16,rw=34,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
tl_3 = {
|
||||
maintex = {"metrostroi_arm/tl_3",w=64,h=16,rw=47,rh=13},
|
||||
full = {"metrostroi_arm/tl_f",w=16,h=16,rw=12,rh=12},
|
||||
h1 = {"metrostroi_arm/tl_h1",w=16,h=16,rw=12,rh=12},
|
||||
h2 = {"metrostroi_arm/tl_h2",w=16,h=16,rw=12,rh=12},
|
||||
},
|
||||
}
|
||||
if CLIENT then
|
||||
for i,segm in pairs(ENT.Types) do
|
||||
for k,tex in pairs(segm) do
|
||||
if type(tex) ~= "table" or type(tex[1]) ~= "string" then continue end
|
||||
tex.mat = surface.GetTextureID(tex[1])
|
||||
end
|
||||
segm.id = i
|
||||
end
|
||||
end
|
||||
|
||||
--------------
|
||||
-- Syntax of table
|
||||
-- {
|
||||
-- station = "ID,abbreviation,full name"
|
||||
-- First line of segments
|
||||
-- {"segment type:occupation checkers,...,occupation checkers:lights:...:lights"},
|
||||
-- Second line of segments
|
||||
-- {x=x indent,skip=y indent(skips y segments vertically),"segment type:occupation checkers main,...,occupation checkers main:occupation checkers alt,...,occupation checkers alt:lights:...:lights"},
|
||||
-- }
|
||||
-- segment type can have > or ! on start, when we want mirror it vertically or horisontally
|
||||
-- Occupation checkers can be triggers(have @ in start of trigger name) or signals
|
||||
-- Lights can be empty, if we want take light name from occupation checkers
|
||||
-- Lights can have ! when stay in right direction or !! when stay in opposite direction
|
||||
-- Lights can have > when we want switch light location from bottom to top
|
||||
-- Examples
|
||||
--{
|
||||
-- station = "001,ST,Station name",
|
||||
-- {
|
||||
-- {"1:L1:!","1:L3:!","sw:@sw1trigger:@sw3trigger"}
|
||||
-- {x=1,"1:L2",">sw:@sw2trigger:@sw3rigger"},
|
||||
-- }
|
||||
--}
|
||||
--------------
|
||||
Metrostroi.ARMConfig = {
|
||||
--[=[
|
||||
{
|
||||
station = "451,ВБ,Уоллеса брина",
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","sw:1","3:1","3:1"},
|
||||
{x=7,"0.5:1","4sws:1",">4sws:1","1:1","1:1"},{skip=1},
|
||||
{x=7,"0.5:1","!4sws:1",">!4sws:1","1:1","1:1"},
|
||||
{"0.5:1","0.5:1","0.5:1","0.5:1","1:1","1:1","1:1","!sw:1","3:1","3:1"},
|
||||
},{
|
||||
station="915,РЧ,Речная",
|
||||
{x=3.5,"0.5:RX22","1:RX22","1:RX20","0.5:RX98","4sw:::RX1:0",">4sw:::RX3:","1","2","2","1","1"},{skip=3},
|
||||
{"1:201","0.5:203","0.5:205","0.5:207","0.5:209","0.5:211","0.5:213","1:215","1:217","0.5:219","!4sw:::RX2::!!2RX95",">!4sw:::RX4:","1","2","2","1","1"},
|
||||
},{
|
||||
station="110,МД,Международная",
|
||||
{"1:145//:!1","1:143:!1","1:141//:!1","0.5:RC137","0.5:139M:!1","3:137:!>1","sw:@wt_md_s1:@wt_md_s1:MD1:!!>2D:!>2G","3:@wt_md_t1_1::!2MD3","2:@wt_md_t1_2"},
|
||||
{x=9,"4sws:@wt_md_s3::MD3",">4sws:@wt_md_s5::MD5:!2MD1","2:@wt_md_t3"},{skip=1},
|
||||
{x=9,"!4sws:@wt_md_s4::MD4",">!4sws:@wt_md_s6::MD6:!>2MD2","2:@wt_md_t4"},
|
||||
{"1:MD148:!!2","1:MD146:!!2","1:MD144:!!2","1:MD142:!!2:!1 OP","1:MD140:!!2","1:RC144A","1:RC142","!sw:@wt_md_s2:@wt_md_s2:MD2:!!2MD138G:!1E","3:@wt_md_t2_1::!>2MD4","2:@wt_md_t2_2"},
|
||||
objects={
|
||||
{type="b",name="МЕЖДУНАРОДНАЯ",x1=4+0.3,y1=0+0.6,x2=7-0.3,y2=4-0.6,},
|
||||
{type="cl",path=1,x=4+0.4,y=0+0.65},
|
||||
{type="cl",path=2,x=7-0.4,y=4-0.65, right=true},
|
||||
},
|
||||
buttons = {
|
||||
{type="r" ,y=4-0.6 ,x=0,name="2I"},
|
||||
{type="pn",y=4-0.6 ,x=0.3,name="2IA"},
|
||||
{type="r" ,y=4-0.6 ,x=4,name="OP"},
|
||||
{type="r" ,y=4 ,x=6+0.4, name="MD138G"},
|
||||
{type="r" ,y=4-0.6 ,x=9,name="E"},
|
||||
{type="r" ,y=3 ,x=12,name="4I"},
|
||||
{type="r" ,y=1-0.6 ,x=12,name="3I"},
|
||||
{type="r" ,y=0-0.6 ,x=6+0.4, name="D"},
|
||||
{type="pn",y=0-0.6 ,x=6.7,name="DA"},
|
||||
{type="r" ,y=0 ,x=9,name="G"},
|
||||
{type="pn",y=1+0.3 ,x=1.4,name="CPS"},
|
||||
{type="rn",y=2-0.3 ,x=1.4,name="ГОК"},
|
||||
{type="pn",y=1+0.3 ,x=2.5,name="CRI"},
|
||||
{type="rn",y=2-0.3 ,x=2.5,name="ОМО"},
|
||||
|
||||
{type="rn",y=1.6 ,x=9,name="АО 3П"},
|
||||
{type="rn",y=2.4 ,x=9,name="АО 4П"},
|
||||
},
|
||||
info= {
|
||||
{y=4.7,x=6.3,text="ТЕСТ"},
|
||||
{y=4.7,x=7.65,text="АВ:Х3",col=Color(50,230,50)},
|
||||
{y=4.95,x=7.65,text="АВ:ДВ",col=Color(50,230,50)},
|
||||
{y=5.2, x=7.65,text="УПО",col=Color(50,230,50)},
|
||||
{y=4.7,x=9,text="П1ДЦ",col=Color(255,230,50)},
|
||||
{y=4.95,x=9,text="П2ДЦ",col=Color(255,230,50)},
|
||||
},
|
||||
routes = {
|
||||
["2I-OP"] = {
|
||||
signals={"MD148","MD146","MD144","MD142"},mode=1,
|
||||
first={0,4},last={3,4},
|
||||
},
|
||||
["OP-MD138G"] = {
|
||||
signals={"MD140"},mode=1,
|
||||
first={4,4},last={6,4},
|
||||
},
|
||||
["MD138G-4I"] = {
|
||||
signals={"MD138G"},mode=3,
|
||||
first={7,4},last={12,3},
|
||||
},
|
||||
["MD138G-3I"] = {
|
||||
signals={"MD138G"},mode=3,
|
||||
first={7,4},last={12,1},checks={{9,1},{10.5,3}},
|
||||
},
|
||||
["4I-OP"] = {
|
||||
signals={"MD2"},mode=3,
|
||||
first={12,3},last={4,4},
|
||||
},
|
||||
["3I-OP"] = {
|
||||
signals={"MD1"},mode=3,
|
||||
first={12,1},last={4,4},checks={{9,1},{10.5,3}},
|
||||
},
|
||||
["MD138G-E"] = {
|
||||
signals={"MD138G"},mode=3,
|
||||
first={7,4},last={9,4},
|
||||
},
|
||||
["E-MD138G"] = {
|
||||
signals={"E"},mode=3,
|
||||
first={7,4},last={4,4},
|
||||
},
|
||||
["D-4I"] = {
|
||||
signals={"D"},mode=3,
|
||||
first={7,0},last={12,3},checks={{9,3},{10.5,1}},
|
||||
},
|
||||
["D-3I"] = {
|
||||
signals={"D"},mode=3,
|
||||
first={7,0},last={12,1},
|
||||
},
|
||||
["D-G"] = {
|
||||
signals={"D"},mode=3,
|
||||
first={7,0},last={9,0},
|
||||
},
|
||||
["G-D"] = {
|
||||
signals={"G"},mode=3, first={7,0},last={4,0},
|
||||
},
|
||||
["4I-D"] = {
|
||||
signals={"MD2"},mode=3,
|
||||
first={12,3},last={4,0},checks={{9,3},{10.5,1},{3.5,0}},ignore={{12,3}}
|
||||
},
|
||||
["3I-D"] = {
|
||||
signals={"MD1"},mode=3,
|
||||
first={12,1},last={4,0},checks={{3.5,0}},
|
||||
},
|
||||
},
|
||||
signals = {
|
||||
--"LensesStr": "YYG-RW",
|
||||
MD148={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD146={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD144={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",Y="1",YG="13",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD142={
|
||||
Mode=1, --AB 1/5
|
||||
R="3",RY="31",Y="1",G="2",IS="4", --Lenses ID
|
||||
Autostop = true,AO = false,bs=4,
|
||||
},
|
||||
MD140={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="42",--[[ Y="1",--]] YG="13",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,bs=3,
|
||||
},
|
||||
MD138G={
|
||||
Mode=1, --AB 1/5
|
||||
R="3",RY="32",W="1",IS="4", --Lenses ID
|
||||
Autostop = true,AO = false,bs=1,
|
||||
},
|
||||
MD3={
|
||||
Mode=1, --AB 1/5
|
||||
R="1",IS="2",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD4={
|
||||
Mode=1, --AB 1/5
|
||||
R="1",IS="2",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD1={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
MD2={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
E={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
G={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
D={
|
||||
Mode=1, --AB 1/5
|
||||
R="2",W="1",IS="3",
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
}
|
||||
},{
|
||||
station="112,ПТ,Политехническая",
|
||||
{x=1,"1:PT2TB","2:PT2TA","2:PT2T:!!2PT2","2:PT4SA:!!2PT4",">2swm:@wt_pt_t4::PT4:!3PT968M:!!2G ","1:PT966A","2:PT966:!>2","sw:@wt_pt_t6::PT6:!>2PT964:!!>3A","1:962"},
|
||||
{x=15,"1:PT6SS","1:963"},
|
||||
{x=1,"1:77:!1","1:75:!1","1:73:!1","1:71:!>1",">2swm:@wt_pt_t1::PT1:!!>2B","!2swm:@wt_pt_t3::PT3:!>2PT69","1:PT67M:!2","1:PT65B","1:PT65A","1:PT65:!2","1:PT63:!2:!!1 OP ","1:PT61:!2","1:PT59:!2","1:PT57:!2"},{skip=1},
|
||||
{"1:PT70:!!2:!1 OP2 ","1:PT68:!!2","2:@wt_pt_t2:!!2PT66","!2swm:@wt_pt_t4::PT2:!!3PT64","2","2:62:!!1","1:60:!!1","2:60A","1:58M:!!1","1:56:!!1","1:54:!!1","1: 52:!!1"},
|
||||
{},
|
||||
objects={
|
||||
{type="b",name="ПОЛИТЕХНИ-\nЧЕСКАЯ I",x1=10+0.3,y1=0+0.6,x2=13-0.3,y2=2-0.6,},
|
||||
{type="b",name="ПОЛИТЕХНИ-\nЧЕСКАЯ II",x1=10+0.3,y1=4+0.6,x2=13-0.3,y2=6-0.6,},
|
||||
{type="cl",path=3,x=10+0.4,y=0+0.3},
|
||||
{type="cl",path=1,x=10+0.4,y=1+0.3},
|
||||
{type="cl",path=2,x=13-0.4,y=5-0.3, right=true},
|
||||
},
|
||||
labels = {
|
||||
|
||||
},
|
||||
buttons = {
|
||||
--{type="r",y=0-0.6 ,x=1, start="3T",target={1,0},flip=true},
|
||||
--{type="r",y=0 ,x=3+0.4,start="PT2",target={1,0},flip=true},
|
||||
|
||||
--{type="r",y=4-0.6 ,x=1, signal=" OP2 "},
|
||||
--{type="r",y=4 ,x=-1+0.4, signal="PT70"},
|
||||
--{type="r",y=4 ,x=3+0.4, signal="2P",target={8,4}},
|
||||
----{type="r",y=4 ,x=7+0.4, signal="62"},
|
||||
--{type="r",y=2 ,x=5, signal="71"},
|
||||
--{type="r",y=2-0.6 ,x=4+0.4, signal="B",target={5,2}},
|
||||
--{type="r",y=2-0.6 ,x=17, signal="PT57"},
|
||||
--{type="r",y=2-0.6 ,x=10, signal="PT67M"},
|
||||
--{type="r",y=2 ,x=12+0.4,signal=" OP "},
|
||||
--{type="r",y=0-0.6 ,x=10, signal="PT968M",flip=true},
|
||||
--{type="r",y=0 ,x=15, signal="PT964",flip=true},
|
||||
--{type="r",y=1-0.6 ,x=15, signal="4O",target={15,1},flip=true},
|
||||
--{type="r",y=0-0.6 ,x=12+0.4,signal="A",flip=true},
|
||||
},
|
||||
routes = {
|
||||
--[[ PT2 = {"A"},
|
||||
PT70 = {" OP ","A","2P"},
|
||||
--PT64 = {" OP ","A","PT64"},
|
||||
B = {" OP ","A"},
|
||||
PT57 = {"PT67M"},
|
||||
PT964 = {"PT968M"},
|
||||
PT67M = {"71"," OP2 "},
|
||||
PT968M = {"3T","71"," OP2 "},
|
||||
A={"4O"}--]]
|
||||
},
|
||||
signals = {
|
||||
--"LensesStr": "YYG-RW",
|
||||
PT70={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT68={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT66={
|
||||
Mode=1, --AB 1/5
|
||||
R="4",RY="41",Y="2",YG="23",G="3",IS="5", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
},
|
||||
PT64={ --"YWY-GRW
|
||||
Mode=1, --AB 1/5
|
||||
R="5",RY="51",Y="3",YG="34",G="4",IS="6",W="2",YY="13",YbY="1b3", --Lenses ID
|
||||
Autostop = true,AO = false,
|
||||
routes = {
|
||||
[" OP "]={path=2,mode=3},--Path-2, Mode: W
|
||||
A={path=3,mode=2},--Path-2, Mode: YY
|
||||
}
|
||||
}
|
||||
}
|
||||
},{
|
||||
station="115,ОК,Октябрьская",
|
||||
{"1","1","1","1","3","sw:::OK1","1"},
|
||||
{x=9,"4sws:::OK3",">4sws:::OK5","1"},{skip=1},
|
||||
{x=9,"!4sws:::OK4",">!4sws:::OK6","1"},
|
||||
{"1","1","1","1","3","!sw:::OK2","5"},
|
||||
objects={
|
||||
{type="b",name="ОКТЯБРЬСКАЯ",x1=4+0.3,y1=0+0.6,x2=7-0.3,y2=4-0.6,},
|
||||
{type="cl",path=1,x=4+0.4,y=0+0.65},
|
||||
{type="cl",path=2,x=7-0.4,y=4-0.65, right=true},
|
||||
},
|
||||
}--]=]
|
||||
}
|
||||
|
||||
print("MetrostroiARM:Generating ARM table...")
|
||||
local errors,warnings = 0,0
|
||||
local function ARMGenError(text,err)
|
||||
MsgC(Color(255,err and 0 or 255,0),"MetrostroiARM:"..text.."\n")
|
||||
ErrorNoHalt()
|
||||
if err then errors = errors + 1 else warnings = warnings + 1 end
|
||||
end
|
||||
|
||||
local function ParseARMTable(text,station,line,segm)
|
||||
local resultTbl = {}
|
||||
|
||||
local tbl = string.Explode(":",text)
|
||||
|
||||
local typ = tbl[1]
|
||||
if typ:find("^[>!]") then
|
||||
resultTbl.invertX = typ:find(">")
|
||||
resultTbl.invertY = typ:find("!")
|
||||
typ = typ:gsub("^[>!]+","")
|
||||
end
|
||||
local segmTyp = ENT.Types[tonumber(typ) or typ]
|
||||
if not segmTyp then return {error = 1,type = tbl[1]} end
|
||||
table.remove(tbl,1)
|
||||
|
||||
for i,str in ipairs(tbl) do
|
||||
if str:find(",") then
|
||||
tbl[i] = string.Explode(",",str)
|
||||
end
|
||||
if str:sub(1,2) == "!!" then
|
||||
resultTbl.signal2 = str:sub(3,-1)
|
||||
elseif str[1] == "!" then
|
||||
resultTbl.signal1 = str:sub(2,-1)
|
||||
end
|
||||
end
|
||||
resultTbl.occup = type(tbl[1]) == "table" and tbl[1] or {tbl[1]}
|
||||
if segmTyp.occup_a then
|
||||
resultTbl.occupAlt = type(tbl[2]) == "table" and tbl[2] or {tbl[2]}
|
||||
resultTbl.switch = tbl[3]
|
||||
if segmTyp.occup_x then
|
||||
resultTbl.occup2 = type(tbl[4]) == "table" and tbl[4] or {tbl[4]}
|
||||
end
|
||||
end
|
||||
|
||||
if resultTbl.signal1 then
|
||||
local signal = resultTbl.signal1:gsub("^[>]+","")
|
||||
local top = resultTbl.signal1:find("^>")
|
||||
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal1 = {name=name,type=typ or 1,top = top,segm=resultTbl,dir=false}
|
||||
end
|
||||
if resultTbl.signal2 then
|
||||
local signal = resultTbl.signal2:gsub("^[>]+","")
|
||||
local top = resultTbl.signal2:find("^>")
|
||||
local typ = tonumber(signal[1])
|
||||
local name = signal:sub(2,-1)
|
||||
if not typ then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment not found. Using default 1",station,line,segm),false)
|
||||
name = signal[1]..name
|
||||
elseif typ < 1 or typ > 3 then
|
||||
ARMGenError(Format("Parser warning. Signal type in id station %d line %d segm %d segment have wrong ID, must be in range 1..3. Using default 1",station,line,segm),false)
|
||||
typ = 1
|
||||
end
|
||||
if name == "" then name = resultTbl.occup[1] end
|
||||
resultTbl.signal2 = {name=name,type=typ or 1,top = top,segm=resultTbl,dir=true}
|
||||
end
|
||||
resultTbl.type = typ
|
||||
resultTbl.width = segmTyp.width or 1
|
||||
resultTbl.segm = segmTyp
|
||||
return resultTbl
|
||||
end
|
||||
|
||||
|
||||
Metrostroi.ARMConfigGenerated = {}
|
||||
local id = 0
|
||||
for i,station in ipairs(Metrostroi.ARMConfig) do
|
||||
if not Metrostroi.ARMConfigGenerated[i] then Metrostroi.ARMConfigGenerated[i] = {} end
|
||||
local genStation = Metrostroi.ARMConfigGenerated[i]
|
||||
local y = 0
|
||||
|
||||
MsgC(Color(0, 222, 255),"MetrostroiARM:Solving station ",i,"\n")
|
||||
if #station == 0 then ARMGenError(Format("Parser warning. Empty station %d! Skipping...",i),false) continue end
|
||||
if not station.station then ARMGenError(Format("Parser error. Can't find station name in station %d! Skipping...",i),true) continue end
|
||||
|
||||
local stationTbl = string.Explode(",",station.station)
|
||||
if not stationTbl or #stationTbl < 3 or not tonumber(stationTbl[1]) then ARMGenError(Format("Parser error. Malformed station data in station %d! Skipping...",i),true) continue end
|
||||
|
||||
genStation.id = stationTbl[1]
|
||||
genStation.shortname = stationTbl[2]
|
||||
genStation.name = stationTbl[3]
|
||||
genStation.buttons = {}
|
||||
genStation.routes = station.routes or {}
|
||||
genStation.objects = station.objects or {}
|
||||
genStation.info = station.info or {}
|
||||
genStation.signals = station.signals or {}
|
||||
for lineID,line in ipairs(station) do
|
||||
local x = line.x or 0
|
||||
for segmID,segm in ipairs(line) do
|
||||
if type(segm) ~= "string" then
|
||||
ARMGenError(Format("Parser error on station %d line %d segm %d, excepted string,got %s. Skipping segment...",i,lineID,segmID,type(segm)),true)
|
||||
continue
|
||||
end
|
||||
local segmTbl= ParseARMTable(segm,i,lineID,segmID)
|
||||
if segmTbl.error then
|
||||
ARMGenError(Format("Parser warning. Skipping station %d line %d segm %d segment, type error(type '%s' not found)",i,lineID,segmID,segmTbl.type),false)
|
||||
continue
|
||||
end
|
||||
if segmTbl.signal1 then
|
||||
for name,sig in pairs(genStation.signals) do
|
||||
if name==segmTbl.signal1.name then
|
||||
sig.sig = segmTbl.signal1
|
||||
sig.segm = segmTbl
|
||||
end
|
||||
end
|
||||
end
|
||||
if segmTbl.signal2 then
|
||||
for name,sig in pairs(genStation.signals) do
|
||||
if name==segmTbl.signal2.name then
|
||||
sig.sig = segmTbl.signal2
|
||||
sig.segm = segmTbl
|
||||
end
|
||||
end
|
||||
end
|
||||
segmTbl.x = x
|
||||
segmTbl.y = y
|
||||
segmTbl.id = table.insert(genStation,segmTbl)
|
||||
x = x + (segmTbl.width or 1)
|
||||
end
|
||||
y = y + (line.skip or 1)
|
||||
end
|
||||
if station.buttons then
|
||||
for _,button in pairs(station.buttons) do
|
||||
button.pressable = false
|
||||
button.selected = false
|
||||
button.isbutton = true
|
||||
if button.type == "r" then
|
||||
button.segm = ENT.Types.button_normal
|
||||
end
|
||||
table.insert(genStation.buttons,button)
|
||||
end
|
||||
end
|
||||
if station.routes then
|
||||
for name,route in pairs(station.routes) do
|
||||
route.name = name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ENT.FindSegment(station,x,y)
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm.x == x and segm.y == y then return segm end
|
||||
end
|
||||
end
|
||||
|
||||
local function GetXY(x,y)
|
||||
return 100+x*36,100+y*70
|
||||
end
|
||||
|
||||
local function GetSegmPos(segm,alt)
|
||||
local x,y = segm.x,segm.y
|
||||
local segmt = segm.segm
|
||||
local u0,v0,u1,v1 = 0,0,1,1
|
||||
if segm.invertX then u0,u1 = 1,0 end
|
||||
if segm.invertY then v0,v1 = 1,0 end
|
||||
if alt == nil then
|
||||
return GetXY(x+segm.width*u0,y)
|
||||
elseif alt == false and segmt.next_m then
|
||||
return GetXY(x+segmt.next_m.x-segm.width*u0,y+segmt.next_m.y)
|
||||
--print(123,x,y)
|
||||
elseif alt and segmt.next_a then
|
||||
return GetXY(x+segmt.next_a.x*u1-segmt.next_a.x*u0+segmt.width*u0,y+segmt.next_a.y*v1-segmt.next_a.y*v0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function ARMSetNextCompare(posX,posY,segm,nsegm)
|
||||
local xp,yp = GetSegmPos(segm)
|
||||
local x,y = GetSegmPos(nsegm)
|
||||
if sx and posX == x and posY == y then
|
||||
nsegm.prev = segm
|
||||
return true
|
||||
end
|
||||
|
||||
sx,sy = GetSegmPos(nsegm,false)
|
||||
if sx and posX == sx and posY == sy then
|
||||
nsegm.next_m = segm
|
||||
return true
|
||||
end
|
||||
if not nsegm.segm.next_a then return end
|
||||
sx,sy = GetSegmPos(nsegm,true)
|
||||
if x ~= xp and y ~= yp and sx and posX == sx and posY == sy then
|
||||
nsegm.next_a = segm
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ARMSetNext(station)
|
||||
for csegmid,csegm in ipairs(station) do
|
||||
for segmid,segm in ipairs(station) do
|
||||
if segm == csegm then continue end
|
||||
|
||||
local posX,posY = GetSegmPos(csegm)
|
||||
if ARMSetNextCompare(posX,posY,csegm,segm) then
|
||||
csegm.prev = segm
|
||||
--break
|
||||
end
|
||||
local posOX,posOY = GetSegmPos(csegm,false)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_m = segm
|
||||
--break
|
||||
end
|
||||
local posAX,posAY = GetSegmPos(segm)
|
||||
if not csegm.segm.next_a or posX == posAX or posY == posAY then continue end
|
||||
posOX,posOY = GetSegmPos(csegm,true)
|
||||
if ARMSetNextCompare(posOX,posOY,csegm,segm) then
|
||||
csegm.next_a = segm
|
||||
--break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,st in ipairs(Metrostroi.ARMConfigGenerated) do ARMSetNext(st) end
|
||||
|
||||
local iter = 0
|
||||
function ENT.TraceSegments(station,segm,to,dir,last,checked,trace)
|
||||
if not checked then iter=0 checked = {} end
|
||||
iter = iter + 1
|
||||
if iter > 10000 then ARMGenError(Format("Routes generation error. Max iter reached!"),true) return false end
|
||||
|
||||
if not trace then trace = {} end
|
||||
if last == to then return trace end
|
||||
if not segm or checked[segm] then return restbl end
|
||||
checked[segm] = true
|
||||
local segmIndex = table.insert(trace,{segm.id})
|
||||
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local segmP = segm.prev
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if segmA and mainM then
|
||||
local trace= table.Copy(trace)
|
||||
trace[segmIndex][2] = true
|
||||
local result = ENT.TraceSegments(station,segmA,to,dir,segm,checked,trace)
|
||||
if result then return result end
|
||||
end
|
||||
if segmM and mainM then
|
||||
return ENT.TraceSegments(station,segmM,to,dir,segm,checked,trace)
|
||||
end
|
||||
if segmP and mainP then
|
||||
trace[segmIndex][2] = last and segm.next_a == last or nil-- or segmP.next_a == segm or nil
|
||||
return ENT.TraceSegments(station,segmP,to,dir,segm,checked,trace)
|
||||
end
|
||||
if segm == to then return trace end
|
||||
end
|
||||
for i,station in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
for name,route in pairs(station.routes) do
|
||||
if not route.first or not route.last then ARMGenError(Format("Route check[%s]. Skipping route, missing first/last...",name),false) continue end
|
||||
|
||||
local first,last = ENT.FindSegment(station,route.first[1],route.first[2]),ENT.FindSegment(station,route.last[1],route.last[2])
|
||||
if not first or not last then ARMGenError(Format("Route check[%s]. Skipping route, can't find first/last on selected pos...",name),false) continue end
|
||||
|
||||
if route.checks then
|
||||
for k,segmt in pairs(route.checks) do
|
||||
route.checks[k] = ENT.FindSegment(station,segmt[1],segmt[2])
|
||||
end
|
||||
end
|
||||
local trace1 = ENT.TraceSegments(station,first,last,false)
|
||||
if trace1 then
|
||||
route.dir,route.route,route.directions = false,{},{}
|
||||
for i,segm in ipairs(trace1) do
|
||||
table.insert(route.route,station[segm[1]])
|
||||
route.directions[i] = segm[2]
|
||||
end
|
||||
if route.ignore then
|
||||
route.ignores = {}
|
||||
for k,segmti in pairs(route.ignore) do
|
||||
local segm = ENT.FindSegment(station,segmti[1],segmti[2])
|
||||
for i,segmt in ipairs(route.route) do
|
||||
if segm == segmt then route.ignores[i] = segm end
|
||||
end
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
local trace2 = ENT.TraceSegments(station,first,last,true)
|
||||
if trace2 then
|
||||
route.dir,route.route,route.directions = true,{},{}
|
||||
for i,segm in ipairs(trace2) do
|
||||
table.insert(route.route,station[segm[1]])
|
||||
route.directions[i] = segm[2]
|
||||
end
|
||||
if route.ignore then
|
||||
route.ignores = {}
|
||||
for k,segmti in pairs(route.ignore) do
|
||||
local segm = ENT.FindSegment(station,segmti[1],segmti[2])
|
||||
for i,segmt in ipairs(route.route) do
|
||||
if segm == segmt then route.ignores[i] = segm end
|
||||
end
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
ARMGenError(Format("Route check[%s]. Can't find path from start on end.",name),false)
|
||||
end
|
||||
for _,button in pairs(station.buttons) do
|
||||
for name,route in pairs(station.routes) do
|
||||
if name:find("-") then
|
||||
local buttonName = name:sub(1,name:find("-")-1)
|
||||
local buttonNameEnd = name:sub(name:find("-")+1,-1)
|
||||
if button.name == buttonName then
|
||||
if not route.startButtons then route.startButtons = {} end
|
||||
table.insert(route.startButtons, button)
|
||||
button.pressable = true
|
||||
|
||||
if not button.routes then button.routes = {} end
|
||||
table.insert(button.routes,route)
|
||||
end
|
||||
if button.name == buttonNameEnd then
|
||||
if not route.endButtons then route.endButtons = {} end
|
||||
table.insert(route.endButtons, button)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if errors == 0 and warnings == 0 then
|
||||
MsgC(Color(0,255,0),"MetrostroiARM:Generate finished without errors and warnings.\n")
|
||||
elseif errors == 0 then
|
||||
MsgC(Color(255,255,0),"MetrostroiARM:Generate finished with "..warnings.." warnings.\n")
|
||||
else
|
||||
MsgC(Color(255,0,0),"MetrostroiARM:Generate finished with "..errors.." errors and "..warnings.." warnings!\n")
|
||||
end
|
||||
--PrintTable(Metrostroi.ARMConfigGenerated)
|
||||
|
||||
for k,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
Metrostroi.ARMTable[k] = {
|
||||
occChecks = {},
|
||||
net = {},
|
||||
signal = {},
|
||||
switch = {},
|
||||
routes = {},
|
||||
}
|
||||
end
|
||||
@@ -1,53 +0,0 @@
|
||||
include("shared.lua")
|
||||
local frame = nil
|
||||
function CreateFrame()
|
||||
if !frame or !frame:IsValid() then
|
||||
local self = net.ReadEntity()
|
||||
local Map = game.GetMap() or ""
|
||||
if Map:find("gm_metrostroi") and Map:find("lite") then
|
||||
Map = "gm_metrostroi_lite"
|
||||
elseif Map:find("gm_metrostroi") then
|
||||
Map = "gm_metrostroi"
|
||||
elseif Map:find("gm_mus_orange_line") and Map:find("long") then
|
||||
Map = "gm_orange"
|
||||
elseif Map:find("gm_mus_orange_line") then
|
||||
Map = "gm_orange_lite"
|
||||
end
|
||||
frame = vgui.Create("DFrame")
|
||||
frame:SetDeleteOnClose(true)
|
||||
frame:SetTitle("Dispatch control")
|
||||
--frame:SetSize(275, 34+24*17)
|
||||
frame:SetDraggable(false)
|
||||
frame:SetSizable(false)
|
||||
frame:MakePopup()
|
||||
|
||||
frame:SetSize(ScrW()-40,ScrH()-40)
|
||||
frame:Center()
|
||||
local StationChoose = vgui.Create( "DComboBox",frame )
|
||||
StationChoose:SetPos( 5, 30 )
|
||||
StationChoose:SetSize( 250, 20 )
|
||||
StationChoose:SetValue( "Choose station" )
|
||||
for k,v in pairs(Metrostroi.WorkingStations[Map][1]) do
|
||||
if Metrostroi.AnnouncerData[v] then StationChoose:AddChoice(Metrostroi.AnnouncerData[v][1]) end
|
||||
end
|
||||
|
||||
local PlayerChoose = vgui.Create( "DComboBox",frame )
|
||||
PlayerChoose:SetPos( ScrW()-300,30 )
|
||||
PlayerChoose:SetSize( 250, 20 )
|
||||
PlayerChoose:SetValue( "Choose player" )
|
||||
for i = 1,20 do
|
||||
PlayerChoose:AddChoice(i)
|
||||
end
|
||||
|
||||
local Main = vgui.Create( "DPanel",frame )
|
||||
Main:SetPos(0,60)
|
||||
Main:SetSize(frame:GetWide(),frame:GetTall()-60)
|
||||
Main.Paint = function(self,w,h)
|
||||
surface.DrawRect(5, 0, w-10, h-5)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
function ENT:Initialize()
|
||||
end
|
||||
net.Receive("TrackController",CreateFrame)
|
||||
@@ -1,29 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
util.AddNetworkString("TrackController")
|
||||
local function ShowWindowOnCL(ply,ent)
|
||||
net.Start("TrackController")
|
||||
net.WriteEntity(ent)
|
||||
net.Send(ply)
|
||||
end
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/metrostroi/signals/clock_time.mdl")
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
function ENT:SpawnFunction( ply, tr, ClassName )
|
||||
|
||||
if ( !tr.Hit ) then return end
|
||||
|
||||
local SpawnPos = tr.HitPos + tr.HitNormal * 16
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:SetPos( SpawnPos )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
ShowWindowOnCL(ply,ent)
|
||||
return ent
|
||||
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.Category = "Metrostroi (utility)"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
@@ -1,53 +0,0 @@
|
||||
include("shared.lua")
|
||||
local frame = nil
|
||||
function CreateFrame()
|
||||
if !frame or !frame:IsValid() then
|
||||
local self = net.ReadEntity()
|
||||
local Map = game.GetMap() or ""
|
||||
if Map:find("gm_metrostroi") and Map:find("lite") then
|
||||
Map = "gm_metrostroi_lite"
|
||||
elseif Map:find("gm_metrostroi") then
|
||||
Map = "gm_metrostroi"
|
||||
elseif Map:find("gm_mus_orange_line") and Map:find("long") then
|
||||
Map = "gm_orange"
|
||||
elseif Map:find("gm_mus_orange_line") then
|
||||
Map = "gm_orange_lite"
|
||||
end
|
||||
frame = vgui.Create("DFrame")
|
||||
frame:SetDeleteOnClose(true)
|
||||
frame:SetTitle("Dispatch control")
|
||||
--frame:SetSize(275, 34+24*17)
|
||||
frame:SetDraggable(false)
|
||||
frame:SetSizable(false)
|
||||
frame:MakePopup()
|
||||
|
||||
frame:SetSize(ScrW()-40,ScrH()-40)
|
||||
frame:Center()
|
||||
local StationChoose = vgui.Create( "DComboBox",frame )
|
||||
StationChoose:SetPos( 5, 30 )
|
||||
StationChoose:SetSize( 250, 20 )
|
||||
StationChoose:SetValue( "Choose station" )
|
||||
for k,v in pairs(Metrostroi.WorkingStations[Map][1]) do
|
||||
if Metrostroi.AnnouncerData[v] then StationChoose:AddChoice(Metrostroi.AnnouncerData[v][1]) end
|
||||
end
|
||||
|
||||
local PlayerChoose = vgui.Create( "DComboBox",frame )
|
||||
PlayerChoose:SetPos( ScrW()-300,30 )
|
||||
PlayerChoose:SetSize( 250, 20 )
|
||||
PlayerChoose:SetValue( "Choose player" )
|
||||
for i = 1,20 do
|
||||
PlayerChoose:AddChoice(i)
|
||||
end
|
||||
|
||||
local Main = vgui.Create( "DPanel",frame )
|
||||
Main:SetPos(0,60)
|
||||
Main:SetSize(frame:GetWide(),frame:GetTall()-60)
|
||||
Main.Paint = function(self,w,h)
|
||||
surface.DrawRect(5, 0, w-10, h-5)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
function ENT:Initialize()
|
||||
end
|
||||
net.Receive("TrackController",CreateFrame)
|
||||
@@ -1,29 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
util.AddNetworkString("TrackController")
|
||||
local function ShowWindowOnCL(ply,ent)
|
||||
net.Start("TrackController")
|
||||
net.WriteEntity(ent)
|
||||
net.Send(ply)
|
||||
end
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/metrostroi/signals/clock_time.mdl")
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
function ENT:SpawnFunction( ply, tr, ClassName )
|
||||
|
||||
if ( !tr.Hit ) then return end
|
||||
|
||||
local SpawnPos = tr.HitPos + tr.HitNormal * 16
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:SetPos( SpawnPos )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
ShowWindowOnCL(ply,ent)
|
||||
return ent
|
||||
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.PrintName = "Train door"
|
||||
ENT.Category = "Metrostroi (utility)"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
@@ -1,53 +0,0 @@
|
||||
include("shared.lua")
|
||||
local frame = nil
|
||||
function CreateFrame()
|
||||
if !frame or !frame:IsValid() then
|
||||
local self = net.ReadEntity()
|
||||
local Map = game.GetMap() or ""
|
||||
if Map:find("gm_metrostroi") and Map:find("lite") then
|
||||
Map = "gm_metrostroi_lite"
|
||||
elseif Map:find("gm_metrostroi") then
|
||||
Map = "gm_metrostroi"
|
||||
elseif Map:find("gm_mus_orange_line") and Map:find("long") then
|
||||
Map = "gm_orange"
|
||||
elseif Map:find("gm_mus_orange_line") then
|
||||
Map = "gm_orange_lite"
|
||||
end
|
||||
frame = vgui.Create("DFrame")
|
||||
frame:SetDeleteOnClose(true)
|
||||
frame:SetTitle("Dispatch control")
|
||||
--frame:SetSize(275, 34+24*17)
|
||||
frame:SetDraggable(false)
|
||||
frame:SetSizable(false)
|
||||
frame:MakePopup()
|
||||
|
||||
frame:SetSize(ScrW()-40,ScrH()-40)
|
||||
frame:Center()
|
||||
local StationChoose = vgui.Create( "DComboBox",frame )
|
||||
StationChoose:SetPos( 5, 30 )
|
||||
StationChoose:SetSize( 250, 20 )
|
||||
StationChoose:SetValue( "Choose station" )
|
||||
for k,v in pairs(Metrostroi.WorkingStations[Map][1]) do
|
||||
if Metrostroi.AnnouncerData[v] then StationChoose:AddChoice(Metrostroi.AnnouncerData[v][1]) end
|
||||
end
|
||||
|
||||
local PlayerChoose = vgui.Create( "DComboBox",frame )
|
||||
PlayerChoose:SetPos( ScrW()-300,30 )
|
||||
PlayerChoose:SetSize( 250, 20 )
|
||||
PlayerChoose:SetValue( "Choose player" )
|
||||
for i = 1,20 do
|
||||
PlayerChoose:AddChoice(i)
|
||||
end
|
||||
|
||||
local Main = vgui.Create( "DPanel",frame )
|
||||
Main:SetPos(0,60)
|
||||
Main:SetSize(frame:GetWide(),frame:GetTall()-60)
|
||||
Main.Paint = function(self,w,h)
|
||||
surface.DrawRect(5, 0, w-10, h-5)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
function ENT:Initialize()
|
||||
end
|
||||
net.Receive("TrackController",CreateFrame)
|
||||
@@ -1,29 +0,0 @@
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("shared.lua")
|
||||
include("shared.lua")
|
||||
util.AddNetworkString("TrackController")
|
||||
local function ShowWindowOnCL(ply,ent)
|
||||
net.Start("TrackController")
|
||||
net.WriteEntity(ent)
|
||||
net.Send(ply)
|
||||
end
|
||||
function ENT:Initialize()
|
||||
self:SetModel("models/metrostroi/signals/clock_time.mdl")
|
||||
end
|
||||
|
||||
function ENT:Think()
|
||||
end
|
||||
function ENT:SpawnFunction( ply, tr, ClassName )
|
||||
|
||||
if ( !tr.Hit ) then return end
|
||||
|
||||
local SpawnPos = tr.HitPos + tr.HitNormal * 16
|
||||
local ent = ents.Create( ClassName )
|
||||
ent:SetPos( SpawnPos )
|
||||
ent:Spawn()
|
||||
ent:Activate()
|
||||
|
||||
ShowWindowOnCL(ply,ent)
|
||||
return ent
|
||||
|
||||
end
|
||||
@@ -1,7 +0,0 @@
|
||||
ENT.Type = "anim"
|
||||
|
||||
ENT.PrintName = "Train sound provider"
|
||||
ENT.Category = "Metrostroi (utility)"
|
||||
|
||||
ENT.Spawnable = false
|
||||
ENT.AdminSpawnable = false
|
||||
@@ -1,489 +0,0 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Simulation acceleration DLL support
|
||||
--------------------------------------------------------------------------------
|
||||
if Turbostroi and not Turbostroi.SetMTAffinityMask then return end
|
||||
local turbostroiTrains = {}
|
||||
if not TURBOSTROI then
|
||||
local FPS = 33
|
||||
local messageTimeout = 0
|
||||
local messageCounter = 0
|
||||
local dataCache = {{},{}}
|
||||
hook.Add("EntityRemoved","Turbostroi",function(ent)
|
||||
if dataCache[ent] then
|
||||
dataCache[ent] = nil
|
||||
end
|
||||
if turbostroiTrains[ent] then
|
||||
turbostroiTrains[ent] = nil
|
||||
end
|
||||
end)
|
||||
for k,ent in pairs(ents.GetAll()) do
|
||||
if ent.Base == "gmod_subway_base" and not ent.NoTrain and not ent.DontAccelerateSimulation then
|
||||
turbostroiTrains[ent] = true
|
||||
end
|
||||
end
|
||||
hook.Add("OnEntityCreated","Turbostroi",function(ent)
|
||||
timer.Simple(0,function()
|
||||
if IsValid(ent) and ent.Base == "gmod_subway_base" and not ent.NoTrain and not ent.DontAccelerateSimulation then
|
||||
turbostroiTrains[ent] = true
|
||||
end
|
||||
end)
|
||||
end)
|
||||
local inputCache = {}
|
||||
local id,system,name,index,value
|
||||
local _DEBUGPRINT
|
||||
local function updateTrains(trains)
|
||||
--local recvMessage = Turbostroi.RecvMessage
|
||||
-- Get data packets from simulation
|
||||
for train in pairs(trains) do
|
||||
if not dataCache[train] then
|
||||
if not Turbostroi.SendMessage(train,5,"","",0,0) then return end
|
||||
dataCache[train] = {wiresW = {}}
|
||||
|
||||
for sys_name,system in pairs(train.Systems) do
|
||||
if system.OutputsList and system.DontAccelerateSimulation then
|
||||
for _,name in pairs(system.OutputsList) do
|
||||
local value = system[name] or 0
|
||||
if type(value) == "boolean" then value = value and 1 or 0 end
|
||||
if type(value) == "number" then
|
||||
if not dataCache[train][sys_name] then dataCache[train][sys_name] = {} end
|
||||
dataCache[train][sys_name][name] = math.Round(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,message in pairs(Turbostroi.RecvMessages(train)) do --NEWTURBOSTROI
|
||||
id,system,name,index,value = unpack(message,0) --NEWTURBOSTROI
|
||||
--while true do --OLDTURBOSTROI
|
||||
--id,system,name,index,value = Turbostroi.RecvMessage(train)
|
||||
if id == 1 then
|
||||
if train.Systems[system] then
|
||||
train.Systems[system][name] = value
|
||||
if train.TriggerTurbostroiInput then train:TriggerTurbostroiInput(system,name,value) end
|
||||
end
|
||||
end
|
||||
if id == 2 then
|
||||
if index == 0 and name ~= "bass" then index = nil end
|
||||
if value == 0 and name ~= "bass" then value = nil end
|
||||
if name == "" then name = nil end
|
||||
--net.WriteString(name)
|
||||
train:PlayOnce(system,name,index,value)
|
||||
end
|
||||
if id == 3 then
|
||||
if name == "on" then
|
||||
--print("[!]Wire "..index.." starts update! Value "..value)
|
||||
dataCache[train]["wiresW"][index] = value
|
||||
--train:WriteTrainWire(index,value)
|
||||
if not train.TrainWireWritersID[index] then train.TrainWireWritersID[index] = true end
|
||||
train.TrainWireTurbostroi[index] = value
|
||||
if train.TriggerTurbostroiInput then train:TriggerTurbostroiInput("TrainWire",index,value) end
|
||||
else
|
||||
--print("[!]Wire "..index.." stop update!")
|
||||
dataCache[train]["wiresW"][index] = nil
|
||||
end
|
||||
end
|
||||
if id == 4 then
|
||||
if train.Systems[system] then
|
||||
train.Systems[system]:TriggerInput(name,value)
|
||||
end
|
||||
end
|
||||
if id == 5 then
|
||||
for twid,value in pairs(dataCache[train]["wiresW"]) do
|
||||
--train:WriteTrainWire(twid,value)
|
||||
end
|
||||
end
|
||||
if id == 6 then
|
||||
if IsValid(Player(index)) then
|
||||
if value==0 then
|
||||
Player(index):PrintMessage( HUD_PRINTCONSOLE, "--START" )
|
||||
print("--START")
|
||||
end
|
||||
Player(index):PrintMessage( HUD_PRINTCONSOLE, system )
|
||||
print(system)
|
||||
end
|
||||
end
|
||||
--print(id,name)
|
||||
|
||||
--if not id then
|
||||
--break--OLDTURBOSTROI
|
||||
--end
|
||||
messageCounter = messageCounter + 1
|
||||
end
|
||||
end
|
||||
-- Send train wire values
|
||||
-- Output all system values
|
||||
for train in pairs(trains) do
|
||||
if train.ReadTrainWire then
|
||||
for i in pairs(train.TrainWires) do
|
||||
if not dataCache[train]["wires"] then dataCache[train]["wires"] = {} end
|
||||
if dataCache[train]["wires"][i] ~= train:ReadTrainWire(i) then
|
||||
if Turbostroi.SendMessage(train,3,"","",i,train:ReadTrainWire(i)) then
|
||||
dataCache[train]["wires"][i] = train:ReadTrainWire(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
for sys_name,system in pairs(train.Systems) do
|
||||
if system.OutputsList and system.DontAccelerateSimulation then
|
||||
for _,name in pairs(system.OutputsList) do
|
||||
local value = system[name] or 0
|
||||
if type(value) == "boolean" then
|
||||
value = value and 1 or 0
|
||||
end
|
||||
if type(value) == "number" then
|
||||
value = math.Round(value)
|
||||
if not dataCache[train][sys_name] then dataCache[train][sys_name] = {} end
|
||||
if dataCache[train][sys_name][name] ~= value then
|
||||
if Turbostroi.SendMessage(train,1,sys_name,name,0,value) then
|
||||
dataCache[train][sys_name][name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if Turbostroi then
|
||||
concommand.Add("metrostroi_turbostroi_run",function(ply,_,_,cmd)
|
||||
if not IsValid(ply) then return end
|
||||
local train = ply:GetTrain()
|
||||
if IsValid(train) then
|
||||
print(cmd:sub(1,2),cmd:sub(3,4))
|
||||
Turbostroi.SendMessage(train,6,cmd:sub(1,255),cmd:sub(256,511),ply:UserID(),0)
|
||||
end
|
||||
end)
|
||||
function Turbostroi.TriggerInput(train,system,name,value)
|
||||
local v = value or 0
|
||||
if type(value) == "boolean" then v = value and 1 or 0 end
|
||||
Turbostroi.SendMessage(train,4,system,name,0,v)
|
||||
--end
|
||||
end
|
||||
Turbostroi.SetMTAffinityMask(8) -- CPU5 CPU4 on 6 core --NEWTURBOSTROI
|
||||
Turbostroi.SetSTAffinityMask(7) -- 0 - disabled --NEWTURBOSTROI
|
||||
Turbostroi.SetSimulationFPS(FPS)
|
||||
hook.Add("Think", "Turbostroi_Think", function()
|
||||
if not Turbostroi then return end
|
||||
|
||||
-- Proceed with the think loop
|
||||
--Turbostroi.SetTargetTime(CurTime()) //depricated! now using engine
|
||||
--Turbostroi.Think() //depricated! now using engine
|
||||
|
||||
-- Update all types of trains
|
||||
--for k,v in ipairs(turbostroiTrains) do
|
||||
updateTrains(turbostroiTrains)
|
||||
--end
|
||||
-- HACK
|
||||
GLOBAL_SKIP_TRAIN_SYSTEMS = nil
|
||||
|
||||
-- Print stats
|
||||
if ((CurTime() - messageTimeout) > 1.0) then
|
||||
messageTimeout = CurTime()
|
||||
--RunConsoleCommand("say",Format("Metrostroi: %d messages per second (%d per tick)",messageCounter,messageCounter / FPS))
|
||||
messageCounter = 0
|
||||
end
|
||||
end)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Turbostroi scripts
|
||||
--------------------------------------------------------------------------------
|
||||
-- NEW API
|
||||
local ffi = require("ffi")
|
||||
local C = ffi.load("gmsv_turbostroi_win32")
|
||||
ffi.cdef[[
|
||||
bool ThreadSendMessage(void *p, int message, const char* system_name, const char* name, double index, double value);
|
||||
]]
|
||||
|
||||
Metrostroi = {}
|
||||
local dataCache = {wires = {},wiresW = {},wiresL = {}}
|
||||
Metrostroi.BaseSystems = {} -- Systems that can be loaded
|
||||
Metrostroi.Systems = {} -- Constructors for systems
|
||||
|
||||
LoadSystems = {} -- Systems that must be loaded/initialized
|
||||
GlobalTrain = {} -- Train emulator
|
||||
GlobalTrain.Systems = {} -- Train systems
|
||||
GlobalTrain.TrainWires = {}
|
||||
GlobalTrain.WriteTrainWires = {}
|
||||
|
||||
TimeMinus = 0
|
||||
_Time = 0
|
||||
function CurTime()
|
||||
--return CurrentTime-TimeMinus
|
||||
return _Time
|
||||
end
|
||||
--function CurTime() return os.clock() end
|
||||
|
||||
function Metrostroi.DefineSystem(name)
|
||||
TRAIN_SYSTEM = {}
|
||||
Metrostroi.BaseSystems[name] = TRAIN_SYSTEM
|
||||
|
||||
-- Create constructor
|
||||
Metrostroi.Systems[name] = function(train,...)
|
||||
local tbl = { _base = name }
|
||||
local TRAIN_SYSTEM = Metrostroi.BaseSystems[tbl._base]
|
||||
if not TRAIN_SYSTEM then print("No system: "..tbl._base) return end
|
||||
for k,v in pairs(TRAIN_SYSTEM) do
|
||||
if type(v) == "function" then
|
||||
tbl[k] = function(...)
|
||||
if not Metrostroi.BaseSystems[tbl._base][k] then
|
||||
print("ERROR",k,tbl._base)
|
||||
end
|
||||
return Metrostroi.BaseSystems[tbl._base][k](...)
|
||||
end
|
||||
else
|
||||
tbl[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
tbl.Initialize = tbl.Initialize or function() end
|
||||
tbl.Think = tbl.Think or function() end
|
||||
tbl.Inputs = tbl.Inputs or function() return {} end
|
||||
tbl.Outputs = tbl.Outputs or function() return {} end
|
||||
tbl.TriggerInput = tbl.TriggerInput or function() end
|
||||
tbl.TriggerOutput = tbl.TriggerOutput or function() end
|
||||
|
||||
tbl.Train = train
|
||||
tbl:Initialize(...)
|
||||
tbl.OutputsList = tbl:Outputs()
|
||||
tbl.InputsList = tbl:Inputs()
|
||||
tbl.IsInput = {}
|
||||
for k,v in pairs(tbl.InputsList) do tbl.IsInput[v] = true end
|
||||
return tbl
|
||||
end
|
||||
end
|
||||
|
||||
function GlobalTrain.LoadSystem(self,a,b,...)
|
||||
local name
|
||||
local sys_name
|
||||
if b then
|
||||
name = b
|
||||
sys_name = a
|
||||
else
|
||||
name = a
|
||||
sys_name = a
|
||||
end
|
||||
|
||||
if not Metrostroi.Systems[name] then error("No system defined: "..name) end
|
||||
if self.Systems[sys_name] then error("System already defined: "..sys_name) end
|
||||
|
||||
self[sys_name] = Metrostroi.Systems[name](self,...)
|
||||
self[sys_name].Name = sys_name
|
||||
self[sys_name].BaseName = name
|
||||
self.Systems[sys_name] = self[sys_name]
|
||||
|
||||
-- Don't simulate on here
|
||||
local no_acceleration = Metrostroi.BaseSystems[name].DontAccelerateSimulation
|
||||
if no_acceleration then
|
||||
self.Systems[sys_name].Think = function() end
|
||||
self.Systems[sys_name].TriggerInput = function(train,name,value)
|
||||
local v = value or 0
|
||||
if type(value) == "boolean" then v = value and 1 or 0 end
|
||||
C.ThreadSendMessage(_userdata, 4,sys_name,name,0,v)
|
||||
end -- replace with new api
|
||||
|
||||
--Precache values
|
||||
elseif self[sys_name].OutputsList then
|
||||
dataCache[sys_name] = {}
|
||||
for _,name in pairs(self[sys_name].OutputsList) do
|
||||
dataCache[sys_name][name] = 0--self[sys_name][name] or 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function GlobalTrain.PlayOnce(self,soundid,location,range,pitch)
|
||||
C.ThreadSendMessage(_userdata, 2,soundid or "",location or "",range or 0,pitch or 0) -- replace with new api
|
||||
end
|
||||
|
||||
function GlobalTrain.ReadTrainWire(self,n)
|
||||
return self.TrainWires[n] or 0
|
||||
end
|
||||
|
||||
function GlobalTrain.WriteTrainWire(self,n,v)
|
||||
self.WriteTrainWires[n] = v
|
||||
end
|
||||
|
||||
|
||||
GlobalTrain.DeltaTime = 0.33
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Main train code (turbostroi side)
|
||||
--------------------------------------------------------------------------------
|
||||
print("[!] Train initialized!")
|
||||
function Think(skipped)
|
||||
-- This is just blatant copy paste from init.lua of base train entity
|
||||
local self = GlobalTrain
|
||||
|
||||
--[[ if skipped then
|
||||
self.BeSkip = self.BeSkip or CurTime()
|
||||
return
|
||||
else
|
||||
self.PrevTime = self.PrevTime or CurTime()
|
||||
if self.BeSkip then
|
||||
--print(1,(CurTime()-self.BeSkip)-0.03)
|
||||
TimeMinus = TimeMinus + math.max(0,(CurTime()-self.BeSkip)-0.03)
|
||||
--print(2,TimeMinus)
|
||||
self.BeSkip = false
|
||||
end
|
||||
end--]]
|
||||
|
||||
-- Is initialized?
|
||||
if not self.Initialized then
|
||||
Initialize()
|
||||
return
|
||||
end
|
||||
|
||||
self.DeltaTime = (CurrentTime - self.PrevTime)--self.DeltaTime+math.min(0.02,((CurrentTime - self.PrevTime)-self.DeltaTime)*0.1)
|
||||
self.PrevTime = CurrentTime
|
||||
if skipped or self.DeltaTime<=0 then return end
|
||||
_Time = _Time+self.DeltaTime
|
||||
|
||||
-- Perform data exchange
|
||||
DataExchange()
|
||||
|
||||
-- Simulate according to schedule
|
||||
for i,s in ipairs(self.Schedule) do
|
||||
for k,v in ipairs(s) do
|
||||
v:Think(self.DeltaTime / (v.SubIterations or 1),i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Initialize()
|
||||
if not CurrentTime then return end
|
||||
print("[!] Loading systems")
|
||||
local time = os.clock()
|
||||
for k,v in pairs(LoadSystems) do
|
||||
GlobalTrain:LoadSystem(k,v)
|
||||
end
|
||||
print(string.format("[!] -Took %.2fs",os.clock()-time))
|
||||
GlobalTrain.PrevTime = CurrentTime
|
||||
local iterationsCount = 1
|
||||
if (not GlobalTrain.Schedule) or (iterationsCount ~= GlobalTrain.Schedule.IterationsCount) then
|
||||
GlobalTrain.Schedule = { IterationsCount = iterationsCount }
|
||||
local SystemIterations = {}
|
||||
|
||||
-- Find max number of iterations
|
||||
local maxIterations = 0
|
||||
for k,v in pairs(GlobalTrain.Systems) do
|
||||
SystemIterations[k] = (v.SubIterations or 1)
|
||||
maxIterations = math.max(maxIterations,(v.SubIterations or 1))
|
||||
end
|
||||
|
||||
-- Create a schedule of simulation
|
||||
for iteration=1,maxIterations do
|
||||
GlobalTrain.Schedule[iteration] = {}
|
||||
-- Populate schedule
|
||||
for k,v in pairs(GlobalTrain.Systems) do
|
||||
if ((iteration)%(maxIterations/(v.SubIterations or 1))) == 0 then
|
||||
table.insert(GlobalTrain.Schedule[iteration],v)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
GlobalTrain.Initialized = true
|
||||
end
|
||||
|
||||
local id,system,name,index,value
|
||||
function DataExchange()
|
||||
-- Get data packets
|
||||
for i,message in pairs(RecvMessages()) do
|
||||
id,system,name,index,value = unpack(message,0) --NEWTURBOSTROI
|
||||
--while true do
|
||||
--id,system,name,index,value = RecvMessage() --OLDTURBOSTROI
|
||||
if id == 1 then
|
||||
if GlobalTrain.Systems[system] then
|
||||
GlobalTrain.Systems[system][name] = value
|
||||
end
|
||||
end
|
||||
if id == 3 then
|
||||
dataCache["wiresW"][index] = value
|
||||
end
|
||||
if id == 4 then
|
||||
if GlobalTrain.Systems[system] then
|
||||
GlobalTrain.Systems[system]:TriggerInput(name,value)
|
||||
end
|
||||
end
|
||||
if id == 5 then
|
||||
dataCache["wiresL"] = {}
|
||||
end
|
||||
if id == 6 then
|
||||
local scr = [[
|
||||
local _retdata=""
|
||||
local print = function(...)
|
||||
for k,v in ipairs({...}) do _retdata = _retdata..tostring(v).."\t" end
|
||||
_retdata = _retdata.."\n"
|
||||
end
|
||||
]]
|
||||
scr = scr..system..name.."\n"
|
||||
scr = scr.."return _retdata"
|
||||
local data,err = loadstring(scr)
|
||||
if data then
|
||||
local ret = tostring(data()) or "N\\A"
|
||||
for i=0,math.ceil(#ret/63) do
|
||||
C.ThreadSendMessage(_userdata, 6, ret:sub(i*63,(i+1)*63-1), "",index,i)
|
||||
end
|
||||
else
|
||||
print(err)
|
||||
C.ThreadSendMessage(_userdata, 6, tostring(err), "",index,0)
|
||||
end
|
||||
--Turbostroi.SendMessage(train,6,cmd:sub(1,255),cmd:sub(256,511),ply:UserID(),0)
|
||||
end
|
||||
if not id then break end
|
||||
end
|
||||
for twid,value in pairs(dataCache["wiresW"]) do
|
||||
GlobalTrain.TrainWires[twid] = value
|
||||
end
|
||||
|
||||
-- Output all variable values
|
||||
for sys_name,system in pairs(GlobalTrain.Systems) do
|
||||
if system.OutputsList and (not system.DontAccelerateSimulation) then
|
||||
for _,name in pairs(system.OutputsList) do
|
||||
local value = (system[name] or 0)
|
||||
--if type(value) == "boolean" then value = value and 1 or 0 end
|
||||
if not dataCache[sys_name] then print(sys_name) end
|
||||
if dataCache[sys_name][name] ~= value then
|
||||
--print(sys_name,name,value)
|
||||
--if SendMessage(1,sys_name,name,0,tonumber(value) or 0) then -- OLD API
|
||||
if C.ThreadSendMessage(_userdata, 1, sys_name , name, 0, tonumber(value) or 0) then -- NEW API
|
||||
dataCache[sys_name][name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Output train wire writes
|
||||
for twID,value in pairs(GlobalTrain.WriteTrainWires) do
|
||||
--local value = tonumber(value) or 0
|
||||
if dataCache["wires"][twID] ~= value then
|
||||
dataCache["wires"][twID] = value
|
||||
dataCache["wiresL"][twID] = false
|
||||
end
|
||||
if not dataCache["wiresL"][twID] or dataCache["wiresL"][twID]~=GlobalTrain.PrevTime then
|
||||
--SendMessage(3,"","on",tonumber(twID) or 0,dataCache["wires"][twID]) -- OLD API
|
||||
C.ThreadSendMessage(_userdata, 3, "", "on", tonumber(twID) or 0, dataCache["wires"][twID]) -- NEW API
|
||||
--print("[!]Wire "..twID.." starts update! Value "..dataCache["wires"][twID])
|
||||
end
|
||||
GlobalTrain.WriteTrainWires[twID] = nil
|
||||
dataCache["wiresL"][twID] = CurTime()
|
||||
end
|
||||
for twID,time in pairs(dataCache["wiresL"]) do
|
||||
if time~=CurTime() then
|
||||
C.ThreadSendMessage(_userdata,3, "", "off", tonumber(twID) or 0, 0)
|
||||
--print("[!]Wire "..twID.." stops update!")
|
||||
dataCache["wiresL"][twID] = nil
|
||||
end
|
||||
end
|
||||
--SendMessage(5,"","",0,0) -- OLD API
|
||||
--C.ThreadSendMessage(_userdata, 5,"","",0,0) -- NEW API
|
||||
--print(string.format("%s %s",count,#msgCache))
|
||||
--count = 0
|
||||
|
||||
end
|
||||
@@ -1,125 +0,0 @@
|
||||
Metrostroi.ARMTable = {signal = {},switch = {},trigger = {}}
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString "metrostroi-arm"
|
||||
hook.Add("Think","metrostroi_arm_remove",function()
|
||||
for i,v in ipairs(Metrostroi.ARMTable) do
|
||||
if IsValid(v.Controller) and v.Controller.Station ~= i then
|
||||
v.Controller = nil
|
||||
v.net = {}
|
||||
end
|
||||
end
|
||||
end)
|
||||
net.Receive("metrostroi-arm",function(_,ply)
|
||||
local station = net.ReadUInt(16)
|
||||
--print("Player "..tostring(ply).." request full sync."..station)
|
||||
net.Start("metrostroi-arm")
|
||||
net.WriteBool(true)
|
||||
net.WriteInt(station,16)
|
||||
net.WriteTable(Metrostroi.ARMTable[station].net)
|
||||
net.Send(ply)
|
||||
end)
|
||||
function Metrostroi.ARMGet(name,typ)
|
||||
if not name or not Metrostroi.ARMTable[typ] then return end
|
||||
if typ == "signal" then
|
||||
local signal = Metrostroi.ARMTable[typ][name]
|
||||
if not IsValid(signal) then
|
||||
Metrostroi.ARMTable[typ][name] = Metrostroi.GetSignalByName(name)
|
||||
return false
|
||||
end
|
||||
return signal
|
||||
end
|
||||
if typ == "switch" then
|
||||
local switch = Metrostroi.ARMTable[typ][name]
|
||||
if not IsValid(switch) then
|
||||
Metrostroi.ARMTable[typ][name] = Metrostroi.GetSwitchByName(name)
|
||||
return false
|
||||
end
|
||||
return switch
|
||||
end
|
||||
if typ == "trigger" then
|
||||
local trigger = Metrostroi.ARMTable[typ][name]
|
||||
if not IsValid(trigger) then
|
||||
local triggers = ents.FindByName(name)
|
||||
if #triggers == 1 then
|
||||
trigger = triggers[1]
|
||||
Metrostroi.ARMTable[typ][name] = trigger
|
||||
trigger:Fire("AddOutput","OnEndTouchAll !self:ARMEndTouch::0:-1",0)
|
||||
trigger:Fire("AddOutput","OnStartTouchAll !self:ARMStartTouch::0:-1",0)
|
||||
trigger:Fire("AddOutput","OnTouching !self:ARMStartTouch::0:-1",0)
|
||||
trigger:Fire("TouchTest")
|
||||
end
|
||||
return
|
||||
else
|
||||
return trigger
|
||||
end
|
||||
end
|
||||
end
|
||||
function Metrostroi.ARMSync(station,segmid,id,val)
|
||||
local tbl = Metrostroi.ARMTable[station]and Metrostroi.ARMTable[station].net
|
||||
if not tbl then return end
|
||||
if not tbl[segmid] then tbl[segmid] = {} end
|
||||
if val == false then val = nil end
|
||||
if tbl[segmid][id] == val then return end
|
||||
print("Syncing",station,segmid,id,val)
|
||||
net.Start("metrostroi-arm")
|
||||
net.WriteBool(false)
|
||||
net.WriteUInt(station,16)
|
||||
net.WriteUInt(segmid,16)
|
||||
net.WriteString(id)
|
||||
net.WriteType(val)
|
||||
net.Broadcast()
|
||||
tbl[segmid][id] = val
|
||||
end
|
||||
else
|
||||
hook.Add("Think","arm_think",function()
|
||||
for i,station in ipairs(Metrostroi.ARMTable) do
|
||||
if (not station.LastSync or CurTime()-station.LastSync > 15) and (not Metrostroi.ARMTable.LastSyncRequest or CurTime()-Metrostroi.ARMTable.LastSyncRequest > 1) then
|
||||
print(CurTime(),UnPredictedCurTime(),RealTime(),tostring(IsFirstTimePredicted()))
|
||||
net.Start("metrostroi-arm")
|
||||
net.WriteInt(i,16)
|
||||
net.SendToServer()
|
||||
print("Requesting full sync",i)
|
||||
Metrostroi.ARMTable.LastSyncRequest = CurTime()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
net.Receive("metrostroi-arm",function(_,ply)
|
||||
if net.ReadBool() then
|
||||
local station = net.ReadUInt(16)
|
||||
print("We got sync.",station)
|
||||
Metrostroi.ARMTable[station] = net.ReadTable()
|
||||
Metrostroi.ARMTable[station].LastSync = CurTime()
|
||||
else
|
||||
local station = net.ReadUInt(16)
|
||||
local segmid = net.ReadUInt(16)
|
||||
local id = net.ReadString()
|
||||
local val = net.ReadType()
|
||||
print("Received",station,segmid,id,val)
|
||||
if not Metrostroi.ARMTable[station] then Metrostroi.ARMTable[station] = {} end
|
||||
if not Metrostroi.ARMTable[station][segmid] then Metrostroi.ARMTable[station][segmid] = {} end
|
||||
Metrostroi.ARMTable[station][segmid][id] = val
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
function Metrostroi.GetARMInfo(station,segmid,id)
|
||||
local tbl = Metrostroi.ARMTable[station]
|
||||
if not tbl then return end
|
||||
if not tbl[segmid] then return end
|
||||
return tbl[segmid][id]
|
||||
end
|
||||
end
|
||||
if Metrostroi.ARMConfigGenerated then
|
||||
for k,v in ipairs(Metrostroi.ARMConfigGenerated) do
|
||||
Metrostroi.ARMTable[k] = {
|
||||
occChecks = {},
|
||||
net = {},
|
||||
signal = {},
|
||||
switch = {},
|
||||
trigger = {},
|
||||
routes = {},
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -1,315 +0,0 @@
|
||||
|
||||
local function GetOccupation(tbl)
|
||||
if not tbl then return end
|
||||
for sID,signame in ipairs(tbl) do
|
||||
if signame[1] == "@" then
|
||||
local trigger = Metrostroi.ARMGet(signame:sub(2,-1), "trigger")
|
||||
--if not trigger then print(signame) end
|
||||
if not trigger or trigger.ARMTriggered then
|
||||
return true
|
||||
end
|
||||
elseif signame ~= "" then
|
||||
local signal = Metrostroi.ARMGet(signame, "signal")
|
||||
if not signal or signal.OccupiedBy and signal.OccupiedBy ~= signal then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Metrostroi.CentralisationPrepareRoute(station,route)
|
||||
if not Metrostroi.ARMTable[station].routes then Metrostroi.ARMTable[station].routes = {} end
|
||||
local Routes = Metrostroi.ARMTable[station].routes
|
||||
local stationT = Metrostroi.ARMConfigGenerated[station]
|
||||
if not Routes[route] then
|
||||
local segments = route.route
|
||||
for i,segm in pairs(segments) do
|
||||
if segm.inroute then
|
||||
RunConsoleCommand("say",Format("Station %d. Error building route %s, because there is already another route",station,route))
|
||||
return false
|
||||
end
|
||||
if route.ignores and (not route.ignores or not route.ignores[i]) and segm.occupied then
|
||||
RunConsoleCommand("say",Format("Station %d. Error building route %s. Route occupied!",station,route))
|
||||
return false
|
||||
end
|
||||
end
|
||||
if route.checks then
|
||||
for i,segm in pairs(route.checks) do
|
||||
if segm.inroute then
|
||||
RunConsoleCommand("say",Format("Station %d. Error building route %s, because there is already another route on protective segments",station,route))
|
||||
return false
|
||||
end
|
||||
if route.ignores and (not route.ignores or not route.ignores[i]) and segm.occupied then
|
||||
RunConsoleCommand("say",Format("Station %d. Error building route %s. Protective segments occupied!",station,route))
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _,segm in pairs(segments) do
|
||||
segm.inroute = true
|
||||
end
|
||||
Routes[route] = table.insert(Routes,route)
|
||||
RunConsoleCommand("say",Format("Station %d. Added route %s with ID:%d",station,route,Routes[route]))
|
||||
return true
|
||||
end
|
||||
end
|
||||
local function CentralistationCalculateFreeBS(segm,dir,sigconf,pSeg,rccount)
|
||||
if pSeg then
|
||||
local signal = dir and segm.signal2 or not dir and segm.signal1
|
||||
if signal then
|
||||
local ent = signal.ent
|
||||
if not ent then return 1 end
|
||||
local conf = sigconf[ent.Name]
|
||||
--return (ent.FreeBSARM or ent.FreeBS or 0)+(conf and conf.bs or 1),ent
|
||||
return (ent.FreeBSARM or ent.FreeBS or 0)+rccount,ent
|
||||
end
|
||||
end
|
||||
rccount = (rccount or 0) + 1
|
||||
if not segm or segm.occupied then
|
||||
return rccount
|
||||
end
|
||||
local alt,main = false,true
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
if not alt and not main then return 0 end
|
||||
end
|
||||
|
||||
if pSeg and segm.next_a and (segm.next_a == pSeg and not alt or segm.next_m == pSeg and not main) then return 0 end
|
||||
local segmM,segmA = segm.next_m,segm.next_a
|
||||
local segmP = segm.prev
|
||||
|
||||
|
||||
local mainM = segmM and (dir and segmM.x > segm.x or not dir and segmM.x < segm.x)
|
||||
local mainP = segmP and (dir and segmP.x > segm.x or not dir and segmP.x < segm.x)
|
||||
if mainM then
|
||||
local next
|
||||
if alt and segmA then next = segmA end
|
||||
if main and segmM then next = segmM end
|
||||
return CentralistationCalculateFreeBS(next,dir,sigconf,segm,rccount)
|
||||
end
|
||||
if segmP and mainP then
|
||||
return CentralistationCalculateFreeBS(segmP,dir,sigconf,segm,rccount)
|
||||
end
|
||||
end
|
||||
local function CentralisationSolveSignalLogic(signal,signalE,signalDir,station,segm)
|
||||
if not signalE then return end
|
||||
if station.signals and station.signals[signal] then
|
||||
local sigconf = station.signals[signal]
|
||||
signalE.ControllerLogic = station
|
||||
local target,codes = "",""
|
||||
local alt = false
|
||||
local occupied = segm.occupied
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
if not alt and not main then occupied = true end
|
||||
end
|
||||
if alt then
|
||||
--occupied = occupied or segm.next_a and GetOccupation(segm.next_a)
|
||||
else
|
||||
--occupied = occupied or segm.next_m and GetOccupation(segm.next_m)
|
||||
end
|
||||
|
||||
local route = sigconf.route
|
||||
local free,nextSignal = CentralistationCalculateFreeBS(segm,signalDir,station.signals)
|
||||
--print(free,signalE,signalE.Name)
|
||||
local dir = route and route.dir
|
||||
if route and dir ~= signalDir then
|
||||
print(signalE.Name,dir ,signalDir)
|
||||
route = nil
|
||||
occupied = true
|
||||
end
|
||||
if sigconf.Mode == 1 then
|
||||
if occupied then
|
||||
target = sigconf.R
|
||||
codes = "2"
|
||||
elseif route then
|
||||
if nextSignal then
|
||||
local colors = nextSignal.Colors or ""
|
||||
local segments = route[2]
|
||||
--print(route)
|
||||
local start = false
|
||||
local specialS = sigconf.routes and sigconf.routes[route[1].name]
|
||||
if free < (sigconf.bs or 1) then
|
||||
target = sigconf.RY or sigconf.R
|
||||
elseif route.mode == 3 then
|
||||
target = sigconf.W
|
||||
elseif colors:find("[rR]+") and colors:find("[yY]+") then
|
||||
target = sigconf.Y or sigconf.YG or sigconf.RY or sigconf.R
|
||||
elseif colors:find("[rR]+") then
|
||||
target = sigconf.Y or sigconf.RY or sigconf.R
|
||||
elseif colors:find("[ygYG]+[ygYG]+") or colors:find("[gwGW]+") then
|
||||
target = sigconf.G or sigconf.YG or sigconf.Y or sigconf.RY or sigconf.R
|
||||
elseif colors:find("[yY]+") then
|
||||
target = sigconf.YG or sigconf.G or sigconf.Y or sigconf.RY or sigconf.R
|
||||
else
|
||||
target = sigconf.R
|
||||
end
|
||||
elseif route.mode == 3 then
|
||||
target = sigconf.W
|
||||
else
|
||||
target = sigconf.R
|
||||
end
|
||||
else
|
||||
if free and free < 1 then
|
||||
target = sigconf.R or sigconf.RY or ""
|
||||
else
|
||||
target = sigconf.RY or sigconf.R
|
||||
end
|
||||
codes = "0"
|
||||
end
|
||||
signalE.Red = target==sigconf.R or target==sigconf.RY
|
||||
signalE.AutoEnabled = signalE.AutoEnabled
|
||||
else
|
||||
|
||||
end
|
||||
local sig = ""
|
||||
for i=1,#target do
|
||||
local id = tonumber(target[i])
|
||||
if not id then continue end
|
||||
if #sig < id then sig = sig..string.rep("0",id-#sig) end
|
||||
sig = string.SetChar(sig,tonumber(target[i]),target[i+1]=="b" and "2" or "1")
|
||||
end
|
||||
signalE.Sig = sig
|
||||
signalE.FreeBSARM = occupied and 0 or free
|
||||
signalE.FreeBS = math.ceil(signalE.FreeBSARM or 0)
|
||||
--print(occupied,free,signalE.FreeBS)
|
||||
--print(signalE.Colors,target,signalE.Sig)
|
||||
end
|
||||
end
|
||||
local function CentralisationSolveRoutesLogic(stationID,station)
|
||||
local Routes = Metrostroi.ARMTable[stationID].routes
|
||||
local HasPrepared = true
|
||||
for k,route in ipairs(Routes) do
|
||||
local segments = route.route
|
||||
local directions = route.directions
|
||||
if route.prepared then
|
||||
--HasPrepared = true
|
||||
local done,occupiedN,halfroute = true--,100
|
||||
for segmID,segm in ipairs(segments) do
|
||||
if segm.occupied then
|
||||
if not occupiedN or occupiedN < segmID then occupiedN = segmID end
|
||||
end
|
||||
if segm.route then done = false end
|
||||
if not segm.route then halfroute = true end
|
||||
end
|
||||
if occupiedN then
|
||||
for segmID,segm in ipairs(segments) do
|
||||
if segmID > occupiedN then break end
|
||||
if segm.route == route then
|
||||
segm.route = false
|
||||
segm.inroute = false
|
||||
local signal = route[3] and segm.signal2 or not route[3] and segm.signal1
|
||||
local sig = Metrostroi.ARMGet(signal and signal.name, "signal")
|
||||
end
|
||||
end
|
||||
end
|
||||
if done or halfroute and not occupiedN then
|
||||
for _,segm in ipairs(segments) do
|
||||
segm.inroute = false
|
||||
segm.route = false
|
||||
end
|
||||
for i,signame in pairs(route.signals) do
|
||||
if not station.signals[signame] then continue end
|
||||
station.signals[signame].route = nil
|
||||
end
|
||||
RunConsoleCommand("say",Format("Station %d. Route %s(%d) has destroyed",stationID,route,Routes[route]))
|
||||
table.remove(Routes,Routes[route])
|
||||
Routes[route] = nil
|
||||
for i,v in pairs(Routes) do Routes[v] = i end
|
||||
route.prepared = false
|
||||
end
|
||||
else
|
||||
local Prepared = true
|
||||
--Check for occupation
|
||||
for i,segm in ipairs(segments) do
|
||||
if route.ignores and not route.ignores[i] and segm.occupied then Prepared = false break end
|
||||
if segm.route then Prepared = false break end
|
||||
end
|
||||
--If there is no occupation - check and prepare switches
|
||||
if Prepared then
|
||||
for segmID,segm in ipairs(segments) do
|
||||
if not segm.switch then continue end
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
if not switch then continue end
|
||||
local dir = directions[segmID]
|
||||
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
local alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
--print(route[3],switch,dir)
|
||||
if dir and main or not dir and alt or (not main and not alt) then
|
||||
switch:SwitchTo(dir and "alt" or "main")
|
||||
Prepared = false
|
||||
print("Move",segmID,segm.switch,switch,dir and "alt" or "main")
|
||||
end
|
||||
if not main and not alt then Prepared = false end
|
||||
end
|
||||
end
|
||||
if Prepared then
|
||||
for k,segm in ipairs(segments) do
|
||||
segm.route = route
|
||||
local signal = route[3] and segm.signal2 or not route[3] and segm.signal1
|
||||
local sig = Metrostroi.ARMGet(signal and signal.name, "signal")
|
||||
end
|
||||
for i,signame in pairs(route.signals) do
|
||||
if not station.signals[signame] then continue end
|
||||
station.signals[signame].route = route
|
||||
end
|
||||
route.prepared = true
|
||||
RunConsoleCommand("say",Format("Station %d. Route %s(%d) has assembled",stationID,route,Routes[route]))
|
||||
end
|
||||
end
|
||||
end
|
||||
return HasPrepared
|
||||
end
|
||||
|
||||
function Metrostroi.Centralisation()
|
||||
if not Metrostroi.ARMConfigGenerated then return end
|
||||
for stationID,station in pairs(Metrostroi.ARMConfigGenerated) do
|
||||
--Route logic
|
||||
local HasPrepared = CentralisationSolveRoutesLogic(stationID,station)
|
||||
|
||||
for name, signal in pairs(station.signals) do
|
||||
if signal.sig then
|
||||
local ent = Metrostroi.ARMGet(name, "signal")
|
||||
signal.sig.ent = ent
|
||||
CentralisationSolveSignalLogic(name,ent,signal.sig.dir,station,signal.segm)
|
||||
end
|
||||
end
|
||||
for segmID, segm in ipairs(station) do
|
||||
segm.occupied = segm._occup or GetOccupation(segm.occup) or GetOccupation(segm.occupAlt)
|
||||
if true then
|
||||
if segm.switch then
|
||||
local switch = Metrostroi.ARMGet(segm.switch, "switch")
|
||||
local main = switch and switch.MainTrack and not switch.AlternateTrack
|
||||
local alt = switch and not switch.MainTrack and switch.AlternateTrack
|
||||
if switch and not segm.route and not segm.inroute and not segm.occupied and (alt or not main and not alt) then
|
||||
switch:SwitchTo("main")
|
||||
print("Reset",segm.switch,switch,segmID,segm.route)
|
||||
end
|
||||
end
|
||||
--[[ if segm.signal1 then
|
||||
local ent = Metrostroi.ARMGet(segm.signal1.name, "signal")
|
||||
segm.signal1.ent = ent
|
||||
CentralisationSolveSignalLogic(segm.signal1.name,ent,false,station,segm)
|
||||
end
|
||||
if segm.signal2 then
|
||||
local ent = Metrostroi.ARMGet(segm.signal2.name, "signal")
|
||||
segm.signal2.ent = ent
|
||||
CentralisationSolveSignalLogic(segm.signal2.name,ent,true,station,segm)
|
||||
end--]]
|
||||
--[[ if segm.route and not HasPrepared then
|
||||
segm.route = false
|
||||
segm.inroute = false
|
||||
end--]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
timer.Create("metrostroi_centralisation",0.1,0,Metrostroi.Centralisation)
|
||||
@@ -1,77 +0,0 @@
|
||||
require("bromsock")
|
||||
|
||||
if server then server:Close() end
|
||||
server = BromSock()
|
||||
server:SetOption(0xFFFF, 0x0008, 1)
|
||||
server:SetOption(0x6, 0x0001 , 1)
|
||||
|
||||
if (not server:Listen(1337)) then
|
||||
print("[BS:S] Failed to listen!")
|
||||
else
|
||||
print("[BS:S] Server listening...")
|
||||
end
|
||||
server:SetCallbackConnect(function(sockObj, succ, ip, port )
|
||||
print(sockObj, succ, ip, port )
|
||||
end)
|
||||
local opened = {}
|
||||
concommand.Add("test_command_send",function(_,_,args)
|
||||
local sock = opened[tonumber(args[1])]
|
||||
if not sock then return end
|
||||
local packet = BromPacket()
|
||||
packet:WriteStringRaw(args[2])
|
||||
sock:Send(packet,true)
|
||||
end)
|
||||
concommand.Add("test_command_sendtest",function(_,_,args)
|
||||
local sock = opened[tonumber(args[1])]
|
||||
if not sock then return end
|
||||
local packet = BromPacket()
|
||||
packet:WriteByte(0x00)
|
||||
packet:WriteUInt(1234)
|
||||
packet:WriteStringNT("test")
|
||||
sock:Send(packet,true)
|
||||
end)
|
||||
server:SetCallbackAccept(function(serversock, clientsock)
|
||||
print("[BS:S] Accepted:", serversock, clientsock,clientsock:GetPort())
|
||||
opened[clientsock:GetPort()] = clientsock
|
||||
clientsock:SetCallbackReceive(function(sock, packet)
|
||||
print("[BS:S] Received:", sock, packet)
|
||||
|
||||
local typ = packet:ReadByte()
|
||||
print("[BS:S] Type:", typ)
|
||||
if typ == 0x01 then
|
||||
local trains = {}
|
||||
for k,ent in pairs(ents.GetAll()) do
|
||||
if ent.Base == "gmod_subway_base" and not ent.NoTrain then
|
||||
table.insert(trains,ent)
|
||||
end
|
||||
end
|
||||
|
||||
local packet = BromPacket()
|
||||
packet:WriteByte(0x00)
|
||||
packet:WriteUInt(#trains)
|
||||
sock:Send(packet,true)
|
||||
for k,v in ipairs(trains) do
|
||||
print("Send train",v:GetClass())
|
||||
local packet = BromPacket()
|
||||
packet:WriteByte(0x01)
|
||||
packet:WriteUInt(#trains)
|
||||
packet:WriteUInt(v:EntIndex())
|
||||
packet:WriteStringNT(v:GetClass())
|
||||
sock:Send(packet,true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
clientsock:SetCallbackDisconnect(function(sock)
|
||||
print("[BS:S] Disconnected:", sock)
|
||||
opened[clientsock:GetPort()] = nil
|
||||
end)
|
||||
|
||||
clientsock:SetTimeout(1000)
|
||||
|
||||
clientsock:Receive()
|
||||
|
||||
-- Who's next in line?
|
||||
serversock:Accept()
|
||||
end)
|
||||
server:Accept()
|
||||
Reference in New Issue
Block a user