397 lines
14 KiB
Lua
397 lines
14 KiB
Lua
//ACF unofficial extras feature inject to custom entities.
|
|
//adding Thrust to jet custom engines
|
|
//adding flame effect to jet custom engines
|
|
//adding (soon) exhausts
|
|
//adding (soon) more stuff.
|
|
//by gamerpaddy & Edited by Bouletmarc
|
|
|
|
if SERVER then
|
|
AddCSLuaFile()
|
|
|
|
timer.Destroy("ACFCUSTOM_E_Scan") // clear timer
|
|
|
|
EntitiesTable = {}
|
|
|
|
for k,v in pairs(ents.FindByClass("acf_engine_custom")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
for k,v in pairs(ents.FindByClass("acf_engine_maker")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
|
|
for k,v in pairs(EntitiesTable) do v.acfcustom_e_detected = false end // clear detected engines
|
|
|
|
function acfcustom_e_scan()
|
|
//Redo Table
|
|
EntitiesTable = {}
|
|
for k,v in pairs(ents.FindByClass("acf_engine_custom")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
for k,v in pairs(ents.FindByClass("acf_engine_maker")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
//Custom Engines
|
|
for _,ent in pairs(EntitiesTable) do
|
|
if ent and ent:IsValid() and string.find(ent:GetModel(), "/turbine") and not ent.acfcustom_e_detected then
|
|
ent.acfcustom_e_detected = true
|
|
if GetConVarNumber("sbox_max_acf_modding") > 0 then
|
|
Wire_AdjustInputs(ent,{"Active", "Throttle", "TqAdd", "RpmAdd", "FlywheelMass", "Override", "Thrust", "Thrust Reverse", "FlameEffect", "FlameColor [VECTOR]"})
|
|
else
|
|
Wire_AdjustInputs(ent,{"Active", "Throttle", "Thrust", "Thrust Reverse", "FlameEffect", "FlameColor [VECTOR]"})
|
|
end
|
|
ent.Thrust = 0
|
|
ent.oldPeakTorque = ent.PeakTorque
|
|
ent.oldTriggerInput = ent.TriggerInput
|
|
ent.TriggerInput = function(self, iname, value)
|
|
if not self or not self:IsValid() then return end
|
|
if iname == "Thrust" then self.Thrust = math.Clamp(value,0,100) end
|
|
if iname == "Thrust Reverse" then self.ThrustReverse = (value == 1 and true or false) end
|
|
if iname == "FlameEffect" then self:SetNetworkedBool("acfcustom_e_effects", (value == 1 and true or false) ) end
|
|
if iname == "FlameColor" then self:SetNetworkedVector("acfcustom_e_effect_color", Vector(math.Clamp(value.x or 0, 0, 255), math.Clamp(value.y or 0, 0, 255), math.Clamp(value.z or 0, 0, 255)) ) end
|
|
self.oldTriggerInput(self, iname, value)
|
|
end
|
|
ent.oldThink = ent.Think
|
|
ent.Think = function(self)
|
|
if self and self:IsValid() then
|
|
self.phys = self:GetPhysicsObject()
|
|
self:SetNetworkedFloat( "acfcustom_e_thrust", (self.FlyRPM / self.LimitRPM) * ( ( self.Thrust or 0 )+50) / 100 )
|
|
if self.Thrust ~= 0 and self.phys and self.phys:IsValid() then
|
|
self.CalculatedThrust = ( self.phys:GetMass() * (self.FlyRPM / self.LimitRPM) ) * ((self.Thrust or 0)*50)
|
|
//increasing torque at higher thrust formula incomming... not working right now
|
|
//self.PeakTorque = self.oldPeakTorque - (self.oldPeakTorque * ((self.Thrust or 0)/1000))
|
|
self.phys:ApplyForceCenter( ( (not self.ThrustReverse) and self:GetForward() or -self:GetForward() ) * self.CalculatedThrust)
|
|
end
|
|
end
|
|
self.oldThink(self)
|
|
end
|
|
end
|
|
|
|
--pulsejet mess
|
|
if ent and ent:IsValid() and string.find(ent:GetModel(), "/pulsejet") and not ent.acfcustom_e_detected then
|
|
ent.acfcustom_e_detected = true --inject code only once
|
|
|
|
ent.oldThink = ent.Think --overwriting hooks
|
|
ent.oldOnRemove = ent.OnRemove
|
|
|
|
ent:SetBodygroup(2,0) --off state bodygroup
|
|
|
|
ent.OnRemove = function(self) --overwrite ent:onremove
|
|
if self.Sound2 then
|
|
self.Sound2:Stop() --stop new sound on remove
|
|
end
|
|
self.oldOnRemove(self) --call original onremove
|
|
end
|
|
|
|
local model = ent:GetModel()
|
|
if string.find(model,"pulsejetl.mdl") then
|
|
ent.TraceSize = 350
|
|
ent.SoundOffPitch=100
|
|
elseif string.find(model,"pulsejetm.mdl") then
|
|
ent.TraceSize = 275
|
|
ent.SoundOffPitch=150
|
|
elseif string.find(model,"pulsejets.mdl") then
|
|
ent.TraceSize = 150
|
|
ent.SoundOffPitch=200
|
|
end
|
|
|
|
ent.Think = function(self) --overwrite ent:think
|
|
if self.Sound ~= nil then
|
|
self.Sound:Stop()
|
|
--self.Sound = nil --remove original sound obj
|
|
end
|
|
if self and self:IsValid() then
|
|
self.phys = self:GetPhysicsObject()
|
|
if self.Active ~= false and self.FlyRPM ~=0 and self.phys and self.phys:IsValid() then
|
|
--trace to apply damage
|
|
/*self.acfcustom_etrace = util.TraceLine({
|
|
start = self:GetPos(),
|
|
endpos = self:GetPos() - self:GetForward() * self.TraceSize,
|
|
filter = self
|
|
})
|
|
if self.acfcustom_etrace and self.acfcustom_etrace.Entity and IsValid(self.acfcustom_etrace.Entity) and IsEntity(self.acfcustom_etrace.Entity) then
|
|
ACFCUSTOM_E_ApplyDamage(self.acfcustom_etrace.Entity,self)
|
|
end*/
|
|
|
|
if not self.Sound3 then
|
|
self.Sound3 = CreateSound(self,self.SoundPath) --create sound 2 when engine is on
|
|
self.Sound3:SetSoundLevel(90)
|
|
end
|
|
if not self.Sound3:IsPlaying() then
|
|
self.Sound3:PlayEx(0.6,115) --play
|
|
end
|
|
if self.Sound3 then
|
|
self.Sound3:ChangePitch(100-(math.Clamp(self.Throttle,0,1)*5)) --pitch and volume
|
|
self.Sound3:ChangeVolume(0.6+ (math.Clamp(self.Throttle,0,1)/2.5) )
|
|
end
|
|
|
|
self:SetNetworkedFloat( "acfcustom_e_pjet_thrust",((( math.Clamp(self.Throttle,0,1) or 0 )+0.1)) * (self.Active and 1 or 0) ) --effect size
|
|
self:SetBodygroup(2,1) --on state bodygroup
|
|
|
|
self.CalculatedThrust = ( self.phys:GetMass() * (( math.Clamp(self.Throttle,0,1) or 0)*10000) ) --thrust formula, dont laught lol
|
|
self.phys:ApplyForceCenter( ( self:GetForward() or -self:GetForward() ) * self.CalculatedThrust) --apply formula to phys obj
|
|
else
|
|
self:SetNetworkedFloat( "acfcustom_e_pjet_thrust",0 ) --turn off effects
|
|
if self.Sound3 and self.Sound3:IsPlaying() then
|
|
//local Pitch = 100
|
|
self.Sound3:Stop() --stop sound and remove object
|
|
self.Sound3 = nil
|
|
self:EmitSound("acf_engines/pulsejetoff.wav",90,self.SoundOffPitch,0.5,0)
|
|
end
|
|
self:SetBodygroup(2,0) --off state bodygroup
|
|
self:SetNetworkedFloat( "acfcustom_e_pjet_thrust",0 )
|
|
--this is so fucked up
|
|
end
|
|
end
|
|
self.oldThink(self) --call original think
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
/*function ACFCUSTOM_E_ApplyDamage(ent,self)
|
|
if not self or not self.Owner or not ent then return end
|
|
if(ent:IsPlayer()) then
|
|
ent:TakeDamage(15,self.Owner,self)
|
|
else
|
|
ent:TakeDamage(20,self.Owner,self)
|
|
local HitRes = {}
|
|
|
|
HitRes = ACF_Damage ( ent , {Kinetic = 150,Momentum = 0,Penetration = 15} , 2 , 0 , self.Owner )
|
|
if HitRes and HitRes.Kill then
|
|
constraint.RemoveAll( ent )
|
|
ent:SetParent(nil)
|
|
ent:SetCollisionGroup( COLLISION_GROUP_NONE )
|
|
local Phys = ent:GetPhysicsObject()
|
|
Phys:EnableMotion( true )
|
|
Phys:Wake()
|
|
end
|
|
end
|
|
end*/
|
|
|
|
acfcustom_e_scan()
|
|
timer.Create("ACFCUSTOM_E_Scan",0.25,0,acfcustom_e_scan) // check for new engines
|
|
|
|
end --if server
|
|
|
|
if CLIENT then
|
|
timer.Destroy("ACFCUSTOM_E_Scan") // clear timer
|
|
local emitter = ParticleEmitter(Vector(0,0,0))
|
|
|
|
EntitiesTable = {}
|
|
|
|
for k,v in pairs(ents.FindByClass("acf_engine_custom")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
for k,v in pairs(ents.FindByClass("acf_engine_maker")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
|
|
for k,v in pairs(EntitiesTable) do v.acfcustom_e_detected = false end // clear detected engines
|
|
|
|
function acfcustom_e_scan()
|
|
//Redo Table
|
|
EntitiesTable = {}
|
|
for k,v in pairs(ents.FindByClass("acf_engine_custom")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
for k,v in pairs(ents.FindByClass("acf_engine_maker")) do
|
|
EntitiesTable[k] = v
|
|
end
|
|
//Custom Engines
|
|
for _,ent in pairs(EntitiesTable) do
|
|
if ent and ent:IsValid() and string.find(ent:GetModel(), "/turbine") and not ent.acfcustom_e_detected then
|
|
ent.acfcustom_e_detected = true
|
|
if not notifyShown then
|
|
LocalPlayer():ChatPrint( "Due to a bug in ACF-Extras, the newly added wire inputs can break after duplicating. Please check before use.." )
|
|
notifyShown = true
|
|
end
|
|
ent.GetOffset = function(self)
|
|
local Offset = Vector()
|
|
if self and self:IsValid() then
|
|
local model = self:GetModel()
|
|
if string.find(model,"turbine_l.mdl") then
|
|
Offset = Vector(-50,0,0)
|
|
Size = 1
|
|
elseif string.find(model,"turbine_m.mdl") then
|
|
Offset = Vector(-35,0,0)
|
|
Size = 0.75
|
|
elseif string.find(model,"turbine_s.mdl") then
|
|
Offset = Vector(-25,0,0)
|
|
Size = 0.5
|
|
end
|
|
|
|
end
|
|
return {Size, Offset}
|
|
end
|
|
|
|
ent.CalcNormal = function (self)
|
|
local Offset = self:GetOffset()[2] or Vector()
|
|
return (self:LocalToWorld(Offset) - self:GetPos()):GetNormalized()
|
|
end
|
|
|
|
ent.oldThink = ent.Think
|
|
ent.Think = function(self)
|
|
if self and self:IsValid() then
|
|
if self:GetNetworkedBool("acfcustom_e_effects") then
|
|
self.EffectSize = self:GetNetworkedFloat("acfcustom_e_thrust")
|
|
self.EffectColor = self:GetNetworkedVector("acfcustom_e_effect_color")
|
|
else
|
|
self.EffectSize = 0
|
|
self.EffectColor = Vector()
|
|
end
|
|
--help me!
|
|
end
|
|
self.oldThink(self)
|
|
end
|
|
|
|
ent.oldDraw = ent.Draw
|
|
ent.Draw = function(self)
|
|
if not self or not self:IsValid() then return end
|
|
self.oldDraw(self)
|
|
if self.EffectSize and self.EffectSize > 0 then
|
|
self:EffectDraw_fire()
|
|
end
|
|
end
|
|
ent.EffectDraw_fire = function(self)
|
|
local Size = self:GetOffset()[1] or 1
|
|
local Offset = self:GetOffset()[2] or Vector()
|
|
|
|
if not Size then Size = 1 end
|
|
self.SmokeTimer = self.SmokeTimer or 0
|
|
if ( self.SmokeTimer > CurTime() ) then return end
|
|
self.SmokeTimer = CurTime() + 0.0000005
|
|
local vOffset = self:LocalToWorld(Offset)
|
|
local vNormal = self:CalcNormal()
|
|
local speed = math.Rand(90,252)
|
|
local roll = math.Rand(-90,90)
|
|
--------------------
|
|
local particle = emitter:Add( "particle/fire", vOffset )
|
|
particle:SetVelocity( vNormal * speed )
|
|
particle:SetDieTime( (0.5*Size) * math.Clamp(self.EffectSize or 0,0,1)+0.01 )
|
|
particle:SetStartAlpha( 255 )
|
|
particle:SetEndAlpha( 150 )
|
|
particle:SetStartSize( 15.8 )
|
|
particle:SetEndSize( 9 )
|
|
particle:SetColor( self.EffectColor.x or math.Rand(200,250), self.EffectColor.y or math.Rand(200,250), self.EffectColor.z or math.Rand(200,250) )
|
|
particle:SetRoll( roll )
|
|
--------------------
|
|
local particle3 = emitter:Add( "sprites/heatwave", vOffset )
|
|
particle3:SetVelocity( vNormal * speed )
|
|
particle3:SetDieTime( (0.6*Size) * math.Clamp(self.EffectSize*4 or 0,0,1)+0.1 )
|
|
particle3:SetStartAlpha( 255 )
|
|
particle3:SetEndAlpha( 255 )
|
|
particle3:SetStartSize( 16 )
|
|
particle3:SetEndSize( 18 )
|
|
particle3:SetColor( 255,255,255 )
|
|
particle3:SetRoll( roll )
|
|
--------------------
|
|
vOffset = self:LocalToWorld(Offset)
|
|
local particle2 = emitter:Add( "particle/fire", vOffset )
|
|
particle2:SetVelocity( vNormal * speed )
|
|
particle2:SetDieTime( (0.2*Size) * math.Clamp(self.EffectSize or 0,0,1)+0.01 )
|
|
particle2:SetStartAlpha( 200 )
|
|
particle2:SetEndAlpha( 50 )
|
|
particle2:SetStartSize( 8.8 )
|
|
particle2:SetEndSize( 5 )
|
|
particle2:SetColor( 200,200,200 )
|
|
particle2:SetRoll( roll )
|
|
end
|
|
end
|
|
|
|
if ent and ent:IsValid() and string.find(ent:GetModel(), "/pulsejet") and not ent.acfcustom_e_detected then
|
|
ent.acfcustom_e_detected = true
|
|
|
|
ent.GetOffset = function(self)
|
|
local Offset = Vector()
|
|
if self and self:IsValid() then
|
|
local model = self:GetModel()
|
|
if string.find(model,"pulsejetl.mdl") then
|
|
Offset = Vector(-110,0,0)
|
|
Size = 1
|
|
elseif string.find(model,"pulsejetm.mdl") then
|
|
Offset = Vector(-85,0,0)
|
|
Size = 0.75
|
|
elseif string.find(model,"pulsejets.mdl") then
|
|
Offset = Vector(-50,0,0)
|
|
Size = 0.5
|
|
end
|
|
|
|
end
|
|
return {Size, Offset}
|
|
end
|
|
|
|
ent.CalcNormal = function (self)
|
|
local Offset = self:GetOffset()[2] or Vector()
|
|
return (self:LocalToWorld(Offset) - self:GetPos()):GetNormalized()
|
|
end
|
|
|
|
ent.oldThink = ent.Think
|
|
ent.Think = function(self)
|
|
self.EffectColor = Vector(255,255,255)
|
|
if self and self:IsValid() then
|
|
self.EffectSize = self:GetNetworkedFloat("acfcustom_e_pjet_thrust")
|
|
end
|
|
self.oldThink(self)
|
|
end
|
|
|
|
ent.oldDraw = ent.Draw
|
|
ent.Draw = function(self)
|
|
if not self or not self:IsValid() then return end
|
|
self.oldDraw(self)
|
|
if self.EffectSize and self.EffectSize > 0 then
|
|
self:EffectDraw_fire()
|
|
end
|
|
end
|
|
ent.EffectDraw_fire = function(self)
|
|
local Size = self:GetOffset()[1] or 1
|
|
local Offset = self:GetOffset()[2] or Vector()
|
|
|
|
if not Size then Size = 1 end
|
|
self.SmokeTimer = self.SmokeTimer or 0
|
|
if ( self.SmokeTimer > CurTime() ) then return end
|
|
self.SmokeTimer = CurTime() + 0.0000005
|
|
local vOffset = self:LocalToWorld(Offset)
|
|
local vNormal = self:CalcNormal()
|
|
local speed = math.Rand(150,352) * (self.EffectSize+1)
|
|
local roll = math.Rand(-90,90)
|
|
--------------------
|
|
local particle = emitter:Add( "particle/fire", vOffset )
|
|
particle:SetVelocity( vNormal * (speed*9) )
|
|
particle:SetDieTime( (0.002*Size) * math.Clamp(self.EffectSize or 0,0,1)+0.01 )
|
|
particle:SetStartAlpha( 255 )
|
|
particle:SetEndAlpha( 200 )
|
|
particle:SetStartSize( 15 )
|
|
particle:SetEndSize( 45 )
|
|
particle:SetColor( 230 , 0, 0 )
|
|
particle:SetRoll( roll )
|
|
--------------------
|
|
local particle3 = emitter:Add( "particle/fire", vOffset )
|
|
particle3:SetVelocity( vNormal * (speed*6) )
|
|
particle3:SetDieTime( (0.002*Size) * math.Clamp(self.EffectSize*4 or 0,0,1)+0.1 )
|
|
particle3:SetStartAlpha( 55 )
|
|
particle3:SetEndAlpha( 20 )
|
|
particle3:SetStartSize( 20 )
|
|
particle3:SetEndSize( 30 )
|
|
particle3:SetColor( 220,140,0 )
|
|
particle3:SetRoll( roll )
|
|
--------------------
|
|
vOffset = self:LocalToWorld(Offset)
|
|
|
|
local particle4 = emitter:Add( "sprites/heatwave", vOffset )
|
|
particle4:SetVelocity( vNormal * (speed*9) )
|
|
particle4:SetDieTime( (0.5*Size) * math.Clamp(self.EffectSize or 0,0,1)+0.01 )
|
|
particle4:SetStartAlpha( 255 )
|
|
particle4:SetEndAlpha( 200 )
|
|
particle4:SetStartSize( 15.8 )
|
|
particle4:SetEndSize( 50 )
|
|
particle4:SetColor( 255,255,255 )
|
|
particle4:SetRoll( roll )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
acfcustom_e_scan()
|
|
timer.Create("ACFCUSTOM_E_Scan",0.25,0,acfcustom_e_scan) // check for new engines
|
|
|
|
end // client end |