1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-04 00:52:33 +00:00

release branch init

This commit is contained in:
g_brzhezinskiy
2021-01-02 15:32:05 +03:00
parent 1d05caf866
commit 09566ce158
398 changed files with 8389 additions and 77275 deletions

View File

@@ -1,103 +1,64 @@
include("shared.lua")
-- Bogey-related sounds
ENT.SoundNames = {}
ENT.SoundNames["ted1_703"] = "subway_trains/bogey/engines/703/speed_8.wav"
ENT.SoundNames["ted2_703"] = "subway_trains/bogey/engines/703/speed_16.wav"
ENT.SoundNames["ted3_703"] = "subway_trains/bogey/engines/703/speed_24.wav"
ENT.SoundNames["ted4_703"] = "subway_trains/bogey/engines/703/speed_32.wav"
ENT.SoundNames["ted5_703"] = "subway_trains/bogey/engines/703/speed_40.wav"
ENT.SoundNames["ted6_703"] = "subway_trains/bogey/engines/703/speed_48.wav"
ENT.SoundNames["ted7_703"] = "subway_trains/bogey/engines/703/speed_56.wav"
ENT.SoundNames["ted8_703"] = "subway_trains/bogey/engines/703/speed_64.wav"
ENT.SoundNames["ted9_703"] = "subway_trains/bogey/engines/703/speed_72.wav"
ENT.SoundNames["ted10_703"] = "subway_trains/bogey/engines/703/speed_80.wav"
ENT.SoundNames["ted11_703"] = "subway_trains/bogey/engines/703/speed_88.wav"
--ENT.SoundNames["tedm_703"] = "subway_trains/bogey/engines/703/engines_medium.wav"
ENT.SoundNames["ted1_717"] = "subway_trains/bogey/engines/717/engines_8.wav"
ENT.SoundNames["ted2_717"] = "subway_trains/bogey/engines/717/engines_16.wav"
ENT.SoundNames["ted3_717"] = "subway_trains/bogey/engines/717/engines_24.wav"
ENT.SoundNames["ted4_717"] = "subway_trains/bogey/engines/717/engines_32.wav"
ENT.SoundNames["ted5_717"] = "subway_trains/bogey/engines/717/engines_40.wav"
ENT.SoundNames["ted6_717"] = "subway_trains/bogey/engines/717/engines_48.wav"
ENT.SoundNames["ted7_717"] = "subway_trains/bogey/engines/717/engines_56.wav"
ENT.SoundNames["ted8_717"] = "subway_trains/bogey/engines/717/engines_64.wav"
ENT.SoundNames["ted9_717"] = "subway_trains/bogey/engines/717/engines_72.wav"
ENT.SoundNames["ted10_717"] = "subway_trains/bogey/engines/717/engines_80.wav"
ENT.SoundNames["ted11_720"] = "subway_trains/bogey/engines/720/speed_88.wav"
ENT.SoundNames["ted1_720"] = "subway_trains/bogey/engines/720/speed_8.wav"
ENT.SoundNames["ted2_720"] = "subway_trains/bogey/engines/720/speed_16.wav"
ENT.SoundNames["ted3_720"] = "subway_trains/bogey/engines/720/speed_24.wav"
ENT.SoundNames["ted4_720"] = "subway_trains/bogey/engines/720/speed_32.wav"
ENT.SoundNames["ted5_720"] = "subway_trains/bogey/engines/720/speed_40.wav"
ENT.SoundNames["ted6_720"] = "subway_trains/bogey/engines/720/speed_48.wav"
ENT.SoundNames["ted7_720"] = "subway_trains/bogey/engines/720/speed_56.wav"
ENT.SoundNames["ted8_720"] = "subway_trains/bogey/engines/720/speed_64.wav"
ENT.SoundNames["ted9_720"] = "subway_trains/bogey/engines/720/speed_72.wav"
ENT.SoundNames["ted10_720"] = "subway_trains/bogey/engines/720/speed_80.wav"
--*0.975
--*1.025
ENT.SoundNames["flangea"] = "subway_trains/bogey/skrip1.wav"
ENT.SoundNames["flangeb"] = "subway_trains/bogey/skrip2.wav"
ENT.SoundNames["flange1"] = "subway_trains/bogey/flange_9.wav"
ENT.SoundNames["flange2"] = "subway_trains/bogey/flange_10.wav"
ENT.SoundNames["brakea_loop1"] = "subway_trains/bogey/braking_async1.wav"
ENT.SoundNames["brakea_loop2"] = "subway_trains/bogey/braking_async2.wav"
ENT.SoundNames["brake_loop1"] = "subway_trains/bogey/brake_rattle3.wav"
ENT.SoundNames["brake_loop2"] = "subway_trains/bogey/brake_rattle4.wav"
ENT.SoundNames["brake_loop3"] = "subway_trains/bogey/brake_rattle5.wav"
ENT.SoundNames["brake_loop4"] = "subway_trains/bogey/brake_rattle6.wav"
ENT.SoundNames["brake_loopb"] = "subway_trains/common/junk/junk_background_braking1.wav"
ENT.SoundNames["brake2_loop1"] = "subway_trains/bogey/brake_rattle2.wav"
ENT.SoundNames["brake2_loop2"] = "subway_trains/bogey/brake_rattle_h.wav"
ENT.SoundNames["brake_squeal1"] = "subway_trains/bogey/brake_squeal1.wav"
ENT.SoundNames["brake_squeal2"] = "subway_trains/bogey/brake_squeal2.wav"
ENT.EngineSNDConfig = {
{
{"ted1_703" ,08,00,16,1},
{"ted2_703" ,16,08-4,24,1},
{"ted3_703" ,24,16-4,32,1},
{"ted4_703" ,32,24-4,40,1},
{"ted5_703" ,40,32-4,48,1},
{"ted6_703" ,48,40-4,56,1},
{"ted7_703" ,56,48-4,64,1},
{"ted8_703" ,64,56-4,72,1},
{"ted9_703" ,72,64-4,80,1},
{"ted10_703",80,72-4,88,1},
{"ted11_703",88,80-4 ,1},
},
{
{"ted1_717" ,08,00,16,1},
{"ted2_717" ,16,08-4,24,1},
{"ted3_717" ,24,16-4,32,1},
{"ted4_717" ,32,24-4,40,1},
{"ted5_717" ,40,32-4,48,1},
{"ted6_717" ,48,40-4,56,1},
{"ted7_717" ,56,48-4,64,1},
{"ted8_717" ,64,56-4,72,1},
{"ted9_717" ,72,64-4,80,1},
{"ted10_717",80,72-4 ,1},
},
{
{"ted1_720" ,08,00,16,1*0.4},
{"ted2_720" ,16,08-4,24,1*0.43},
{"ted3_720" ,24,16-4,32,1*0.46},
{"ted4_720" ,32,24-4,40,1*0.49},
{"ted5_720" ,40,32-4,48,1*0.52},
{"ted6_720" ,48,40-4,56,1*0.55},
{"ted7_720" ,56,48-4,64,1*0.58},
{"ted8_720" ,64,56-4,72,1*0.61},
{"ted9_720" ,72,64-4,80,1*0.64},
{"ted10_720",80,72-4,88,1*0.67},
{"ted11_720",88,80-4 ,1*0.7},
},
}
--------------------------------------------------------------------------------
function ENT:ReinitializeSounds()
-- Bogey-related sounds
self.SoundNames = {}
self.EngineSNDConfig = {}
self.SoundNames["ted1_703"] = "subway_trains/bogey/engines/703/speed_8.wav"
self.SoundNames["ted2_703"] = "subway_trains/bogey/engines/703/speed_16.wav"
self.SoundNames["ted3_703"] = "subway_trains/bogey/engines/703/speed_24.wav"
self.SoundNames["ted4_703"] = "subway_trains/bogey/engines/703/speed_32.wav"
self.SoundNames["ted5_703"] = "subway_trains/bogey/engines/703/speed_40.wav"
self.SoundNames["ted6_703"] = "subway_trains/bogey/engines/703/speed_48.wav"
self.SoundNames["ted7_703"] = "subway_trains/bogey/engines/703/speed_56.wav"
self.SoundNames["ted8_703"] = "subway_trains/bogey/engines/703/speed_64.wav"
self.SoundNames["ted9_703"] = "subway_trains/bogey/engines/703/speed_72.wav"
self.SoundNames["ted10_703"] = "subway_trains/bogey/engines/703/speed_80.wav"
self.SoundNames["ted11_703"] = "subway_trains/bogey/engines/703/speed_88.wav"
--self.SoundNames["tedm_703"] = "subway_trains/bogey/engines/703/engines_medium.wav"
self.SoundNames["ted1_717"] = "subway_trains/bogey/engines/717/engines_8.wav"
self.SoundNames["ted2_717"] = "subway_trains/bogey/engines/717/engines_16.wav"
self.SoundNames["ted3_717"] = "subway_trains/bogey/engines/717/engines_24.wav"
self.SoundNames["ted4_717"] = "subway_trains/bogey/engines/717/engines_32.wav"
self.SoundNames["ted5_717"] = "subway_trains/bogey/engines/717/engines_40.wav"
self.SoundNames["ted6_717"] = "subway_trains/bogey/engines/717/engines_48.wav"
self.SoundNames["ted7_717"] = "subway_trains/bogey/engines/717/engines_56.wav"
self.SoundNames["ted8_717"] = "subway_trains/bogey/engines/717/engines_64.wav"
self.SoundNames["ted9_717"] = "subway_trains/bogey/engines/717/engines_72.wav"
self.SoundNames["ted10_717"] = "subway_trains/bogey/engines/717/engines_80.wav"
self.SoundNames["ted11_720"] = "subway_trains/bogey/engines/720/speed_88.wav"
self.SoundNames["ted1_720"] = "subway_trains/bogey/engines/720/speed_8.wav"
self.SoundNames["ted2_720"] = "subway_trains/bogey/engines/720/speed_16.wav"
self.SoundNames["ted3_720"] = "subway_trains/bogey/engines/720/speed_24.wav"
self.SoundNames["ted4_720"] = "subway_trains/bogey/engines/720/speed_32.wav"
self.SoundNames["ted5_720"] = "subway_trains/bogey/engines/720/speed_40.wav"
self.SoundNames["ted6_720"] = "subway_trains/bogey/engines/720/speed_48.wav"
self.SoundNames["ted7_720"] = "subway_trains/bogey/engines/720/speed_56.wav"
self.SoundNames["ted8_720"] = "subway_trains/bogey/engines/720/speed_64.wav"
self.SoundNames["ted9_720"] = "subway_trains/bogey/engines/720/speed_72.wav"
self.SoundNames["ted10_720"] = "subway_trains/bogey/engines/720/speed_80.wav"
--*0.975
--*1.025
self.SoundNames["flangea"] = "subway_trains/bogey/skrip1.wav"
self.SoundNames["flangeb"] = "subway_trains/bogey/skrip2.wav"
self.SoundNames["flange1"] = "subway_trains/bogey/flange_9.wav"
self.SoundNames["flange2"] = "subway_trains/bogey/flange_10.wav"
self.SoundNames["brakea_loop1"] = "subway_trains/bogey/braking_async1.wav"
self.SoundNames["brakea_loop2"] = "subway_trains/bogey/braking_async2.wav"
self.SoundNames["brake_loop1"] = "subway_trains/bogey/brake_rattle3.wav"
self.SoundNames["brake_loop2"] = "subway_trains/bogey/brake_rattle4.wav"
self.SoundNames["brake_loop3"] = "subway_trains/bogey/brake_rattle5.wav"
self.SoundNames["brake_loop4"] = "subway_trains/bogey/brake_rattle6.wav"
self.SoundNames["brake_loopb"] = "subway_trains/common/junk/junk_background_braking1.wav"
self.SoundNames["brake2_loop1"] = "subway_trains/bogey/brake_rattle2.wav"
self.SoundNames["brake2_loop2"] = "subway_trains/bogey/brake_rattle_h.wav"
self.SoundNames["brake_squeal1"] = "subway_trains/bogey/brake_squeal1.wav"
self.SoundNames["brake_squeal2"] = "subway_trains/bogey/brake_squeal2.wav"
-- Remove old sounds
if self.Sounds then
for k,v in pairs(self.Sounds) do
@@ -107,14 +68,20 @@ function ENT:ReinitializeSounds()
-- Create sounds
self.Sounds = {}
self.Playing = {}
for k,v in pairs(self.SoundNames) do
--[[local e = self
--if not file.Exists(v, "MOD") then
-- self.SoundNames[k] = nil
--end
util.PrecacheSound(v)
local e = self
if (k == "brake3a") and IsValid(self:GetNW2Entity("TrainWheels")) then
e = self:GetNW2Entity("TrainWheels")
end]]
self.Sounds[k] = CreateSound(self, Sound(v))
end
self.Sounds[k] = CreateSound(e, Sound(v))
end
self.Async = nil
self.MotorSoundType = nil
end
function ENT:SetSoundState(sound,volume,pitch,name,level )
@@ -151,9 +118,7 @@ end
function ENT:Initialize()
self.MotorPowerSound = 0
self.SmoothAngleDelta = 0
self.CurrentBrakeSqueal = 0
self:ReinitializeSounds()
-- self:ReinitializeSounds()
end
function ENT:OnRemove()
@@ -161,45 +126,79 @@ function ENT:OnRemove()
for k,v in pairs(self.Sounds) do
v:Stop()
end
self.Sounds = {}
self.Sounds = nil
end
end
--------------------------------------------------------------------------------
function ENT:Think()
if not self.Sounds then
self:ReinitializeSounds()
end
self.PrevTime = self.PrevTime or RealTime()-0.33
self.DeltaTime = (RealTime() - self.PrevTime)
self.PrevTime = RealTime()
-- Get interesting parameters
local train = self:GetNW2Entity("TrainEntity")
--local rollingi = math.min(1,train.TunnelCoeff+math.Clamp((train.StreetCoeff-0.6)/0.3,0,1)*0.8)
--print(self:GetPos())
--local rollings = train.StreetCoeff
local soundsmul = 1
local streetC,tunnelC = 0,1
if IsValid(train) then
streetC,tunnelC = train.StreetCoeff or 0,train.TunnelCoeff or 1
soundsmul = math.Clamp(tunnelC^1.5+(streetC^0.5)*0.2,0,1)
end
local motorPower = self:GetMotorPower()
local speed = self:GetSpeed()
-- Engine sound
local motorPower = self:GetMotorPower()*(1+math.max(0,(speed-55)/35)*0.4)
if self.MotorSoundType ~= self:GetNWInt("MotorSoundType",1) or self.DisableEngines ~= self:GetNWBool("DisableEngines") then
if self.MotorSoundType then
for _,snd in ipairs(self.EngineSNDConfig[self.MotorSoundType+1]) do
self:SetSoundState(snd[1],0,0)
end
end
if self.MotorSoundType ~= self:GetNWInt("MotorSoundType",1)then
self.MotorSoundType = self:GetNWInt("MotorSoundType",1)
self.DisableEngines = self:GetNWBool("DisableEngines")
self.MotorSoundArr = self.EngineSNDConfig [self.MotorSoundType+1]
for k,v in pairs(self.EngineSNDConfig) do self:SetSoundState(v[1],0,0) end
self.EngineSNDConfig = {}
if self.MotorSoundType==2 then
table.insert(self.EngineSNDConfig,{"ted1_720" ,08,00,16,1*0.4})
table.insert(self.EngineSNDConfig,{"ted2_720" ,16,08-4,24,1*0.43})
table.insert(self.EngineSNDConfig,{"ted3_720" ,24,16-4,32,1*0.46})
table.insert(self.EngineSNDConfig,{"ted4_720" ,32,24-4,40,1*0.49})
table.insert(self.EngineSNDConfig,{"ted5_720" ,40,32-4,48,1*0.52})
table.insert(self.EngineSNDConfig,{"ted6_720" ,48,40-4,56,1*0.55})
table.insert(self.EngineSNDConfig,{"ted7_720" ,56,48-4,64,1*0.58})
table.insert(self.EngineSNDConfig,{"ted8_720" ,64,56-4,72,1*0.61})
table.insert(self.EngineSNDConfig,{"ted9_720" ,72,64-4,80,1*0.64})
table.insert(self.EngineSNDConfig,{"ted10_720",80,72-4,88,1*0.67})
table.insert(self.EngineSNDConfig,{"ted11_720",88,80-4 ,1*0.7})
elseif self.MotorSoundType==0 then
table.insert(self.EngineSNDConfig,{"ted1_703" ,08,00,16,1})
table.insert(self.EngineSNDConfig,{"ted2_703" ,16,08-4,24,1})
table.insert(self.EngineSNDConfig,{"ted3_703" ,24,16-4,32,1})
table.insert(self.EngineSNDConfig,{"ted4_703" ,32,24-4,40,1})
table.insert(self.EngineSNDConfig,{"ted5_703" ,40,32-4,48,1})
table.insert(self.EngineSNDConfig,{"ted6_703" ,48,40-4,56,1})
table.insert(self.EngineSNDConfig,{"ted7_703" ,56,48-4,64,1})
table.insert(self.EngineSNDConfig,{"ted8_703" ,64,56-4,72,1})
table.insert(self.EngineSNDConfig,{"ted9_703" ,72,64-4,80,1})
table.insert(self.EngineSNDConfig,{"ted10_703",80,72-4,88,1})
table.insert(self.EngineSNDConfig,{"ted11_703",88,80-4 ,1})
else
table.insert(self.EngineSNDConfig,{"ted1_717" ,08,00,16,1})
table.insert(self.EngineSNDConfig,{"ted2_717" ,16,08-4,24,1})
table.insert(self.EngineSNDConfig,{"ted3_717" ,24,16-4,32,1})
table.insert(self.EngineSNDConfig,{"ted4_717" ,32,24-4,40,1})
table.insert(self.EngineSNDConfig,{"ted5_717" ,40,32-4,48,1})
table.insert(self.EngineSNDConfig,{"ted6_717" ,48,40-4,56,1})
table.insert(self.EngineSNDConfig,{"ted7_717" ,56,48-4,64,1})
table.insert(self.EngineSNDConfig,{"ted8_717" ,64,56-4,72,1})
table.insert(self.EngineSNDConfig,{"ted9_717" ,72,64-4,80,1})
table.insert(self.EngineSNDConfig,{"ted10_717",80,72-4 ,1})
end
end
if not self.DisableEngines and self.MotorSoundArr then
self.MotorPowerSound = math.Clamp(self.MotorPowerSound + (motorPower - self.MotorPowerSound)*self.DeltaTime*3,-1.5,1.5)
self.Async = self:GetNWBool("Async")
-- Engine sound
if not self:GetNWBool("DisableEngines") then
self.MotorPowerSound = math.Clamp(self.MotorPowerSound + (motorPower - self.MotorPowerSound)*self.DeltaTime*3,-1,1)
local t = RealTime()*2.5
local modulation = math.max(0,(speed-60)/30)*0.7+(0.2 + 1.0*math.max(0,0.2+math.sin(t)*math.sin(t*3.12)*math.sin(t*0.24)*math.sin(t*4.0)))*math.Clamp((speed-15)/60,0,1)
local modulation = (0.2 + 1.0*math.max(0,0.2+math.sin(t)*math.sin(t*3.12)*math.sin(t*0.24)*math.sin(t*4.0)))*math.Clamp(speed/4,0,1)
local mod2 = 1.0-math.min(1.0,(math.abs(self.MotorPowerSound)/0.1))
if (speed > -1.0) and (math.abs(self.MotorPowerSound)+modulation) >= 0.0 then
--local startVolRamp = 0.2 + 0.8*math.max(0.0,math.min(1.0,(speed - 1.0)*0.5))
@@ -209,6 +208,7 @@ function ENT:Think()
else
powerVolRamp = 0.3*modulation*mod2 + 2*math.abs(self.MotorPowerSound)--2.0*(math.abs(motorPower)^2)
end
--math.max(0.3,math.min(1.0,math.abs(motorPower)))
--local k,x = 1.0,math.max(0,math.min(1.1,(speed-1.0)/80))
--local motorPchRamp = (k*x^3 - k*x^2 + x)
@@ -216,10 +216,11 @@ function ENT:Think()
local volumemul = math.min(1,(speed/4)^3)
local motorsnd = math.min(1.0,math.max(0.0,1.25*(math.abs(self.MotorPowerSound))))
local motorvol = (soundsmul^0.3)*math.Clamp(motorsnd + powerVolRamp,0,1)*volumemul
--local motorsnd = math.min(1.0,math.max(0.0,1.25*(math.abs(self.MotorPowerSound)-0.15) ))
for i,snd in ipairs(self.MotorSoundArr) do
local prev = self.MotorSoundArr[i-1]
local next = self.MotorSoundArr[i+1]
for i,snd in ipairs(self.EngineSNDConfig or {}) do
local prev = self.EngineSNDConfig[i-1]
local next = self.EngineSNDConfig[i+1]
local volume = 1
if prev and speed <= prev[4] then
volume = math.max(0,1-(prev[4]-speed)/(prev[4]-snd[3]))
@@ -227,26 +228,34 @@ function ENT:Think()
volume = math.max(0,(snd[4]-speed)/(snd[4]-next[3]))
end
local pitch = math.max(0,speed/snd[2])+0.06*streetC
self:SetSoundState(snd[1],motorvol*volume*(snd[5] or 1),math.Clamp(pitch,0,2))
if self.Async then
self:SetSoundState(snd[1].."1",motorvol*volume*(snd[5] or 1),math.Clamp(pitch,0,2),snd[1],false)
--self:SetSoundState(snd[1].."2",0,0,true)
else
self:SetSoundState(snd[1].."1",motorvol*volume*(snd[5] or 1),math.Clamp(pitch,0,2),snd[1],false)
--self:SetSoundState(snd[1].."2",0,0,true)
--self:SetSoundState(snd[1].."1",((motorsnd + powerVolRamp)*volume)*(snd.vol or 1)*volumemul,pitch*0.975,snd[1],false)
--self:SetSoundState(snd[1].."2",((motorsnd + powerVolRamp)*volume)*(snd.vol or 1)*volumemul,pitch*1.025,snd[1],true)
end
end
--[[ if self.MotorSoundType==0 then
self:SetSoundState("tedm_703",math.min(1,(soundsmul^0.3)*motorsnd*2)*math.Clamp((speed-20)/10,0,1)*(1-math.Clamp((speed-38)/20,0,1))*0.18,math.max(0,speed/35.4)+0.06*streetC)
else
self:SetSoundState("tedm_703",0,0)
end--]]
else
for k,v in pairs(self.EngineSNDConfig) do
self:SetSoundState(v[1].."1",0,0,v[1],false)
end
self:SetSoundState(v[1].."2",0,0,v[1],true)
end
end
--Stop old sounds when we changind brake squeal type
if self.Async ~= self:GetNWBool("Async") then
self:SetSoundState("brake_loop1",0,0)
self:SetSoundState("brake_loop2",0,0)
self:SetSoundState("brake_loop3",0,0)
self:SetSoundState("brake_loop4",0,0)
self:SetSoundState("brake_loopb",0,0)
self:SetSoundState("brake2_loop1",0,0)
self:SetSoundState("brake2_loop2",0,0)
self:SetSoundState("brakea_loop1",0,0)
self:SetSoundState("brakea_loop2",0,0)
self.Async = self:GetNWBool("Async")
end
-- Brake squeal sound
--if speed > 2 then
--brakeRamp = 1 - math.min(1.0,math.max(0.0,(speed-3)/10.0))
--end
if squealSound == 0 then squealSound = 1 end
if squealSound == 3 then squealSound = 2 end
if self.Async then
local brakeSqueal = self:GetNW2Float("BrakeSqueal",0)
if (brakeSqueal) > 0.0 then
@@ -255,21 +264,52 @@ function ENT:Think()
local squealPitch = nominalSqueal+secondSqueal*0.05
local squealVolume = math.Clamp(speed/2,0,1)
local volume = brakeSqueal*squealVolume* math.Clamp(1-(speed-2)/3,0,1)
local volume = brakeSqueal*squealVolume
self:SetSoundState("brakea_loop1",volume*(1-secondSqueal*0.5)*0.4,squealPitch,false,75)
self:SetSoundState("brakea_loop2",volume*secondSqueal*0.4,squealPitch,false,75)
elseif self.CurrentBrakeSqueal > 0 then
else
self:SetSoundState("brakea_loop1",0,0)
self:SetSoundState("brakea_loop2",0,0)
end
self.CurrentBrakeSqueal = brakeSqueal
self:SetSoundState("brake_loop1",0,0)
self:SetSoundState("brake_loop2",0,0)
self:SetSoundState("brake_loop3",0,0)
self:SetSoundState("brake_loop4",0,0)
self:SetSoundState("brake_loopb",0,0)
self:SetSoundState("brake2_loop1",0,0)
self:SetSoundState("brake2_loop2",0,0)
else
local brakeSqueal1 = math.max(0.0,math.min(2,self:GetNW2Float("BrakeSqueal1")))
if not self.SquealVolume or brakeSqueal1 <= 0 and self.CurrentBrakeSqueal > 0 or self.SquealType ~= self:GetNW2Int("SquealType",1) then
self.SquealType = self:GetNW2Int("SquealType",1)
self.SquealSound1 = "brake_loop"..self.SquealType
self.SquealVolume = self.SquealType == 1 and 0.2 or 1
local squealSound = self:GetNW2Int("SquealSound",0)
local brakeSqueal1 = math.max(0.0,math.min(2,self:GetNW2Float("BrakeSqueal1")))--FIXME math.max(0.0,math.min(1,self:GetNW2Float("BrakeSqueal1")))
--local brakeSqueal2 = 0--FIXME local brakeSqueal2 = math.max(0.0,math.min(1,self:GetNW2Float("BrakeSqueal2")))
--local brakeSqueal2 = math.max(0.0,math.min(1,self:GetNW2Float("BrakeSqueal2")))
--local brakeRamp = math.min(1.0,math.max(0.0,speed/2.0))
local brakeRamp1 = math.min(1.0,math.max(0.0,(speed-10)/50.0))^1.5
local brakeRamp2 = math.min(1.0,math.max(0.0,speed/3.0))
if true or (brakeSqueal1) > 0.0 then
local ramp = 0.3+math.Clamp((40-speed)/40,0,1)*0.7
local typ = self:GetNW2Int("SquealType",1)
self:SetSoundState("brake_loop1",typ==1 and soundsmul*brakeSqueal1*ramp*0.2 or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop2",typ==2 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop3",typ==3 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop4",typ==4 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loopb",typ<=4 and 0*soundsmul*brakeSqueal1*ramp*0.4 or 0,1+0.05*(1.0-brakeRamp2))
--spb only
local loop_h = soundsmul*brakeSqueal1*ramp*0.5
if typ>=5 and loop_h > 0.1 and speed > 1.5 then
if not self.HighLoop then
self.HighLoop = math.random()>0.5 and "brake_squeal2" or "brake_squeal1"
end
self:SetSoundState(self.HighLoop,loop_h*1.5,1)
elseif loop_h<0.02 and self.HighLoop then
self:SetSoundState(self.HighLoop,0,0)
self.HighLoop = false
end
self.StartLoopStrength = loop_h
self:SetSoundState("brake2_loop1",(typ==5 or typ==6) and math.Clamp(loop_h*0.5,0,0.5) or 0,1+0.06*(1.0-brakeRamp2))
self:SetSoundState("brake2_loop2",typ>=6 and loop_h*0.3 or 0,1+0.06*(1.0-brakeRamp2))
--self:SetSoundState("brake_loop2",brakeSqueal*brakeRamp2*0.2,1+0.06*(1.0-brakeRamp2))
else
self:SetSoundState("brake_loop1",0,0)
self:SetSoundState("brake_loop2",0,0)
self:SetSoundState("brake_loop3",0,0)
@@ -277,46 +317,16 @@ function ENT:Think()
self:SetSoundState("brake_loopb",0,0)
self:SetSoundState("brake2_loop1",0,0)
self:SetSoundState("brake2_loop2",0,0)
elseif brakeSqueal1 > 0 then
--local brakeRamp1 = math.min(1.0,math.max(0.0,(speed-10)/50.0))^1.5
local brakeRamp2 = math.min(1.0,math.max(0.0,speed/3.0))
local ramp = 0.3+math.Clamp((40-speed)/40,0,1)*0.7
if self.SquealType <= 4 then
self:SetSoundState(self.SquealSound1,soundsmul*brakeSqueal1*ramp*self.SquealVolume,1+0.05*(1.0-brakeRamp2))
--[[self:SetSoundState("brake_loop1",typ==1 and soundsmul*brakeSqueal1*ramp*0.2 or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop2",typ==2 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop3",typ==3 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loop4",typ==4 and soundsmul*brakeSqueal1*ramp or 0,1+0.05*(1.0-brakeRamp2))
self:SetSoundState("brake_loopb",typ<=4 and 0*soundsmul*brakeSqueal1*ramp*0.4 or 0,1+0.05*(1.0-brakeRamp2))]]
elseif self.SquealType <= 7 then
local loop_h = soundsmul*brakeSqueal1*ramp*0.5
if loop_h > 0.1 and speed > 1.5 then
if not self.HighLoop then
self.HighLoop = math.random()>0.5 and "brake_squeal2" or "brake_squeal1"
end
self:SetSoundState(self.HighLoop,loop_h*1.5,1)
elseif loop_h<0.02 and self.HighLoop then
self:SetSoundState(self.HighLoop,0,0)
self.HighLoop = false
end
self.StartLoopStrength = loop_h
if self.SquealType <= 6 then
self:SetSoundState("brake2_loop1",math.Clamp(loop_h*0.5,0,0.5),1+0.06*(1.0-brakeRamp2))
end
if self.SquealType >= 6 then
self:SetSoundState("brake2_loop2",loop_h*0.3,1+0.06*(1.0-brakeRamp2))
end
end
end
self.CurrentBrakeSqueal = brakeSqueal1
self:SetSoundState("brakea_loop1",0,0)
self:SetSoundState("brakea_loop2",0,0)
end
-- Generate procedural landscape thingy
local a = self:GetPos().x
local b = self:GetPos().y
local c = self:GetPos().z
local f = math.sin(c/200 + a*c/3e7 + b*c/3e7) --math.sin(a/3000)*math.sin(b/3000)
local f = 1--math.sin(c/200 + a*c/3e7 + b*c/3e7) --math.sin(a/3000)*math.sin(b/3000)
-- Calculate flange squeal
self.PreviousAngles = self.PreviousAngles or self:GetAngles()
local deltaAngleYaw = math.abs(self:GetAngles().yaw - self.PreviousAngles.yaw)
@@ -324,14 +334,20 @@ function ENT:Think()
if deltaAngleYaw >= 180 then
deltaAngleYaw = deltaAngleYaw - 360
end
--speed = 80
local speedAdd = math.max(1,math.min(2,1-(speed-60)/40))
local deltaAngle = deltaAngleYaw/math.max(0.1,self.DeltaTime)*speedAdd
deltaAngle = math.max(math.min(1.0,f*10)*math.abs(deltaAngle),0)
self.PreviousAngles = self:GetAngles()
-- Smooth it out
self.SmoothAngleDelta = self.SmoothAngleDelta or 0
local speedSmooth = 4--20-math.Clamp((speed-10)/40,0,1)*16
self.SmoothAngleDelta = math.min(7,self.SmoothAngleDelta + (deltaAngle - self.SmoothAngleDelta)*2*self.DeltaTime)
--[[ if (not (self.SmoothAngleDelta <= 0)) and (not (self.SmoothAngleDelta >= 0)) then
print(self.SmoothAngleDelta)
self.SmoothAngleDelta = 0
end--]]
-- Create sound
local speed_mod = math.min(1.0,math.max(0.0,speed/5))
local flangea = math.Clamp((speed-18)/25,0,1)
@@ -342,7 +358,7 @@ function ENT:Think()
local t = RealTime()
local modulation = 1.5*math.max(0,0.2+math.sin(t)*math.sin(t*3.12)*math.sin(t*0.24)*math.sin(t*4.0))
local pitch40 = math.max(0.9,1.0+(speed-40.0)/160.0)
--local pitch60 = math.max(0.9,1.0+(speed-60.0)/160.0)
local pitch60 = math.max(0.9,1.0+(speed-60.0)/160.0)
-- Play it
self:SetSoundState("flangea",(0.3+soundsmul*0.7)*(speed_mod)*math.Clamp(f2,0,1),pitch40)
self:SetSoundState("flangeb",(0.3+soundsmul*0.7)*(speed_mod)*math.Clamp(f3*modulation,0,1),pitch40)
@@ -353,6 +369,7 @@ end
function ENT:Draw()
self:DrawModel()
--render.DrawLine(self:GetPos(),self:LocalToWorld(Vector(100,0,0)), Color(255,0,0), false)
end
@@ -387,7 +404,7 @@ end
function ENT:DrawGUI(tbl)
if IsValid(c_gui) then c_gui:Close() end
c_gui = vgui.Create("DFrame")
local c_gui = vgui.Create("DFrame")
c_gui:SetDeleteOnClose(true)
c_gui:SetTitle(Metrostroi.GetPhrase("Common.Bogey.Title"))
c_gui:SetSize(0, 0)
@@ -395,7 +412,7 @@ function ENT:DrawGUI(tbl)
c_gui:SetSizable(false)
c_gui:MakePopup()
local scrollPanel = vgui.Create( "DScrollPanel", c_gui )
addButton(scrollPanel,"Common.Bogey.ContactState",tbl.relcontact and "Common.Bogey.CReleased" or "Common.Bogey.CPressed",tbl.relcontact and Color(150,50,0) or Color(0,150,0),tbl.relcontact and "Common.Bogey.CPress" or "Common.Bogey.CRelease",tbl.access,function()
addButton(scrollPanel,"Common.Bogey.ContactState",tbl.relcontact and "Common.Bogey.CReleased" or "Common.Bogey.CPressed",tbl.relcontact and Color(150,50,0) or Color(0,150,0),tbl.relcontact and "Common.Bogey.CPress" or "Common.Bogey.CRelease",tbl.access,function(button)
net.Start("metrostroi-bogey-menu")
net.WriteEntity(self)
net.WriteUInt(0,8)
@@ -403,7 +420,7 @@ function ENT:DrawGUI(tbl)
c_gui:Close()
end)
if tbl.havepb then
addButton(scrollPanel,"Common.Bogey.ParkingBrakeState",tbl.pbdisabled and "Common.Bogey.PBDisabled" or "Common.Bogey.PBEnabled", Color(0,150,0),tbl.pbdisabled and "Common.Bogey.PBEnable" or "Common.Bogey.PBDisable",tbl.access,function()
addButton(scrollPanel,"Common.Bogey.ParkingBrakeState",tbl.pbdisabled and "Common.Bogey.PBDisabled" or "Common.Bogey.PBEnabled", Color(0,150,0),tbl.pbdisabled and "Common.Bogey.PBEnable" or "Common.Bogey.PBDisable",tbl.access,function(button)
net.Start("metrostroi-bogey-menu")
net.WriteEntity(self)
net.WriteUInt(1,8)
@@ -419,7 +436,7 @@ function ENT:DrawGUI(tbl)
function scrollPanel:PerformLayout()
spPefromLayout(self)
if not self.First then self.First = true return end
local _,y = scrollPanel:ChildrenSize()
local x,y = scrollPanel:ChildrenSize()
if self.Centered then return end
self.Centered = true
c_gui:SetSize(512,math.min(350,y)+35)

View File

@@ -14,6 +14,22 @@ COUPLE_MAX_DISTANCE = COUPLE_MAX_DISTANCE ^ 2
COUPLE_MAX_ANGLE = math.cos(math.rad(COUPLE_MAX_ANGLE))
--------------------------------------------------------------------------------
--[[ function ENT:PreEntityCopy()
local BogeyDupe = {}
if IsValid(self.Wheels) then
BogeyDupe.Wheels = self.Wheels:EntIndex()
end
BogeyDupe.BogeyType = self.BogeyType
if WireAddon then
BogeyDupe.WireData = WireLib.BuildDupeInfo( self.Entity )
end
BogeyDupe.NoPhysics = self.NoPhysics
duplicator.StoreEntityModifier(self, "BogeyDupe", BogeyDupe)
end
duplicator.RegisterEntityModifier( "BogeyDupe" , function() end)
--Model,WheelPos,WheelAng,WheelModel,PantLPos,PantRPos,BogeyOffset,{ConnectorPositions}--]]
ENT.Types = {
["702"] = {
"models/metrostroi_train/bogey/metro_bogey_702.mdl",
@@ -59,6 +75,39 @@ ENT.Types = {
Vector(4.3,-63,-3.3),Vector(4.3,63,-3.3),
},
}
--[[ function ENT:PostEntityPaste(ply,ent,createdEntities)
local BogeyDupe = ent.EntityMods.BogeyDupe
if IsValid(self.Wheels) then
self.Wheels:SetParent()
self.Wheels:Remove()
end
self.Wheels = createdEntities[BogeyDupe.Wheels]
self.BogeyType = BogeyDupe.BogeyType
local typ = self.Types[self.BogeyType or "717"]
self:SetModel(typ and typ[1] or "models/metrostroi/metro/metro_bogey.mdl")
if IsValid(self.Wheels) then
if self.BogeyType == "tatra" then
self.Wheels:SetPos(self:LocalToWorld(Vector(0,0.0,-3)))
self.Wheels:SetAngles(self:GetAngles() + Angle(0,0,0))
else
self.Wheels:SetPos(self:LocalToWorld(Vector(0,0.0,-10)))
self.Wheels:SetAngles(self:GetAngles() + Angle(0,90,0))
end
self.Wheels.WheelType = self.BogeyType
self.Wheels.NoPhysics = BogeyDupe.NoPhysics
if self.NoPhysics then
self.Wheels:SetParent(self)
else
self.Wheels:PhysicsInit(SOLID_VPHYSICS)
self.Wheels:SetMoveType(MOVETYPE_VPHYSICS)
self.Wheels:SetSolid(SOLID_VPHYSICS)
constraint.Weld(self,self.Wheels,0,0,0,1,0)
end
if CPPI then self.Wheels:CPPISetOwner(self:CPPIGetOwner()) end
self.Wheels:SetNW2Entity("TrainBogey",self)
end
end--]]
ENT.SnakePos = Vector(-168.25,0,6.5)
ENT.SnakeAng = Angle(0,90,0)
@@ -109,6 +158,8 @@ function ENT:Initialize()
self.PneumaticBrakeForce = 100000.0
self.DisableSound = 0
self.Angle = 0
self.Variables = {}
-- Pressure in brake cylinder
@@ -119,6 +170,7 @@ function ENT:Initialize()
self.DropByPeople = 0
self.PlayTime = { 0, 0 }
self.ContactStates = { false, false }
self.ContactDisables = {false,false}
self.DisableContacts = false
self.DisableContactsManual = false
self.DisableParking = false
@@ -133,25 +185,30 @@ end
function ENT:InitializeWheels()
-- Create missing wheels
if IsValid(self.Wheels) then SafeRemoveEntity(self.Wheels) end
local wheels = ents.Create("gmod_train_wheels")
local typ = self.Types[self.BogeyType or "717"]
wheels.Model = typ[4]
if typ and typ[3] then wheels:SetAngles(self:LocalToWorldAngles(typ[3])) end
if typ and typ[2] then wheels:SetPos(self:LocalToWorld(typ[2])) end
if not IsValid(self.Wheels) then
--print(1)
local wheels = ents.Create("gmod_train_wheels")
local typ = self.Types[self.BogeyType or "717"]
wheels.Model = typ[4]
if typ and typ[3] then wheels:SetAngles(self:LocalToWorldAngles(typ[3])) end
if typ and typ[2] then wheels:SetPos(self:LocalToWorld(typ[2])) end
wheels.WheelType = self.BogeyType
wheels.NoPhysics = self.NoPhysics
wheels:Spawn()
--wheels = ents.Create("gmod_subway_wheels")
--wheels:SetPos(self:LocalToWorld(Vector(0,0.0,-10)))
--wheels:SetAngles(self:GetAngles() + Angle(0,90,0))
wheels.WheelType = self.BogeyType
wheels.NoPhysics = self.NoPhysics
wheels:Spawn()
if self.NoPhysics then
wheels:SetParent(self)
else
constraint.Weld(self,wheels,0,0,0,1,0)
if self.NoPhysics then
wheels:SetParent(self)
else
constraint.Weld(self,wheels,0,0,0,1,0)
end
if CPPI then wheels:CPPISetOwner(self:CPPIGetOwner() or self:GetNW2Entity("TrainEntity"):GetOwner()) end
wheels:SetNW2Entity("TrainBogey",self)
self.Wheels = wheels
end
if CPPI then wheels:CPPISetOwner(self:CPPIGetOwner() or self:GetNW2Entity("TrainEntity"):GetOwner()) end
wheels:SetNW2Entity("TrainBogey",self)
self.Wheels = wheels
end
function ENT:OnRemove()
@@ -179,7 +236,7 @@ function ENT:TriggerInput(iname, value)
end
end
--[[ Checks if there's an advballsocket between two entities
-- Checks if there's an advballsocket between two entities
local function AreCoupled(ent1,ent2)
if ent1.CoupledBogey or ent2.CoupledBogey then return false end
local constrainttable = constraint.FindConstraints(ent1,"AdvBallsocket")
@@ -193,7 +250,7 @@ local function AreCoupled(ent1,ent2)
end
return coupled
end]]
end
-- Adv ballsockets ents by their CouplingPointOffset
function ENT:Couple(ent)
@@ -225,10 +282,11 @@ function ENT:Couple(ent)
end
end
local function AreInCoupleDistance(ent1,ent2)
return ent2:LocalToWorld(ent2.CouplingPointOffset):DistToSqr(ent1:LocalToWorld(ent1.CouplingPointOffset)) < COUPLE_MAX_DISTANCE
local function AreInCoupleDistance(ent,self)
return self:LocalToWorld(self.CouplingPointOffset):DistToSqr(ent:LocalToWorld(ent.CouplingPointOffset)) < COUPLE_MAX_DISTANCE
end
local function AreFacingEachother(ent1,ent2)
return ent1:GetForward():Dot(ent2:GetForward()) < -COUPLE_MAX_ANGLE
end
@@ -248,8 +306,8 @@ end
local function CanCoupleTogether(ent1,ent2)
if ent1.DontHaveCoupler or ent2.DontHaveCoupler then return false end
if ent2:GetClass() ~= ent1:GetClass() then return false end
--if not (ent1.CanCouple and ent1:CanCouple()) then return false end
--if not (ent2.CanCouple and ent2:CanCouple()) then return false end
if not (ent1.CanCouple and ent1:CanCouple()) then return false end
if not (ent2.CanCouple and ent2:CanCouple()) then return false end
if not AreInCoupleDistance(ent1,ent2) then return false end
if not AreFacingEachother(ent1,ent2) then return false end
return true
@@ -381,9 +439,8 @@ function ENT:CheckContact(pos,dir,id,cpos)
if not result.Hit then return end
if result.HitWorld then return true end
local traceEnt = result.Entity
if not self.Connectors[id] and traceEnt:GetClass() == "gmod_track_udochka" then
if result.Entity:GetClass() == "gmod_track_udochka" then
if not traceEnt.Timer and traceEnt.CoupledWith ~= self then
--local vec = Vector(pos.y < 0 and 1 or 1.1,pos.y < 0 and -1 or 1.05, 1)
traceEnt:SetPos(self:LocalToWorld(cpos))
@@ -394,110 +451,105 @@ function ENT:CheckContact(pos,dir,id,cpos)
traceEnt.Coupled = self
sound.Play("udochka_connect.wav",traceEnt:GetPos())
self.Connectors[id] = traceEnt
DropEntityIfHeld(traceEnt)
--[[timer.Simple(0,function()
if not IsValid(traceEnt) or not traceEnt:IsPlayerHolding() then return end
traceEnt:ForcePlayerDrop()
if traceEnt.LastPickup and traceEnt.LastPickup:IsPlayer() then
traceEnt.LastPickup:DropObject()
timer.Simple(0,function()
if IsValid(traceEnt) and traceEnt:IsPlayerHolding() then
traceEnt:ForcePlayerDrop()
if traceEnt.LastPickup and traceEnt.LastPickup:IsPlayer() then
traceEnt.LastPickup:DropObject()
end
end
end)]]
end)
end
end
return false
elseif traceEnt:GetClass() == "player" and self.Voltage > 40 then
local pPos = traceEnt:GetPos()
elseif traceEnt:GetClass() == "player" then
--self.T:WorldToLocal(Entity(3208):GetPos())
if self.Voltage < 40 then return end
local pos = traceEnt:GetPos()
self.VoltageDropByTouch = (self.VoltageDropByTouch or 0) + 1
util.BlastDamage(traceEnt,traceEnt,pPos,64,3.0*self.Voltage)
util.BlastDamage(traceEnt,traceEnt,pos,64,3.0*self.Voltage)
local effectdata = EffectData()
effectdata:SetOrigin(pPos + Vector(0,0,-16+math.random()*(40+0)))
effectdata:SetOrigin(pos + Vector(0,0,-16+math.random()*(40+0)))
util.Effect("cball_explode",effectdata,true,true)
sound.Play("ambient/energy/zap"..math.random(1,3)..".wav",pPos,75,math.random(100,150),1.0)
sound.Play("ambient/energy/zap"..math.random(1,3)..".wav",pos,75,math.random(100,150),1.0)
return
end
return result.Hit
end
local C_Reqiure3rdRail = GetConVar("metrostroi_train_requirethirdrail")
function ENT:CheckVoltage(dT)
-- Check contact states
if (CurTime() - self.CheckTimeout) <= 0.25 then return end
self.CheckTimeout = CurTime()
local supported = C_Reqiure3rdRail:GetInt() > 0 and Metrostroi.MapHasFullSupport()
local feeder = self.Feeder and Metrostroi.Voltages[self.Feeder]
local volt = feeder or Metrostroi.Voltage or 750
if (CurTime() - self.CheckTimeout) > 0.25 then
self.CheckTimeout = CurTime()
self.VoltageDropByTouch = 0
self.NextStates[1] = not self.DisableContacts and not self.DisableContactsManual and not self.ContactDisables[1] and self:CheckContact(self.PantLPos,Vector(0,-1,0),1,self.PantLCPos)
self.NextStates[2] = not self.DisableContacts and not self.DisableContactsManual and not self.ContactDisables[2] and self:CheckContact(self.PantRPos,Vector(0, 1,0),2,self.PantRCPos)
-- Detect changes in contact states
for i=1,2 do
local state = self.NextStates[i]
if state ~= self.ContactStates[i] then
self.ContactStates[i] = state
-- Non-metrostroi maps
if not supported then
self.Voltage = volt
self.NextStates[1] = true
self.NextStates[2] = true
return
end
if state then
self.VoltageDrop = -40*(0.5 + 0.5*math.random())
self.VoltageDropByTouch = 0
self.NextStates[1] = not self.DisableContacts and not self.DisableContactsManual
and self:CheckContact(self.PantLPos,Vector(0,-1,0),1,self.PantLCPos)
self.NextStates[2] = not self.DisableContacts and not self.DisableContactsManual
and self:CheckContact(self.PantRPos,Vector(0, 1,0),2,self.PantRCPos)
local dt = CurTime() - self.PlayTime[i]
self.PlayTime[i] = CurTime()
-- Detect changes in contact states
for i=1,2 do
local state = self.NextStates[i]
if state ~= self.ContactStates[i] then
self.ContactStates[i] = state
if not state then continue end
local volume = 0.53
if dt < 1.0 then volume = 0.43 end
if i == 1 then sound.Play("subway_trains/bogey/tr_"..math.random(1,5)..".wav",self:LocalToWorld(self.PantLPos),65,math.random(90,120),volume) end
if i == 2 then sound.Play("subway_trains/bogey/tr_"..math.random(1,5)..".wav",self:LocalToWorld(self.PantRPos),65,math.random(90,120),volume) end
self.VoltageDrop = -40*(0.5 + 0.5*math.random())
-- Sparking probability
local probability = math.Clamp(1-(self.MotorPower/2),0,1)
if state and (math.random() > probability) then
local effectdata = EffectData()
if i == 1 then effectdata:SetOrigin(self:LocalToWorld(self.PantLPos)) end
if i == 2 then effectdata:SetOrigin(self:LocalToWorld(self.PantRPos)) end
effectdata:SetNormal(Vector(0,0,-1))
util.Effect("stunstickimpact", effectdata, true, true)
local dt = CurTime() - self.PlayTime[i]
self.PlayTime[i] = CurTime()
local volume = 0.53
if dt < 1.0 then volume = 0.43 end
if i == 1 then sound.Play("subway_trains/bogey/tr_"..math.random(1,5)..".wav",self:LocalToWorld(self.PantLPos),65,math.random(90,120),volume) end
if i == 2 then sound.Play("subway_trains/bogey/tr_"..math.random(1,5)..".wav",self:LocalToWorld(self.PantRPos),65,math.random(90,120),volume) end
-- Sparking probability
local probability = math.Clamp(1-(self.MotorPower/2),0,1)
if math.random() > probability then
local effectdata = EffectData()
if i == 1 then effectdata:SetOrigin(self:LocalToWorld(self.PantLPos)) end
if i == 2 then effectdata:SetOrigin(self:LocalToWorld(self.PantRPos)) end
effectdata:SetNormal(Vector(0,0,-1))
util.Effect("stunstickimpact", effectdata, true, true)
local light = ents.Create("light_dynamic")
light:SetPos(effectdata:GetOrigin())
light:SetKeyValue("_light","100 220 255")
light:SetKeyValue("style", 0)
light:SetKeyValue("distance", 256)
light:SetKeyValue("brightness", 5)
light:Spawn()
light:Fire("TurnOn","","0")
light.Time = CurTime()
timer.Simple(0.1,function()
SafeRemoveEntity(light)
end)
sound.Play("subway_trains/bogey/spark.mp3",effectdata:GetOrigin(),75,math.random(100,150),volume)
--self.Train:PlayOnce("zap",sound_source,0.7*volume,50+math.random(90,120))
local light = ents.Create("light_dynamic")
light:SetPos(effectdata:GetOrigin())
light:SetKeyValue("_light","100 220 255")
light:SetKeyValue("style", 0)
light:SetKeyValue("distance", 256)
light:SetKeyValue("brightness", 5)
light:Spawn()
light:Fire("TurnOn","","0")
light.Time = CurTime()
hook.Add("Think",light,function(self)
if CurTime()-self.Time > 0.1 then self:Remove() end
end)
sound.Play("subway_trains/bogey/spark.mp3",effectdata:GetOrigin(),75,math.random(100,150),volume)
--self.Train:PlayOnce("zap",sound_source,0.7*volume,50+math.random(90,120))
end
end
end
end
end
-- Voltage spikes
self.VoltageDrop = math.max(-30,math.min(30,self.VoltageDrop + (0 - self.VoltageDrop)*10*dT))
local feeder = self.Feeder and Metrostroi.Voltages[self.Feeder]
local volt = feeder or Metrostroi.Voltage or 750
-- Non-metrostroi maps
if ((GetConVarNumber("metrostroi_train_requirethirdrail") <= 0)) then-- or
--(not Metrostroi.MapHasFullSupport()) then
self.Voltage = volt + self.VoltageDrop
return
end
-- Detect voltage
self.Voltage = 0
self.DropByPeople = 0
for i=1,2 do
if self.ContactStates[i] then
self.Voltage = volt + self.VoltageDrop
elseif IsValid(self.Connectors[i]) and self.Connectors[i].Coupled == self then
if self.ContactStates[i] then self.Voltage = volt + self.VoltageDrop
elseif IsValid(self.Connectors[i]) and self.Connectors[i].Coupled == (i > 2 and self.Train.RearBogey or self) then
self.Voltage = self.Connectors[i].Power and Metrostroi.Voltage or 0
end
else self.Connectors[i] = nil end
end
if self.VoltageDropByTouch > 0 then
local Rperson = 0.613
@@ -508,12 +560,14 @@ end
function ENT:Think()
-- Re-initialize wheels
if not IsValid(self.Wheels) or self.Wheels:GetNW2Entity("TrainBogey") ~= self then
if (not self.Wheels) or
(not self.Wheels:IsValid()) or
(self.Wheels:GetNW2Entity("TrainBogey") ~= self) then
self:InitializeWheels()
constraint.NoCollide(self.Wheels,self,0,0)
if IsValid(self:GetNW2Entity("TrainEntity")) then
constraint.NoCollide(self.Wheels,self:GetNW2Entity("TrainEntity"),0,0)
constraint.NoCollide(self.Wheels,self,0,0)
end
end
@@ -521,12 +575,13 @@ function ENT:Think()
self.PrevTime = self.PrevTime or CurTime()
self.DeltaTime = (CurTime() - self.PrevTime)
self.PrevTime = CurTime()
self.Angle = self.Wheels.Angle
self:SetNW2Entity("TrainWheels",self.Wheels)
self:CheckVoltage(self.DeltaTime)
-- Skip physics related stuff
if self.NoPhysics or not self.Wheels:GetPhysicsObject():IsValid() then
if not IsValid(self.Wheels) or not self.Wheels:GetPhysicsObject():IsValid() or self.NoPhysics then
self:SetMotorPower(self.MotorPower or 0)
self:SetSpeed(self.Speed or 0)
self:NextThink(CurTime())
@@ -554,19 +609,24 @@ function ENT:Think()
-- Calculate motor power
local motorPower = 0.0
if self.MotorPower > 0.0 then
motorPower = math.Clamp(self.MotorPower, -1, 1)
motorPower = self.MotorPower
else
motorPower = math.Clamp(self.MotorPower*sign, -1, 1)
motorPower = self.MotorPower*sign
end
motorPower = math.max(-1.0,motorPower)
motorPower = math.min(1.0,motorPower)
-- Increace forces on slopes
local slopemul = 1
local slopemul = 1--+math.Clamp(Train:GetAngles():Forward(),0,1)*0.2
local slopemulb = 1
local pitch = self:GetAngles().pitch*sign
if motorPower < 0 and pitch > 3 then
slopemul = slopemul + math.Clamp((math.abs(pitch)-3)/3,0,1)
slopemul = slopemul + math.Clamp((math.abs(pitch)-3)/3,0,1)--[[ *(math.Clamp((self.Speed-55)/5,0,1))--]] *1.5
else
slopemul = slopemul + math.Clamp((pitch-3)/3,0,1)*1.5
end
if -3 > pitch or pitch > 3 then
slopemulb = slopemulb + math.Clamp((math.abs(pitch)-3)/3,0,1)*0.7
end
-- Final brake cylinder pressure
local pneumaticPow = self.PneumaticPow or 1
local pB = not self.DisableParking and self.ParkingBrakePressure or 0
@@ -579,14 +639,10 @@ function ENT:Think()
-- Calculate forces
local motorForce = self.MotorForce*motorPower*slopemul
local pneumaticFactor = math.Clamp(0.5*self.Speed,0,1)*(1+math.Clamp((2-self.Speed)/2,0,1)*0.5)
local pneumaticFactor = math.max(0,math.min(1,0.5*self.Speed))*(1+(math.max(0,math.min(1,(2-self.Speed)/2)))*0.5)
local pneumaticForce = 0
if BrakeCP >= 0.05 then
local slopemulBr = 1
if -3 > pitch or pitch > 3 then
slopemulBr = 1 + math.Clamp((math.abs(pitch)-3)/3,0,1)*0.7
end
pneumaticForce = -sign*pneumaticFactor*self.PneumaticBrakeForce*BrakeCP*slopemulBr
pneumaticForce = -sign*pneumaticFactor*self.PneumaticBrakeForce*BrakeCP*slopemulb
end
-- Compensate forward friction
@@ -618,12 +674,13 @@ function ENT:Think()
-- Calculate brake squeal
self.SquealSensitivity = 1
local k = ((self.SquealSensitivity or 0.5) - 0.5)*2
local BCPress = math.abs(self.BrakeCylinderPressure)
self.RattleRandom = self.RattleRandom or 0.5+math.random()*0.2
local PnF1 = math.Clamp((BCPress-0.6)/0.6,0,2)
local PnF2 = math.Clamp((BCPress-self.RattleRandom)/0.6,0,2)
--local PnF3 = math.Clamp((BCPress-self.RattleRandom+0.15)/0.6,0,1)
local brakeSqueal1 = (PnF1*PnF2)*pneumaticFactor
--local brakeSqueal2 = (PnF1*PnF3)*pneumaticFactor
-- Send parameters to client
if self.DisableSound < 1 then
@@ -631,11 +688,20 @@ function ENT:Think()
end
if self.DisableSound < 2 then
local brakeRamp = math.min(1.0,math.max(0.0,self.Speed/2.0))
if self.Speed > 2 then
--brakeRamp = 1 - math.min(1.0,math.max(0.0,(self.Speed-3)/10.0))
end
-- if brakeRamp > 0.01 and brakeSqueal > 0 then
if self:GetNWBool("Async") then
self:SetNW2Float("BrakeSqueal",(self.BrakeCylinderPressure-0.9)/1.7)
local bcP = self.BrakeCylinderPressure
self:SetNW2Float("BrakeSqueal",(bcP-0.9)/1.7)--3/(absSpeed+bcP^3)*(bcP^3)*0.5)
else
self:SetNW2Float("BrakeSqueal1",brakeSqueal1)
--self:SetNW2Float("BrakeSqueal2",brakeSqueal2)
end
--self:SetBrakeSqueal(self.BrakeSqueal or brakeSqueal)
-- end
end
if self.DisableSound < 3 then
self:SetSpeed(absSpeed)

View File

@@ -31,6 +31,9 @@ physenv.AddSurfaceData([[
"gamematerial" "X"
}
]])
function ENT:SetupDataTables()
self._NetData = {}
end
function ENT:GetSpeed()
return self:GetNW2Int("Speed")/5
end
@@ -43,20 +46,17 @@ end
if SERVER then
function ENT:SetSpeed(val)
if self.OldSpeed == math.floor(val*5) then return end
self.OldSpeed = math.floor(val*5)
self:SetNW2Int("Speed",self.OldSpeed)
if self._NetData[1] == math.floor(val*5) then return end
self:SetNW2Int("Speed",math.floor(val*5))
end
function ENT:SetMotorPower(val)
if self.OldMotorPower == math.floor(val*50) then return end
self.OldMotorPower = math.floor(val*50)
self:SetNW2Int("MotorPower",self.OldMotorPower)
if self._NetData[2] == math.floor(val*50) then return end
self:SetNW2Int("MotorPower",math.floor(val*50))
end
function ENT:SetBrakeSqueal(val)
if self.OldBrakeSqueal == math.floor(val*10) then return end
self.OldBrakeSqueal = math.floor(val*10)
self:SetNW2Int("BrakeSqueal",self.OldBrakeSqueal)
if self._NetData[4] == math.floor(val*10) then return end
self:SetNW2Int("BrakeSqueal",math.floor(val*10))
end
end