1
0
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:
glebqip
2021-01-09 01:42:48 +03:00
committed by GitHub
52 changed files with 0 additions and 23900 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -1,6 +0,0 @@
ENT.Type = "anim"
ENT.Category = "Metrostroi (utility)"
ENT.Spawnable = false
ENT.AdminSpawnable = false

View File

@@ -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)

View File

@@ -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

View File

@@ -1,7 +0,0 @@
ENT.Type = "anim"
ENT.PrintName = "Train door"
ENT.Category = "Metrostroi (utility)"
ENT.Spawnable = false
ENT.AdminSpawnable = false

View File

@@ -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)

View File

@@ -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

View File

@@ -1,7 +0,0 @@
ENT.Type = "anim"
ENT.PrintName = "Train sound provider"
ENT.Category = "Metrostroi (utility)"
ENT.Spawnable = false
ENT.AdminSpawnable = false

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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()