diff --git a/ExtendAPI.md b/ExtendAPI.md new file mode 100644 index 0000000000000000000000000000000000000000..005e30f838b029c9b077a691b68c17f562cb55a9 --- /dev/null +++ b/ExtendAPI.md @@ -0,0 +1,28 @@ +# Extending the API +This is a guide for extending the API and adding more functionality to the courses TDDE25 and TDDD92. + +If a function already exist but you can't use it in python, check and see if it's exist in the library files (pybind). + +1. Create a declaration of your function in the header file. +2. Create a definition of your function in the source file. +3. Depending on which object you decided to extend, you should also add this function to the library file. The library is the pybind, making it possible to use your function in python. +4. Update the documentation. There are instructions on how you build and test the documentation. + + +Example: +We want to add function to unit, returning a bool depending on if it's holding a mineral. We have discovered a function in the SC2 API containing this information (sc2_client.ccp). This is a helper function, it doesn't belong to any object. + +1. In unit.h: ```bool isCarryingMinerals() const;``` +2. In unit.cpp: ```bool Unit::isCarryingMinerals() const +{ + return sc2::IsCarryingMinerals(*m_unit); +}``` +We can access m_unit in the unit file and with sc2::Function() we can access any function in the blizzard API that doesn't belong to any object. The same goes for any object, for example sc2::Point3D makes us able to access the Point3D object. +3. In lib_unit.cpp: ```.def_property_readonly("is_carrying_minerals", &Unit::isCarryingMinerals)``` +4. In the folder named docs we update the documentation. In this case, we update the file unit.rst. + +Common problems: +1. The return in python is a memory address: + Make sure that it returns a correct type. +2. The compiler complains about files I have not even touched: + Make sure that the startUp is library and you have release x64. If you just added a new function in pybind, check it. diff --git a/docs/conf.py b/docs/conf.py index a5b0d56b436bb45793b25c3761d9200951d068fe..8607f50a47d56ddd778917738e9cb0d6d3865818 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,8 +12,10 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. +# Two paths here to work on both Windows and Linux import sys,os sys.path.append(os.path.join(os.getcwd(), "..", "build", "python-api-src", "Release")) +sys.path.append(os.path.join(os.getcwd(), "..", "build", "python-api-src")) # -- Project information ----------------------------------------------------- diff --git a/docs/idabot.rst b/docs/idabot.rst index 94e9927e76f47a410c95475bc473479512bd335e..b604dc987203ba76005918eee7c0987372580d62 100644 --- a/docs/idabot.rst +++ b/docs/idabot.rst @@ -71,6 +71,11 @@ IDABot Ability that researches this upgrade + Example: If we send in UPGRADE_ID.BANSHEECLOAK, it will return + ABILITY_ID.RESEARCH_BANSHEECLOAKINGFIELD. In this case, + the unit of scv has the ability for this. You can then use the + unit.ability(AbilityID) on the scv for creating the upgrade. + .. method:: IDABot.upgrade_mineral_cost(self, UpgradeID) Mineral cost of researching the upgrade @@ -174,6 +179,9 @@ The debug-methods are a great tool for speeding up the process. .. method:: IDABot.debug_set_energy(self, Float, Unit) Set the amount (Float) of energy to the unit + The maximum depends on the unit maxenergy. + Note: This is not in percent of the unit energy. + Same goes for life and shields. .. method:: IDABot.debug_set_life(self, Float, Unit) diff --git a/docs/unit.rst b/docs/unit.rst index e8c09acfa4461a68c91a14a6aa1e818c3ea205bb..16aa1d46c7c8d7ef33073845d400bb05cf11f9ee 100644 --- a/docs/unit.rst +++ b/docs/unit.rst @@ -32,6 +32,9 @@ Unit .. autoattribute:: hit_points .. autoattribute:: max_hit_points + Returns the max health + .. autoattribute:: max_shields + .. autoattribute:: max_energy .. autoattribute:: id .. autoattribute:: is_alive .. autoattribute:: is_blip diff --git a/python-api-src/lib_unit.cpp b/python-api-src/lib_unit.cpp index f7ba369c1cdb4c7cf136feaed86aace5522895d7..de09cc58769e8068353ffaab5d94be400208919c 100644 --- a/python-api-src/lib_unit.cpp +++ b/python-api-src/lib_unit.cpp @@ -39,6 +39,8 @@ void define_unit(py::module & m) .def_property_readonly("gas_left_in_refinery", &Unit::gasLeftInGeyser) .def_property_readonly("minerals_left_in_mineralfield", &Unit::mineralsLeftInMineralfield) .def_property_readonly("owner", &Unit::getOwner) + .def_property_readonly("max_shields", &Unit::maxShields) + .def_property_readonly("max_energy", &Unit::maxEnergy) .def("hold_position", &Unit::holdPosition) .def("patrol", py::overload_cast<const CCPosition &>(&Unit::patrol, py::const_)) .def("stop_dance", &Unit::stopDance) diff --git a/src/IDABot.cpp b/src/IDABot.cpp index b6330b538b182b7b24efd52266f05af68b53083c..cda0ce75922c415a037b86161fb74089a09cede9 100644 --- a/src/IDABot.cpp +++ b/src/IDABot.cpp @@ -339,9 +339,9 @@ void IDABot::CameraMove(Point2DI p) ActionsFeatureLayer()->CameraMove(p); } -const char* IDABot::abilityForUpgrade(sc2::UpgradeID upgrade_id) const +sc2::ABILITY_ID IDABot::abilityForUpgrade(sc2::UpgradeID upgrade_id) const { - return sc2::AbilityTypeToName(Observation()->GetUpgradeData()[upgrade_id].ability_id); + return (sc2::ABILITY_ID)Observation()->GetUpgradeData()[upgrade_id].ability_id; } uint32_t IDABot::UpgradeMineralCost(sc2::UpgradeID upgrade_id) const diff --git a/src/IDABot.h b/src/IDABot.h index 4186904a17081faf4bd6ec3f09166700bb026cba..84e38978f0c93f1328d5a6506b4f8495e0b7d5d8 100644 --- a/src/IDABot.h +++ b/src/IDABot.h @@ -87,7 +87,7 @@ public: const std::vector<Point2D> GetEnemyBaseLocations(); bool HasCreep(Point2D p) const; void CameraMove(Point2DI p); - const char* abilityForUpgrade(sc2::UpgradeID upgrade_id) const; + sc2::ABILITY_ID abilityForUpgrade(sc2::UpgradeID upgrade_id) const; uint32_t UpgradeMineralCost(sc2::UpgradeID upgrade_id) const; uint32_t UpgradeGasCost(sc2::UpgradeID upgrade_id) const; float UpgradeResearchTime(sc2::UpgradeID upgrade_id) const; diff --git a/src/Unit.cpp b/src/Unit.cpp index 0fa7550dd9c0de89af813376bd17448ef10197f2..6f4bcee54eae7b0ead9ce2d19d5fed2757c780af 100644 --- a/src/Unit.cpp +++ b/src/Unit.cpp @@ -470,4 +470,14 @@ bool Unit::isCarryingGas() const bool Unit::isCarryingMinerals() const { return sc2::IsCarryingMinerals(*m_unit); +} + +float Unit::maxShields() const +{ + return m_unit->shield_max; +} + +float Unit::maxEnergy() const +{ + return m_unit->energy_max; } \ No newline at end of file diff --git a/src/Unit.h b/src/Unit.h index a996e372f147d49522e1f833aacfd5c5143326b0..ebb2f44bccbcdc022d810269268e66bb2847ef01 100644 --- a/src/Unit.h +++ b/src/Unit.h @@ -68,6 +68,8 @@ public: int mineralsLeftInMineralfield() const; int getOwner() const; bool isCarryingGas() const; + float maxShields() const; + float maxEnergy() const; void stop () const; diff --git a/src/UnitType.cpp b/src/UnitType.cpp index cf6983564ce0952afe032e97e9671a6d76ef618e..dd564f7e0b74ee97125b95faff718bd3becde1c5 100644 --- a/src/UnitType.cpp +++ b/src/UnitType.cpp @@ -368,7 +368,7 @@ bool UnitType::isMorphedBuilding() const } #else return m_type == BWAPI::UnitTypes::Zerg_Sunken_Colony || - m_type == BWAPI::UnitTypes::Zerg_Spore_Colony ||w + m_type == BWAPI::UnitTypes::Zerg_Spore_Colony || m_type == BWAPI::UnitTypes::Zerg_Lair || m_type == BWAPI::UnitTypes::Zerg_Hive || m_type == BWAPI::UnitTypes::Zerg_Greater_Spire;