--[[#######################################################################
#  File	 :  /units/URL0405/URL0405_script.lua
#  Author(s):  John Comes, David Tomandl, Jessica St. Croix, Gordon Duclos
#  Summary  :  Cybran Spider Bot Script
#  -----------------------------
#  Modif.by :  AsdrubaelVect
#  Rev.Date :  5 septembre 2009
#  -----------------------------
#  Revis.by :  Manimal
#  Rev.Date :  20 novembre 2009
#  -----------------------------
#  Copyright © 2005 Gas Powered Games, Inc.  All rights reserved.
#######################################################################]]--
#######################################################################
local Game = import('/lua/game.lua')

#VARIABLE ''GLOBALE'' (par Manimal)
local MyModPath = Game.MyModPath
#######################################################################


local CWalkingLandUnit = import( MyModPath .. '/hook/lua/cybranunits.lua').CWalkingLandUnit

local Weapon = import('/lua/sim/Weapon.lua').Weapon
local CybranWeaponsFile = import('/lua/cybranweapons.lua')
local CDFHeavyMicrowaveLaserGenerator = CybranWeaponsFile.CDFHeavyMicrowaveLaserGenerator
local CDFElectronBolterWeapon = CybranWeaponsFile.CDFElectronBolterWeapon
local CAAMissileNaniteWeapon = CybranWeaponsFile.CAAMissileNaniteWeapon
local explosion = import('/lua/defaultexplosions.lua')
local CreateDeathExplosion = explosion.CreateDefaultHitExplosionAtBone
local EffectTemplate = import('/lua/EffectTemplates.lua')
local utilities = import('/lua/Utilities.lua')
local EffectUtil = import('/lua/EffectUtilities.lua')
local CANTorpedoLauncherWeapon = CybranWeaponsFile.CANTorpedoLauncherWeapon
local Entity = import('/lua/sim/Entity.lua').Entity

####UPGRADE02
local CDFHvyProtonCannonWeapon = CybranWeaponsFile.CDFHvyProtonCannonWeapon

local Buff = import('/lua/sim/Buff.lua')

local hasHEBI = false
local hasHEBII = false
local hasHEBI = false
local hasHEBIV = false
local hasHEBV = false

URL0405 = Class(CWalkingLandUnit) {
    WalkingAnimRate = 1.2,

    Weapons = {
        MainGun = Class(CDFHeavyMicrowaveLaserGenerator) {},
        RightLaserTurret = Class(CDFElectronBolterWeapon) {},
        LeftLaserTurret = Class(CDFElectronBolterWeapon) {},
        RightAntiAirMissile = Class(CAAMissileNaniteWeapon) {},
        LeftAntiAirMissile = Class(CAAMissileNaniteWeapon) {},
        Torpedo = Class(CANTorpedoLauncherWeapon) {},
		####UPGRADE02
		ParticleGunUpgrade02 = Class(CDFHvyProtonCannonWeapon) {},
		####UPGRADE04
		ParticleGunUpgrade04 = Class(CDFHvyProtonCannonWeapon) {},
		######UPGRADE05
		Upgrade05Gun = Class(CDFHeavyMicrowaveLaserGenerator) {},
    },
	
	OnCreate = function(self)
        CWalkingLandUnit.OnCreate(self)
		###UPGRADE01
		self:HideBone('Upgrade01_01', true)
		self:HideBone('Upgrade01_02', true)
		self:HideBone('Upgrade01_03', true)
		self:HideBone('Upgrade01_04', true)
		self:HideBone('Upgrade01_05', true)
		self:HideBone('Upgrade01_06', true)
		self:HideBone('Upgrade01_07', true)
		###UPGRADE02
		self:HideBone('Upgrade02_01', true)
		###UPGRADE03
		self:HideBone('Upgrade03_01', true)
		self:HideBone('Upgrade03_02', true)
		self:HideBone('Upgrade03_03', true)
		self:HideBone('Upgrade03_04', true)
		self:HideBone('Upgrade03_05', true)
		self:HideBone('Upgrade03_06', true)
		###UPGRADE04 
		self:HideBone('Upgrade04_01', true)
		###UPGRADE05 
		self:HideBone('Upgrade05_01', true)
		self.hasHEBI = false
		self.hasHEBII = false
		self.hasHEBIII = false
		self.hasHEBIV = false
		self.hasHEBV = false	
    end,	
    
    OnStartBeingBuilt = function(self, builder, layer)
        CWalkingLandUnit.OnStartBeingBuilt(self, builder, layer)
        if not self.AnimationManipulator then
            self.AnimationManipulator = CreateAnimator(self)
            self.Trash:Add(self.AnimationManipulator)
        end
        self.AnimationManipulator:PlayAnim(self:GetBlueprint().Display.AnimationActivate, false):SetRate(0)
    end,
     
    OnStopBeingBuilt = function(self,builder,layer)
        CWalkingLandUnit.OnStopBeingBuilt(self,builder,layer)
		####VET SYST
		self:SetWeaponEnabledByLabel('MainGun', true)
		self:SetWeaponEnabledByLabel('RightLaserTurret', true)
		self:SetWeaponEnabledByLabel('LeftLaserTurret', true)
		self:SetWeaponEnabledByLabel('RightAntiAirMissile', true)
		self:SetWeaponEnabledByLabel('LeftAntiAirMissile', true)
		####UPGRADE02
		self:SetWeaponEnabledByLabel('ParticleGunUpgrade02', false)
		####UPGRADE04
		self:SetWeaponEnabledByLabel('ParticleGunUpgrade04', false)
		####UPGRADE05
		self:SetWeaponEnabledByLabel('Upgrade05Gun', false)
		self.WeaponsEnabled = true
		self:AddUnitCallback(self.OnVeteran, 'OnVeteran') 
		###/VET SYSt
        if self.AnimationManipulator then
            self:SetUnSelectable(true)
            self.AnimationManipulator:SetRate(1)
            
            self:ForkThread(function()
                WaitSeconds(self.AnimationManipulator:GetAnimationDuration()*self.AnimationManipulator:GetRate())
                self:SetUnSelectable(false)
                self.AnimationManipulator:Destroy()
            end)
        end        
        self:SetMaintenanceConsumptionActive()
        local layer = self:GetCurrentLayer()
        if(layer == 'Land') then
            self:CreateUnitAmbientEffect(layer)
			if self.SonarEnt then
                self.SonarEnt:Destroy()
            end
	        self:SetWeaponEnabledByLabel('Torpedo', false)
        elseif (layer == 'Seabed') then
            self:CreateUnitAmbientEffect(layer)
            self:EnableUnitIntel('SonarStealth')
            self.SonarEnt = Entity {}
            self.Trash:Add(self.SonarEnt)
            self.SonarEnt:InitIntel(self:GetArmy(), 'Sonar', 76)
            self.SonarEnt:EnableIntel('Sonar')
            self.SonarEnt:AttachBoneTo(-1, self, 0)
	        self:SetWeaponEnabledByLabel('Torpedo', true)
        end
        self.WeaponsEnabled = true
    end,
	
	#Level#
	OnVeteran = function ( self )
        local bp = self:GetBlueprint()
		local enh = 'VeterancyI'
		local bpEnh = bp.ExpeWars_Enhancement[enh]
		if not bpEnh then return end
        local bpEnhEAVLevel = bpEnh.EnabledAtVeterancyLevel
		if bpEnhEAVLevel and bpEnhEAVLevel > 0 and ( self.VeteranLevel == bpEnhEAVLevel ) then
			if enh =='VeterancyI' then	
				###Speed 10%
				self:SetSpeedMult(bp.Physics.Upgrade01SpeedMultiplier)  
				###Meshe
				self:ShowBone('Upgrade01_01', true)
				self:ShowBone('Upgrade01_02', true)
				self:ShowBone('Upgrade01_03', true)
				self:ShowBone('Upgrade01_04', true)
				self:ShowBone('Upgrade01_05', true)
				self:ShowBone('Upgrade01_06', true)
				self:ShowBone('Upgrade01_07', true)
				hasHEBI = true
				hasHEBII = false
				hasHEBIII = false
				hasHEBIV = false
				hasHEBV = false	
				###HP 20%		
                BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFI',
                    DisplayName = 'CYBRANHEALTHBUFFI',
                    BuffType = 'MAXHEALTHI',
					Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
						Health = {
                            Add = 2500,
                            Mult = 1.0,
                        },
                    },
                }
            end
			Buff.ApplyBuff(self, 'CYBRANHEALTHBUFFI')
		end	
	##################################
        local bp = self:GetBlueprint()
		local enh = 'VeterancyII'
		local bpEnh = bp.ExpeWars_Enhancement[enh]
		if not bpEnh then return end
        local bpEnhEAVLevel = bpEnh.EnabledAtVeterancyLevel
		# ADDS MY CUSTOM ENHANCEMENT !
		if bpEnhEAVLevel and bpEnhEAVLevel > 0 and ( self.VeteranLevel == bpEnhEAVLevel ) then
			if enh =='VeterancyII' then

				###New Weapon	
				self:SetWeaponEnabledByLabel('ParticleGunUpgrade02', true)
				###Meshe
				self:ShowBone('Upgrade02_01', true)
				hasHEBI = true
				hasHEBII = true    # Signale HEB INSTALLÉ
				hasHEBIII = false
				hasHEBIV = false
				hasHEBV = false	
            BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFII',
                    DisplayName = 'CYBRANHEALTHBUFFII',
                    BuffType = 'MAXHEALTHII',
                    Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
                        Health = {
                            Add = 500,
                            Mult = 1.0,
                        },						
                    },
                }
            end
			Buff.ApplyBuff(self, 'CYBRANHEALTHBUFFII')
		end	
	##################################
        local bp = self:GetBlueprint()
		local enh = 'VeterancyIII'
		local bpEnh = bp.ExpeWars_Enhancement[enh]
		if not bpEnh then return end
        local bpEnhEAVLevel = bpEnh.EnabledAtVeterancyLevel
		# ADDS MY CUSTOM ENHANCEMENT !
		if bpEnhEAVLevel and bpEnhEAVLevel > 0 and ( self.VeteranLevel == bpEnhEAVLevel ) then
			if enh =='VeterancyIII' then	
				###Speed 10%
				self:SetSpeedMult(bp.Physics.Upgrade02SpeedMultiplier)  
				###Meshe
				self:ShowBone('Upgrade03_01', true)
				self:ShowBone('Upgrade03_02', true)
				self:ShowBone('Upgrade03_03', true)
				self:ShowBone('Upgrade03_04', true)
				self:ShowBone('Upgrade03_05', true)
				self:ShowBone('Upgrade03_06', true)
				hasHEBI = true
				hasHEBII = true
				hasHEBIII = true
				hasHEBIV = false
				hasHEBV = false		

                BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFIII',
                    DisplayName = 'CYBRANHEALTHBUFFIII',
                    BuffType = 'MAXHEALTHIII',
					Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
						Health = {
                            Add = 500,
                            Mult = 1.0,
                        },
                    },
                }
            end
			Buff.ApplyBuff(self, 'CYBRANHEALTHBUFFIII')
		end	
	##################################
        local bp = self:GetBlueprint()
		local enh = 'VeterancyIV'
		local bpEnh = bp.ExpeWars_Enhancement[enh]
		if not bpEnh then return end
        local bpEnhEAVLevel = bpEnh.EnabledAtVeterancyLevel
		# ADDS MY CUSTOM ENHANCEMENT !
		if bpEnhEAVLevel and bpEnhEAVLevel > 0 and ( self.VeteranLevel == bpEnhEAVLevel ) then
			if enh =='VeterancyIV' then
				###New Weapon	
				self:SetWeaponEnabledByLabel('ParticleGunUpgrade04', true)    
				###Meshe
				self:ShowBone('Upgrade04_01', true)
				hasHEBI = true
				hasHEBII = true
				hasHEBIII = true
				hasHEBIV = true
				hasHEBV = false
            BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFIV',
                    DisplayName = 'CYBRANHEALTHBUFFIV',
                    BuffType = 'MAXHEALTHIIV',
					Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
						Health = {
                            Add = 500,
                            Mult = 1.0,
                        },
                    },
                }
            end
			Buff.ApplyBuff(self, 'CYBRANHEALTHBUFFIV')
		end	
	##################################
        local bp = self:GetBlueprint()
		local enh = 'VeterancyV'
		local bpEnh = bp.ExpeWars_Enhancement[enh]
		if not bpEnh then return end
        local bpEnhEAVLevel = bpEnh.EnabledAtVeterancyLevel
		# ADDS MY CUSTOM ENHANCEMENT !
		if bpEnhEAVLevel and bpEnhEAVLevel > 0 and ( self.VeteranLevel == bpEnhEAVLevel ) then
			if enh =='VeterancyV' then	
				###Meshe
				self:ShowBone('Upgrade05_01', true)
				###WEAPON
				self:SetWeaponEnabledByLabel('Upgrade05Gun', true)
				hasHEBI = true  
				hasHEBII = true    # Signale HEB INSTALLÉ
				hasHEBIII = true	
				hasHEBIV = true
				hasHEBV = true
                BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFV',
                    DisplayName = 'CYBRANHEALTHBUFFV',
                    BuffType = 'MAXHEALTHV',
                    Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
                        Health = {
                            Add = 2000,
                            Mult = 1.0,
                        },						
                    },
                }
            end
			Buff.ApplyBuff(self, 'CYBRANHEALTHBUFFV')
		end		
	end,		

	OnLayerChange = function(self, new, old)
		CWalkingLandUnit.OnLayerChange(self, new, old)
		if self.WeaponsEnabled then
			if( new == 'Land' ) then
			    self:CreateUnitAmbientEffect(new)
			    if self.SonarEnt then
                    self.SonarEnt:Destroy()
                end
	            self:SetWeaponEnabledByLabel('Torpedo', false)
			elseif ( new == 'Seabed' ) then
			    self:CreateUnitAmbientEffect(new)
			    if self.SonarEnt then
                    self.SonarEnt:Destroy()
                end
                self.SonarEnt = Entity {}
                self.Trash:Add(self.SonarEnt)
                self.SonarEnt:InitIntel(self:GetArmy(), 'Sonar', 76)
                self.SonarEnt:EnableIntel('Sonar')
                self.SonarEnt:AttachBoneTo(-1, self, 0)
	            self:SetWeaponEnabledByLabel('Torpedo', true)
			end
		end
	end,
	
    AmbientExhaustBones = {
		'Exhaust01',
		'Exhaust02',
		'Exhaust03',
		'Exhaust06',
		'Exhaust05',
    },	
    
    AmbientLandExhaustEffects = {
		'/effects/emitters/dirty_exhaust_smoke_02_emit.bp',
		'/effects/emitters/dirty_exhaust_sparks_02_emit.bp',			
	},
	
    AmbientSeabedExhaustEffects = {
		'/effects/emitters/underwater_vent_bubbles_02_emit.bp',			
	},	
	
	CreateUnitAmbientEffect = function(self, layer)
	    if( self.AmbientEffectThread != nil ) then
	       self.AmbientEffectThread:Destroy()
        end	 
        if self.AmbientExhaustEffectsBag then
            EffectUtil.CleanupEffectBag(self,'AmbientExhaustEffectsBag')
        end        
        
        self.AmbientEffectThread = nil
        self.AmbientExhaustEffectsBag = {} 
	    if layer == 'Land' then
	        self.AmbientEffectThread = self:ForkThread(self.UnitLandAmbientEffectThread)
	    elseif layer == 'Seabed' then
	        local army = self:GetArmy()
			for kE, vE in self.AmbientSeabedExhaustEffects do
				for kB, vB in self.AmbientExhaustBones do
					table.insert( self.AmbientExhaustEffectsBag, CreateAttachedEmitter(self, vB, army, vE ))
				end
			end	        
	    end          
	end, 
	
	UnitLandAmbientEffectThread = function(self)
		while not self:IsDead() do
            local army = self:GetArmy()			
			
			for kE, vE in self.AmbientLandExhaustEffects do
				for kB, vB in self.AmbientExhaustBones do
					table.insert( self.AmbientExhaustEffectsBag, CreateAttachedEmitter(self, vB, army, vE ))
				end
			end
			
			WaitSeconds(2)
			EffectUtil.CleanupEffectBag(self,'AmbientExhaustEffectsBag')
							
			WaitSeconds(utilities.GetRandomFloat(1,7))
		end		
	end,

    OnKilled = function(self, inst, type, okr)
        self.Trash:Destroy()
        self.Trash = TrashBag()
        if self.AmbientExhaustEffectsBag then
            EffectUtil.CleanupEffectBag(self,'AmbientExhaustEffectsBag')
        end
        CWalkingLandUnit.OnKilled(self, inst, type, okr)
    end,

    CreateDamageEffects = function(self, bone, army )
        for k, v in EffectTemplate.DamageFireSmoke01 do
            CreateAttachedEmitter( self, bone, army, v ):ScaleEmitter(1.5)
        end
    end,

    CreateDeathExplosionDustRing = function( self )
        local blanketSides = 18
        local blanketAngle = (2*math.pi) / blanketSides
        local blanketStrength = 1
        local blanketVelocity = 2.8

        for i = 0, (blanketSides-1) do
            local blanketX = math.sin(i*blanketAngle)
            local blanketZ = math.cos(i*blanketAngle)

            local Blanketparts = self:CreateProjectile('/effects/entities/DestructionDust01/DestructionDust01_proj.bp', blanketX, 1.5, blanketZ + 4, blanketX, 0, blanketZ)
                :SetVelocity(blanketVelocity):SetAcceleration(-0.3)
        end        
    end,

    CreateFirePlumes = function( self, army, bones, yBoneOffset )
        local proj, position, offset, velocity
        local basePosition = self:GetPosition()
        for k, vBone in bones do
            position = self:GetPosition(vBone)
            offset = utilities.GetDifferenceVector( position, basePosition )
            velocity = utilities.GetDirectionVector( position, basePosition ) # 
            velocity.x = velocity.x + utilities.GetRandomFloat(-0.3, 0.3)
            velocity.z = velocity.z + utilities.GetRandomFloat(-0.3, 0.3)
            velocity.y = velocity.y + utilities.GetRandomFloat( 0.0, 0.3)
            proj = self:CreateProjectile('/effects/entities/DestructionFirePlume01/DestructionFirePlume01_proj.bp', offset.x, offset.y + yBoneOffset, offset.z, velocity.x, velocity.y, velocity.z)
            proj:SetBallisticAcceleration(utilities.GetRandomFloat(-1, -2)):SetVelocity(utilities.GetRandomFloat(3, 4)):SetCollision(false)
            
            local emitter = CreateEmitterOnEntity(proj, army, '/effects/emitters/destruction_explosion_fire_plume_02_emit.bp')

            local lifetime = utilities.GetRandomFloat( 12, 22 )
        end
    end,

    CreateExplosionDebris = function( self, army )
        for k, v in EffectTemplate.ExplosionDebrisLrg01 do
            CreateAttachedEmitter( self, 'URL0402', army, v )
        end
    end,

    DeathThread = function(self)
        self:PlayUnitSound('Destroyed')
        local army = self:GetArmy()

        # Create Initial explosion effects
        explosion.CreateFlash( self, 'Center_Turret01', 4.5, army )
        CreateAttachedEmitter(self, 'URL0402', army, '/effects/emitters/destruction_explosion_concussion_ring_03_emit.bp')
        CreateAttachedEmitter(self,'URL0402', army, '/effects/emitters/explosion_fire_sparks_02_emit.bp')
        self:CreateFirePlumes( army, {'Center_Turret01'}, 0 )

        self:CreateFirePlumes( army, {'Right_Leg01_B01','Right_Leg03_B01','Left_Leg03_B01',}, 0.5 )

        self:CreateExplosionDebris( army )
        self:CreateExplosionDebris( army )
        self:CreateExplosionDebris( army )

        WaitSeconds(1)
        
        # Create damage effects on turret bone
        CreateDeathExplosion( self, 'Center_Turret01', 1.5)
        self:CreateDamageEffects( 'URL0402bis', army )
        self:CreateDamageEffects( 'URL0402bis', army )

        WaitSeconds( 1 )
        self:CreateFirePlumes( army, {'Right_Leg01_B01','Right_Leg03_B01','Left_Leg03_B01',}, 0.5 )
        WaitSeconds(0.3)
        self:CreateDeathExplosionDustRing()
        WaitSeconds(0.4)


        # When the spider bot impacts with the ground
        # Effects: Explosion on turret, dust effects on the muzzle tip, large dust ring around unit
        # Other: Damage force ring to force trees over and camera shake
        self:ShakeCamera(50, 5, 0, 1)
        CreateDeathExplosion( self, 'Left_Turret_Muzzle', 1)
        for k, v in EffectTemplate.FootFall01 do
            CreateAttachedEmitter(self,'Center_Turret_Muzzle01',army, v):ScaleEmitter(2)          
            CreateAttachedEmitter(self,'Center_Turret_Muzzle01',army, v):ScaleEmitter(2) 
        end


        self:CreateExplosionDebris( army )
        self:CreateExplosionDebris( army )

        local x, y, z = unpack(self:GetPosition())
        z = z + 3
        DamageRing(self, {x,y,z}, 0.1, 3, 1, 'Force', true)
        WaitSeconds(0.5)
        CreateDeathExplosion( self, 'Center_Turret01', 2)

        # Finish up force ring to push trees
        DamageRing(self, {x,y,z}, 0.1, 3, 1, 'Force', true)

        # Explosion on and damage fire on various bones
        CreateDeathExplosion( self, 'Right_Leg0' .. Random(1,3) .. '_B0' .. Random(1,3), 0.25)
        CreateDeathExplosion( self, 'Left_Projectile01', 2)
        self:CreateFirePlumes( army, {'Left_Projectile01'}, -1 )
        self:CreateDamageEffects( 'Right_Turret', army )
        WaitSeconds(0.5)
        
        CreateDeathExplosion( self, 'Left_Leg0' .. Random(1,3) .. '_B0' .. Random(1,3), 0.25)
        self:CreateDamageEffects( 'Right_Leg01_B03', army )
        WaitSeconds(0.5)
        CreateDeathExplosion( self, 'Left_Turret_Muzzle', 1)
        self:CreateExplosionDebris( army )
        
        CreateDeathExplosion( self, 'Right_Leg0' .. Random(1,3) .. '_B0' .. Random(1,3), 0.25)
        self:CreateDamageEffects( 'Right_Projectile0' .. Random(1,2), army )
        WaitSeconds(0.5)
        
        CreateDeathExplosion( self, 'Left_Leg0' .. Random(1,3) .. '_B0' .. Random(1,3), 0.25)
        CreateDeathExplosion( self, 'Left_Projectile01', 2 )
        self:CreateDamageEffects( 'Left_Leg03_B03', army )

        self:CreateWreckage(0.1)
        self:Destroy()
    end,
}

TypeClass = URL0405
