ACF_CustomMod/lua/autorun/acf_extras_custom.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