--[[#######################################################################
#  File	 :  /units/XRL0405/XRL0405_script.lua
#  Author(s):  GPG Devs
#  Summary  :  Megalith 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 MobileUnit = import('/lua/defaultunits.lua').MobileUnit
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 Entity = import('/lua/sim/Entity.lua').Entity

local Weapon = import('/lua/sim/Weapon.lua').Weapon
local CybranWeaponsFile = import('/lua/cybranweapons.lua')
local CDFHvyProtonCannonWeapon = CybranWeaponsFile.CDFHvyProtonCannonWeapon
local CANNaniteTorpedoWeapon = CybranWeaponsFile.CANNaniteTorpedoWeapon
local CIFSmartCharge = CybranWeaponsFile.CIFSmartCharge
local CAABurstCloudFlakArtilleryWeapon = CybranWeaponsFile.CAABurstCloudFlakArtilleryWeapon
###UPGRADE02
local CDFElectronBolterWeapon1 = CybranWeaponsFile.CDFElectronBolterWeapon
local CDFElectronBolterWeapon2 = CybranWeaponsFile.CDFElectronBolterWeapon
local Effects = import('/lua/effecttemplates.lua')

###04
local CybranModWeaponsFile = import( MyModPath .. '/hook/lua/cybranmoddedweapons.lua')
local CDFHvyBFGWeapon = CybranModWeaponsFile.CDFHvyBFGWeapon
###05
local CDFRocketIridiumWeapon02 = import('/lua/cybranweapons.lua').CDFRocketIridiumWeapon02

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

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

XRL0405 = Class(CWalkingLandUnit) {
    WalkingAnimRate = 1.2,

    Weapons = {
        ParticleGunRight = Class(CDFHvyProtonCannonWeapon) {},
        ParticleGunLeft = Class(CDFHvyProtonCannonWeapon) {},
        Torpedo01 = Class(CANNaniteTorpedoWeapon) {},
        Torpedo02 = Class(CANNaniteTorpedoWeapon) {},
        Torpedo03 = Class(CANNaniteTorpedoWeapon) {},
        Torpedo04 = Class(CANNaniteTorpedoWeapon) {},
        AntiTorpedo = Class(CIFSmartCharge) {},
        --AAGun = Class(CAABurstCloudFlakArtilleryWeapon) {},
		###UPGRADE02
		Bolter01 = Class(CDFElectronBolterWeapon1) {
			PlayFxWeaponPackSequence = function(self)
                if self.SpinManip then
                    self.SpinManip:SetTargetSpeed(0)
                end
                self.ExhaustEffects = EffectUtil.CreateBoneEffects( self.unit, 'BolterLeft01', self.unit:GetArmy(), Effects.WeaponSteam01 )
                CDFElectronBolterWeapon1.PlayFxWeaponPackSequence(self)
            end,
        
            PlayFxRackSalvoChargeSequence = function(self)
                if not self.SpinManip then 
                    self.SpinManip = CreateRotator(self.unit, 'LeftBolterRotator01', 'z', nil, 240, 150, 160)
                    self.unit.Trash:Add(self.SpinManip)
                end
                
                if self.SpinManip then
                    self.SpinManip:SetTargetSpeed(600)
                end
                CDFElectronBolterWeapon1.PlayFxRackSalvoChargeSequence(self)
            end,            
            
            PlayFxRackSalvoReloadSequence = function(self)
                if self.SpinManip then
                    self.SpinManip:SetTargetSpeed(0)
                end
                self.ExhaustEffects = EffectUtil.CreateBoneEffects( self.unit, 'BolterLeft01', self.unit:GetArmy(), Effects.WeaponSteam01 )
                CDFElectronBolterWeapon1.PlayFxRackSalvoChargeSequence(self)
            end,
		},
		
		Bolter02 = Class(CDFElectronBolterWeapon2) {
		
			PlayFxWeaponPackSequence = function(self)
                if self.SpinManip1 then
                    self.SpinManip1:SetTargetSpeed(0)
                end
                self.ExhaustEffects1 = EffectUtil.CreateBoneEffects( self.unit, 'BolterRight01', self.unit:GetArmy(), Effects.WeaponSteam01 )
                CDFElectronBolterWeapon2.PlayFxWeaponPackSequence(self)
            end,
        
            PlayFxRackSalvoChargeSequence = function(self)
                if not self.SpinManip1 then 
                    self.SpinManip1 = CreateRotator(self.unit, 'RightBolterRotator01', 'z', nil, -240, -150, -160)
                    self.unit.Trash:Add(self.SpinManip1)
                end
                
                if self.SpinManip1 then
                    self.SpinManip1:SetTargetSpeed(-600)
                end
                CDFElectronBolterWeapon2.PlayFxRackSalvoChargeSequence(self)
            end,            
            
            PlayFxRackSalvoReloadSequence = function(self)
                if self.SpinManip1 then
                    self.SpinManip1:SetTargetSpeed(-0)
                end
                self.ExhaustEffects1 = EffectUtil.CreateBoneEffects( self.unit, 'BolterRight01', self.unit:GetArmy(), Effects.WeaponSteam01 )
                CDFElectronBolterWeapon2.PlayFxRackSalvoChargeSequence(self)
            end,
		},
		###
		BFGunRight = Class(CDFHvyBFGWeapon) {},
		BFGunLeft = Class(CDFHvyBFGWeapon) {},
		###UPGRADE05
		MissileRack = Class(CDFRocketIridiumWeapon02) {},
    },
    
	OnCreate = function(self)
        CWalkingLandUnit.OnCreate(self)
		###UPGRADE01
		self:HideBone('Upgrade01_01', true)
		###UPGRADE02
		self:HideBone('Upgrade02_01', true)
		self:HideBone('Upgrade02_02', true)
		###UPGRADE03
		self:HideBone('Upgrade03_01', true)
		###UPGRADE04 
		self:HideBone('Upgrade04_01', true)
		self:HideBone('Upgrade04_02', 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('ParticleGunRight', true)
		self:SetWeaponEnabledByLabel('ParticleGunLeft', true)
		self:SetWeaponEnabledByLabel('Torpedo01', true)
		self:SetWeaponEnabledByLabel('Torpedo02', true)
		self:SetWeaponEnabledByLabel('Torpedo03', true)
		self:SetWeaponEnabledByLabel('Torpedo04', true)
		self:SetWeaponEnabledByLabel('AntiTorpedo', true)
		####UPGRADE02
		self:SetWeaponEnabledByLabel('Bolter01', false)
		self:SetWeaponEnabledByLabel('Bolter02', false)
		####UPGRADE04
		self:SetWeaponEnabledByLabel('BFGunRight', false)
		self:SetWeaponEnabledByLabel('BFGunLeft', false)
		####UPGRADE05
		self:SetWeaponEnabledByLabel('MissileRack', false)
		self:AddUnitCallback(self.OnVeteran, 'OnVeteran') 
		###/VET SYSt
        local layer = self:GetCurrentLayer()
        # If created with F2 on land, then play the transform anim.
        if(layer == 'Land') then
	        self:SetWeaponEnabledByLabel('AAGun', true)       
			# Disable Torpedo
	        self:SetWeaponEnabledByLabel('Torpedo01', false)
        elseif (layer == 'Seabed') then
            self:EnableUnitIntel('SonarStealth')
			# Enable Torpedo
	        self:SetWeaponEnabledByLabel('Torpedo01', true)      
        end
        self.WeaponsEnabled = true      
        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
    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	
				###Health 20%
				 
				###Meshe
				self:ShowBone('Upgrade01_01', 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 = {
						MaxHealth = {
                            Add = 10000,
                            Mult = 1.0,
                        },
						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('Bolter01', true)
				self:SetWeaponEnabledByLabel('Bolter02', true)
				###Meshe
				self:ShowBone('Upgrade02_01', true)
				self:ShowBone('Upgrade02_02', 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	
				###Meshe
				self:ShowBone('Upgrade03_01', true)
				hasHEBI = true
				hasHEBII = true
				hasHEBIII = true
				hasHEBIV = false
				hasHEBV = false		

                BuffBlueprint {
                    Name = 'CYBRANHEALTHBUFFIII',
                    DisplayName = 'CYBRANHEALTHBUFFIII',
                    BuffType = 'MAXHEALTHIII',
					Stacks = 'REPLACE',
                    Duration = -1,
                    Affects = {
						MaxHealth = {
                            Add = 2000,
                            Mult = 1.0,
                        },
						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('BFGunRight', true)    
				self:SetWeaponEnabledByLabel('BFGunLeft', true)    
				###Meshe
				self:ShowBone('Upgrade04_01', true)
				self:ShowBone('Upgrade04_02', 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)
				###MissileRack
				self:SetWeaponEnabledByLabel('MissileRack', 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
			local LandSpeedMult = self:GetBlueprint().Physics.WaterSpeedMultiplier
			if( new == 'Land' ) then
				# Enable Land weapons
			    if self.SonarEnt then
                    self.SonarEnt:Destroy()
                end
			    # Disable Torpedo
	            self:SetWeaponEnabledByLabel('Torpedo01', false)
    	        self:SetWeaponEnabledByLabel('AAGun', true)
	 	  	  # Set movement speed back to default
              self:SetSpeedMult(1)
			elseif ( new == 'Seabed' ) then
				# Enable Torpedo
	            self:SetWeaponEnabledByLabel('Torpedo01', true)
	 			# Increase speed while in water
              self:SetSpeedMult(LandSpeedMult)
			end
		end
	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, 'XRL0403', army, v ):OffsetEmitter( 0, 5, 0 )
        end
    end,

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

        # Create Initial explosion effects
        explosion.CreateFlash( self, 'Left_Leg01_B01', 4.5, army )
        CreateAttachedEmitter(self, 'XRL0403', army, '/effects/emitters/destruction_explosion_concussion_ring_03_emit.bp'):OffsetEmitter( 0, 5, 0 )
        CreateAttachedEmitter(self,'XRL0403', army, '/effects/emitters/explosion_fire_sparks_02_emit.bp'):OffsetEmitter( 0, 5, 0 )
        CreateAttachedEmitter(self,'XRL0403', army, '/effects/emitters/distortion_ring_01_emit.bp')
        self:CreateFirePlumes( army, {'XRL0403'}, 0 )

        self:CreateFirePlumes( army, {'Right_Leg01_B01','Right_Leg02_B01','Left_Leg02_B01',}, 0.5 )

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

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

        WaitSeconds( 1 )
        self:CreateFirePlumes( army, {'Right_Leg01_B01','Right_Leg02_B01','Left_Leg02_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(40, 4, 1, 3.8)
        CreateDeathExplosion( self, 'Left_Turret_Barrel', 1)

        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, 'Right_Turret', 2)

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

        local bp = self:GetBlueprint()
        for i, numWeapons in bp.Weapon do
            if(bp.Weapon[i].Label == 'MegalithDeath') then
                DamageArea(self, self:GetPosition(), bp.Weapon[i].DamageRadius, bp.Weapon[i].Damage, bp.Weapon[i].DamageType, bp.Weapon[i].DamageFriendly)
                break
            end
        end

        # Explosion on and damage fire on various bones
        CreateDeathExplosion( self, 'Right_Leg0' .. Random(1,2) .. '_B0' .. Random(1,2), 0.25)
        CreateDeathExplosion( self, 'Flare_Muzzle03', 2)
        self:CreateFirePlumes( army, {'Torpedo_Muzzle11'}, -1 )
        self:CreateDamageEffects( 'Right_Turret', army )
        WaitSeconds(0.5)
        
        CreateDeathExplosion( self, 'Left_Leg0' .. Random(1,2) .. '_B0' .. Random(1,2), 0.25)
        self:CreateDamageEffects( 'Right_Footfall_02', army )
        WaitSeconds(0.5)
        CreateDeathExplosion( self, 'Left_Turret_Muzzle01', 1)
        self:CreateExplosionDebris( army )
        
        CreateDeathExplosion( self, 'Right_Leg0' .. Random(1,2) .. '_B0' .. Random(1,2), 0.25)
        self:CreateDamageEffects( 'Torpedo_Muzzle01', army )
        WaitSeconds(0.5)
        
        CreateDeathExplosion( self, 'Left_Leg0' .. Random(1,2) .. '_B0' .. Random(1,2), 0.25)
        CreateDeathExplosion( self, 'Flare_Muzzle06', 2 )
        self:CreateDamageEffects( 'Left_Leg02_B02', army )
        explosion.CreateFlash( self, 'Right_Leg01_B01', 3.2, army )        

        self:CreateWreckage(0.1)
        self:ShakeCamera(3, 2, 0, 0.15)
        self:Destroy()
    end,
    
    
    OnMotionHorzEventChange = function( self, new, old )
        CWalkingLandUnit.OnMotionHorzEventChange(self, new, old)
        
        if ( old == 'Stopped' ) then
            local bpDisplay = self:GetBlueprint().Display
            if bpDisplay.AnimationWalk and self.Animator then
                self.Animator:SetDirectionalAnim(true)
                self.Animator:SetRate(bpDisplay.AnimationWalkRate)
            end
         end
    end,
}

TypeClass = XRL0405
