mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
init
This commit is contained in:
518
lua/weapons/gmod_tool/stools/train_spawner.lua
Normal file
518
lua/weapons/gmod_tool/stools/train_spawner.lua
Normal file
@@ -0,0 +1,518 @@
|
||||
|
||||
--local TOOL = player.GetBySteamID("STEAM_0:1:31566374"):GetTool("train_spawner")
|
||||
TOOL.AddToMenu = false
|
||||
|
||||
if CLIENT then
|
||||
language.Add("Tool.train_spawner.name", "Train Spawner")
|
||||
language.Add("Tool.train_spawner.desc", "Spawn a train")
|
||||
language.Add("Tool.train_spawner.0", "Primary: Spawns a full train. Secondary: Reverse facing (yellow ed when facing the opposite side).")
|
||||
language.Add("Undone_81-7036", "Undone 81-7036 (does not work)")
|
||||
language.Add("Undone_81-7037", "Undone 81-7037 (does not work)")
|
||||
language.Add("Undone_81-717", "Undone 81-717")
|
||||
language.Add("Undone_81-714", "Undone 81-714")
|
||||
language.Add("Undone_Ezh3", "Undone Ezh3")
|
||||
language.Add("Undone_Ema508T", "Undone Em508T")
|
||||
language.Add("SBoxLimit_spawner_wrong_pos","Wrong train position! Can't spawn")
|
||||
language.Add("SBoxLimit_spawner_restrict","This train is restricted for you")
|
||||
end
|
||||
|
||||
local function Trace(ply,tr)
|
||||
local verticaloffset = 5 -- Offset for the train model
|
||||
local distancecap = 2000 -- When to ignore hitpos and spawn at set distanace
|
||||
local pos, ang = nil
|
||||
local inhibitrerail = false
|
||||
|
||||
--TODO: Make this work better for raw base ent
|
||||
|
||||
if tr.Hit then
|
||||
-- Setup trace to find out of this is a track
|
||||
local tracesetup = {}
|
||||
tracesetup.start=tr.HitPos
|
||||
tracesetup.endpos=tr.HitPos+tr.HitNormal*80
|
||||
tracesetup.filter=ply
|
||||
|
||||
local tracedata = util.TraceLine(tracesetup)
|
||||
|
||||
if tracedata.Hit then
|
||||
-- Trackspawn
|
||||
pos = (tr.HitPos + tracedata.HitPos)/2 + Vector(0,0,verticaloffset)
|
||||
ang = tracedata.HitNormal
|
||||
ang:Rotate(Angle(0,90,0))
|
||||
ang = ang:Angle()
|
||||
-- Bit ugly because Rotate() messes with the orthogonal vector | Orthogonal? I wrote "origional?!" :V
|
||||
else
|
||||
-- Regular spawn
|
||||
if tr.HitPos:Distance(tr.StartPos) > distancecap then
|
||||
-- Spawnpos is far away, put it at distancecap instead
|
||||
pos = tr.StartPos + tr.Normal * distancecap
|
||||
inhibitrerail = true
|
||||
else
|
||||
-- Spawn is near
|
||||
pos = tr.HitPos + tr.HitNormal * verticaloffset
|
||||
end
|
||||
ang = Angle(0,tr.Normal:Angle().y,0)
|
||||
end
|
||||
else
|
||||
-- Trace didn't hit anything, spawn at distancecap
|
||||
pos = tr.StartPos + tr.Normal * distancecap
|
||||
ang = Angle(0,tr.Normal:Angle().y,0)
|
||||
end
|
||||
return {pos,ang,inhibitrerail}
|
||||
end
|
||||
|
||||
function UpdateGhostPos(pl)
|
||||
local trace = util.TraceLine(util.GetPlayerTrace(pl))
|
||||
local tbl = Metrostroi.RerailGetTrackData(trace.HitPos,pl:GetAimVector())
|
||||
|
||||
if not tbl then tbl = Trace(pl, trace) end
|
||||
local class = IsValid(trace.Entity) and trace.Entity:GetClass()
|
||||
|
||||
local pos,ang = Vector(0,0,0),Angle(0,0,0)
|
||||
if tbl[3] ~= nil then
|
||||
pos = tbl[1]+Vector(0,0,55)
|
||||
ang = tbl[2]
|
||||
return pos,ang,false,not class or (class == "func_door" or class == "prop_door_rotating")
|
||||
else
|
||||
pos = tbl.centerpos + Vector(0,0,112)
|
||||
ang = tbl.right:Angle()+Angle(0,90,0)
|
||||
return pos,ang,true,not class or (class == "func_door" or class == "prop_door_rotating")
|
||||
end
|
||||
end
|
||||
|
||||
function UpdateWagPos(pl)
|
||||
local trace = util.TraceLine(util.GetPlayerTrace(pl))
|
||||
local tbl = Metrostroi.RerailGetTrackData(trace.HitPos,pl:GetAimVector())
|
||||
|
||||
if not tbl then tbl = Trace(pl, trace) end
|
||||
local pos,ang = Vector(0,0,0),Angle(0,0,0)
|
||||
if tbl[3] ~= nil then
|
||||
pos = tbl[1]
|
||||
ang = tbl[2]
|
||||
return pos,ang,false
|
||||
else
|
||||
pos = tbl.centerpos + Vector(0,0,112-55)
|
||||
ang = tbl.right:Angle()+Angle(0,90,0)
|
||||
return pos,ang,true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function TOOL:UpdateGhost()
|
||||
local good,canDraw
|
||||
for i,e in ipairs(self.GhostEntities) do
|
||||
local t = self.Model[i]
|
||||
local pos,ang
|
||||
if i==1 then
|
||||
pos,ang,good,canDraw = UpdateGhostPos(self:GetOwner())
|
||||
if self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev") then
|
||||
ang = ang+Angle(0,180,0)
|
||||
end
|
||||
elseif type(t) ~= "string" then
|
||||
pos,ang = self.GhostEntities[1]:LocalToWorld(t.pos or Vector(0,0,0)),self.GhostEntities[1]:LocalToWorldAngles(self.Model[i].ang or Angle(0,0,0))
|
||||
else
|
||||
pos,ang = self.GhostEntities[1]:GetPos(),self.GhostEntities[1]:GetAngles()
|
||||
end
|
||||
e:SetNoDraw(not canDraw)
|
||||
--if not pos then bad = true else pos,ang = rpos,rang end
|
||||
if not good then
|
||||
e:SetColor(Color(255,150,150,255))
|
||||
elseif self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev") then
|
||||
e:SetColor(Color(255,255,150,255))
|
||||
else
|
||||
e:SetColor(Color(255,255,255,255))
|
||||
end
|
||||
e:SetPos(pos)
|
||||
e:SetAngles(ang)
|
||||
end
|
||||
end
|
||||
|
||||
function TOOL:Holster()
|
||||
if not IsFirstTimePredicted() or SERVER then return end
|
||||
end
|
||||
|
||||
--local owner
|
||||
function TOOL:Think()
|
||||
if not self.Train then return end
|
||||
--owner = self:GetOwner()
|
||||
--self.tbl = self:GetConvar()
|
||||
--self.int = self.tbl.Prom > 0 or !Trains[self.tbl.Train][1]:find("Ezh3")
|
||||
if CLIENT and self.Train.Spawner.model then
|
||||
if not self.GhostEntities then self.GhostEntities = {} end
|
||||
if not IsValid(self.GhostEntities[1]) or self.Model ~= self.Train.Spawner.model then
|
||||
self.Model = self.Train.Spawner.model
|
||||
for _,e in pairs(self.GhostEntities) do SafeRemoveEntity(e) end
|
||||
self.GhostEntities = {}
|
||||
if type(self.Model) == "string" then
|
||||
self.GhostEntities[1] = ClientsideModel(self.Model,RENDERGROUP_OPAQUE)
|
||||
self.GhostEntities[1]:SetModel(self.Model)
|
||||
else
|
||||
for i,t in pairs(self.Model) do
|
||||
if type(t) == "string" then
|
||||
self.GhostEntities[i] = ClientsideModel(t,RENDERGROUP_OPAQUE)
|
||||
self.GhostEntities[i]:SetModel(t)
|
||||
else
|
||||
self.GhostEntities[i] = ClientsideModel(t[1],RENDERGROUP_OPAQUE)
|
||||
self.GhostEntities[i]:SetModel(t[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,e in pairs(self.GhostEntities) do
|
||||
e:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
e.GetBodyColor = function() return Vector(1,1,1) end
|
||||
e.GetDirtLevel = function() return 0.25 end
|
||||
end
|
||||
hook.Add("Think",self.GhostEntities[1],function()
|
||||
if not IsValid(self.Owner:GetActiveWeapon()) or self.Owner:GetActiveWeapon():GetClass()~="gmod_tool" or GetConVarString("gmod_toolmode") ~= "train_spawner" then
|
||||
self:OnRemove()
|
||||
end
|
||||
end)
|
||||
|
||||
local oldOR = self.GhostEntities[1].OnRemove
|
||||
self.GhostEntities[1].OnRemove = function(ent)
|
||||
hook.Remove("Think",ent)
|
||||
oldOR(ent)
|
||||
end
|
||||
else
|
||||
self:UpdateGhost()
|
||||
end
|
||||
end
|
||||
---if SERVER then self.Rev = self.Rev end
|
||||
end
|
||||
|
||||
function TOOL:SetSettings(ent, ply, i,inth)
|
||||
local rot = false
|
||||
if i > 1 then
|
||||
rot = i == self.tbl.WagNum and true or math.random() > 0.5
|
||||
end
|
||||
end
|
||||
|
||||
local function SetValue(ent,id,val)
|
||||
if type(val) == "number" then
|
||||
ent:SetNW2Int(id,val)
|
||||
elseif type(val) == "string" then
|
||||
ent:SetNW2String(id,val)
|
||||
elseif type(val) == "boolean" then
|
||||
ent:SetNW2Bool(id,val)
|
||||
end
|
||||
end
|
||||
|
||||
function TOOL:SpawnWagon(trace)
|
||||
if CLIENT then return end
|
||||
local ply = self:GetOwner()
|
||||
|
||||
local FIXFIXFIX = {}
|
||||
for i=1,math.random(12) do
|
||||
FIXFIXFIX[i] = ents.Create("env_sprite")
|
||||
FIXFIXFIX[i]:Spawn()
|
||||
end
|
||||
|
||||
local LastRot,LastEnt = false
|
||||
local trains = {}
|
||||
for i=1,self.Settings.WagNum do
|
||||
local spawnfunc = self.Train.Spawner.spawnfunc
|
||||
local ent
|
||||
if i == 1 then
|
||||
if spawnfunc then
|
||||
ent = self.Train:SpawnFunction(ply,trace,spawnfunc(i,self.Settings,self.Train),self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev"),UpdateWagPos)
|
||||
else
|
||||
ent = self.Train:SpawnFunction(ply,trace,self.Train.Spawner.head or self.Train.ClassName,self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev"),UpdateWagPos)
|
||||
end
|
||||
--nil,self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev") and Angle(0,180,0) or Angle(0,0,0)) --Create a first entity in queue
|
||||
if ent then
|
||||
undo.Create(self.Train.Spawner.head or self.Train.ClassName)
|
||||
else
|
||||
self:GetOwner():LimitHit("spawner_wrong_pos")
|
||||
return false
|
||||
end
|
||||
--if self:GetOwner():GetNW2Bool("metrostroi_train_spawner_rev") then
|
||||
--ent:SetAngles(ent:LocalToWorldAngles(Angle(0,180,0)))
|
||||
--end
|
||||
--if self.Rot then
|
||||
end
|
||||
if i > 1 then
|
||||
local rot = (i==self.Settings.WagNum or math.random() > 0.5) -- Rotate last wagon or rotate it randomly
|
||||
if spawnfunc then
|
||||
ent = ents.Create(spawnfunc(i,self.Settings,self.Train))
|
||||
else
|
||||
ent = ents.Create(i~=self.Settings.WagNum and self.Train.Spawner.interim or self.Train.Spawner.head or self.Train.ClassName)
|
||||
end
|
||||
ent.Owner = ply
|
||||
ent:Spawn()
|
||||
-- Invert bogeys by rotation
|
||||
local bogeyL1,bogeyE1,bogeyE2
|
||||
local couplL1,couplE1,couplE2
|
||||
if LastRot then
|
||||
bogeyL1 = LastEnt.FrontBogey
|
||||
couplL1 = LastEnt.FrontCouple
|
||||
else
|
||||
bogeyL1 = LastEnt.RearBogey
|
||||
couplL1 = LastEnt.RearCouple
|
||||
end
|
||||
if rot then
|
||||
bogeyE1,bogeyE2 = ent.RearBogey,ent.FrontBogey
|
||||
couplE1,couplE2 = ent.FrontCouple,ent.RearCouple
|
||||
else
|
||||
bogeyE1,bogeyE2 = ent.FrontBogey,ent.RearBogey
|
||||
couplE1,couplE2 = ent.RearCouple,ent.FrontCouple
|
||||
end
|
||||
local haveCoupler = couplL1 ~= nil
|
||||
if haveCoupler then
|
||||
bogeyE1:SetAngles(ent:LocalToWorldAngles(bogeyE1.SpawnAng))
|
||||
bogeyE2:SetAngles(ent:LocalToWorldAngles(bogeyE1.SpawnAng))
|
||||
-- Set bogey position by our bogey couple offset and lastent bogey couple offset
|
||||
couplE1:SetPos(
|
||||
couplL1:LocalToWorld(
|
||||
Vector(
|
||||
couplL1.CouplingPointOffset.x*1.1+couplE1.CouplingPointOffset.x*1.1,
|
||||
couplL1.CouplingPointOffset.y-couplE1.CouplingPointOffset.y,
|
||||
couplL1.CouplingPointOffset.z-couplE1.CouplingPointOffset.z
|
||||
)
|
||||
)
|
||||
)
|
||||
-- Set bogey angles
|
||||
couplE1:SetAngles(couplL1:LocalToWorldAngles(Angle(0,180,0)))
|
||||
-- Set entity position by bogey pos and bogey offset
|
||||
couplE2:SetAngles(couplE1:LocalToWorldAngles(Angle(0,180,0)))
|
||||
ent:SetPos(couplE1:LocalToWorld(couplE1.SpawnPos*Vector(rot and -1 or 1,-1,-1)))
|
||||
-- Set entity angles by last ent and rotation
|
||||
ent:SetAngles(LastEnt:LocalToWorldAngles(Angle(0,rot ~= LastRot and 180 or 0,0)))
|
||||
|
||||
-- Set bogey pos
|
||||
bogeyE1:SetPos(ent:LocalToWorld(bogeyE1.SpawnPos))
|
||||
bogeyE2:SetPos(ent:LocalToWorld(bogeyE2.SpawnPos))
|
||||
-- Set bogey angles
|
||||
bogeyE1:SetAngles(ent:LocalToWorldAngles(bogeyE1.SpawnAng))
|
||||
bogeyE2:SetAngles(ent:LocalToWorldAngles(bogeyE1.SpawnAng))
|
||||
else
|
||||
-- Set bogey position by our bogey couple offset and lastent bogey couple offset
|
||||
bogeyE1:SetPos(
|
||||
bogeyL1:LocalToWorld(
|
||||
Vector(bogeyL1.CouplingPointOffset.x*1.1+bogeyE1.CouplingPointOffset.x*1.05,bogeyL1.CouplingPointOffset.y-bogeyE1.CouplingPointOffset.y,bogeyL1.CouplingPointOffset.z-bogeyE1.CouplingPointOffset.z)
|
||||
)
|
||||
)
|
||||
-- Set bogey angles
|
||||
bogeyE1:SetAngles(bogeyL1:LocalToWorldAngles(Angle(0,180,0)))
|
||||
-- Set entity position by bogey pos and bogey offset
|
||||
bogeyE2:SetAngles(bogeyE1:LocalToWorldAngles(Angle(0,180,0)))
|
||||
ent:SetPos(bogeyE1:LocalToWorld(bogeyE1.SpawnPos*Vector(rot and -1 or 1,-1,-1)))
|
||||
-- Set entity angles by last ent and rotation
|
||||
ent:SetAngles(LastEnt:LocalToWorldAngles(Angle(0,rot ~= LastRot and 180 or 0,0)))
|
||||
-- Set second bogey pos
|
||||
bogeyE2:SetPos(ent:LocalToWorld(bogeyE2.SpawnPos))
|
||||
end
|
||||
|
||||
Metrostroi.RerailTrain(ent) --Rerail train
|
||||
--LastEnt:LocalToWorld(bogeyL1:WorldToLocal(Vector))))
|
||||
|
||||
LastRot = rot
|
||||
end
|
||||
table.insert(trains,ent)
|
||||
undo.AddEntity(ent)
|
||||
--[[
|
||||
ent:SetMoveType(MOVETYPE_NONE)
|
||||
ent.FrontBogey:SetMoveType(MOVETYPE_NONE)
|
||||
ent.RearBogey:SetMoveType(MOVETYPE_NONE)
|
||||
if IsValid(ent.FrontCouple) then
|
||||
ent.FrontCouple:SetMoveType(MOVETYPE_NONE)
|
||||
ent.RearCouple:SetMoveType(MOVETYPE_NONE)
|
||||
end]]
|
||||
|
||||
for _, set in ipairs(self.Train.Spawner) do
|
||||
local val = self.Settings[set[1]]
|
||||
if set[3] == "List" then
|
||||
if set[6] and type(set[6]) == "function" then set[6](ent,val,LastRot,i,self.Settings.WagNum) else SetValue(ent,set[1],val) end
|
||||
elseif set[3] == "Boolean" then
|
||||
if set[5] and type(set[5]) == "function" then set[5](ent,val,LastRot,i,self.Settings.WagNum) else ent:SetNW2Bool(set[1],val) end
|
||||
elseif set[3] == "Slider" then
|
||||
if set[8] and type(set[8]) == "function" then set[8](ent,val,LastRot,i,self.Settings.WagNum) else ent:SetNW2Int(set[1],val) end
|
||||
end
|
||||
end
|
||||
if self.Train.Spawner.func then self.Train.Spawner.func(ent,i,self.Settings.WagNum,LastRot) end
|
||||
if self.Train.Spawner.wagfunc then ent:GenerateWagonNumber(function(_,number) return self.Train.Spawner.wagfunc(ent,i,number) end) end
|
||||
if ent.TrainSpawnerUpdate then ent:TrainSpawnerUpdate() end
|
||||
for k,v in pairs(ent.CustomSpawnerUpdates) do if k ~= "BaseClass" then v(ent) end end
|
||||
hook.Run("MetrostroiSpawnerUpdate",ent,self.Settings)
|
||||
ent:UpdateTextures()
|
||||
ent.FrontAutoCouple = i > 1 and i < self.Settings.WagNum
|
||||
ent.RearAutoCouple = true
|
||||
LastEnt = ent
|
||||
end
|
||||
undo.SetPlayer(ply)
|
||||
undo.SetCustomUndoText("Undone a train")
|
||||
undo.Finish()
|
||||
if self.Train.Spawner.postfunc then self.Train.Spawner.postfunc(trains,self.Settings.WagNum) end
|
||||
--if self.Settings.AutoCouple and #trains > 1 then
|
||||
local CoupledTrains,WagNum = 0,self.Settings.WagNum
|
||||
local function StopCoupling()
|
||||
if not IsValid(trains[1]) or not trains[1].IgnoreEngine then return end
|
||||
for _,train in ipairs(trains) do
|
||||
train.FrontBogey.BrakeCylinderPressure = 3
|
||||
train.RearBogey.BrakeCylinderPressure = 3
|
||||
train.FrontBogey.MotorPower = 0
|
||||
train.RearBogey.MotorPower = 0
|
||||
train.OnCoupled = nil
|
||||
end
|
||||
timer.Simple(1,function() for i,train in ipairs(trains) do train.IgnoreEngine = false end end)
|
||||
end
|
||||
for i,train in ipairs(trains) do
|
||||
train.IgnoreEngine = true
|
||||
train.RearBogey.MotorForce = 40000
|
||||
train.FrontBogey.MotorForce = 40000
|
||||
train.RearBogey.PneumaticBrakeForce = 50000
|
||||
train.FrontBogey.PneumaticBrakeForce = 50000
|
||||
if i==#trains then
|
||||
train.RearBogey.MotorPower = 1
|
||||
train.FrontBogey.MotorPower = 0
|
||||
else
|
||||
train.RearBogey.MotorPower = 0
|
||||
train.FrontBogey.MotorPower = 0
|
||||
end
|
||||
if i==1 then
|
||||
train.FrontBogey.BrakeCylinderPressure = 3
|
||||
train.RearBogey.BrakeCylinderPressure = 3
|
||||
else
|
||||
train.FrontBogey.BrakeCylinderPressure = 0
|
||||
train.RearBogey.BrakeCylinderPressure = 0
|
||||
end
|
||||
train.OnCoupled = function(ent)
|
||||
CoupledTrains = CoupledTrains + 0.5
|
||||
if CoupledTrains==WagNum-1 then StopCoupling() end
|
||||
end
|
||||
end
|
||||
timer.Simple(3+1*#trains,StopCoupling)
|
||||
--end
|
||||
--self.rot = false
|
||||
for k,v in pairs(FIXFIXFIX) do SafeRemoveEntity(v) end
|
||||
end
|
||||
|
||||
function TOOL:OnRemove()
|
||||
self:Finish()
|
||||
end
|
||||
function TOOL:Finish()
|
||||
for _,e in pairs(self.GhostEntities) do SafeRemoveEntity(e) end
|
||||
self.GhostEntities = {}
|
||||
end
|
||||
|
||||
function TOOL:Reload(trace)
|
||||
if CLIENT then return end
|
||||
local spawner = ents.Create("gmod_train_spawner")
|
||||
spawner:SpawnFunction(self:GetOwner())
|
||||
end
|
||||
function TOOL:LeftClick(trace)
|
||||
if not self.Train then return end
|
||||
local class = IsValid(trace.Entity) and trace.Entity:GetClass()
|
||||
if class and (trace.Entity.Spawner or class ~= "func_door" and class ~= "prop_door_rotating") then
|
||||
if SERVER then
|
||||
if trace.Entity.ClassName == (self.Train.Spawner.head or self.Train.ClassName) or trace.Entity.ClassName == self.Train.Spawner.interim then
|
||||
local LastEnt
|
||||
local trains = {}
|
||||
for k,ent in ipairs(trace.Entity.WagonList) do
|
||||
--[[
|
||||
local rot = ent.RearTrain and ent.RearTrain.FrontTrain == ent or ent.FrontTrain and ent.FrontTrain.RearTrain == ent
|
||||
if not LastRot then
|
||||
rot = ent.RearTrain and ent.RearTrain.RearTrain == ent or ent.FrontTrain and ent.FrontTrain.FrontTrain == ent
|
||||
end]]
|
||||
local rot = ent.RearTrain == LastEnt
|
||||
LastEnt = ent
|
||||
for i, set in ipairs(self.Train.Spawner) do
|
||||
local val = self.Settings[set[1]]
|
||||
if set[3] == "List" then
|
||||
if set[6] and type(set[6]) == "function" then set[6](ent,val,rot,k,self.Settings.WagNum) else SetValue(ent,set[1],val) end
|
||||
elseif set[3] == "Boolean" then
|
||||
if set[5] and type(set[5]) == "function" then set[5](ent,val,rot,k,self.Settings.WagNum) else ent:SetNW2Bool(set[1],val) end
|
||||
elseif set[3] == "Slider" then
|
||||
if set[8] and type(set[8]) == "function" then set[8](ent,val,rot,k,self.Settings.WagNum) else ent:SetNW2Int(set[1],val) end
|
||||
end
|
||||
end
|
||||
if self.Train.Spawner.func then self.Train.Spawner.func(ent,k,self.Settings.WagNum,rot) end
|
||||
ent:GenerateWagonNumber(self.Train.Spawner.wagfunc)
|
||||
if ent.TrainSpawnerUpdate then ent:TrainSpawnerUpdate() end
|
||||
for k,v in pairs(ent.CustomSpawnerUpdates) do if k ~= "BaseClass" then v(ent) end end
|
||||
hook.Run("MetrostroiSpawnerUpdate",ent,self.Settings)
|
||||
ent:UpdateTextures()
|
||||
table.insert(trains,ent)
|
||||
|
||||
end
|
||||
if self.Train.Spawner.postfunc then self.Train.Spawner.postfunc(trains,self.Settings.WagNum) end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
if not self.AllowSpawn or not self.Train then return end
|
||||
if SERVER then
|
||||
if self.Settings.WagNum > GetConVarNumber("metrostroi_maxwagons") then
|
||||
self.Settings.WagNum = GetConVarNumber("metrostroi_maxwagons")
|
||||
end
|
||||
|
||||
if Metrostroi.TrainCountOnPlayer(self:GetOwner()) + self.Settings.WagNum > GetConVarNumber("metrostroi_maxtrains_onplayer")*GetConVarNumber("metrostroi_maxwagons")
|
||||
or Metrostroi.TrainCount() + self.Settings.WagNum > GetConVarNumber("metrostroi_maxtrains")*GetConVarNumber("metrostroi_maxwagons") then
|
||||
self:GetOwner():LimitHit("train_limit")
|
||||
return true
|
||||
end
|
||||
if hook.Run("MetrostroiSpawnerRestrict",self:GetOwner(),self.Settings) then
|
||||
self:GetOwner():LimitHit("spawner_restrict")
|
||||
return true
|
||||
end
|
||||
end
|
||||
self:SpawnWagon(trace)
|
||||
return
|
||||
end
|
||||
|
||||
function TOOL:RightClick(trace)
|
||||
if not self.Train then return end
|
||||
if IsValid(trace.Entity) then
|
||||
if SERVER then
|
||||
if trace.Entity.ClassName == (self.Train.Spawner.head or self.Train.ClassName) or trace.Entity.ClassName == self.Train.Spawner.interim then
|
||||
local LastEnt
|
||||
local trains = {}
|
||||
for k,ent in pairs(trace.Entity.WagonList) do
|
||||
local rot = ent.RearTrain == LastEnt
|
||||
LastEnt = ent
|
||||
if ent ~= trace.Entity then continue end
|
||||
for i, set in ipairs(self.Train.Spawner) do
|
||||
local val = self.Settings[set[1]]
|
||||
if set[3] == "List" then
|
||||
if set[6] and type(set[6]) == "function" then set[6](ent,val,rot,k,self.Settings.WagNum,true) else SetValue(ent,set[1],val) end
|
||||
elseif set[3] == "Boolean" then
|
||||
if set[5] and type(set[5]) == "function" then set[5](ent,val,rot,k,self.Settings.WagNum,true) else ent:SetNW2Bool(set[1],val) end
|
||||
elseif set[3] == "Slider" then
|
||||
if set[8] and type(set[8]) == "function" then set[8](ent,val,rot,k,self.Settings.WagNum,true) else ent:SetNW2Int(set[1],val) end
|
||||
end
|
||||
end
|
||||
if self.Train.Spawner.func then self.Train.Spawner.func(ent,k,self.Settings.WagNum,rot) end
|
||||
ent:GenerateWagonNumber(self.Train.Spawner.wagfunc)
|
||||
if ent.TrainSpawnerUpdate then ent:TrainSpawnerUpdate() end
|
||||
for k,v in pairs(ent.CustomSpawnerUpdates) do if k ~= "BaseClass" then v(ent) end end
|
||||
hook.Run("MetrostroiSpawnerUpdate",ent,self.Settings)
|
||||
ent:UpdateTextures()
|
||||
table.insert(trains,ent)
|
||||
if self.Train.Spawner.postfunc then self.Train.Spawner.postfunc(trains,self.Settings.WagNum) end
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
if not self.AllowSpawn or not self.Train then return end
|
||||
if CLIENT then return end
|
||||
self.Rev = not self.Rev
|
||||
self:GetOwner():SetNW2Bool("metrostroi_train_spawner_rev",self.Rev)
|
||||
|
||||
end
|
||||
|
||||
function TOOL.BuildCPanel(panel)
|
||||
panel:AddControl("Header", { Text = "#Tool.train_spawner.name", Description = "#Tool.train_spawner.desc" })
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
util.AddNetworkString "train_spawner_open"
|
||||
net.Receive("train_spawner_open",function(len,ply)
|
||||
ply:ConCommand("gmod_tool train_spawner")
|
||||
ply:SelectWeapon("gmod_tool")
|
||||
local tool = ply:GetTool("train_spawner")
|
||||
tool.AllowSpawn = true
|
||||
tool.Settings = net.ReadTable()
|
||||
local ENT = scripted_ents.Get(tool.Settings.Train)
|
||||
if not ENT then tool.AllowSpawn = false else tool.Train = ENT end
|
||||
end)
|
||||
return
|
||||
end
|
||||
Reference in New Issue
Block a user