Guest User

4D_defaultcollisionbeams.lua

a guest
May 15th, 2015
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.17 KB | None | 0 0
  1. ------------------------------------------------------------------------------
  2. --  File        :   /mods/4DC_FAF_Release/lua/4D_defaultcollisionbeams.lua
  3. --  Author(s)   :   EbolaSoup, Resin Smoker, Optimus Prime, Vissroid, Eddy, Domino
  4. --  Copyright © 2015 4DC_FAF_Release, All rights reserved.
  5. ------------------------------------------------------------------------------
  6.  
  7. local CollisionBeam = import('/lua/sim/CollisionBeam.lua').CollisionBeam
  8. local EffectTemplate = import('/lua/EffectTemplates.lua')
  9. local Custom_4D_EffectTemplate = import('/mods/4DC_FAF_Release/lua/4D_EffectTemplates.lua')
  10. local utilities = import('/lua/utilities.lua')
  11. EmtBpPath = '/effects/emitters/'
  12.  
  13. ------------------------------
  14. --   Base class that defines all other 4DC beam types (Do not delete)
  15. ------------------------------
  16. CustomBeam = Class(CollisionBeam) {
  17.  
  18.     -- Default beam FX
  19.     FxImpactUnit = EffectTemplate.DefaultProjectileLandUnitImpact,
  20.     FxUnitHitScale = 0.3,
  21.     FxImpactLand = EffectTemplate.DefaultProjectileLandImpact,
  22.     FxLandHitScale = 0.3,
  23.     FxImpactWater = EffectTemplate.DefaultProjectileWaterImpact,
  24.     FxImpactUnderWater = EffectTemplate.DefaultProjectileUnderWaterImpact,
  25.     FxImpactAirUnit = EffectTemplate.DefaultProjectileAirUnitImpact,
  26.     FxImpactProp = {},
  27.     FxImpactShield = {},
  28.     FxImpactNone = {},
  29.  
  30.     OnImpact = function(self, impactType, targetEntity)
  31.         local myDebug = false
  32.         if myDebug then LOG('*** OnImpact ***') end
  33.         if self then
  34.             if impactType == 'Terrain' and self.ScorchSize then
  35.                 if self.Scorching == nil then
  36.                     self.Scorching = self:ForkThread( self.ScorchThread )
  37.                 end
  38.             elseif not impactType == 'Unit' and self.ScorchSize then
  39.                 KillThread(self.Scorching)
  40.                 self.Scorching = nil
  41.             end
  42.             self.ImpactPos = self:GetPosition()
  43.             CollisionBeam.OnImpact(self, impactType, targetEntity)
  44.         end
  45.     end,
  46.  
  47.     DoDamage = function(self, instigator, damageData, targetEntity)
  48.         local myDebug = false
  49.         if myDebug then LOG('*** DoDamage ***') end
  50.         if self and damageData then
  51.             if not instigator then
  52.                 instigator = self
  53.             end
  54.             if myDebug then LOG('   instigator: ', instigator:GetEntityId()) end
  55.             if self.Weapon:GetBlueprint().ChainLighningSpec and targetEntity then
  56.                 if myDebug then LOG('   Calling Chain Lightning') end
  57.                 if self.ChainLightningThread then
  58.                     KillThread(self.ChainLightningThread)
  59.                     self.ChainLightningThread = nil
  60.                 end
  61.                 self.Bp = self.Weapon:GetBlueprint()
  62.                 self.ChainSpec = self.Bp.ChainLighningSpec
  63.                 self.ChainFx = {}
  64.                 self.DmgUnitsTable = {}
  65.                 self.ChainLightningThread = self:ForkThread( self.DoChainLightning, instigator, damageData, targetEntity )
  66.             else
  67.                 if myDebug then LOG('   Normal beam, calling CollisionBeam.DoDamage') end
  68.                 CollisionBeam.DoDamage(self, instigator, damageData, targetEntity)
  69.             end
  70.         else
  71.             if myDebug then LOG('   "self" or Damage.Data is Invalid') end
  72.         end
  73.     end,
  74.  
  75.     DoChainLightning = function(self, instigator, damageData, targetEntity)
  76.         local myDebug = false
  77.         if myDebug then LOG('*** DoChainLightning ***') end
  78.         if myDebug then LOG('   instigator: ', instigator:GetEntityId()) end
  79.         local army = self:GetArmy()
  80.         local beamLifeTime
  81.         if self.Bp.BeamLifetime > 0.25 then
  82.             beamLifeTime = self.Bp.BeamLifetime
  83.         elseif self.Bp.BeamCollisionDelay > 0.25 then
  84.             beamLifeTime = self.Bp.BeamCollisionDelay
  85.         else
  86.             beamLifeTime = 0.25
  87.         end
  88.         if not self.ChainSpec.Forks or self.ChainSpec.Forks < 1 then
  89.             self.ChainSpec.Forks = Random(2, 6)
  90.         end
  91.         if not self.ChainSpec.JumpRadius or self.ChainSpec.JumpRadius < 1 then
  92.             self.ChainSpec.JumpRadius = Random(4, 10)
  93.         end
  94.         table.insert(self.DmgUnitsTable, targetEntity)
  95.         local oldTarget = targetEntity
  96.         local forkCounter = 1
  97.         while self and forkCounter <= self.ChainSpec.Forks do
  98.             if myDebug then LOG('   While do ForkLightning loop') end
  99.             local targets = self:GetValidTargetsAlongScaledVector(instigator, oldTarget, (self.ChainSpec.JumpRadius))
  100.             local tblSize =  table.getsize(targets)
  101.             if myDebug then LOG('       tblSize: ', tblSize) end
  102.             if tblSize > 0 then
  103.                 local currentTarget
  104.                 if not self.ChainSpec.Branches or self.ChainSpec.Branches < 1 then
  105.                     self.ChainSpec.Branches = Random(2, 6)
  106.                 end
  107.                 for i = 1, self.ChainSpec.Branches do
  108.                     local ran = Random(1,tblSize)
  109.                     currentTarget = targets[ran].unit
  110.                     if currentTarget != nil and not currentTarget:BeenDestroyed() and currentTarget != instigator and currentTarget != targetEntity and currentTarget != oldTarget then
  111.                         if myDebug then LOG('           CurrentTarget Id: ', currentTarget.id) end
  112.                         self:ForkThread(self.ChainLightningFX, oldTarget, currentTarget, army, beamLifeTime)
  113.                         table.insert(self.DmgUnitsTable, currentTarget)
  114.                     end
  115.                 end
  116.                 oldTarget = currentTarget
  117.             end
  118.             targets = nil
  119.             forkCounter = forkCounter + 1
  120.         end
  121.         local numTargets = table.getsize(self.DmgUnitsTable)
  122.         if numTargets > 0 then
  123.             if myDebug then
  124.                 for a, b in self.DmgUnitsTable do
  125.                     LOG('   unit to damage ID: ', b:GetEntityId())
  126.                     LOG('   instigator: ', instigator:GetEntityId())
  127.                 end
  128.             end
  129.             local dmgMod = damageData.DamageAmount
  130.             if self.ChainSpec.DamageForm == 'Divide' then
  131.                 dmgMod = dmgMod / numTargets
  132.             end
  133.             if myDebug then LOG('   dmgMOD / units spread: ', repr(dmgMod), 'DamageForm: ', repr(self.ChainSpec.DamageForm)) end
  134.             for a, b in self.DmgUnitsTable do
  135.                 if b and not b:BeenDestroyed() then
  136.                     Damage(instigator, self:GetPosition(), b, dmgMod, damageData.DamageType)
  137.                 end
  138.             end        
  139.         end
  140.     end,
  141.  
  142.     GetValidTargetsAlongScaledVector = function(self, instigator, oldTarget, scale)
  143.         local myDebug = false
  144.         if myDebug then LOG('GetValidTargetsAlongScaledVector') end
  145.         if instigator and oldTarget and scale then
  146.             --Get a list of avlaible targets in the direction the beam was originally fired
  147.             local tPos = oldTarget:GetPosition()
  148.             local vPos = utilities.GetScaledDirectionVector(tPos, self.ImpactPos, scale)
  149.             local modPos = Vector(vPos[1] + tPos[1], tPos[2], vPos[3] + tPos[3])
  150.             if myDebug then
  151.                 LOG('impact x: ', self.ImpactPos[1],'impact y: ', self.ImpactPos[2],'impact z: ', self.ImpactPos[3])
  152.                 LOG('tPos x: ', tPos[1],'tPos y: ', tPos[2],'tPos z: ', tPos[3])
  153.                 LOG('vPos x: ', vPos[1],'vPos y: ', vPos[2],'vPos z: ', vPos[3])
  154.                 LOG('modPos x: ', modPos[1],'modPos y: ', modPos[2],'modPos z: ', modPos[3], 'scale: ', scale)
  155.             end
  156.             --local targets = utilities.GetEnemyUnitsInSphere( self, modPos, scale )
  157.             local targets = GetEntitiesInRect( Rect( modPos[1] - scale, modPos[3] - scale, modPos[1] + scale, modPos[3] + scale) )
  158.             --Filter out targets we've already chained to if any
  159.             if table.getsize(self.DmgUnitsTable) > 0 then
  160.                 for a, b in self.DmgUnitsTable do
  161.                     table.remove(targets, self.DmgUnitsTable[b])
  162.                 end
  163.             end
  164.             if myDebug then LOG('   Number of "filtered" targets found at range: ', scale, 'table size: ', table.getsize(targets)) end
  165.             if table.getsize(targets) < 1 then return nil end
  166.             --Sort the remaining targets by range
  167.             local sortTargByDist = {}
  168.             for a, b in targets do
  169.                 if not b:BeenDestroyed() and b:GetHealth() > 0 and b != instigator and b != oldTarget then
  170.                     table.insert(sortTargByDist, {dist = utilities.XZDistanceTwoVectors(self.ImpactPos, b:GetPosition()),id = b:GetEntityId() ,unit = b})
  171.                 end
  172.             end
  173.             table.sort(sortTargByDist, sort_by('dist'))
  174.             if myDebug then
  175.                 LOG('   Number of sorted targets: ', table.getsize(sortTargByDist))
  176.                 for c, d in sortTargByDist do
  177.                     LOG('       Unit: ', d.id, ' Distance: ', utilities.XZDistanceTwoVectors(self.ImpactPos, d.unit:GetPosition()) )
  178.                 end
  179.             end
  180.             return sortTargByDist
  181.         else
  182.             if myDebug then LOG('   Data passed is missing or invalid, returning nil') end
  183.             return nil
  184.         end
  185.     end,
  186.  
  187.     ChainLightningFX = function(self, target1, target2, army, duration)
  188.         local myDebug = false
  189.         if myDebug then LOG('*** ChainLightningFX ***') end
  190.         for a, b in self.FxBeamEndPoint do
  191.             if myDebug then LOG('   Impacts') end
  192.             local fx = CreateAttachedEmitter(target2, -1, army, b ):ScaleEmitter(self.FxBeamEndPointScale)
  193.             table.insert( self.BeamEffectsBag, fx)
  194.             table.insert( self.ChainFx, fx)
  195.             self.Trash:Add(fx)
  196.             target2.Trash:Add(fx)          
  197.         end
  198.         for c, d in self.FxBeam do
  199.             if target1 and not target1:BeenDestroyed() and target2 and not target2:BeenDestroyed() then
  200.                 if myDebug then LOG('   Beams') end
  201.                 local beam = AttachBeamEntityToEntity(target1, -1, target2, -1, army, d)
  202.                 local offset = 0.1
  203.                 if IsUnit(target2) then
  204.                     offSet = (target2:GetBlueprint().Physics.SizeY or 1) / 2
  205.                 end
  206.                 beam:OffsetEmitter(0, offset, 0)               
  207.                 table.insert(self.BeamEffectsBag, beam)
  208.                 table.insert(self.ChainFx, beam)               
  209.                 self.Trash:Add(beam)
  210.                 target2.Trash:Add(beam)
  211.             end
  212.         end
  213.         WaitSeconds(duration)
  214.         if self.ChainFx then
  215.             for e, f in self.ChainFx do
  216.                 f:Destroy()
  217.             end
  218.         end
  219.     end,
  220.  
  221.     ScorchThread = function(self)
  222.         local myDebug = false
  223.         if myDebug then LOG('*** ScorchThread ***') end
  224.         local army = self:GetArmy()
  225.         local CurrentPosition = self:GetPosition(1)
  226.         local LastPosition = Vector(0,0,0)
  227.         local skipCount = 1
  228.         while true do
  229.             if utilities.GetDistanceBetweenTwoVectors( CurrentPosition, LastPosition ) > 0.25 or skipCount > 100 then
  230.                 local size = utilities.GetRandomFloat( -self.ScorchSize , self.ScorchSize )
  231.                 CreateSplat( CurrentPosition, utilities.GetRandomFloat(0,2*math.pi), self.ScorchTexture, size, size, 25, 25, army )
  232.                 LastPosition = CurrentPosition
  233.                 skipCount = 1
  234.             else
  235.                 skipCount = skipCount + self.ScorchSplatDropTime
  236.             end
  237.             WaitSeconds( self.ScorchSplatDropTime or 0.1 )
  238.             CurrentPosition = self:GetPosition(1)
  239.         end
  240.     end,
  241.  
  242.     OnDisable = function( self )
  243.         local myDebug = false
  244.         if myDebug then LOG('*** OnDisable ***') end
  245.         CollisionBeam.OnDisable(self)
  246.         KillThread(self.Scorching)
  247.         KillThread(self.ChainLightningThread)
  248.         self.Scorching = nil
  249.     end,
  250. }
  251.  
  252. ------------------------------
  253. --  Chain Lighting beam for the Seraphem transformable heavy bot
  254. ------------------------------
  255.  
  256. xsl0310_LightningBeam = Class(CustomBeam) {
  257.     FxBeamStartPoint = EffectTemplate.SExperimentalUnstablePhasonLaserMuzzle01,
  258.     FxBeam = Custom_4D_EffectTemplate.LightingStrikeBeam,
  259.     FxBeamEndPoint = EffectTemplate.OthuyElectricityStrikeHit,
  260.     FxBeamEndPointScale = 0.1,
  261.     ScorchSize = 0.5,
  262.     ScorchSplatDropTime = 0.1,
  263.     ScorchTexture = 'czar_mark01_albedo',
  264.     TerrainImpactType = 'LargeBeam01',
  265.     TerrainImpactScale = 1,
  266. }
  267.  
  268. ------------------------------
  269. --  Green beam for the Cybran Vampire
  270. ------------------------------
  271.  
  272. VampireGreenLaserCollisionBeam = Class(CustomBeam) {
  273.  
  274.     FxBeam = {'/mods/4DC_FAF_Release/effects/Emitters/green_laser_beam_02_emit.bp'},
  275.     FxImpactUnit = {
  276.         '/mods/4DC_FAF_Release/effects/Emitters/green_hit_unit_emit.bp',
  277.         '/mods/4DC_FAF_Release/effects/Emitters/green_beam_hit_sparks_emit.bp',
  278.         EmtBpPath .. 'beam_hit_smoke_01_emit.bp',
  279.     },
  280.     FxUnitHitScale = 0.5,
  281.     FxImpactLand = {
  282.         EmtBpPath .. 'dirtchunks_01_emit.bp',
  283.         EmtBpPath .. 'dust_cloud_05_emit.bp',
  284.         EmtBpPath .. 'beam_hit_smoke_01_emit.bp',
  285.     },
  286.     FxLandHitScale = 0.5,
  287.     ScorchSplatDropTime = 1,
  288.     ScorchSize = 0.25,
  289.     ScorchTexture = 'czar_mark01_albedo',
  290.     TerrainImpactType = 'LargeBeam01',
  291.     TerrainImpactScale = 1,
  292.  
  293. }
Advertisement
Add Comment
Please, Sign In to add comment