BWAPI
|
00001 #include "CombatManager.h" 00002 #include "Common.h" 00003 #include "Squad.h" 00004 00005 #include <BWAPI.h> 00006 #include <BWTA.h> 00007 00008 #include <string> 00009 00010 using namespace BWAPI; 00011 using BWTA::Chokepoint; 00012 00013 using namespace std; 00014 00015 00016 void CombatManager::onMatchStart() 00017 { 00018 Player* enemy = Broodwar->enemy(); 00019 if( enemy != NULL ) 00020 { 00021 // Get the likely enemy base location (furthest from myStart) 00022 // TODO - this should probably be calculated only once, 00023 // maybe we should have a Manager::onMatchStart() method? 00024 TilePosition myStart = Broodwar->self()->getStartLocation(); 00025 TilePosition target; 00026 double maxDistance = 0.0; 00027 set<TilePosition>& startPositions = Broodwar->getStartLocations(); 00028 set<TilePosition>::iterator pit = startPositions.begin(); 00029 set<TilePosition>::iterator pend = startPositions.end(); 00030 for(; pit != pend; ++pit) 00031 { 00032 TilePosition pos = *pit; 00033 const double distance = pos.getDistance(myStart); 00034 if( distance > maxDistance ) 00035 { 00036 target = pos; 00037 maxDistance = distance; 00038 } 00039 } 00040 00041 enemyBase = Position(target); 00042 } 00043 } 00044 00045 void CombatManager::update() 00046 { 00047 // Get new agents into state 00048 addNewAgents(); 00049 00050 // TODO : Merge squads 00051 00052 // Attack? 00053 const int numTroops = agents.size(); 00054 const int threshold = 50; 00055 00056 if( numTroops >= threshold ) 00057 { 00058 // Attack with full force (adjust to lower) 00059 for (SquadVectorIter it = squads.begin(); it != squads.end(); it++) 00060 { 00061 Agent *a = (*it)->getLeader(); 00062 if (a != NULL) 00063 { 00064 a->setState(AttackState); 00065 a->setPositionTarget(enemyBase); 00066 } 00067 } 00068 } 00069 00070 /* Update squads */ 00071 for (SquadVectorIter it = squads.begin(); it != squads.end(); it++) 00072 { 00073 (*it)->update(); 00074 } 00075 /* Base class updates Agents */ 00076 Manager::update(); 00077 } 00078 00079 00080 void CombatManager::addNewAgents() 00081 { 00082 // If we have any new Agents, they should go in the unassigned set 00083 AgentSetIter it = agents.begin(); 00084 AgentSetIter end = agents.end(); 00085 for(; it != end; ++it) 00086 { 00087 Agent *agent = *it; 00088 if( assignedAgents.find(agent) == assignedAgents.end() ) 00089 { 00090 unassignedAgents.insert(agent); 00091 // TODO - this is a hack to make them defend in the right place 00092 Chokepoint *cp = BWTA::getNearestChokepoint(agent->getUnit().getPosition()); 00093 if( cp != NULL ) 00094 agent->setPositionTarget(cp->getCenter()); 00095 else 00096 agent->setPositionTarget(Position(Broodwar->self()->getStartLocation())); 00097 00098 // Assign Agent to a Squad (only 1 atm) 00099 if (squads.empty()) 00100 { 00101 squads.push_back(new Squad()); 00102 } 00103 // Create a new squad if current is full 00104 if (squads.back()->getAgents().size() > 10) 00105 { 00106 squads.push_back(new Squad()); 00107 } 00108 Squad *squad = squads.back(); 00109 00110 squad->addAgent(*it); 00111 if (squad->getLeader() == NULL) 00112 { 00113 squad->setLeader(*it); 00114 } 00115 unassignedAgents.erase(agent); 00116 assignedAgents.insert(agent); 00117 } 00118 } 00119 } 00120 00121 void CombatManager::draw() 00122 { 00123 Broodwar->drawTextScreen(2, 20, 00124 "\x11 CM : (SCV=%d) (Marine=%d) (Firebat=%d) (Medic=%d)", 00125 numAgents(UnitTypes::Terran_SCV), 00126 numAgents(UnitTypes::Terran_Marine), 00127 numAgents(UnitTypes::Terran_Firebat), 00128 numAgents(UnitTypes::Terran_Medic)); 00129 00130 for (SquadVectorIter it = squads.begin(); it != squads.end(); it++) 00131 { 00132 (*it)->draw(); 00133 } 00134 00135 Manager::draw(); 00136 }