1 // Copyright Hugh Perkins 2006, 2009
2 // hughperkins@gmail.com http://manageddreams.com
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 //  more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program in the file licence.txt; if not, write to the
16 // Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17 // 1307 USA
18 // You can find the licence also on the web at:
19 // http://www.opensource.org/licenses/gpl-license.php
20 //
21 // ======================================================================================
22 //
23 
24 package hughai;
25 
26 import java.util.*;
27 import java.util.Map;
28 
29 import com.springrts.ai.*;
30 import com.springrts.ai.oo.clb.*;
31 
32 import hughai.basictypes.*;
33 import hughai.mapping.*;
34 import hughai.packcoordinators.*;
35 import hughai.unitdata.*;
36 import hughai.utils.*;
37 
38 
39 // this class works out appropriate enemies to attack, based on profile we define for it
40 // since different units have a different preference for attacking (air vs ground vs speed etc), we need a different object for each
41 public class EnemySelector
42 {
43    public double maxenemyspeed;
44    public boolean WaterOk;
45    public boolean BadTerrainOk;
46 
47    CSAI csai;
48    OOAICallback aicallback;
49    LogFile logfile;
50    EnemyTracker enemyTracker;
51    UnitDefHelp unitdefhelp;
52    Maps maps;
53 
54    int startarea = 0;
55    UnitDef typicalunitdef;
56 
EnemySelector( PlayerObjects playerObjects, double maxenemyspeed, UnitDef typicalunitdef )57    public EnemySelector( PlayerObjects playerObjects, double maxenemyspeed, UnitDef typicalunitdef )
58    {
59       csai = playerObjects.getCSAI();
60       aicallback = csai.aicallback;
61       logfile = playerObjects.getLogFile();
62       enemyTracker = playerObjects.getEnemyTracker();
63       unitdefhelp = playerObjects.getUnitDefHelp();
64       maps = playerObjects.getMaps();
65 
66       // csai.EnemyEntersLOSEvent += new CSAI.EnemyEntersLOSHandler( EnemyEntersLOS );
67 
68       this.maxenemyspeed = maxenemyspeed;
69       //this.WaterOk = WaterOk;
70      // this.BadTerrainOk = BadTerrainOk;
71 
72       this.typicalunitdef = typicalunitdef;
73       //    startarea = maps.getMovementMaps().GetArea(typicalunitdef, startpos);
74    }
75 
InitStartPos(TerrainPos startpos)76    public void InitStartPos(TerrainPos startpos)
77    {
78       startarea = maps.getMovementMaps().GetArea(typicalunitdef, startpos);
79    }
80 
81    // this is going to have to interact with all sorts of stuff in the future
82    // for now keep it simple
83    // for now we look for nearby buildings, then nearby enemy units with low speed, then anything
ChooseAttackPoint( TerrainPos friendlypos )84    public TerrainPos ChooseAttackPoint( TerrainPos friendlypos )
85    {
86       boolean gotbuilding = false;
87       boolean gotknownunit = false;
88       float BestSquaredDistance = 100000000000f;
89 
90       Unit besttarget = null;
91       UnitDef defforbestid = null;
92       TerrainPos posforbestid = null;
93       //   logfile.WriteLine( "EnemySelector: checking mobile... " );
94       // mobile units first:
95       for( Unit enemy : enemyTracker.getEnemyUnits() ) {
96          UnitDef enemyunitdef = enemyTracker.getEnemyUnitDefByUnit().get( enemy );
97          TerrainPos enemypos = TerrainPos.fromAIFloat3( enemy.getPos() );
98          //Float3 enemypos = EnemyMap.GetInstance().
99          // logfile.WriteLine( "Found building " +
100          if (maps.getMovementMaps().GetArea(typicalunitdef, enemypos) == startarea)
101          {
102             if (enemypos.GetSquaredDistance(new TerrainPos() ) > 1)
103             {
104                float thissquareddistance = friendlypos.GetSquaredDistance( enemypos);
105                //   logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.toString() + " squareddistance: " + thissquareddistance );
106                if ( enemyunitdef != null)
107                {
108                   //   logfile.WriteLine( "unitdef not null " + unitdef.getHumanName() + " ismobile: " + unitdefhelp.IsMobile( unitdef ).toString() );
109                   //   logfile.WriteLine( "gotbuilding = " + gotbuilding.toString() );
110                   if (gotbuilding)
111                   {
112                      if (!unitdefhelp.IsMobile(enemyunitdef))
113                      {
114                         if (thissquareddistance < BestSquaredDistance)
115                         {
116                            //  logfile.WriteLine( "best building so far" );
117                            besttarget = enemy;
118                            gotbuilding = true;
119                            gotknownunit = true;
120                            posforbestid = enemypos;
121                            defforbestid = enemyunitdef;
122                            BestSquaredDistance = thissquareddistance;
123                         }
124                      }
125                   }
126                   else
127                   {
128                      if (enemyunitdef.getSpeed() < maxenemyspeed) // if we already have building we dont care
129                      {
130                         if (thissquareddistance < BestSquaredDistance)
131                         {
132                            //    logfile.WriteLine( "best known so far" );
133                            besttarget = enemy;
134                            gotknownunit = true;
135                            posforbestid = enemypos;
136                            defforbestid = enemyunitdef;
137                            BestSquaredDistance = thissquareddistance;
138                         }
139                      }
140                   }
141                }
142                else // if unitdef unknown
143                {
144                   //  logfile.WriteLine( "gotknownunit = " + gotknownunit.toString() );
145                   if (!gotknownunit) // otherwise just ignore unknown units
146                   {
147                      if (thissquareddistance < BestSquaredDistance)
148                      {
149                         //    logfile.WriteLine( "best unknown so far" );
150                         besttarget = enemy;
151                         posforbestid = enemypos;
152                         defforbestid = enemyunitdef;
153                         BestSquaredDistance = thissquareddistance;
154                      }
155                   }
156                }
157             }
158          }
159       }
160 
161       // static now
162       for( Unit enemy : enemyTracker.getEnemyPosByStaticUnit().keySet() ) {
163          TerrainPos enemypos = enemyTracker.getEnemyPosByStaticUnit().get( enemy );
164          float thissquareddistance = friendlypos.GetSquaredDistance( enemypos );
165          //  logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.toString() + " squareddistance: " + thissquareddistance );
166          if( thissquareddistance < BestSquaredDistance )
167          {
168             //   logfile.WriteLine( "EnemySelector: best distance so far" );
169             besttarget = enemy;
170             gotbuilding = true;
171             gotknownunit = true;
172             posforbestid = enemypos;
173             //defforbestid = unitdef;
174          }
175       }
176 
177       //if( enemyTracker.EnemyStaticPosByDeployedId.Contains( bestid ) )
178       // {
179       //     enemyTracker.EnemyStaticPosByDeployedId.remove( bestid );
180       // }
181 
182       return posforbestid;
183    }
184 }
185