-----------------------------------------------------------------------------
--  File     : /mods/4DC_V0.8/units/Singularity_Helper/Singularity_Helper_script.lua
--
--  Author(s): Resin Smoker, Mithy & Bulletmagnet
--
--  Summary  : Singularityn Helper unit
--
--  Note     : Unit based off ideas from JZ's Microcollapsar
--
--  Copyright © 2011 4DC_V0.8  All rights reserved.
-----------------------------------------------------------------------------

local Unit = import('/lua/sim/Unit.lua').Unit
local utilities = import('/lua/utilities.lua')
local EffectTemplate = import('/lua/EffectTemplates.lua')

Singularity_Helper = Class(Unit) {

-- File pathing and special paramiters called --------------------------- 
                                              
    -- Setup call backs between helper and parent
    Parent = nil,

    SetParent = function(self, parent, helperName)
        self.Parent = parent
        self.Helper = helperName
    end,

--------------------------------------------------------------------------    
                    
    OnCreate = function(self,builder,layer)
        Unit.OnCreate(self,builder,layer)
        -- Set helper unit to be non-vis and undamageable
        self:SetCanTakeDamage(false)         
        self:SetVizToAllies('Never') 
        self:SetVizToFocusPlayer('Never') 
        self:SetVizToNeutrals('Never')
        self:SetVizToEnemies('Never') 
    end,                        

    PassTargetToHelper = function( self, target, duration ) 
        -- Activate helper for a given target so long as the target isnt already attached to another helper
        if target and not target:BeenDestroyed() and duration > 0 and not target.HasHelper then
            if IsUnit(target) then
                -- Detach target if in transport
                if target:IsUnitState('Attached') then
                    target:DetachFrom()
                end
                -- Disable shields if active
                if target:ShieldIsOn() then
                    target:DisableShield()
                end
            end
            target.HasHelper = true
            self:ForkThread(self.HelperThread, target, duration) 
        else         
            self:Destroy() 
        end 
    end,
	
    HelperThread = function(self, target, duration)  
        self.LifeTimeThreadHandle = self:ForkThread(self.LifeTimeThread, target, duration) 
        -- Create the slider 
        local tx, ty, tz = unpack(target:GetPosition())
        local sx, sy, sz = unpack(self:GetPosition())
        local dx = sx - tx
        local dy = ty - sy
        local dz = sz - tz  
        self.Slider = CreateSlider(self, 'turret', dx, dy, dz, -1 , true) 
        self.Slider:SetSpeed(-1)
        self.Slider:SetGoal(dx, dy, dz)                  
        WaitFor(self.Slider)
        if not target:BeenDestroyed() then                 
	        -- Attach the slider
	        target:AttachBoneTo(-1, self, 'turret')                    
	        -- Move the slider          
	        local dist = VDist3(self:GetPosition(), target:GetPosition())
	        self.Slider:SetSpeed(1 + dist)
	        self.Slider:SetGoal(0,0,0)         
	        -- Create vacuum suck up from ground effects on the unit targetted
	        for k, v in EffectTemplate.ACollossusTractorBeamVacuum01 do
	            if IsUnit(target) then
	                CreateEmitterAtEntity( target, target:GetArmy(),v ):ScaleEmitter(0.25 * target:GetFootPrintSize()/0.5)
	                -- Spin the target wildly
	                self.Trash:Add(CreateRotator(self, 'turret', 'x', nil, 0, Random(-100, 100), 250)) 
	                self.Trash:Add(CreateRotator(self, 'turret', 'y', nil, 0, Random(-100, 100), 250))                          
	                self.Trash:Add(CreateRotator(self, 'turret', 'z', nil, 0, Random(-100, 100), 250))                 
	            end
	        end                          
	        WaitFor(self.Slider)
		        -- Give player the reclaimed mass & energy of the target
	        if not target:BeenDestroyed() then  	        
		        local bp = target:GetBlueprint()
		        local mass, energy
		        if bp.Economy.BuildCostMass and bp.Economy.BuildCostEnergy then
				    mass = bp.Economy.BuildCostMass 
				    energy = bp.Economy.BuildCostEnergy  			    
				else 			       			
				    mass = bp.Economy.ReclaimMassMax
		            energy = bp.Economy.ReclaimEnergyMax   
				end
		        if mass >= 1 then 
		            self:GetAIBrain():GiveResource('Mass', mass)
		        end          
		        if energy >= 1 then                       
		            self:GetAIBrain():GiveResource('Energy', energy)
		        end         
		        target:Destroy()           
		        self:Destroy()  
	        end
	    end       
    end,
       
    LifeTimeThread = function(self, target, duration)   
        -- Allows the helper unit to live a finite amount of time        
        WaitSeconds(duration)
        if not self:BeenDestroyed() then 
	        if target and not target:BeenDestroyed() then 
	            if target:IsUnitState('Attached') then           
	                target:DetachFrom()
	            end
	        end       
	        self:Destroy()
        end                   
    end,
    
    OnDestroy = function(self)
        -- Clears the helper from the parents table 
        if self.Parent and not self.Parent:IsDead() then 
            table.removeByValue(self.Parent.HelperTable, self) 
            self.Parent = nil 
        end
        -- Ends the LifeTime monitor       
        KillThread(self.LifeTimeThreadHandle)
        Unit.OnDestroy(self)
    end,     
}
TypeClass = Singularity_Helper