mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
348 lines
14 KiB
Lua
348 lines
14 KiB
Lua
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
|