protected override void FireWeapon( UnitWeaponSystem _weaponSys ,
							  			NamedObject _TargetUnit )
    {
        if( true == GlobalSingleton.GetGlobalSingletonObj().GetComponent<AutoPlayMachine>().m_Active )
            return ;

        string weaponComponent = "" ;
        // check phaser
        weaponComponent = _weaponSys.FindAbleWeaponComponent( RandomAWeaponKeyword() ,
                                                             _TargetUnit.Name ) ;

        if( 0 == weaponComponent.Length )
        {
            // Debug.Log( "FireWeapon() no available weapon" ) ;
            this.SetState( AI_Fire_State.MoveToTarget ) ;
            return ;
        }

        // fire
        if( true == _weaponSys.ActiveWeapon( weaponComponent ,
                                             _TargetUnit ,
                                             ConstName.UnitDataComponentUnitIntagraty ) )
        {
            this.SetState( AI_Fire_State.WaitForReload ) ;
        }
    }
    // 檢查武器並移動 , 會檢查是在範圍內 還是不能發射
    protected override bool CheckWeaponAndMoveToTarget( UnitData _unitData , 
													   UnitWeaponSystem _weaponSys ,
													   Vector3 _TargetPosition )
    {
        string weaponInRange = "" ;
        Vector3 vecToTarget = Vector3.zero ;
        Vector3 norVecToTarget = Vector3.zero ;
        float angleOfTarget = 0.0f ;
        float dotOfUp = 0.0f ;
        string IMPLUSE_ENGINE_RATIO = ConstName.UnitDataComponentImpulseEngineRatio ;

        // 剛轉換過來不要檢查武器
        if( m_State.ElapsedFromLast() > 0.5f )
        {
            // check fire phaser weapon is available
            weaponInRange = _weaponSys.FindAbleToShootTargetWeaponComponent( RandomAWeaponKeyword() ,
                                                                  m_TargetNow.Obj ) ;
            // Debug.Log( "weaponInRange=" + weaponInRange) ;
            if( 0 != weaponInRange.Length )
            {
                this.SetState( AI_Fire_State.StopAndFireToTarget ) ;
                return true ;
            }
        }

        // move to target
        if( true == MathmaticFunc.FindTargetRelation( this.gameObject ,
                                                     _TargetPosition ,
                                                     ref vecToTarget ,
                                                     ref norVecToTarget ,
                                                     ref angleOfTarget ,
                                                     ref dotOfUp ) )
        {
            if( true == _unitData.standardParameters.ContainsKey( IMPLUSE_ENGINE_RATIO ) )
            {
                // speed to maximum
                if( vecToTarget.sqrMagnitude > m_MaximumWeaponRange * m_MaximumWeaponRange )
                    _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].ToMax() ;
                else
                    _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].Clear() ;
            }

            // angular speed
            _unitData.AngularRatioHeadTo( angleOfTarget ,
                                          dotOfUp ,
                                          0.1f ) ;
        }

        return false ;
    }
    // 前往第二目標
    protected bool CheckMoveToTarget( UnitData _unitData , 
									  UnitWeaponSystem _weaponSys ,
									  Vector3 _TargetPosition , 
									  float _ImpulseSpeed = 1.0f )
    {
        Vector3 vecToTarget = Vector3.zero ;
        Vector3 norVecToTarget = Vector3.zero ;
        float angleOfTarget = 0.0f ;
        float dotOfUp = 0.0f ;
        string IMPLUSE_ENGINE_RATIO = ConstName.UnitDataComponentImpulseEngineRatio ;

        if( true == MathmaticFunc.FindTargetRelation( this.gameObject ,
                                                     _TargetPosition ,
                                                     ref vecToTarget ,
                                                     ref norVecToTarget ,
                                                     ref angleOfTarget ,
                                                     ref dotOfUp ) )
        {

            if( vecToTarget.sqrMagnitude < m_ReachDistanceSquare )
            {
                this.SetState( AI_Fire_State.MoveToTarget ) ;
                return true ;
            }

            if( true == _unitData.standardParameters.ContainsKey( IMPLUSE_ENGINE_RATIO ) )
            {
                _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].now =
                    _unitData.standardParameters[ IMPLUSE_ENGINE_RATIO ].max * _ImpulseSpeed ;

            }

            // angular speed
            _unitData.AngularRatioHeadTo( angleOfTarget ,
                                          dotOfUp ,
                                          0.1f ) ;

        }

        return false ;
    }
    // 發射武器
    protected override void FireWeapon( UnitWeaponSystem _weaponSys ,
							   		   NamedObject _TargetObject )
    {
        string weaponComponent = "" ;
        // check phaser
        weaponComponent = _weaponSys.FindAbleWeaponComponent( RandomAWeaponKeyword() ,
                                                              _TargetObject.Name ) ;
        if( 0 == weaponComponent.Length )
        {
            // no available weapon
            this.SetState( AI_Fire_State.MoveToTarget ) ;
            return ;
        }

        // fire
        if( true == _weaponSys.ActiveWeapon( weaponComponent ,
                                             _TargetObject ,
                                             ConstName.UnitDataComponentUnitIntagraty ) )
        {
            this.SetState( AI_Fire_State.WaitForReload ) ;
        }
    }
    /*
    # 在函式 TryFireWeapon() 中,呼叫武器系統 依照關鍵字 取得 可以發射的武器部件
    # 在函式 TryFireWeapon() 中,呼叫武器系統 傳入 武器部件名稱 目標船艦名稱 發射武器
    # 失敗時發出警告聲
    # 失敗時顯示武器範圍
    */
    private bool TryFireWeapon( UnitWeaponSystem _WeaponSys , 
								string _WeaponKeyword ,
								SelectInformation _SelectionInfo )
    {
        // find correct weapon
        string TargetComponentObjectName = ConstName.CreateComponent3DObjectName( _SelectionInfo.TargetUnitName ,
                                                                                  _SelectionInfo.m_TargetComponentName ) ;
        string mainCause = "" ;
        string weaponComponentName = _WeaponSys.FindAbleWeaponComponent( _WeaponKeyword ,
                                                                         TargetComponentObjectName ,
                                                                         ref mainCause ) ;
        bool ret = false ;
        // Debug.Log( "ActiveTrackorBeam3() weaponComponentName=" + weaponComponentName ) ;
        if( false == ( ret = _WeaponSys.ActiveWeapon( weaponComponentName ,
                                       		  		  _SelectionInfo.GetTargetUnit() ,
                                                      _SelectionInfo.m_TargetComponentName ) ) )
        {
            // fire weapon fail : beep
            if( null != m_Audio_WeaponFailBeep )
            {
                // show weapon range
                ShowWeaponRange( _WeaponKeyword ) ;

                this.gameObject.audio.PlayOneShot( m_Audio_WeaponFailBeep ) ;

                MessageQueueManager manager = GlobalSingleton.GetMessageQueueManager() ;
                if( null != manager )
                    manager.AddMessage( mainCause ) ;
            }
        }
        return ret ;
    }
    // 取得最大的武器清單,並依照排序
    private List<string> RetrievePossibleWeaponListInOrder( UnitData _unitData , 
															UnitWeaponSystem _weaponSys )
    {
        List<string> ret = new List<string>() ;
        List<string> allWeapens = _unitData.GetAllWeaponComponentNameVec() ;
        List<string> realWeapons = new List<string>() ;

        // 剔除trackor beam
        foreach( string weapon in allWeapens )
        {
            if( -1 == weapon.IndexOf( ConstName.UnitDataComponentWeaponTrackorBeamPrefix ) )
            {
                // no trackor beam
                realWeapons.Add( weapon ) ;
            }
        }

        while( realWeapons.Count > 0 )
        {
            // 找最遠的
            float maxRange = -1 ;
            string maxRangeString = "" ;
            foreach( string weapon in realWeapons )
            {

                float rangeThis = _unitData.componentMap[ weapon ].m_WeaponParam.m_Range ;
                if( rangeThis > maxRange )
                {
                    maxRange = rangeThis ;
                    maxRangeString = weapon ;
                }
            }
            realWeapons.Remove( maxRangeString ) ;
            ret.Add( maxRangeString ) ;
        }

        return ret ;
    }
    private string FindMostCloestWeaponComponent( UnitData _unitData ,
												  UnitWeaponSystem _weaponSys ,
												  NamedObject _possibleUnit ,
												  List<string> _possibleWeaponList ,													
												  ref Dictionary<string , SelectInformation> _fireList )
    {
        string ret = "" ;

        Dictionary<string,float> angleMap = new Dictionary<string, float>() ;
        foreach( string weaponComponentName in _possibleWeaponList )
        {
            // Debug.Log( "weaponComponentName=" + weaponComponentName ) ;
            if( false == _weaponSys.m_WeaponDataMap.ContainsKey( weaponComponentName ) )
            {
                continue ;
            }

            // no trackor beam
            if( -1 != weaponComponentName.IndexOf( ConstName.UnitDataComponentWeaponTrackorBeamPrefix ) )
            {
                continue ;
            }
            if( true == _fireList.ContainsKey( weaponComponentName ) )
            {
                // 如果已經用掉了就跳過不作
                continue ;
            }

            if( 0 !=
                ( _weaponSys.FindAbleWeaponComponent( weaponComponentName , _possibleUnit.Obj ) ).Length
                )
            {

                WeaponDataSet weapenDataSet = _weaponSys.m_WeaponDataMap[ weaponComponentName ] ;
                Vector3 toTargetVec = _possibleUnit.Obj.transform.position - this.gameObject.transform.position ;
                Vector3 toComponentVec = weapenDataSet.Component3DObject.transform.position - this.gameObject.transform.position ;
                float angle = Vector3.Angle( toComponentVec , toTargetVec ) ;
                angleMap[ weaponComponentName ] = angle ;
                // Debug.Log( "toComponentVec=" + toComponentVec ) ;
                // Debug.Log( "toTargetVec=" + toTargetVec ) ;
                // Debug.Log( "angleMap[ weaponComponentName ]=" + angle ) ;
            }
        }

        // 尋找angle值最小的
        float angleMin = 361.0f ;
        Dictionary<string,float>.Enumerator e = angleMap.GetEnumerator() ;
        while( e.MoveNext() )
        {
            if( e.Current.Value < angleMin )
            {
                angleMin = e.Current.Value ;
                ret = e.Current.Key ;
            }
        }
        // Debug.Log( "FindMostCloestWeaponComponent() ret=" + ret ) ;
        return ret ;
    }
    private bool TryFireWeaponInMultiAttackMode( UnitData _unitData ,
												UnitSensorSystem _sensorSys ,
												UnitWeaponSystem _weaponSys , 
												UnitSelectionSystem _selectSys ,
												ref Dictionary<string , SelectInformation > _fireList )
    {
        bool ret = false ;
        // 取得最大可能的瞄準框
        int maxSelectionNum = _selectSys.m_MaxSelectionNum ;
        int selectionIndexNow = 0 ;
        string [] selectionKeyArray = new string[ _selectSys.m_Selections.Count ] ;
        _selectSys.m_Selections.Keys.CopyTo( selectionKeyArray , 0 ) ;

        // 取得最大的武器清單,並依照距離來排序
        List<string> possibleWeaponList = RetrievePossibleWeaponListInOrder( _unitData , _weaponSys ) ;

        // 取得所有的可能敵人,並依照距離來排序
        List<NamedObject> possibleUnits = RetrievePossibleUnitInOrder( _sensorSys );

        // 目標是讓所有的武器都分別對上不同的敵人.然後設定好所有的瞄準框.最後全部開火.
        foreach( NamedObject possibleUnit in possibleUnits )
        {
            // Debug.Log( "possibleUnit=" + possibleUnit.Name ) ;
            // 假如瞄準框已經用盡,離開
            if( selectionIndexNow == maxSelectionNum - 1  )
                break ;

            // 每一個單位,找到可以發射的武器,而且最接近中線的武器
            string weaponComponentName = FindMostCloestWeaponComponent( _unitData ,
                                                                        _weaponSys ,
                                                                        possibleUnit ,
                                                                        possibleWeaponList ,
                                                                        ref _fireList ) ;
            // Debug.Log( "weaponComponentName=" + weaponComponentName ) ;
            if( 0 == weaponComponentName.Length )
                continue ;

            // 指定瞄準框的資訊
            string key = selectionKeyArray[ selectionIndexNow ] ;
            _selectSys.m_Selections[ key ].TargetUnitName = possibleUnit.Name ;
            _selectSys.m_Selections[ key ].TargetUnitObject = possibleUnit.Obj ;
            // Debug.Log( "_selectSys.m_Selections " + key + " " + possibleUnit.Name ) ;
            _fireList[ weaponComponentName ] = _selectSys.m_Selections[ key ] ;
            ++selectionIndexNow ;
            ret = true ;
        }

        // 針對每個瞄準框,發射指定的武器
        return ret ;
    }
 // 取得武器距離參數
 protected void RetrieveDataMaximumWeaponRange( UnitWeaponSystem _WeaponSys , ref List<string> _weaponKeywords )
 {
     float minWeaponRange = 9999 ;
     if( _weaponKeywords.Count > 0 )
     {
         foreach( string keyword in _weaponKeywords )
         {
             float weaponRange = _WeaponSys.FindMaximumWeaponRange( keyword ) ;
             if( weaponRange < minWeaponRange )
                 minWeaponRange = weaponRange ;
         }
         m_MaximumWeaponRange = minWeaponRange ;
     }
     else
     {
         m_MaximumWeaponRange = _WeaponSys.FindMaximumWeaponRange( "" ) ;
     }
     // Debug.Log( "RetrieveDataMaximumWeaponRange() " +m_MaximumWeaponRange ) ;
 }
    protected bool CheckAbleRunAI( out UnitData _UnitData ,
								   out UnitWeaponSystem _weaponSys )
    {
        return ( true == CheckUnitData( out _UnitData ) &&
                 true == CheckWeaponSys( out _weaponSys ) ) ;
    }
    protected override void FireWeapon( UnitWeaponSystem _weaponSys ,
							  			NamedObject _TargetUnit )
    {
        if( true == GlobalSingleton.GetGlobalSingletonObj().GetComponent<AutoPlayMachine>().m_Active )
            return ;

        string weaponComponent = "" ;
        string specifiedWeapon = RandomAWeaponKeyword() ;
        // 距離太遠
        string weaponInRange = _weaponSys.FindAbleToShootTargetWeaponComponent( specifiedWeapon , _TargetUnit.Obj ) ;
        // Debug.Log( "weaponInRange=" + weaponInRange ) ;
        if( 0 == weaponInRange.Length )
        {
            // no available weapon
            this.SetState( AI_Fire_State.MoveToTarget ) ;
            return ;
        }

        string weaponReady = _weaponSys.FindAbleToFireWeaponComponent( specifiedWeapon ) ;
        #if DEBUG
        Debug.Log( "FireWeapon() weaponReady=" + weaponReady ) ;
        #endif
        if( 0 == weaponReady.Length )
        {
            // no available weapon
            this.SetState( AI_Fire_State.WaitForReload ) ;
            return ;
        }

        // 檢查正在reload
        weaponComponent = _weaponSys.FindAbleWeaponComponent( specifiedWeapon , _TargetUnit.Obj ) ;
        // Debug.Log( "weaponReady=" + weaponComponent ) ;
        if( 0 == weaponComponent.Length )
        {
            // no available weapon
            this.SetState( AI_Fire_State.WaitForReload ) ;
            return ;
        }

        // Debug.Log( "_weaponSys.ActiveWeapon" ) ;
        // fire
        if( true == _weaponSys.ActiveWeapon( weaponComponent ,
                                            _TargetUnit ,
                                            ConstName.UnitDataComponentUnitIntagraty ) )
        {
            this.SetState( AI_Fire_State.WaitForReload ) ;
        }
    }
Пример #12
0
 protected virtual bool CheckWeaponSys( out UnitWeaponSystem _weapon )
 {
     _weapon = this.gameObject.GetComponent<UnitWeaponSystem>() ;
     return ( null != _weapon ) ;
 }