From e6b395c0d77d2a2c79e9c038a231801ceb039928 Mon Sep 17 00:00:00 2001
From: Rojikku98 <be.edvin@gmail.com>
Date: Sun, 26 Jul 2020 17:27:17 +0200
Subject: [PATCH] Started work on onUnityDestroyed

---
 python-api-src/lib_replay_unit.cpp | 10 ++++++----
 python-api-src/library.cpp         |  1 +
 python-api-src/library.h           |  2 +-
 src/IDAReplayObserver.cpp          | 15 ++++++++++++++-
 src/IDAReplayObserver.h            |  3 +++
 src/UnitInformation.cpp            | 21 ++++++++++++++++++++-
 src/UnitInformation.h              |  1 +
 7 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/python-api-src/lib_replay_unit.cpp b/python-api-src/lib_replay_unit.cpp
index 411b2e220..9dfd83d1c 100644
--- a/python-api-src/lib_replay_unit.cpp
+++ b/python-api-src/lib_replay_unit.cpp
@@ -6,7 +6,8 @@ void define_replay_unit(py::module & m)
 {
 	py::class_<UnitInformation>(m, "ReplayUnit")
 		.def_property_readonly("id", &UnitInformation::getID)
-		.def_property_readonly("unit_type", &UnitInformation::getType, "The name of the type")
+		.def_property_readonly("unit_type", &UnitInformation::getType, "The id of the type")
+		.def_property_readonly("unit_type_name", &UnitInformation::getTypeName, "The name of the type")
 		.def_property_readonly("position", &UnitInformation::getPosition, "The :class:`library.Point2D` of the unit")
 		.def_property_readonly("tile_position", &UnitInformation::getTilePosition, "The :class:`library.Point2DI` of the unit")
 		.def_property_readonly("hit_points", &UnitInformation::getHitPoints)
@@ -27,8 +28,9 @@ void define_replay_unit(py::module & m)
 		.def_property_readonly("is_valid", &UnitInformation::isValid)
 		.def_property_readonly("is_training", &UnitInformation::isTraining)
 		.def_property_readonly("is_blip", &UnitInformation::isBlip)
-		.def_property_readonly("target", &UnitInformation::getTarget)
-		.def_property_readonly("has_target", &UnitInformation::hasTarget)
+		// Has target and target crashes if the target died in the same frame
+		//.def_property_readonly("target", &UnitInformation::getTarget)
+		//.def_property_readonly("has_target", &UnitInformation::hasTarget)
 		.def_property_readonly("max_hit_points", &UnitInformation::getMaxHitPoints)
 		.def_property_readonly("progress", &UnitInformation::getProgress)
 		.def_property_readonly("current_ability_id", &UnitInformation::getCurrentAbilityID, "The AbilityID of currently used ability")
@@ -37,6 +39,6 @@ void define_replay_unit(py::module & m)
 		.def_property_readonly("is_carrying_minerals", &UnitInformation::isCarryingMinerals)
 		.def("__hash__", [](const UnitInformation & unit) { return std::hash<const sc2::Unit *>{}(unit.getUnitPtr()); })
 		.def(py::self == py::self)
-		.def("__repr__", [](const UnitInformation & unit) { return "<Unit of type: '" + unit.getType() + "'>"; })
+		.def("__repr__", [](const UnitInformation & unit) { return "<Unit of type: '" + unit.getTypeName() + "'>"; })
 		;
 }
diff --git a/python-api-src/library.cpp b/python-api-src/library.cpp
index 1ec48212a..21611296f 100644
--- a/python-api-src/library.cpp
+++ b/python-api-src/library.cpp
@@ -99,6 +99,7 @@ PYBIND11_MODULE(library, m)
 		.def("on_step", &IDAReplayObserver::OnStep)
 		.def("on_game_end", &IDAReplayObserver::OnGameEnd)
 		.def("get_all_units", &IDAReplayObserver::GetAllUnits, "Returns a list of all units")
+		.def("on_unit_destroyed", &IDAReplayObserver::OnUnitInfomationDestroyed, "unit"_a)
 		;
 
     py::class_<sc2::PlayerSetup>(m, "PlayerSetup");
diff --git a/python-api-src/library.h b/python-api-src/library.h
index daee1f3fe..89118af07 100644
--- a/python-api-src/library.h
+++ b/python-api-src/library.h
@@ -62,7 +62,7 @@ public:
     }
 };
 
-//todo fixa!
+
 class PyReplayObserver : public IDAReplayObserver
 {
 public:
diff --git a/src/IDAReplayObserver.cpp b/src/IDAReplayObserver.cpp
index 21e20e456..26c57d0dd 100644
--- a/src/IDAReplayObserver.cpp
+++ b/src/IDAReplayObserver.cpp
@@ -5,7 +5,6 @@ void IDAReplayObserver::setUnits()
 {
 	
 	m_allUnits.clear();
-	Control()->GetObservation();
 	for (auto & unit : Observation()->GetUnits())
 	{
 		m_allUnits.push_back(UnitInformation(unit, *this));
@@ -36,8 +35,22 @@ void IDAReplayObserver::OnGameEnd()
 {
 }
 
+void IDAReplayObserver::OnUnitDestroyed(const sc2::Unit* unit)
+{
+	UnitInformation unitInformation = UnitInformation(unit, *this);
+	OnUnitInfomationDestroyed(&unitInformation);
+}
+
+
+
 UnitInformation IDAReplayObserver::GetUnit(const CCUnitID tag) const
 {		
+	std::cout << tag << std::endl;
+	if (tag == 0) {
+		std::cout << "TAG == 0" << std::endl;
+	}
+	UnitInformation(Observation()->GetUnit(tag), *(IDAReplayObserver *)this);
+	std::cout << "OK" << std::endl;
 	return UnitInformation(Observation()->GetUnit(tag), *(IDAReplayObserver *)this);
 }
 
diff --git a/src/IDAReplayObserver.h b/src/IDAReplayObserver.h
index de78d6b52..16eaae6e5 100644
--- a/src/IDAReplayObserver.h
+++ b/src/IDAReplayObserver.h
@@ -24,6 +24,9 @@ public:
 	void OnGameStart() override;
 	void OnStep() override;
 	void OnGameEnd() override;
+	void OnUnitDestroyed(const sc2::Unit*) override;
+	virtual void OnUnitInfomationDestroyed(const UnitInformation*);
+
 	UnitInformation GetUnit(const CCUnitID tag) const;
 
 
diff --git a/src/UnitInformation.cpp b/src/UnitInformation.cpp
index ab42e9f2b..a33b23f24 100644
--- a/src/UnitInformation.cpp
+++ b/src/UnitInformation.cpp
@@ -14,17 +14,31 @@ UnitInformation::UnitInformation(const sc2::Unit * unit, IDAReplayObserver & rep
 		
 }
 
+ std::string UnitInformation::getTypeName() const
+ {
+	 return sc2::UnitTypeToName(m_unit->unit_type);
+ }
+
 bool UnitInformation::hasTarget() const
 {
 	BOT_ASSERT(isValid(), "Unit is not valid");
-
+	std::cout << "HAS TARGET" << std::endl;
 	if (getUnitPtr()->orders.size() > 0) {
 		if (getUnitPtr()->orders[0].target_unit_tag != NULL) {
 			CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
+			//The tag is for somereason a null tag
+			if (t_id == sc2::NullTag) {
+				return false;
+			}
+			std::cout << "1MID HAS TARGET" << std::endl;
+			std::cout << "2MID HAS TARGET" << std::endl;
+			std::cout << "valid" << m_replayObserver->GetUnit(t_id).getType() << std::endl;
+			std::cout << "AFTER" << std::endl;
 			// IDABot finds the unit with this tag, and returns true if valid
 			return m_replayObserver->GetUnit(t_id).isValid();
 		}
 	}
+	std::cout << "END HAS TARGET" << std::endl;
 
 	return false;
 }
@@ -33,12 +47,17 @@ UnitInformation UnitInformation::getTarget() const
 {
 	BOT_ASSERT(isValid(), "Unit is not valid");
 
+
 	// if unit has order, check tag of target of first order
 	if (getUnitPtr()->orders.size() > 0) {
 		// t_id is set to the unit tag of the target
 		CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
 		//The tag is for somereason a null tag
 		if (t_id == sc2::NullTag) {
+			
+			std::cout << "nullTAG" << std::endl;
+			std::cout << "type " << sc2::UnitTypeToName(m_unit->unit_type) <<"pos " << getPosition().x << " x y "<< getPosition().y << ", id " << getID() << "player " << getPlayer() << std::endl;
+			std::cout << getUnitPtr()->orders.size() << std::endl;
 			return *this;
 		}
 		// IDAReplayObserver finds the unit with this tag
diff --git a/src/UnitInformation.h b/src/UnitInformation.h
index 86a7656a6..8352c5ba4 100644
--- a/src/UnitInformation.h
+++ b/src/UnitInformation.h
@@ -14,6 +14,7 @@ public:
 		UnitInformation(const sc2::Unit * unit, IDAReplayObserver & replayObserver);
 
 		std::string getType() const;
+		std::string getTypeName() const;
 		bool hasTarget() const;
 		UnitInformation getTarget() const;
 
-- 
GitLab