diff --git a/.gitignore b/.gitignore
index 567609b1234a9b8806c5a05da6c866e480aa148d..0023a727e767c45c3521dc3f0e2ed635bb81f1ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
 build/
+.idea
+venv
+.vs
diff --git a/docs/.gitignore b/docs/.gitignore
index 105f812a5862ebf713d87bb2b570654541f0b195..267169afdf7084bd04be62a6e0d70f8598c2f970 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -1,2 +1,4 @@
 _autosummary/
 _build/
+venv
+.idea
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
new file mode 100644
index 0000000000000000000000000000000000000000..eca68a0e79ecee259c30a89b057d8958c7f68fbc
--- /dev/null
+++ b/docs/_templates/layout.html
@@ -0,0 +1,6 @@
+{% extends "!layout.html" %}
+
+  {% block menu %}
+    {{ super() }}
+    <a href="py-modindex.html">modindex</a>
+  {% endblock %}
\ No newline at end of file
diff --git a/docs/constants.rst b/docs/constants.rst
index f75b8535ddfbc859aa49b75c7110fb012100ea6d..a4e6275503d69b560cc017b8c1ee0eb89580e112 100644
--- a/docs/constants.rst
+++ b/docs/constants.rst
@@ -46,3 +46,6 @@ Race
    The following attribute means a randomly selected race from the three above:
 
    .. attribute:: Race.Random
+
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 853063d021db997dbda0cd6a6f8100b9cdfe40d7..3aa8a8297e315e6078da07097a743cbb4a8e3ff8 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -38,6 +38,27 @@ The source code for all additional dependencies (including pybind11) are registe
 
 The system is built using cmake, see the file `CMakeLists.txt <https://gitlab.liu.se/starcraft-ai-course/pycommandcenter/blob/master/CMakeLists.txt>`_ in the project root.
 
+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).
+
+#. Create a declaration of your function in the header file.
+#. Create a definition of your function in the source file.
+#. 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.
+#. 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.
+
+#. In unit.h: bool isCarryingMinerals() const;
+#. 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.
+#. In lib_unit.cpp: .def_property_readonly("is_carrying_minerals", &Unit::isCarryingMinerals)
+#. In the folder named docs we update the documentation. In this case, we update the file unit.rst.
+
+Common problems:
+
+#. The return in python is a memory address: Make sure that it returns a correct type.
+#. 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.
+#. The bot crashes whit a exit code -1073741819 (0xC0000005): Make sure that you dont read null values.
 
 Document the new features / changes you have made
 -------------------------------------------------
@@ -61,3 +82,5 @@ Read the comments on your merge request and make the necessary changes
 In this step someone will review your changes and make comments. These comments might ask you to make changes to the code or documentation. These changes must be done before the merge request is accepted. Therefore it is important to make merge requests several days before eventual deadlines.
 
 Once the merge request has been accepted the code is now part of PyCommandCenter. Congratulations and thank you for your contribution to the project!
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/coordinates.rst b/docs/coordinates.rst
index 294d8eea35bef9b8f6b70dac75a921702c1acb91..fb74871e26f4a5a45f9a16451ae9910756e8b20f 100644
--- a/docs/coordinates.rst
+++ b/docs/coordinates.rst
@@ -81,3 +81,4 @@ below:
 
    print(p1.distance(p2))  # prints: 2.8284...
 
+.. toctree::
\ No newline at end of file
diff --git a/docs/gettingstarted.rst b/docs/gettingstarted.rst
index 037793e338f9110230000d487491afb6ac174866..c68a47300c4efa3530aec4bfe6a2f6f9428f5800 100644
--- a/docs/gettingstarted.rst
+++ b/docs/gettingstarted.rst
@@ -150,3 +150,4 @@ to:
 
 where ``SomeOtherBot`` is a bot defined in the same way as ``MyAgent``.
 
+.. toctree::
\ No newline at end of file
diff --git a/docs/helpers.rst b/docs/helpers.rst
index 15cc665061d3ba8606024b55399998a459dd264b..68802b440ee021816569900ad82f6520ae54db31 100644
--- a/docs/helpers.rst
+++ b/docs/helpers.rst
@@ -188,3 +188,5 @@ BuildingPlacer
    If you want to place a town hall, take a look at attribute `depot_location` of :class:`library.BaseLocation`.
 
    If you want to place a refinery, take a look at attribute `geysers` of :class:`library.BaseLocation` and the method build_target of :class:`library.Unit`.
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/idabot.rst b/docs/idabot.rst
index ad95df7bd7b4bcf3b5a9208f911bda67ebddf81f..6a4c6be2f210cfc04ad3b0ccc10ce43ad113caf2 100644
--- a/docs/idabot.rst
+++ b/docs/idabot.rst
@@ -191,3 +191,4 @@ The debug-methods are a great tool for speeding up the process.
 
       Set the amount (Float) of shield to the unit
 
+.. toctree::
\ No newline at end of file
diff --git a/docs/idareplayobserver.rst b/docs/idareplayobserver.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d2379aefe762981f6bd342a26c7c96c4304a485e
--- /dev/null
+++ b/docs/idareplayobserver.rst
@@ -0,0 +1,48 @@
+IDAReplayObserver
+=================
+
+.. class:: library.IDAReplayObserver
+
+   This is a class for following a replay.
+
+   Inherited methods:
+
+   .. method:: IDAReplayObserver.on_game_start(self)
+
+      This method is called when a replay has started, when you inherit it you have to
+      call the parent's on_game_start method in order to make it work (see
+      :ref:`replays`).
+
+   .. method:: IDAReplayObserver.on_step(self)
+
+      This method is called on every tick of the replay, when you inherit it you
+      have to call the parent's on_step method in order to make it work (see
+      :ref:`replays`).
+
+   .. method:: IDAReplayObserver.on_game_end(self)
+
+      This method is called when the replay has ended, when you inherit it you have to
+      call the parent's on_game_start method in order to make it work (see
+      :ref:`replays`).
+
+   .. method:: IDAReplayObserver.on_unit_created(self)
+
+      This method is called when the an unit is created, that includes when an unit leaves a refinery. This only works if replay perspective is not set to 0.
+
+   .. method:: IDAReplayObserver.on_unit_destroyed(self)
+
+      This unit is called when a unit is destroyed.
+
+   Methods:
+
+   .. method:: IDAReplayObserver.get_all_units(self) -> List[library.ReplayUnit]
+
+      Retrieves a list of all visible units
+
+   .. method:: IDAReplayObserver.get_player_race(self, player_id) -> library.Race
+
+      Returns the players race
+
+
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
index 153c9df4954c1266a97d4b7933b7fb54ae6b4344..da345dada9ea6d61e89b35860c335efcdd0aef95 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -22,13 +22,18 @@ Table of contents
    :maxdepth: 3
 
    gettingstarted
+   Library<_autosummary/library>
+   Coordinator<_autosummary/library.Coordinator>
    helpers
    idabot
    unit
    types
    coordinates
    constants
-   
+   replays
+   idareplayobserver
+   replayunit
+
 .. autosummary::
    :toctree: _autosummary
    :hidden:
diff --git a/docs/replays.rst b/docs/replays.rst
new file mode 100644
index 0000000000000000000000000000000000000000..af3307805042078bc4de4903642b827ee6a2e08e
--- /dev/null
+++ b/docs/replays.rst
@@ -0,0 +1,108 @@
+.. _replays:
+
+Replays
+=======
+This page will describe two different techniques for handling replays. The
+first technique parses the information saved in the replay file. The second
+uses the information in the replay file to actually replay the game. The
+different techniques have certain advantages and disadvantages. The main
+one is that the reader is a lot faster while replaying the game provides
+a lot more information.
+
+
+
+SC2Reader
+---------
+SC2Reader_ is a library that can be used to implement the first technique.
+
+Here is a short example that uses SC2Reader to extract the build order.
+
+
+.. _SC2Reader: https://github.com/ggtracker/sc2reader
+
+.. code-block:: python
+
+    import sc2reader
+    import json
+    from sc2reader.factories import SC2Factory
+
+    # The path to the replays
+    PATH = "../Replays"
+
+    def main():
+        # Creates a generator of all the replays in the dictionary
+        replays = sc2reader.load_replays(PATH, load_level=3)
+        games = []
+        # Loops through every relay
+        for replay in replays:
+            building_order = []
+            if is_terran_vs_terran(replay):
+                # Loops through every event
+                for event in replay.events:
+                    # Check if the event is that a building is crated
+                    if type(event) == sc2reader.events.tracker.UnitInitEvent:
+                        if event.unit.name not in building_order:
+                            building_order.append(event.unit.name)
+                games.append(building_order)
+        return games
+
+
+    def is_terran_vs_terran(replay):
+        try:
+            return sc2reader.constants.LOCALIZED_RACES[replay.players[0].play_race] == "Terran" \
+               and sc2reader.constants.LOCALIZED_RACES[replay.players[1].play_race] == "Terran"
+        except(KeyError):
+            return False
+
+    if __name__ == '__main__':
+        games = main()
+        text = json.dumps(games)
+        print("Res: " + text)
+
+
+SC2Reader has good documation_ that also describe what information
+could be found. `What is in a Replay`_ and Events_ gives a good idea
+if the information you want could be collected with SC2Reader.
+
+.. _documation: https://sc2reader.readthedocs.io/en/latest/index.html
+.. _What is in a Replay: https://sc2reader.readthedocs.io/en/latest/articles/whatsinareplay.html
+.. _Events: https://sc2reader.readthedocs.io/en/latest/events/index.html
+
+ReplayObserver
+--------------
+This is the second technique it is much like using a bot but with the difference
+that no action can be preform just observations.
+
+
+.. code-block:: python
+
+    from library import *
+
+
+    class MyObserver(ReplayObserver):
+        def __init__(self):
+            ReplayObserver.__init__(self)
+
+        def on_game_start(self):
+            ReplayObserver.on_game_start(self)
+
+        def on_step(self):
+            ReplayObserver.on_step(self)
+
+
+    def main():
+
+        coordinator = Coordinator(r"D:/StarCraft II/Versions/Base69232/SC2_x64.exe")
+        if coordinator.load_replay_list("D:/Replays/"):
+            observer = MyObserver()
+            coordinator.add_replay_observer(observer)
+            while coordinator.update():
+                pass
+        else:
+            print("No replays found")
+
+
+    if __name__ == "__main__":
+        main()
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/replayunit.rst b/docs/replayunit.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7d27a67eb9e9e956856a5bced9a4a11723f47285
--- /dev/null
+++ b/docs/replayunit.rst
@@ -0,0 +1,75 @@
+ReplayUnit
+==========
+
+.. class:: library.ReplayUnit
+
+   An instance of the class Unit represents one unit in a replay. A ReplayUnit is a
+   :class:`library.Unit` white some limitations.
+
+   It is possible to use ReplayUnit as keys in a dictionary, which might be helpful
+   for bookkeeping.
+
+   Properties:
+
+   .. autoattribute:: buffs
+
+      Returns a list of BuffID
+
+   .. autoattribute:: build_percentage
+   .. autoattribute:: energy
+   .. autoattribute:: facing
+
+      Returns the direction the unit is facing
+
+   .. autoattribute:: hit_points
+   .. autoattribute:: max_hit_points
+   .. autoattribute:: id
+   .. autoattribute:: is_alive
+   .. autoattribute:: is_blip
+
+      Returns true if unit is a "blip" - a ping on the map.
+
+   .. autoattribute:: is_being_constructed
+
+      Returns build_progress > 0
+
+   .. autoattribute:: is_burrowed
+   .. autoattribute:: is_cloaked
+   .. autoattribute:: is_completed
+
+      Returns build_progress >= 1
+
+   .. autoattribute:: is_flying
+   .. autoattribute:: is_idle
+   .. autoattribute:: is_powered
+   .. autoattribute:: is_training
+   .. autoattribute:: is_valid
+   .. attribute:: ReplayUnit.player
+
+      Returns the constant corresponding to player which this unit belongs to.
+      See :ref:`playerconstants` for more information.
+
+   .. autoattribute:: position
+   .. autoattribute:: current_ability_id
+
+   .. autoattribute:: progress
+
+      Returns the progress of currently used ability (-1 if not using ability)
+
+   .. autoattribute:: radius
+
+      Retruns the radius of the unit
+
+   .. autoattribute:: shields
+   .. autoattribute:: tile_position
+   .. autoattribute:: unit_type
+
+      Returns the :class:`library.UnitType` of the unit
+
+   .. autoattribute:: weapon_cooldown
+   .. autoattribute:: is_carrying_minerals
+
+      Returns if this unit is currently holding minerals
+
+
+.. toctree::
\ No newline at end of file
diff --git a/docs/types.rst b/docs/types.rst
index dd9986f59ffb4543fb5b1165a395d28ff6b5a251..1227e4b87db0148a47be1d818a784188e00a98e8 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -53,3 +53,4 @@ EffectID is for things like ravager bile, or fungal or even a scan.
    :members:
    :undoc-members:
 
+.. toctree::
\ No newline at end of file
diff --git a/docs/unit.rst b/docs/unit.rst
index 16aa1d46c7c8d7ef33073845d400bb05cf11f9ee..55a65d72c4c4f55dfd892d81ad19027c5bbaefc1 100644
--- a/docs/unit.rst
+++ b/docs/unit.rst
@@ -133,3 +133,5 @@ Unit
    .. automethod:: stop_dance
 
       Stop and dance
+
+.. toctree::
\ No newline at end of file
diff --git a/python-api-src/lib_replay_unit.cpp b/python-api-src/lib_replay_unit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6e898aaa64ed3a2b1f86e52eab7f817629b693e8
--- /dev/null
+++ b/python-api-src/lib_replay_unit.cpp
@@ -0,0 +1,42 @@
+#include "library.h"
+
+namespace py = pybind11;
+
+void define_replay_unit(py::module & m)
+{
+	py::class_<ReplayUnit>(m, "ReplayUnit")
+		.def_property_readonly("id", &ReplayUnit::getID)
+		.def_property_readonly("unit_type", &ReplayUnit::getType, "The :class :`library.UnitType` of the unit")
+		.def_property_readonly("position", &ReplayUnit::getPosition, "The :class:`library.Point2D` of the unit")
+		.def_property_readonly("tile_position", &ReplayUnit::getTilePosition, "The :class:`library.Point2DI` of the unit")
+		.def_property_readonly("hit_points", &ReplayUnit::getHitPoints)
+		.def_property_readonly("shields", &ReplayUnit::getShields)
+		.def_property_readonly("energy", &ReplayUnit::getEnergy)
+		.def_property_readonly("player", &ReplayUnit::getPlayer)
+		.def_property_readonly("build_percentage", &ReplayUnit::getBuildPercentage)
+		.def_property_readonly("weapon_cooldown", &ReplayUnit::getWeaponCooldown)
+		.def_property_readonly("is_completed", &ReplayUnit::isCompleted)
+		.def_property_readonly("is_being_constructed", &ReplayUnit::isBeingConstructed)
+		.def_property_readonly("is_cloaked", &ReplayUnit::isCloaked)
+		.def_property_readonly("is_flying", &ReplayUnit::isFlying)
+		.def_property_readonly("buffs", &ReplayUnit::buffs)
+		.def_property_readonly("is_alive", &ReplayUnit::isAlive)
+		.def_property_readonly("is_powered", &ReplayUnit::isPowered)
+		.def_property_readonly("is_idle", &ReplayUnit::isIdle)
+		.def_property_readonly("is_burrowed", &ReplayUnit::isBurrowed)
+		.def_property_readonly("is_valid", &ReplayUnit::isValid)
+		.def_property_readonly("is_training", &ReplayUnit::isTraining)
+		.def_property_readonly("is_blip", &ReplayUnit::isBlip)
+		.def_property_readonly("target", &ReplayUnit::getTarget)
+		.def_property_readonly("has_target", &ReplayUnit::hasTarget)
+		.def_property_readonly("max_hit_points", &ReplayUnit::getMaxHitPoints)
+		.def_property_readonly("progress", &ReplayUnit::getProgress)
+		.def_property_readonly("current_ability_id", &ReplayUnit::getCurrentAbilityID, "The AbilityID of currently used ability")
+		.def_property_readonly("facing", &ReplayUnit::getFacing)
+		.def_property_readonly("radius", &ReplayUnit::getRadius)
+		.def_property_readonly("is_carrying_minerals", &ReplayUnit::isCarryingMinerals)
+		.def("__hash__", [](const ReplayUnit & unit) { return std::hash<const sc2::Unit *>{}(unit.getUnitPtr()); })
+		.def(py::self == py::self)
+		.def("__repr__", [](const ReplayUnit & unit) { return "<Unit of type: '" + unit.getType().getName() + "'>"; })
+		;
+}
diff --git a/python-api-src/lib_tech_tree.cpp b/python-api-src/lib_tech_tree.cpp
index 44012c40d5833fb2530e2c3c156786885473b442..2f388455f8a9647e486b910a7be5f090bb8be353 100644
--- a/python-api-src/lib_tech_tree.cpp
+++ b/python-api-src/lib_tech_tree.cpp
@@ -26,5 +26,7 @@ void define_tech_tree(py::module & m)
 
     py::class_<TechTree>(m, "TechTree")
         .def("get_data", py::overload_cast<const UnitType &>(&TechTree::getData, py::const_))
-        .def("get_data", py::overload_cast<const CCUpgrade &>(&TechTree::getData, py::const_));
+        .def("get_data", py::overload_cast<const CCUpgrade &>(&TechTree::getData, py::const_))
+		.def("suppress_warnings", &TechTree::setSuppressWarnings, "Suppress type and uppgrade warnings" ,"b"_a)
+		;
 }
diff --git a/python-api-src/library.cpp b/python-api-src/library.cpp
index 09e5067015fa373382a85cf07039dbf87b1cfc83..07700758413ec714ed641ee4bd360ee1333952b8 100644
--- a/python-api-src/library.cpp
+++ b/python-api-src/library.cpp
@@ -8,6 +8,7 @@ PYBIND11_MODULE(library, m)
 
     define_typeenums(m);
     define_unit(m);
+	define_replay_unit(m);
     define_unittype(m);
     define_util(m);
     define_point(m);
@@ -26,7 +27,11 @@ PYBIND11_MODULE(library, m)
         .def("launch_starcraft", &sc2::Coordinator::LaunchStarcraft)
         .def("start_game", &sc2::Coordinator::StartGame, "map_path"_a)
         .def("update", &sc2::Coordinator::Update)
-        .def("set_real_time", &sc2::Coordinator::SetRealtime);
+        .def("set_real_time", &sc2::Coordinator::SetRealtime)
+		.def("load_replay_list",&sc2::Coordinator::SetReplayPath, "replay_path"_a)
+		.def("add_replay_observer",&sc2::Coordinator::AddReplayObserver, "replay_observer"_a)
+		.def("set_replay_perspective",&sc2::Coordinator::SetReplayPerspective, "perspective"_a)
+		;
 
     py::enum_<sc2::Race>(m, "Race")
         .value("Terran", sc2::Race::Terran)
@@ -121,6 +126,33 @@ PYBIND11_MODULE(library, m)
 
 	// API extended summer 2020
 
+
+
+	py::class_<sc2::ReplayObserver>(m, "ReplayObserver")
+		.def(py::init());
+
+	py::class_<IDAReplayObserver, PyReplayObserver, sc2::ReplayObserver>(m, "IDAReplayObserver")
+		.def(py::init())
+		.def("on_game_start", &IDAReplayObserver::OnGameStart)
+		.def("on_step", &IDAReplayObserver::OnStep)
+		.def("on_game_end", &IDAReplayObserver::OnGameEnd)
+		.def("get_all_units", &IDAReplayObserver::GetAllUnits, "Returns a list of all units")
+		.def("get_player_race", &IDAReplayObserver::GetPlayerRace,"player_id"_a)
+		.def("get_replay_path", &IDAReplayObserver::GetReplayPath)
+		.def("get_result_for_player", &IDAReplayObserver::GetResultForPlayer, "player_id"_a)
+		.def("on_unit_destroyed", &IDAReplayObserver::OnReplayUnitDestroyed, "unit"_a)
+		.def("on_unit_created", &IDAReplayObserver::OnReplayUnitCreated, "unit"_a)
+		.def_property_readonly("tech_tree", &IDAReplayObserver::GetTechTree)
+		;
+
+	
+
+	py::enum_<sc2::GameResult>(m, "GameResult")
+		.value("Win", sc2::GameResult::Win)
+		.value("Loss", sc2::GameResult::Loss)
+		.value("Tie", sc2::GameResult::Tie)
+		.value("Undecided", sc2::GameResult::Undecided);
+
     py::class_<sc2::PlayerSetup>(m, "PlayerSetup");
 
     py::enum_<sc2::Difficulty>(m, "Difficulty")
diff --git a/python-api-src/library.h b/python-api-src/library.h
index fb671e11555b6bfad74f8fc45baf7093a3b89e6c..3f9114d0685218dec0f51e838031976f622c5709 100644
--- a/python-api-src/library.h
+++ b/python-api-src/library.h
@@ -3,6 +3,7 @@
 #include <pybind11/pybind11.h>
 #include <sc2api/sc2_api.h>
 #include "../src/IDABot.h"
+#include "../src/IDAReplayObserver.h"
 #include <iostream>
 #include <pybind11/stl.h> /* Automatic conversion from std::vector to Python lists */
 #include <pybind11/operators.h> /* Convenient operator support */
@@ -21,7 +22,7 @@ public:
     }
 
     Coordinator(std::string path) : sc2::Coordinator()
-    {
+    {	
         std::vector<std::string> arguments = { "pycommandcenter", "-e", path };
         CustomLoadSettings(arguments);
     }
@@ -61,10 +62,67 @@ public:
     }
 };
 
+
+class PyReplayObserver : public IDAReplayObserver
+{
+public:
+	using IDAReplayObserver::IDAReplayObserver;
+	void OnGameStart() override
+	{
+		PYBIND11_OVERLOAD_NAME(
+			void,
+			IDAReplayObserver,
+			"on_game_start",
+			OnGameStart
+		);
+	}
+	void OnStep() override
+	{
+		PYBIND11_OVERLOAD_NAME(
+			void,
+			IDAReplayObserver,
+			"on_step",
+			OnStep
+		);
+	}
+	void OnGameEnd() override
+	{
+		PYBIND11_OVERLOAD_NAME(
+			void,
+			IDAReplayObserver,
+			"on_game_end",
+			OnGameEnd
+
+		);
+	}
+	void OnReplayUnitDestroyed(const ReplayUnit *unit) override
+	{
+		PYBIND11_OVERLOAD_NAME(
+			void,
+			IDAReplayObserver,
+			"on_unit_destroyed",
+			OnReplayUnitDestroyed,
+			unit
+		);
+	}
+	void OnReplayUnitCreated(const ReplayUnit *unit) override
+	{
+		PYBIND11_OVERLOAD_NAME(
+			void,
+			IDAReplayObserver,
+			"on_unit_created",
+			OnReplayUnitCreated,
+			unit
+		);
+	}
+	
+};
+
 // The functions below are all defined in different .cpp files, in order 
 // to keep compilation snappy
 void define_typeenums(pybind11::module & m);
 void define_unit(pybind11::module & m);
+void define_replay_unit(pybind11::module & m);
 void define_unittype(pybind11::module &m);
 void define_util(pybind11::module &m);
 void define_point(pybind11::module &m);
diff --git a/src/IDABot.cpp b/src/IDABot.cpp
index cda0ce75922c415a037b86161fb74089a09cede9..10c29c16ce0c28d2cd0b6bf40a7a62ea33ee1140 100644
--- a/src/IDABot.cpp
+++ b/src/IDABot.cpp
@@ -72,12 +72,11 @@ void IDABot::OnStep()
 	m_map.onFrame();
 	m_unitInfo.onFrame();
 	m_bases.onFrame();
-
 	// -----------------------------------------------------------------
 	// Draw debug interface, and send debug interface to the Sc2 client.
 	// -----------------------------------------------------------------
 	Debug()->SendDebug();
-    m_buildingPlacer.drawReservedTiles();
+	m_buildingPlacer.drawReservedTiles();
 }
 
 void IDABot::setUnits()
diff --git a/src/IDAReplayObserver.cpp b/src/IDAReplayObserver.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53be250dbb8a6acd746c432716f35c400fd8ea0c
--- /dev/null
+++ b/src/IDAReplayObserver.cpp
@@ -0,0 +1,132 @@
+#include "IDAReplayObserver.h"
+#include "Util.h"
+
+void IDAReplayObserver::setUnits()
+{
+	m_allUnits.clear();
+	m_allUnitsID.clear();
+	for (auto & unit : Observation()->GetUnits())
+	{
+		ReplayUnit replayUnit = ReplayUnit(unit, *this);
+		m_allUnits.push_back(replayUnit);
+		m_allUnitsID.insert(replayUnit.getID());
+	}
+}
+
+IDAReplayObserver::IDAReplayObserver():
+	sc2::ReplayObserver(),
+	m_techTree(*this)
+{
+}
+
+void IDAReplayObserver::OnGameStart()
+{
+	setUnits();
+	m_techTree.onStart();
+
+}
+
+void IDAReplayObserver::OnStep()
+{
+	setUnits();
+}
+
+void IDAReplayObserver::OnGameEnd()
+{
+}
+
+void IDAReplayObserver::OnUnitDestroyed(const sc2::Unit* unit)
+{
+	ReplayUnit unitInformation = ReplayUnit(unit, *this);
+	OnReplayUnitDestroyed(&unitInformation);
+}
+
+void IDAReplayObserver::OnReplayUnitDestroyed(const ReplayUnit *)
+{
+	
+}
+
+void IDAReplayObserver::OnUnitCreated(const sc2::Unit * unit)
+{
+	ReplayUnit unitInformation = ReplayUnit(unit, *this);
+	OnReplayUnitCreated(&unitInformation);
+}
+
+void IDAReplayObserver::OnReplayUnitCreated(const ReplayUnit *)
+{
+}
+
+void IDAReplayObserver::OnBuildingConstructionComplete(const sc2::Unit *unit)
+{
+	ReplayUnit unitInformation = ReplayUnit(unit, *this);
+	OnReplayUnitCreated(&unitInformation);
+}
+
+
+
+
+ReplayUnit IDAReplayObserver::GetUnit(const CCUnitID tag) const
+{	
+	
+		return ReplayUnit(Observation()->GetUnit(tag), *(IDAReplayObserver *)this);
+
+}
+
+bool IDAReplayObserver::UnitExists(const CCUnitID tag) const
+{
+	return m_allUnitsID.find(tag) != m_allUnitsID.end();
+	
+}
+
+
+
+
+
+
+const std::vector<ReplayUnit>& IDAReplayObserver::GetAllUnits() const
+{
+
+	return m_allUnits;
+}
+
+CCRace IDAReplayObserver::GetPlayerRace(int player)
+{	
+	return ReplayControl()->GetReplayInfo().players[player].race;
+}
+
+std::string IDAReplayObserver::GetReplayPath()
+{
+	return ReplayControl()->GetReplayInfo().replay_path;
+}
+
+sc2::GameResult IDAReplayObserver::GetResultForPlayer(int player)
+{
+	return ReplayControl()->GetReplayInfo().players[player].game_result;
+}
+
+const TechTree & IDAReplayObserver::GetTechTree() const
+{
+	return m_techTree;
+}
+
+const TypeData & IDAReplayObserver::Data(const UnitType & type) const
+{
+	return m_techTree.getData(type);
+}
+
+const TypeData & IDAReplayObserver::Data(const CCUpgrade & type) const
+{
+	return m_techTree.getData(type);
+}
+
+const TypeData & IDAReplayObserver::Data(const MetaType & type) const
+{
+	return m_techTree.getData(type);
+}
+
+const TypeData & IDAReplayObserver::Data(const Unit & unit) const
+{
+	return m_techTree.getData(unit.getType());
+}
+
+
diff --git a/src/IDAReplayObserver.h b/src/IDAReplayObserver.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe620b535372e15d5a11ba18c6e46d7b86269ce4
--- /dev/null
+++ b/src/IDAReplayObserver.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <deque>
+#include <limits>
+
+#include "Common.h"
+#include "ReplayUnit.h"
+#include "TechTree.h"
+
+
+class ReplayUnit;
+
+class IDAReplayObserver : public sc2::ReplayObserver
+{
+	void setUnits();
+	std::vector<ReplayUnit>       m_allUnits;
+	std::set<CCUnitID>         m_allUnitsID;
+	TechTree                m_techTree;
+
+
+
+public:
+	IDAReplayObserver();
+	
+	void OnGameStart() override;
+	void OnStep() override;
+	void OnGameEnd() override;
+	void OnUnitDestroyed(const sc2::Unit*) override;
+	virtual void OnReplayUnitDestroyed(const ReplayUnit*);
+	void OnUnitCreated(const sc2::Unit*);
+	virtual void OnReplayUnitCreated(const ReplayUnit*);
+	void OnBuildingConstructionComplete(const sc2::Unit*);
+
+	ReplayUnit GetUnit(const CCUnitID tag) const;
+	bool UnitExists(const CCUnitID tag) const;
+
+
+	const std::vector<ReplayUnit> & GetAllUnits() const;
+	CCRace GetPlayerRace(int player);
+	std::string GetReplayPath();
+	sc2::GameResult GetResultForPlayer(int player);
+
+	const TechTree & GetTechTree() const;
+
+	const TypeData & Data(const UnitType & type) const;
+	const TypeData & Data(const CCUpgrade & type) const;
+	const TypeData & Data(const MetaType & type) const;
+	const TypeData & Data(const Unit & unit) const;
+
+};
+
diff --git a/src/ReplayUnit.cpp b/src/ReplayUnit.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e2c100d73ed4efdb9f69a491794688d58f018f2
--- /dev/null
+++ b/src/ReplayUnit.cpp
@@ -0,0 +1,56 @@
+#include "ReplayUnit.h"
+
+
+
+ReplayUnit::ReplayUnit(const sc2::Unit * unit, IDAReplayObserver & replayObserver)
+	: m_replayObserver(&replayObserver), Unit(unit), m_type(unit->unit_type, replayObserver, replayObserver)
+{
+	
+}
+
+const UnitType & ReplayUnit::getType() const
+{
+	return m_type;
+}
+
+bool ReplayUnit::hasTarget() const
+{
+	BOT_ASSERT(isValid(), "Unit is not valid");
+	if (getUnitPtr()->orders.size() > 0) {
+		if (getUnitPtr()->orders[0].target_unit_tag != NULL) {
+			CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
+			// IDAReplayObserver checks if the unit with this tag still exists
+			if (m_replayObserver->UnitExists(t_id)){
+				// IDAReplayObserver finds the unit with this tag, and returns true if valid
+				return m_replayObserver->GetUnit(t_id).isValid();
+			}
+		}
+	}
+
+	return false;
+}
+
+ReplayUnit ReplayUnit::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;
+		// Checks if the tag is a null tag or the unit have been removed
+		if (t_id != sc2::NullTag && m_replayObserver->UnitExists(t_id)){
+			// IDAReplayObserver finds the unit with this tag
+			return m_replayObserver->GetUnit(t_id);
+		}
+	}
+	return *this;
+}
+
+int ReplayUnit::getPlayer() const
+{
+	return m_unit->owner;
+}
+
+
diff --git a/src/ReplayUnit.h b/src/ReplayUnit.h
new file mode 100644
index 0000000000000000000000000000000000000000..23fc50c1e7fc37de672ae04f9e39a8767f559e70
--- /dev/null
+++ b/src/ReplayUnit.h
@@ -0,0 +1,22 @@
+#pragma once
+#include "Unit.h"
+#include "IDAReplayObserver.h"
+
+class IDAReplayObserver;
+
+//! A Unit that have a replayobserver insted of an Agent, 
+class ReplayUnit: public Unit
+{
+	mutable IDAReplayObserver * m_replayObserver;
+	UnitType m_type;
+
+public:
+		ReplayUnit(const sc2::Unit * unit, IDAReplayObserver & replayObserver);
+
+		const UnitType & getType() const;
+		bool hasTarget() const;
+		ReplayUnit getTarget() const;
+		int getPlayer() const;
+
+
+};
\ No newline at end of file
diff --git a/src/TechTree.cpp b/src/TechTree.cpp
index aca2be4e7d6614d41de6714f8523e2cbbc634b5d..d0a94c49e05cc43eb9f9f6063029dc40783fb284 100644
--- a/src/TechTree.cpp
+++ b/src/TechTree.cpp
@@ -2,8 +2,8 @@
 #include "IDABot.h"
 #include "MetaType.h"
 
-TechTree::TechTree(IDABot & bot)
-    : m_bot(bot)
+TechTree::TechTree(sc2::Client & client)
+    : m_client(client), suppressWarnings(false)
 {
 
 }
@@ -31,7 +31,7 @@ void TechTree::onStart()
 
     for (const BuildDescription & description : tree.BuildDescriptions())
     {
-        if (m_unitTypeData.count(UnitType(description.result_type, m_bot)) == 0)
+        if (m_unitTypeData.count(UnitType(description.result_type, m_client)) == 0)
         {
             //std::cout << "Inserting new information about UNIT_TYPEID: " 
             //    << sc2::UnitTypeToName(description.result_type) << " (" 
@@ -39,7 +39,7 @@ void TechTree::onStart()
             //    << std::endl;
         }
 
-        TypeData & data = m_unitTypeData[UnitType(description.result_type, m_bot)];
+        TypeData & data = m_unitTypeData[UnitType(description.result_type, m_client)];
 
         // If this is the first time we a way to build this type, remove previous data
         if (updated.count(description.result_type) == 0)
@@ -53,19 +53,19 @@ void TechTree::onStart()
             data.buildAbility = sc2::ABILITY_ID::INVALID;
         }
 
-        data.whatBuilds.push_back(UnitType(description.producer_type, m_bot));
+        data.whatBuilds.push_back(UnitType(description.producer_type, m_client));
 
         if (description.build_ability != sc2::ABILITY_ID::INVALID) data.buildAbility = description.build_ability;
         if (description.morph_ability != sc2::ABILITY_ID::INVALID) data.morphAbility = description.morph_ability;
 
         for (sc2::UNIT_TYPEID unit_typeid : description.buildings_needed)
         {
-            data.requiredUnits.push_back(UnitType(unit_typeid, m_bot));
+            data.requiredUnits.push_back(UnitType(unit_typeid, m_client));
         }
 
         for (sc2::UNIT_TYPEID unit_typeid : description.addons_needed)
         {
-            data.requiredAddons.push_back(UnitType(unit_typeid, m_bot));
+            data.requiredAddons.push_back(UnitType(unit_typeid, m_client));
         }
     }
 
@@ -81,11 +81,11 @@ void TechTree::onStart()
         for (const ResearchDescription & description : tree.HowToResearch(id))
         {
             data.buildAbility = description.ability_used;
-            data.whatBuilds.push_back(UnitType(description.producer_type, m_bot));
+            data.whatBuilds.push_back(UnitType(description.producer_type, m_client));
 
             for (sc2::UNIT_TYPEID unit_typeid : description.buildings_needed)
             {
-                data.requiredUnits.push_back(UnitType(unit_typeid, m_bot));
+                data.requiredUnits.push_back(UnitType(unit_typeid, m_client));
             }
 
             for (sc2::UPGRADE_ID upgrade_id : description.upgrades_needed)
@@ -96,158 +96,163 @@ void TechTree::onStart()
     }
 }
 
+void TechTree::setSuppressWarnings(bool b)
+{
+	suppressWarnings = b;
+}
+
 
 void TechTree::initUnitTypeData()
 {
-    m_unitTypeData[UnitType(0, m_bot)] = TypeData();
+    m_unitTypeData[UnitType(0, m_client)] = TypeData();
 
     // Protoss Buildings                                                                                  unit  bld   wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLONOVERCHARGED, m_bot)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::EFFECT_PHOTONOVERCHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_bot), UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_bot)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::BUILD_PYLON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_NEXUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR, m_bot)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_ASSIMILATOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot)] =         { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_CYBERNETICSCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot), UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot)] =              { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_DARKSHRINE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FLEETBEACON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FORGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GATEWAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot)] =                { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOTONCANNON, m_bot)] =            { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_PHOTONCANNON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSBAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSFACILITY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot)] =          { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TEMPLARARCHIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot)] =         { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TWILIGHTCOUNCIL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_bot)] =                { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, {}, { sc2::UPGRADE_ID::WARPGATERESEARCH } }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLONOVERCHARGED, m_client)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::EFFECT_PHOTONOVERCHARGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_client), UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PYLON, m_client)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::BUILD_PYLON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_NEXUS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ASSIMILATOR, m_client)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_ASSIMILATOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client)] =         { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_CYBERNETICSCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client), UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client)] =              { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_DARKSHRINE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FLEETBEACON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client)] =                   { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FORGE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client)] =                 { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GATEWAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client)] =                { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOTONCANNON, m_client)] =            { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_PHOTONCANNON, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSBAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROBOTICSFACILITY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client)] =          { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TEMPLARARCHIVE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client)] =         { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_TWILIGHTCOUNCIL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPGATE, m_client)] =                { sc2::Race::Protoss, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, {}, { sc2::UPGRADE_ID::WARPGATERESEARCH } }; 
 
     // Protoss Units                                                                                      unit  bld   wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_bot)] =                   { sc2::Race::Protoss, 0, 0, 1, 0, true, false,  true, false, false, false, false, sc2::ABILITY_ID::TRAIN_PROBE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_bot)] =          { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MOTHERSHIPCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ZEALOT, m_bot)] =                  { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZEALOT, sc2::ABILITY_ID::TRAINWARP_ZEALOT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_SENTRY, m_bot)] =                  { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SENTRY, sc2::ABILITY_ID::TRAINWARP_SENTRY, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STALKER, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_STALKER, sc2::ABILITY_ID::TRAINWARP_STALKER, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_HIGHTEMPLAR, m_bot)] =             { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HIGHTEMPLAR, sc2::ABILITY_ID::TRAINWARP_HIGHTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKTEMPLAR, m_bot)] =             { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DARKTEMPLAR, sc2::ABILITY_ID::TRAINWARP_DARKTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ADEPT, m_bot)] =                   { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ADEPT, sc2::ABILITY_ID::TRAINWARP_ADEPT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_COLOSSUS, m_bot)] =                { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_COLOSSUS,  0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DISRUPTOR, m_bot)] =               { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DISRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPPRISM, m_bot)] =               { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WARPPRISM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_OBSERVER, m_bot)] =                { sc2::Race::Protoss, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_OBSERVER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_IMMORTAL, m_bot)] =                { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_IMMORTAL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CARRIER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_bot)] =                  { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ORACLE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOENIX, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_PHOENIX, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_VOIDRAY, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VOIDRAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, {}, {} };  
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPEST, m_bot)] =                 { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_TEMPEST, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_INTERCEPTOR, m_bot)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INTERCEPTORS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLESTASISTRAP, m_bot)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STASISTRAP, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_bot) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PROBE, m_client)] =                   { sc2::Race::Protoss, 0, 0, 1, 0, true, false,  true, false, false, false, false, sc2::ABILITY_ID::TRAIN_PROBE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_MOTHERSHIPCORE, m_client)] =          { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MOTHERSHIPCORE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_NEXUS, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ZEALOT, m_client)] =                  { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZEALOT, sc2::ABILITY_ID::TRAINWARP_ZEALOT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_SENTRY, m_client)] =                  { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SENTRY, sc2::ABILITY_ID::TRAINWARP_SENTRY, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_STALKER, m_client)] =                 { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_STALKER, sc2::ABILITY_ID::TRAINWARP_STALKER, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_HIGHTEMPLAR, m_client)] =             { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HIGHTEMPLAR, sc2::ABILITY_ID::TRAINWARP_HIGHTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKTEMPLAR, m_client)] =             { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DARKTEMPLAR, sc2::ABILITY_ID::TRAINWARP_DARKTEMPLAR, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ADEPT, m_client)] =                   { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ADEPT, sc2::ABILITY_ID::TRAINWARP_ADEPT, { UnitType(sc2::UNIT_TYPEID::PROTOSS_GATEWAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_COLOSSUS, m_client)] =                { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_COLOSSUS,  0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_DISRUPTOR, m_client)] =               { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DISRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_WARPPRISM, m_client)] =               { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WARPPRISM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_OBSERVER, m_client)] =                { sc2::Race::Protoss, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_OBSERVER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_IMMORTAL, m_client)] =                { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_IMMORTAL, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSFACILITY, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_client)] =                 { sc2::Race::Protoss, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CARRIER, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_client)] =                  { sc2::Race::Protoss, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ORACLE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_PHOENIX, m_client)] =                 { sc2::Race::Protoss, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_PHOENIX, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_VOIDRAY, m_client)] =                 { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VOIDRAY, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, {}, {} };  
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPEST, m_client)] =                 { sc2::Race::Protoss, 0, 0, 4, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_TEMPEST, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_STARGATE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_INTERCEPTOR, m_client)] =             { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INTERCEPTORS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CARRIER, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLESTASISTRAP, m_client)] =        { sc2::Race::Protoss, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STASISTRAP, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_ORACLE, m_client) }, {}, {} }; 
 
     // Terran Buildings                                                                      m  g  s  t  unit  bld   wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)] =            { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_COMMANDCENTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot)] =              { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::BUILD_SUPPLYDEPOT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };  
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REFINERY, m_bot)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_REFINERY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot)] =                   { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ARMORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SENSORTOWER, m_bot)] =              { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SENSORTOWER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot)] =                  { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FUSIONCORE, m_bot)] =               { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FUSIONCORE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot)] =             { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GHOSTACADEMY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BUNKER, m_bot)] =                   { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BUNKER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ENGINEERINGBAY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MISSILETURRET, m_bot)] =            { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_MISSILETURRET, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_ORBITALCOMMAND, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot)] =        { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_PLANETARYFORTRESS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)] =            { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_COMMANDCENTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client)] =              { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false,  true, false, false, sc2::ABILITY_ID::BUILD_SUPPLYDEPOT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };  
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REFINERY, m_client)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_REFINERY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client)] =                   { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ARMORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SENSORTOWER, m_client)] =              { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SENSORTOWER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client)] =                  { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FUSIONCORE, m_client)] =               { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_FUSIONCORE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client)] =                 { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client)] =             { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_GHOSTACADEMY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BUNKER, m_client)] =                   { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BUNKER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ENGINEERINGBAY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MISSILETURRET, m_client)] =            { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_MISSILETURRET, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_ORBITALCOMMAND, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client)] =        { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_PLANETARYFORTRESS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {} };
 
     // Terran Addons                                                                         m  g  s  t  unit  bld   wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSREACTOR, m_bot)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYREACTOR, m_bot)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTREACTOR, m_bot)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSREACTOR, m_client)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_BARRACKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYREACTOR, m_client)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client)] =           { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_FACTORY, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTREACTOR, m_client)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_REACTOR_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client)] =          { sc2::Race::Terran, 0, 0, 0, 0, true, true, false, false, false, false, true, sc2::ABILITY_ID::BUILD_TECHLAB_STARPORT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
 
     // Terran Equivalent Buildings
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_bot)] =       m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_bot)];
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_bot)] =           m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot)];
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_bot)] =      m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)];
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_bot)] =            m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot)];
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_bot)] =     m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)];
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_bot)] =           m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOTLOWERED, m_client)] =       m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SUPPLYDEPOT, m_client)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSFLYING, m_client)] =           m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTERFLYING, m_client)] =      m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYFLYING, m_client)] =            m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMANDFLYING, m_client)] =     m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)];
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTFLYING, m_client)] =           m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client)];
 
     // Terran Units                                                                          m  g  s  t  unit  bld    wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot)] =                      { sc2::Race::Terran, 0, 0, 1, 0, true, false,  true, false, false, false, false, sc2::ABILITY_ID::TRAIN_SCV, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOST, m_bot)] =                    { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_GHOST, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARAUDER, m_bot)] =                 { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARAUDER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARINE, m_bot)] =                   { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REAPER, m_bot)] =                   { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_REAPER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_HELLION, m_bot)] =                  { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HELLION, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_CYCLONE, m_bot)] =                  { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CYCLONE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };  
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SIEGETANK, m_bot)] =                { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SIEGETANK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THOR, m_bot)] =                     { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} };  
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_WIDOWMINE, m_bot)] =                { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WIDOWMINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_NUKE, m_bot)] =                     { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NUKE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BANSHEE, m_bot)] =                  { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANSHEE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BATTLECRUISER, m_bot)] =            { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BATTLECRUISER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_LIBERATOR, m_bot)] =                { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_LIBERATOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_VIKINGFIGHTER, m_bot)] =            { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIKINGFIGHTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_RAVEN, m_bot)] =                    { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_RAVEN, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_bot), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MEDIVAC, m_bot)] =                  { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MEDIVAC, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_bot) }, {}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MULE, m_bot)] =                     { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot) }, {}, {} }; 
-	m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THORAP, m_bot)] =                   { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0,{ UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_bot) },{},{} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client)] =                      { sc2::Race::Terran, 0, 0, 1, 0, true, false,  true, false, false, false, false, sc2::ABILITY_ID::TRAIN_SCV, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_GHOST, m_client)] =                    { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_GHOST, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARAUDER, m_client)] =                 { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARAUDER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MARINE, m_client)] =                   { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MARINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_REAPER, m_client)] =                   { sc2::Race::Terran, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_REAPER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKS, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_HELLION, m_client)] =                  { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HELLION, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_CYCLONE, m_client)] =                  { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CYCLONE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };  
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_SIEGETANK, m_client)] =                { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SIEGETANK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THOR, m_client)] =                     { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} };  
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_WIDOWMINE, m_client)] =                { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_WIDOWMINE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_NUKE, m_client)] =                     { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NUKE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BANSHEE, m_client)] =                  { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BANSHEE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_BATTLECRUISER, m_client)] =            { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_BATTLECRUISER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_LIBERATOR, m_client)] =                { sc2::Race::Terran, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_LIBERATOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_VIKINGFIGHTER, m_client)] =            { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIKINGFIGHTER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_RAVEN, m_client)] =                    { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_RAVEN, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_TECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORYTECHLAB, m_client), UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MEDIVAC, m_client)] =                  { sc2::Race::Terran, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MEDIVAC, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORT, m_client) }, {}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_MULE, m_client)] =                     { sc2::Race::Terran, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::EFFECT_CALLDOWNMULE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client) }, {}, {} }; 
+	m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_THORAP, m_client)] =                   { sc2::Race::Terran, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_THOR, 0,{ UnitType(sc2::UNIT_TYPEID::TERRAN_FACTORY, m_client) },{},{} };
 
     // Zerg Buildings                                                                      m  g  s  t  unit  bld   wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_HATCHERY, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EXTRACTOR, m_bot)] =                  { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_EXTRACTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPAWNINGPOOL, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot)] =           { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_EVOLUTIONCHAMBER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BANELINGNEST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_HYDRALISKDEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot)] =             { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INFESTATIONPIT, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSCANAL, m_bot)] =                 { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSWORM, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSNETWORK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot)] =                { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROACHWARREN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPINECRAWLER, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPINECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_GREATERSPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPORECRAWLER, m_bot)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPORECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot)] =            { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ULTRALISKCAVERN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)] =                       { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::MORPH_LAIR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot) }, {UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot)}, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot)] =                       { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::MORPH_HIVE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };  
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::BUILD_HATCHERY, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EXTRACTOR, m_client)] =                  { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false,  true, false, false, false, sc2::ABILITY_ID::BUILD_EXTRACTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPAWNINGPOOL, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client)] =           { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_EVOLUTIONCHAMBER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_BANELINGNEST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_HYDRALISKDEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client)] =             { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_INFESTATIONPIT, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSCANAL, m_client)] =                 { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSWORM, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_NYDUSNETWORK, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_NYDUSNETWORK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client)] =                { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ROACHWARREN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPINECRAWLER, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPINECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client)] =                      { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::MORPH_GREATERSPIRE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SPORECRAWLER, m_client)] =               { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_SPORECRAWLER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client)] =            { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false, false, false, sc2::ABILITY_ID::BUILD_ULTRALISKCAVERN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)] =                       { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::MORPH_LAIR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client) }, {UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client)}, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client)] =                       { sc2::Race::Zerg, 0, 0, 0, 0, true, true, false, false, false,  true, false, sc2::ABILITY_ID::MORPH_HIVE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };  
 
     // Zerg Units                                                                          m  g  s  t  unit  bld    wrk    rfn    sup    hall   add
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_OVERLORD, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false,  true, false, false, sc2::ABILITY_ID::TRAIN_OVERLORD, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELING, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::MORPH_BANELING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot) }, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_CORRUPTOR, m_bot)] =                  { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CORRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DRONE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, {}, {} }; 
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISK, m_bot)] =                  { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HYDRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LURKERDENMP, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTOR, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_INFESTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_MUTALISK, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MUTALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACH, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ROACH, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SWARMHOSTMP, m_bot)] =                { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SWARMHOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISK, m_bot)] =                  { sc2::Race::Zerg, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ULTRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_VIPER, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIPER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ZERGLING, m_bot)] =                   { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZERGLING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_QUEEN, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_QUEEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_bot)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EGG, m_bot)] =                        { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_OVERLORD, m_client)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false,  true, false, false, sc2::ABILITY_ID::TRAIN_OVERLORD, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_BANELING, m_client)] =                   { sc2::Race::Zerg, 0, 0, 0, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::MORPH_BANELING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client) }, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_CORRUPTOR, m_client)] =                  { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_CORRUPTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_DRONE, m_client)] =                      { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_DRONE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, {}, {} }; 
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISK, m_client)] =                  { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_HYDRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LURKERDENMP, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_INFESTOR, m_client)] =                   { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_INFESTOR, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_MUTALISK, m_client)] =                   { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_MUTALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ROACH, m_client)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ROACH, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_SWARMHOSTMP, m_client)] =                { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_SWARMHOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISK, m_client)] =                  { sc2::Race::Zerg, 0, 0, 6, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ULTRALISK, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_VIPER, m_client)] =                      { sc2::Race::Zerg, 0, 0, 3, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_VIPER, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_ZERGLING, m_client)] =                   { sc2::Race::Zerg, 0, 0, 1, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_ZERGLING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_QUEEN, m_client)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, sc2::ABILITY_ID::TRAIN_QUEEN, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LARVA, m_client)] =                      { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_EGG, m_client)] =                        { sc2::Race::Zerg, 0, 0, 2, 0, true, false, false, false, false, false, false, 0, 0, { UnitType() }, { UnitType() }, {} };
 
     // Set the Mineral / Gas cost of each unit
     for (auto & kv : m_unitTypeData)
     {
         if (!kv.first.isValid()) { continue; }
         
-        auto & data = m_bot.Observation()->GetUnitTypeData()[kv.first.getAPIUnitType()];
+        auto & data = m_client.Observation()->GetUnitTypeData()[kv.first.getAPIUnitType()];
                 
         kv.second.mineralCost = data.mineral_cost;
         kv.second.gasCost     = data.vespene_cost;
     }
 
     // fix the cumulative prices of morphed buildings
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)).mineralCost;
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot)).mineralCost;
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)).mineralCost;
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_bot)).mineralCost;
-    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot)).mineralCost;
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)).mineralCost;
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client)).mineralCost;
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_PLANETARYFORTRESS, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)).mineralCost;
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::TERRAN_ORBITALCOMMAND, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::TERRAN_COMMANDCENTER, m_client)).mineralCost;
+    m_unitTypeData[UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client)].mineralCost -= getData(UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client)).mineralCost;
 }
 
 void TechTree::initUpgradeData()
@@ -256,102 +261,105 @@ void TechTree::initUpgradeData()
     m_upgradeData[0] = TypeData();
 
     // Terran Upgrades
-    m_upgradeData[sc2::UPGRADE_ID::BANSHEECLOAK] =                      { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEECLOAKINGFIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::BANSHEESPEED] =                      { sc2::Race::Terran, 200, 200, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEEHYPERFLIGHTROTORS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::BATTLECRUISERENABLESPECIALIZATIONS]= { sc2::Race::Terran, 150, 150, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BATTLECRUISERWEAPONREFIT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::DRILLCLAWS] =                        { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_DRILLINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::HIGHCAPACITYBARRELS] =               { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INFERNALPREIGNITER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::HISECAUTOTRACKING] =                 { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HISECAUTOTRACKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::LIBERATORAGRANGEUPGRADE] =           { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADVANCEDBALLISTICS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::MAGFIELDLAUNCHERS] =                 { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CYCLONELOCKONDAMAGE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::MEDIVACINCREASESPEEDBOOST] =         { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HIGHCAPACITYFUELTANKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::NEOSTEELFRAME] =                     { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEOSTEELFRAME, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PERSONALCLOAKING] =                  { sc2::Race::Terran, 150, 150, 0, 1920, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PERSONALCLOAKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PUNISHERGRENADES] =                  { sc2::Race::Terran,  50,  50, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CONCUSSIVESHELLS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::RAVENCORVIDREACTOR] =                { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENCORVIDREACTOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::RAVENRECALIBRATEDEXPLOSIVES] =       { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENRECALIBRATEDEXPLOSIVES, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::SHIELDWALL] =                        { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_COMBATSHIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::STIMPACK] =                          { sc2::Race::Terran, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_STIMPACK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANBUILDINGARMOR] =               { sc2::Race::Terran, 150, 150, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSTRUCTUREARMORUPGRADE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1] =        { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2] =        { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL3] =        { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1] =       { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2] =       { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL3] =       { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_bot) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1] =           { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2] =           { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL3] =           { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1] =  { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2] =  { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL3] =  { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1] =        { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2] =        { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL3] =        { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_bot) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::BANSHEECLOAK] =                      { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEECLOAKINGFIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::BANSHEESPEED] =                      { sc2::Race::Terran, 200, 200, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BANSHEEHYPERFLIGHTROTORS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::BATTLECRUISERENABLESPECIALIZATIONS]= { sc2::Race::Terran, 150, 150, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BATTLECRUISERWEAPONREFIT, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::DRILLCLAWS] =                        { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_DRILLINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::HIGHCAPACITYBARRELS] =               { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INFERNALPREIGNITER, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::HISECAUTOTRACKING] =                 { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HISECAUTOTRACKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::LIBERATORAGRANGEUPGRADE] =           { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADVANCEDBALLISTICS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_STARPORTTECHLAB, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::MAGFIELDLAUNCHERS] =                 { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CYCLONELOCKONDAMAGE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::MEDIVACINCREASESPEEDBOOST] =         { sc2::Race::Terran, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_HIGHCAPACITYFUELTANKS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::NEOSTEELFRAME] =                     { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEOSTEELFRAME, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PERSONALCLOAKING] =                  { sc2::Race::Terran, 150, 150, 0, 1920, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PERSONALCLOAKING, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_GHOSTACADEMY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PUNISHERGRENADES] =                  { sc2::Race::Terran,  50,  50, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CONCUSSIVESHELLS, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::RAVENCORVIDREACTOR] =                { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENCORVIDREACTOR, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::RAVENRECALIBRATEDEXPLOSIVES] =       { sc2::Race::Terran, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_RAVENRECALIBRATEDEXPLOSIVES, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::SHIELDWALL] =                        { sc2::Race::Terran, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_COMBATSHIELD, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_BARRACKSTECHLAB, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::STIMPACK] =                          { sc2::Race::Terran, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_STIMPACK, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_SCV, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANBUILDINGARMOR] =               { sc2::Race::Terran, 150, 150, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSTRUCTUREARMORUPGRADE, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1] =        { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2] =        { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL3] =        { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYARMORSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1] =       { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2] =       { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL3] =       { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANINFANTRYWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ENGINEERINGBAY, m_client) }, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {sc2::UPGRADE_ID::TERRANINFANTRYWEAPONSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1] =           { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2] =           { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL3] =           { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANSHIPWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANSHIPWEAPONSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1] =  { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2] =  { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL3] =  { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEANDSHIPPLATINGLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEANDSHIPARMORSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1] =        { sc2::Race::Terran, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2] =        { sc2::Race::Terran, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL3] =        { sc2::Race::Terran, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TERRANVEHICLEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::TERRAN_ARMORY, m_client) }, {}, {sc2::UPGRADE_ID::TERRANVEHICLEWEAPONSLEVEL2} };
 
     // Protoss Upgrades
-    m_upgradeData[sc2::UPGRADE_ID::ADEPTPIERCINGATTACK] =               { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADEPTRESONATINGGLAIVES, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::BLINKTECH] =                         { sc2::Race::Protoss, 150, 150, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BLINK, 0,                   { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::CARRIERLAUNCHSPEEDUPGRADE] =         { sc2::Race::Protoss, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INTERCEPTORGRAVITONCATAPULT, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::CHARGE] =                            { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHARGE, 0,                  { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::DARKTEMPLARBLINKUPGRADE] =           { sc2::Race::Protoss, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_SHADOWSTRIKE, 0,            { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::EXTENDEDTHERMALLANCE] =              { sc2::Race::Protoss, 200, 200, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_EXTENDEDTHERMALLANCE, 0,    { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::GRAVITICDRIVE] =                     { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICDRIVE, 0,           { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::OBSERVERGRAVITICBOOSTER] =           { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICBOOSTER, 0,         { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PHOENIXRANGEUPGRADE] =               { sc2::Race::Protoss, 150, 150, 0, 1440, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PHOENIXANIONPULSECRYSTALS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1] =            { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL1, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2] =            { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL2, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL3] =            { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL3, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1] =           { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL2] =           { sc2::Race::Protoss, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3] =           { sc2::Race::Protoss, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_bot) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1] =         { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2] =         { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1 } };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL3] =         { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2 } };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1] =        { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2] =        { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1 } };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL3] =        { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2 } };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1] =              { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2] =              { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1 } };
-    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL3] =              { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_bot) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::PSISTORMTECH] =                      { sc2::Race::Protoss, 200, 200, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PSISTORM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::WARPGATERESEARCH] =                  { sc2::Race::Protoss,  50,  50, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_bot) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ADEPTPIERCINGATTACK] =               { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ADEPTRESONATINGGLAIVES, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::BLINKTECH] =                         { sc2::Race::Protoss, 150, 150, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BLINK, 0,                   { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::CARRIERLAUNCHSPEEDUPGRADE] =         { sc2::Race::Protoss, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_INTERCEPTORGRAVITONCATAPULT, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::CHARGE] =                            { sc2::Race::Protoss, 100, 100, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHARGE, 0,                  { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::DARKTEMPLARBLINKUPGRADE] =           { sc2::Race::Protoss, 100, 100, 0, 2720, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_SHADOWSTRIKE, 0,            { UnitType(sc2::UNIT_TYPEID::PROTOSS_DARKSHRINE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::EXTENDEDTHERMALLANCE] =              { sc2::Race::Protoss, 200, 200, 0, 2240, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_EXTENDEDTHERMALLANCE, 0,    { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::GRAVITICDRIVE] =                     { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICDRIVE, 0,           { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::OBSERVERGRAVITICBOOSTER] =           { sc2::Race::Protoss, 100, 100, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GRAVITICBOOSTER, 0,         { UnitType(sc2::UNIT_TYPEID::PROTOSS_ROBOTICSBAY, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PHOENIXRANGEUPGRADE] =               { sc2::Race::Protoss, 150, 150, 0, 1440, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PHOENIXANIONPULSECRYSTALS, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1] =            { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL1, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2] =            { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL2, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL3] =            { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRARMORLEVEL3, 0,   { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRARMORSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1] =           { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL2] =           { sc2::Race::Protoss, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3] =           { sc2::Race::Protoss, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSAIRWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FLEETBEACON, m_client) }, {sc2::UPGRADE_ID::PROTOSSAIRWEAPONSLEVEL3} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1] =         { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2] =         { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL1 } };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL3] =         { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDARMORSLEVEL2 } };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1] =        { sc2::Race::Protoss, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2] =        { sc2::Race::Protoss, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL1 } };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL3] =        { sc2::Race::Protoss, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSGROUNDWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSGROUNDWEAPONSLEVEL2 } };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1] =              { sc2::Race::Protoss, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2] =              { sc2::Race::Protoss, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL1 } };
+    m_upgradeData[sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL3] =              { sc2::Race::Protoss, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PROTOSSSHIELDSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_FORGE, m_client) }, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TWILIGHTCOUNCIL, m_client) }, { sc2::UPGRADE_ID::PROTOSSSHIELDSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::PSISTORMTECH] =                      { sc2::Race::Protoss, 200, 200, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PSISTORM, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_TEMPLARARCHIVE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::WARPGATERESEARCH] =                  { sc2::Race::Protoss,  50,  50, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_WARPGATE, 0, { UnitType(sc2::UNIT_TYPEID::PROTOSS_CYBERNETICSCORE, m_client) }, {}, {} };
 
     // Zerg Upgrades
-    m_upgradeData[sc2::UPGRADE_ID::BURROW] =                            { sc2::Race::Zerg, 100, 100, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BURROW, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::CENTRIFICALHOOKS] =                  { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CENTRIFUGALHOOKS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_bot) }, {}, {} }; 
-    m_upgradeData[sc2::UPGRADE_ID::CHITINOUSPLATING] =                  { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHITINOUSPLATING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::EVOLVEGROOVEDSPINES] =               { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GROOVEDSPINES, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::EVOLVEMUSCULARAUGMENTS] =            { sc2::Race::Zerg, 150, 150, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MUSCULARAUGMENTS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::GLIALRECONSTITUTION] =               { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GLIALREGENERATION, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_upgradeData[sc2::UPGRADE_ID::INFESTORENERGYUPGRADE] =             { sc2::Race::Zerg, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PATHOGENGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::NEURALPARASITE] =                    { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEURALPARASITE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::OVERLORDSPEED] =                     { sc2::Race::Zerg, 100, 100, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PNEUMATIZEDCARAPACE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {}, {} };                       
-    m_upgradeData[sc2::UPGRADE_ID::TUNNELINGCLAWS] =                    { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TUNNELINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1] =             { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2] =             { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1 } };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL3] =             { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2 } };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1] =            { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2] =            { sc2::Race::Zerg, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1 } };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL3] =            { sc2::Race::Zerg, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_bot) }, {UnitType( sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2 } };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1] =            { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2] =            { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL3] =            { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGLINGATTACKSPEED] =               { sc2::Race::Zerg, 200, 200, 0, 2080, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGADRENALGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGLINGMOVEMENTSPEED] =             { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGMETABOLICBOOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1] =            { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2] =            { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL3] =            { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1] =          { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, {}, {} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2] =          { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_bot), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1} };
-    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL3] =          { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_bot) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_bot) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::BURROW] =                            { sc2::Race::Zerg, 100, 100, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_BURROW, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::CENTRIFICALHOOKS] =                  { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CENTRIFUGALHOOKS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_BANELINGNEST, m_client) }, {}, {} }; 
+    m_upgradeData[sc2::UPGRADE_ID::CHITINOUSPLATING] =                  { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_CHITINOUSPLATING, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ULTRALISKCAVERN, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::EVOLVEGROOVEDSPINES] =               { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GROOVEDSPINES, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::EVOLVEMUSCULARAUGMENTS] =            { sc2::Race::Zerg, 150, 150, 0, 1600, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_MUSCULARAUGMENTS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HYDRALISKDEN, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::GLIALRECONSTITUTION] =               { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_GLIALREGENERATION, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_upgradeData[sc2::UPGRADE_ID::INFESTORENERGYUPGRADE] =             { sc2::Race::Zerg, 150, 150, 0, 1280, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PATHOGENGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::NEURALPARASITE] =                    { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_NEURALPARASITE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_INFESTATIONPIT, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::OVERLORDSPEED] =                     { sc2::Race::Zerg, 100, 100, 0,  960, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_PNEUMATIZEDCARAPACE, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_HATCHERY, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {}, {} };                       
+    m_upgradeData[sc2::UPGRADE_ID::TUNNELINGCLAWS] =                    { sc2::Race::Zerg, 150, 150, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_TUNNELINGCLAWS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_ROACHWARREN, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1] =             { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2] =             { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL1 } };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL3] =             { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERARMORSLEVEL2 } };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1] =            { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2] =            { sc2::Race::Zerg, 175, 175, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL1 } };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL3] =            { sc2::Race::Zerg, 250, 250, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGFLYERATTACKLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPIRE, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_GREATERSPIRE, m_client) }, {UnitType( sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, { sc2::UPGRADE_ID::ZERGFLYERWEAPONSLEVEL2 } };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1] =            { sc2::Race::Zerg, 150, 150, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2] =            { sc2::Race::Zerg, 225, 225, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL3] =            { sc2::Race::Zerg, 300, 300, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGGROUNDARMORLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGGROUNDARMORSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGLINGATTACKSPEED] =               { sc2::Race::Zerg, 200, 200, 0, 2080, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGADRENALGLANDS, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGLINGMOVEMENTSPEED] =             { sc2::Race::Zerg, 100, 100, 0, 1760, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGLINGMETABOLICBOOST, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_SPAWNINGPOOL, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1] =            { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2] =            { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL3] =            { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMELEEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMELEEWEAPONSLEVEL2} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1] =          { sc2::Race::Zerg, 100, 100, 0, 2560, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL1, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, {}, {} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2] =          { sc2::Race::Zerg, 150, 150, 0, 3040, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL2, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_LAIR, m_client), UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL1} };
+    m_upgradeData[sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL3] =          { sc2::Race::Zerg, 200, 200, 0, 3520, false, false, false, false, false, false, false, sc2::ABILITY_ID::RESEARCH_ZERGMISSILEWEAPONSLEVEL3, 0, { UnitType(sc2::UNIT_TYPEID::ZERG_EVOLUTIONCHAMBER, m_client) }, { UnitType(sc2::UNIT_TYPEID::ZERG_HIVE, m_client) }, {sc2::UPGRADE_ID::ZERGMISSILEWEAPONSLEVEL2} };
 }
 
 const TypeData & TechTree::getData(const UnitType & type) const
 {
     if (m_unitTypeData.find(type) == m_unitTypeData.end())
     {
-        std::cout << "WARNING: Unit type not found: " << type.getName() << "\n";
+		if (!suppressWarnings)
+		{
+			std::cout << "WARNING: Unit type not found: " << type.getName() << "\n";
+		}
         return m_unitTypeData.begin()->second;
     }
 
@@ -362,7 +370,10 @@ const TypeData & TechTree::getData(const CCUpgrade & type)  const
 {
     if (m_upgradeData.find(type) == m_upgradeData.end())
     {
-        std::cout << "WARNING: Upgrade not found: " << sc2::UpgradeIDToName(type) << "\n";
+		if (!suppressWarnings) 
+		{
+			std::cout << "WARNING: Upgrade not found: " << sc2::UpgradeIDToName(type) << "\n";
+		}
         return m_unitTypeData.begin()->second;
     }
 
diff --git a/src/TechTree.h b/src/TechTree.h
index c20274588af9ba27576510abbd5c8013f7997960..412aaf49c0b50c5781dbb4825a1fadc1a62651b0 100644
--- a/src/TechTree.h
+++ b/src/TechTree.h
@@ -31,18 +31,21 @@ struct TypeData
 
 class TechTree
 {
-    IDABot & m_bot;
+    sc2::Client & m_client;
     std::map<UnitType, TypeData>  m_unitTypeData;
     std::map<CCUpgrade, TypeData> m_upgradeData;
 
     void initUnitTypeData();
     void initUpgradeData();
+	bool suppressWarnings;
 
 public:
 
-    TechTree(IDABot & bot);
+    TechTree(sc2::Client & client);
     void onStart();
 
+	void setSuppressWarnings(bool b);
+
     const TypeData & getData(const UnitType & type) const;
     const TypeData & getData(const CCUpgrade & type) const;
     const TypeData & getData(const MetaType & type) const;
diff --git a/src/Unit.cpp b/src/Unit.cpp
index 6f4bcee54eae7b0ead9ce2d19d5fed2757c780af..50b5fa4df5485a7fba382a06bcc2431fceedec02 100644
--- a/src/Unit.cpp
+++ b/src/Unit.cpp
@@ -13,7 +13,14 @@ Unit::Unit(const sc2::Unit * unit, IDABot & bot)
 	: m_bot(&bot)
 	, m_unit(unit)
 	, m_unitID(unit->tag)
-	, m_unitType(unit->unit_type, bot)
+	, m_unitType(unit->unit_type, bot, bot)
+{
+
+}
+
+Unit::Unit(const sc2::Unit * unit)
+	: m_unit(unit)
+	, m_unitID(unit->tag)
 {
 
 }
@@ -328,17 +335,14 @@ void Unit::ability(sc2::AbilityID ability, const Unit& target) const
 Unit Unit::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;
-        // IDABot finds the unit with this tag
-        return m_bot->GetUnit(t_id);
+		// t_id is set to the unit tag of the target
+		CCUnitID t_id = getUnitPtr()->orders[0].target_unit_tag;
+		// IDABot finds the unit with this tag
+		return m_bot->GetUnit(t_id);
     }
-
-    Unit this_unit = Unit(m_unit, *m_bot);
-    return this_unit;
+    return *this;
 }
 
 bool Unit::hasTarget() const
diff --git a/src/Unit.h b/src/Unit.h
index ebb2f44bccbcdc022d810269268e66bb2847ef01..f68a09bf1b3e4dd4fad4043265e52cf85a0a49e9 100644
--- a/src/Unit.h
+++ b/src/Unit.h
@@ -11,13 +11,15 @@ class Unit
     CCUnitID    m_unitID;
     UnitType    m_unitType;
 
-    const sc2::Unit * m_unit;
+protected:   
+	const sc2::Unit * m_unit;
 
 public:
 
     Unit();
 
     Unit(const sc2::Unit * unit, IDABot & bot);
+	Unit(const sc2::Unit * unit);
     const sc2::Unit * getUnitPtr() const;
     const sc2::UnitTypeID & getAPIUnitType() const;
 
diff --git a/src/UnitType.cpp b/src/UnitType.cpp
index dd564f7e0b74ee97125b95faff718bd3becde1c5..56b113e6ca713f53de307fefad181b39ec6c437e 100644
--- a/src/UnitType.cpp
+++ b/src/UnitType.cpp
@@ -1,20 +1,43 @@
 #include "UnitType.h"
 #include "IDABot.h"
+#include "IDAReplayObserver.h"
 
 UnitType::UnitType()
-    : m_bot(nullptr)
+    : m_client(nullptr)
     , m_type(0)
 {
 
 }
 
-UnitType::UnitType(const sc2::UnitTypeID & type, IDABot & bot)
-    : m_bot(&bot)
+UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client)
+    : m_client(&client)
     , m_type(type)
+	, m_bot(nullptr)
+	, m_observer(nullptr)
+
 {
     
 }
 
+UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDABot & bot)
+	: m_client(&client)
+	, m_type(type)
+	, m_bot(&bot)
+	, m_observer(nullptr)
+{
+}
+
+UnitType::UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDAReplayObserver & observer)
+	: m_client(&client)
+	, m_type(type)
+	, m_observer(&observer)
+	, m_bot(nullptr)
+
+{
+}
+
+
+
 sc2::UnitTypeID UnitType::getAPIUnitType() const
 {
     return m_type;
@@ -47,7 +70,7 @@ std::string UnitType::getName() const
 
 CCRace UnitType::getRace() const
 {
-    return m_bot->Observation()->GetUnitTypeData()[m_type].race;
+    return m_client->Observation()->GetUnitTypeData()[m_type].race;
 }
 
 bool UnitType::isCombatUnit() const
@@ -192,7 +215,7 @@ bool UnitType::isWorker() const
 CCPositionType UnitType::getAttackRange() const
 {
 #ifdef SC2API
-    auto & weapons = m_bot->Observation()->GetUnitTypeData()[m_type].weapons;
+    auto & weapons = m_client->Observation()->GetUnitTypeData()[m_type].weapons;
     
     if (weapons.empty())
     {
@@ -220,7 +243,20 @@ int UnitType::tileWidth() const
 #ifdef SC2API
     if (isMineral()) { return 2; }
     if (isGeyser()) { return 3; }
-    else { return (int)(2 * m_bot->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius); }
+	else {
+		if (m_bot != nullptr)
+		{
+			return (int)(2 * m_client->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius);
+		}
+		else if (m_observer != nullptr)
+		{
+			return (int)(2 * m_client->Observation()->GetAbilityData()[m_observer->Data(*this).buildAbility].footprint_radius);
+		}
+		else
+		{
+			return -1;
+		}
+	}
 #else
     return m_type.tileWidth();
 #endif
@@ -231,16 +267,42 @@ int UnitType::tileHeight() const
 #ifdef SC2API
     if (isMineral()) { return 1; }
     if (isGeyser()) { return 3; }
-    else { return (int)(2 * m_bot->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius); }
+    else {
+		if (m_bot != nullptr)
+		{
+			return (int)(2 * m_client->Observation()->GetAbilityData()[m_bot->Data(*this).buildAbility].footprint_radius);
+		}
+		else if (m_observer != nullptr)
+		{
+			return (int)(2 * m_client->Observation()->GetAbilityData()[m_observer->Data(*this).buildAbility].footprint_radius);
+		}
+		else
+		{
+			return -1;
+		}
+	}
 #else
     return m_type.tileHeight();
 #endif
+
 }
 
 bool UnitType::isAddon() const
 {
 #ifdef SC2API
-    return m_bot->Data(*this).isAddon;
+	if (m_bot != nullptr)
+	{
+		return m_bot->Data(*this).isAddon;
+	}
+	else if (m_observer != nullptr)
+	{
+		return m_observer->Data(*this).isAddon;
+	}
+	else
+	{
+		return false;
+	}
+    
 #else
     return m_type.isAddon();
 #endif
@@ -249,7 +311,19 @@ bool UnitType::isAddon() const
 bool UnitType::isBuilding() const
 {
 #ifdef SC2API
-    return m_bot->Data(*this).isBuilding;
+	if (m_bot != nullptr)
+	{
+		return m_bot->Data(*this).isBuilding;
+	}
+	else if (m_observer != nullptr)
+	{
+		return m_observer->Data(*this).isBuilding;
+	}
+	else 
+	{
+		return false;
+	}
+    
 #else
     return m_type.isBuilding();
 #endif
@@ -258,7 +332,7 @@ bool UnitType::isBuilding() const
 int UnitType::supplyProvided() const
 {
 #ifdef SC2API
-    return (int)m_bot->Observation()->GetUnitTypeData()[m_type].food_provided;
+    return (int)m_client->Observation()->GetUnitTypeData()[m_type].food_provided;
 #else
     return m_type.supplyProvided();
 #endif
@@ -267,7 +341,7 @@ int UnitType::supplyProvided() const
 int UnitType::supplyRequired() const
 {
 #ifdef SC2API
-    return (int)m_bot->Observation()->GetUnitTypeData()[m_type].food_required;
+    return (int)m_client->Observation()->GetUnitTypeData()[m_type].food_required;
 #else
     return m_type.supplyRequired();
 #endif
@@ -276,7 +350,7 @@ int UnitType::supplyRequired() const
 int UnitType::mineralPrice() const
 {
 #ifdef SC2API
-    return (int)m_bot->Observation()->GetUnitTypeData()[m_type].mineral_cost;
+    return (int)m_client->Observation()->GetUnitTypeData()[m_type].mineral_cost;
 #else
     return m_type.mineralPrice();
 #endif
@@ -285,7 +359,7 @@ int UnitType::mineralPrice() const
 int UnitType::gasPrice() const
 {
 #ifdef SC2API
-    return (int)m_bot->Observation()->GetUnitTypeData()[m_type].vespene_cost;
+    return (int)m_client->Observation()->GetUnitTypeData()[m_type].vespene_cost;
 #else
     return m_type.gasPrice();
 #endif
@@ -377,30 +451,30 @@ bool UnitType::isMorphedBuilding() const
 
 int UnitType::getMovementSpeed() const
 {
-    return m_bot->Observation()->GetUnitTypeData()[m_type].movement_speed;
+    return m_client->Observation()->GetUnitTypeData()[m_type].movement_speed;
 }
 
 int UnitType::getSightRange() const
 {
-    return m_bot->Observation()->GetUnitTypeData()[m_type].sight_range;
+    return m_client->Observation()->GetUnitTypeData()[m_type].sight_range;
 }
 
 UnitTypeID UnitType::getRequiredStructure() const
 {
-    return m_bot->Observation()->GetUnitTypeData()[m_type].tech_requirement;
+    return m_client->Observation()->GetUnitTypeData()[m_type].tech_requirement;
 }
 
 std::vector<sc2::UnitTypeID> UnitType::getEquivalentUnits() const
 {
-	return m_bot->Observation()->GetUnitTypeData()[m_type].tech_alias;
+	return m_client->Observation()->GetUnitTypeData()[m_type].tech_alias;
 }
 
 bool UnitType::requiredAttached() const
 {
-	return m_bot->Observation()->GetUnitTypeData()[m_type].require_attached;
+	return m_client->Observation()->GetUnitTypeData()[m_type].require_attached;
 }
 
 float UnitType::getBuildTime() const
 {
-	return m_bot->Observation()->GetUnitTypeData()[m_type].build_time;
+	return m_client->Observation()->GetUnitTypeData()[m_type].build_time;
 }
\ No newline at end of file
diff --git a/src/UnitType.h b/src/UnitType.h
index 7f3bbbe530ffc6859f7ceb8cff1c691af42afb31..1491bb11d335f2b9ed01dd7fcf60b01b8dc9eea6 100644
--- a/src/UnitType.h
+++ b/src/UnitType.h
@@ -4,17 +4,24 @@
 
 
 class IDABot;
+class IDAReplayObserver;
 
 class UnitType
 {
-    mutable IDABot * m_bot;
+    mutable sc2::Client * m_client;
+	mutable IDABot * m_bot;
+	mutable IDAReplayObserver * m_observer;
+
     sc2::UnitTypeID m_type;
 
 public:
 
     UnitType();
 
-    UnitType(const sc2::UnitTypeID & type, IDABot & bot);
+    UnitType(const sc2::UnitTypeID & type, sc2::Client & client);
+	UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDABot & m_bot);
+	UnitType(const sc2::UnitTypeID & type, sc2::Client & client, IDAReplayObserver & observer);
+
     sc2::UnitTypeID getAPIUnitType() const;
     bool is(const sc2::UnitTypeID & type) const;