BWAPI
|
00001 #pragma once 00002 #include "Tech.h" 00003 #include "../Locations/Static/Map.h" 00004 #include "../../Utils/Component.h" 00005 #include "../../Utils/Event.h" 00006 #include <list> 00007 #include <sstream> 00008 #include <hash_map> 00009 #include <boost/iterator/transform_iterator.hpp> 00010 00011 class Techs 00012 { 00013 private: 00014 struct UpgradeCompare 00015 { 00016 bool operator()(const std::pair<BWAPI::UpgradeType, int>& upgrade1, const std::pair<BWAPI::UpgradeType, int>& upgrade2) const 00017 { 00018 if (upgrade1.first < upgrade2.first) 00019 return true; 00020 else if (upgrade1.first > upgrade2.first) 00021 return false; 00022 else 00023 return upgrade1.second < upgrade2.second; 00024 } 00025 }; 00026 struct UpgradeHashCompare : public stdext::hash_compare<std::pair<BWAPI::UpgradeType, int>, UpgradeCompare> 00027 { 00028 size_t operator()(const std::pair<BWAPI::UpgradeType, int>& upgrade) const 00029 { 00030 return 17 * upgrade.first.getID() + 47 * upgrade.second; 00031 } 00032 bool operator()(const std::pair<BWAPI::UpgradeType, int>& upgrade1, const std::pair<BWAPI::UpgradeType, int>& upgrade2) const 00033 { 00034 return UpgradeCompare()(upgrade1, upgrade2); 00035 } 00036 }; 00037 public: 00038 static UnitTypeTech* NexusTech; 00039 static UnitTypeTech* PylonTech; 00040 static UnitTypeTech* AssimilatorTech; 00041 static UnitTypeTech* GatewayTech; 00042 static UnitTypeTech* ShieldBatteryTech; 00043 static UnitTypeTech* ForgeTech; 00044 static UnitTypeTech* PhotonCannonTech; 00045 static UnitTypeTech* CyberneticsCoreTech; 00046 static UnitTypeTech* RoboticsFacilityTech; 00047 static UnitTypeTech* RoboticsSupportBayTech; 00048 static UnitTypeTech* ObservatoryTech; 00049 static UnitTypeTech* StargateTech; 00050 static UnitTypeTech* FleetBeaconTech; 00051 static UnitTypeTech* ArbiterTribunalTech; 00052 static UnitTypeTech* CitadelOfAdunTech; 00053 static UnitTypeTech* TemplarArchivesTech; 00054 00055 static UnitTypeTech* ProbeTech; 00056 static UnitTypeTech* ZealotTech; 00057 static UnitTypeTech* DragoonTech; 00058 static UnitTypeTech* HighTemplarTech; 00059 static UnitTypeTech* DarkTemplarTech; 00060 static UnitTypeTech* ArchonTech; 00061 static UnitTypeTech* DarkArchonTech; 00062 static UnitTypeTech* ReaverTech; 00063 static UnitTypeTech* ShuttleTech; 00064 static UnitTypeTech* ObserverTech; 00065 static UnitTypeTech* CorsairTech; 00066 static UnitTypeTech* ScoutTech; 00067 static UnitTypeTech* CarrierTech; 00068 static UnitTypeTech* ArbiterTech; 00069 00070 static TechTypeTech* DisruptionWebTech; 00071 static TechTypeTech* FeedbackTech; 00072 static TechTypeTech* HallucinationTech; 00073 static TechTypeTech* MaelstromTech; 00074 static TechTypeTech* MindControlTech; 00075 static TechTypeTech* PsionicStormTech; 00076 static TechTypeTech* RecallTech; 00077 static TechTypeTech* StasisFieldTech; 00078 00079 static UpgradeTypeTech* GroundWeapons[3]; // upgrade ground weapons level 1-2-3 00080 static UpgradeTypeTech* GroundArmor[3]; // upgrade ground armor level 1-2-3 00081 static UpgradeTypeTech* AirWeapons[3]; // upgrade air weapons level 1-2-3 00082 static UpgradeTypeTech* AirArmor[3]; // upgrade air armor level 1-2-3 00083 static UpgradeTypeTech* PlasmaShields[3]; // upgrade plasma shields 1-2-3 00084 static UpgradeTypeTech* SingularityCharge; // increase Dragoon attack range 00085 static UpgradeTypeTech* LegEnhancements; // faster Zealot movement 00086 static UpgradeTypeTech* GraviticDrive; // faster Shuttle movement 00087 static UpgradeTypeTech* CarrierCapacity; // max 8 interceptors (instead of 4) 00088 static UpgradeTypeTech* ReaverCapacity; // max 10 Scarabs (instead of 5) 00089 static UpgradeTypeTech* ScarabDamage; // upgrade Scarab damage (125 instead of 100) 00090 static UpgradeTypeTech* GraviticBoosters; // faster Observer movement 00091 static UpgradeTypeTech* SensorArray; // increase Observer sight range 00092 static UpgradeTypeTech* ApialSensors; // increase Scout sight range 00093 static UpgradeTypeTech* GraviticThrusters; // faster Scout movement 00094 static UpgradeTypeTech* ArgusJewel; // +50 Corsair energy 00095 static UpgradeTypeTech* ArgusTalisman; // +50 Dark Archon energy 00096 static UpgradeTypeTech* KhaydarinAmulet; // +50 Templar energy 00097 static UpgradeTypeTech* KhaydarinCore; // +50 Arbiter energy 00098 00099 template <class TechTypes> 00100 static void onStart(const Map* map); 00101 00102 static void onEnd(); 00103 00104 static UnitTypeTech* getUnitTypeTech(BWAPI::UnitType unitType) 00105 { 00106 stdext::hash_map<BWAPI::UnitType, UnitTypeTech*>::const_iterator it = UnitTypeTechs.find(unitType); 00107 if (it == UnitTypeTechs.end()) 00108 { 00109 return NULL; 00110 } 00111 else 00112 { 00113 return it->second; 00114 } 00115 } 00116 static TechTypeTech* getTechTypeTech(BWAPI::TechType techType) 00117 { 00118 stdext::hash_map<BWAPI::TechType, TechTypeTech*>::const_iterator it = TechTypeTechs.find(techType); 00119 if (it == TechTypeTechs.end()) 00120 { 00121 return NULL; 00122 } 00123 else 00124 { 00125 return it->second; 00126 } 00127 } 00128 static UpgradeTypeTech* getUpgradeTypeTech(BWAPI::UpgradeType upgradeType, int level = 1) 00129 { 00130 stdext::hash_map<std::pair<BWAPI::UpgradeType, int>, UpgradeTypeTech*>::const_iterator it = UpgradeTypeTechs.find(std::make_pair(upgradeType, level)); 00131 if (it == UpgradeTypeTechs.end()) 00132 { 00133 return NULL; 00134 } 00135 else 00136 { 00137 return it->second; 00138 } 00139 } 00140 00141 DECLARE_EVENT1(OnTechAcquired, Tech*); 00142 static OnTechAcquired& getTechAcquiredEvent() { return s_techAcquiredEvent; } 00143 00144 DECLARE_EVENT1(OnTechLost, Tech*); 00145 static OnTechLost& getTechLostEvent() { return s_techLostEvent; } 00146 00147 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_map<BWAPI::UnitType, UnitTypeTech*>::const_iterator::value_type>, 00148 stdext::hash_map<BWAPI::UnitType, UnitTypeTech*>::const_iterator> 00149 unit_type_tech_const_iterator; 00150 static std::pair<unit_type_tech_const_iterator, unit_type_tech_const_iterator> getUnitTypeTechs() 00151 { 00152 return std::make_pair(unit_type_tech_const_iterator(UnitTypeTechs.begin()), unit_type_tech_const_iterator(UnitTypeTechs.end())); 00153 } 00154 00155 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_map<BWAPI::TechType, TechTypeTech*>::const_iterator::value_type>, 00156 stdext::hash_map<BWAPI::TechType, TechTypeTech*>::const_iterator> 00157 tech_type_tech_const_iterator; 00158 static std::pair<tech_type_tech_const_iterator, tech_type_tech_const_iterator> getTechTypeTechs() 00159 { 00160 return std::make_pair(tech_type_tech_const_iterator(TechTypeTechs.begin()), tech_type_tech_const_iterator(TechTypeTechs.end())); 00161 } 00162 00163 typedef boost::transform_iterator<extract_pair_second_const<stdext::hash_map<std::pair<BWAPI::UpgradeType, int>, UpgradeTypeTech*, UpgradeHashCompare>::const_iterator::value_type>, 00164 stdext::hash_map<std::pair<BWAPI::UpgradeType, int>, UpgradeTypeTech*, UpgradeHashCompare>::const_iterator> 00165 upgrade_type_tech_const_iterator; 00166 static std::pair<upgrade_type_tech_const_iterator, upgrade_type_tech_const_iterator> getUpgradeTypeTechs() 00167 { 00168 return std::make_pair(upgrade_type_tech_const_iterator(UpgradeTypeTechs.begin()), upgrade_type_tech_const_iterator(UpgradeTypeTechs.end())); 00169 } 00170 00171 typedef concatenate_iterators<boost::tuple<std::pair<unit_type_tech_const_iterator, unit_type_tech_const_iterator>, 00172 std::pair<tech_type_tech_const_iterator, tech_type_tech_const_iterator>, 00173 std::pair<upgrade_type_tech_const_iterator, upgrade_type_tech_const_iterator>>, 00174 const Tech*> 00175 tech_const_iterator; 00176 static std::pair<tech_const_iterator, tech_const_iterator> getAllTechs() 00177 { 00178 return std::make_pair(tech_const_iterator(boost::make_tuple(std::make_pair(unit_type_tech_const_iterator(UnitTypeTechs.begin()), unit_type_tech_const_iterator(UnitTypeTechs.end())), 00179 std::make_pair(tech_type_tech_const_iterator(TechTypeTechs.begin()), tech_type_tech_const_iterator(TechTypeTechs.end())), 00180 std::make_pair(upgrade_type_tech_const_iterator(UpgradeTypeTechs.begin()), upgrade_type_tech_const_iterator(UpgradeTypeTechs.end())))), 00181 tech_const_iterator(boost::make_tuple(std::make_pair(unit_type_tech_const_iterator(UnitTypeTechs.end()), unit_type_tech_const_iterator(UnitTypeTechs.end())), 00182 std::make_pair(tech_type_tech_const_iterator(TechTypeTechs.end()), tech_type_tech_const_iterator(TechTypeTechs.end())), 00183 std::make_pair(upgrade_type_tech_const_iterator(UpgradeTypeTechs.end()), upgrade_type_tech_const_iterator(UpgradeTypeTechs.end()))))); 00184 } 00185 00186 private: 00187 friend class Tech; 00188 friend class UnitTypeTech; 00189 friend class TechTypeTech; 00190 friend class UpgradeTypeTech; 00191 00192 static void addUnitTypeTech(UnitTypeTech* tech) 00193 { 00194 std::pair<stdext::hash_map<BWAPI::UnitType, UnitTypeTech*>::iterator, bool> result = 00195 UnitTypeTechs.insert(std::make_pair(tech->getType(), tech)); 00196 if (!result.second) 00197 { 00198 const std::string name = tech->getType().getName(); 00199 throw std::runtime_error(std::string("Unit type tech duplicates \"") + name + "\""); 00200 } 00201 } 00202 00203 static void addTechTypeTech(TechTypeTech* tech) 00204 { 00205 std::pair<stdext::hash_map<BWAPI::TechType, TechTypeTech*>::iterator, bool> result = 00206 TechTypeTechs.insert(std::make_pair(tech->getTech(), tech)); 00207 if (!result.second) 00208 { 00209 const std::string name = tech->getTech().getName(); 00210 throw std::runtime_error(std::string("Tech type duplicates \"") + name + "\""); 00211 } 00212 } 00213 00214 static void addUpgradeTypeTech(UpgradeTypeTech* tech) 00215 { 00216 std::pair<stdext::hash_map<std::pair<BWAPI::UpgradeType, int>, UpgradeTypeTech*>::iterator, bool> result = 00217 UpgradeTypeTechs.insert(std::make_pair(std::make_pair(tech->getUpgrade(), tech->getLevel()), tech)); 00218 if (!result.second) 00219 { 00220 const std::string name = tech->getUpgrade().getName(); 00221 std::stringstream ss; 00222 ss << "Upgrade type tech duplicates \"" << name << " level " << tech->getLevel() << "\""; 00223 throw std::runtime_error(ss.str()); 00224 } 00225 } 00226 00227 static OnTechAcquired s_techAcquiredEvent; 00228 static OnTechLost s_techLostEvent; 00229 00230 static stdext::hash_map<BWAPI::UnitType, UnitTypeTech*> UnitTypeTechs; 00231 static stdext::hash_map<BWAPI::TechType, TechTypeTech*> TechTypeTechs; 00232 static stdext::hash_map<std::pair<BWAPI::UpgradeType, int>, UpgradeTypeTech*, UpgradeHashCompare> UpgradeTypeTechs; 00233 00234 static const Map* s_map; 00235 00236 class TechEvents : public Component 00237 { 00238 public: 00239 static void onStart(const Map* map) 00240 { 00241 s_techEvents.m_onOwnUnitCompletedId = map->getUnitCompletedEvent().subscribe(&s_techEvents.m_onOwnUnitCompletedEventHandler, NULL); 00242 s_techEvents.m_onOwnUnitRemovedId = map->getOwnUnitRemovedEvent().subscribe(&s_techEvents.m_onOwnUnitRemovedEventHandler, NULL); 00243 } 00244 static void onEnd(const Map* map) 00245 { 00246 map->getUnitCompletedEvent().unsubscribe(s_techEvents.m_onOwnUnitCompletedId); 00247 map->getOwnUnitRemovedEvent().unsubscribe(s_techEvents.m_onOwnUnitRemovedId); 00248 } 00249 void onOwnUnitCompleted(void* data, BWAPI::Unit* unit); 00250 void onOwnUnitRemoved(void* data, OwnUnit* ownUnit); 00251 private: 00252 static TechEvents s_techEvents; 00253 TechEvents() 00254 : m_onOwnUnitCompletedEventHandler(*this) 00255 , m_onOwnUnitRemovedEventHandler(*this) 00256 {} 00257 Map::OnUnitCompleted::SubscriberID m_onOwnUnitCompletedId; 00258 Map::OnOwnUnitRemoved::SubscriberID m_onOwnUnitRemovedId; 00259 EVENT_HANDLER1(TechEvents, onOwnUnitCompleted, BWAPI::Unit*) m_onOwnUnitCompletedEventHandler; 00260 EVENT_HANDLER1(TechEvents, onOwnUnitRemoved, OwnUnit*) m_onOwnUnitRemovedEventHandler; 00261 }; 00262 friend class TechEvents; 00263 }; 00264 00265 template <class TechTypes> 00266 void Techs::onStart(const Map* map) 00267 { 00268 s_map = map; 00269 TechEvents::onStart(map); 00270 00271 // Techs must be ordered in correct dependency order... else you must add each tech to the maps before setting up the dependencies 00272 NexusTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Nexus); 00273 PylonTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Pylon); 00274 AssimilatorTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Assimilator); 00275 GatewayTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Gateway); 00276 ShieldBatteryTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Shield_Battery); 00277 ForgeTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Forge); 00278 PhotonCannonTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Photon_Cannon); 00279 CyberneticsCoreTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Cybernetics_Core); 00280 RoboticsFacilityTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Robotics_Facility); 00281 RoboticsSupportBayTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Robotics_Support_Bay); 00282 ObservatoryTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Observatory); 00283 CitadelOfAdunTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Citadel_of_Adun); 00284 TemplarArchivesTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Templar_Archives); 00285 StargateTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Stargate); 00286 FleetBeaconTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Fleet_Beacon); 00287 ArbiterTribunalTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Arbiter_Tribunal); 00288 00289 ProbeTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Probe); 00290 ZealotTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Zealot); 00291 DragoonTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Dragoon); 00292 HighTemplarTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_High_Templar); 00293 DarkTemplarTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Dark_Templar); 00294 ArchonTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Archon); 00295 DarkArchonTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Dark_Archon); 00296 ReaverTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Reaver); 00297 ShuttleTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Shuttle); 00298 ObserverTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Observer); 00299 CorsairTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Corsair); 00300 ScoutTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Scout); 00301 CarrierTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Carrier); 00302 ArbiterTech = TechTypes::instantiateUnitTypeTech(BWAPI::UnitTypes::Protoss_Arbiter); 00303 00304 DisruptionWebTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Disruption_Web); 00305 FeedbackTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Feedback); 00306 HallucinationTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Hallucination); 00307 MaelstromTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Maelstrom); 00308 MindControlTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Mind_Control); 00309 PsionicStormTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Psionic_Storm); 00310 RecallTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Recall); 00311 StasisFieldTech = TechTypes::instantiateTechTypeTech(BWAPI::TechTypes::Stasis_Field); 00312 00313 GroundWeapons[0] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Weapons, 1); 00314 GroundWeapons[1] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Weapons, 2); 00315 GroundWeapons[2] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Weapons, 3); 00316 GroundArmor[0] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Armor, 1); 00317 GroundArmor[1] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Armor, 2); 00318 GroundArmor[2] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Ground_Armor, 3); 00319 AirWeapons[0] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Weapons, 1); 00320 AirWeapons[1] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Weapons, 2); 00321 AirWeapons[2] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Weapons, 3); 00322 AirArmor[0] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Armor, 1); 00323 AirArmor[1] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Armor, 2); 00324 AirArmor[2] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Air_Armor, 3); 00325 PlasmaShields[0] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Plasma_Shields, 1); 00326 PlasmaShields[1] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Plasma_Shields, 2); 00327 PlasmaShields[2] = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Protoss_Plasma_Shields, 3); 00328 SingularityCharge = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Singularity_Charge); 00329 LegEnhancements = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Leg_Enhancements); 00330 GraviticDrive = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Gravitic_Drive); 00331 CarrierCapacity = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Carrier_Capacity); 00332 ReaverCapacity = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Reaver_Capacity); 00333 ScarabDamage = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Scarab_Damage); 00334 GraviticBoosters = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Gravitic_Boosters); 00335 SensorArray = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Sensor_Array); 00336 ApialSensors = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Apial_Sensors); 00337 GraviticThrusters = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Gravitic_Thrusters); 00338 ArgusJewel = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Argus_Jewel); 00339 ArgusTalisman = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Argus_Talisman); 00340 KhaydarinAmulet = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Khaydarin_Amulet); 00341 KhaydarinCore = TechTypes::instantiateUpgradeTypeTech(BWAPI::UpgradeTypes::Khaydarin_Core); 00342 }