"""
Created on Thu Apr  2 11:41:59 2020

@author: adrian
"""
import numpy as np
import sc2
from sc2 import Race, Difficulty
from sc2.constants import *
from sc2.player import Bot, Computer, Human


def unit_list(self):
    # List of stats: No. of attacks, Damage, Bonus damage, Bonus attribute, Attack speed, Attack point for both ground and air 
    # Hp, Shields, Armor, Shield armor, Range, Movement speed, Splash area, Unit size, Attribute, Is air, Minerals, Vespene, Supply
    # Terran    
    # Terran: Note that many units have different forms and each form has a different unit name! -> Hellion/Hellbat, Widow mine, Siege tank, Viking, Liberator
    # Excluded units: Raven, Widow mine
    self.terran_army = [MARINE, MARAUDER, REAPER, GHOST, HELLION, HELLIONTANK, WIDOWMINE, SIEGETANK, SIEGETANKSIEGED, CYCLONE, THOR, THORAP, VIKINGFIGHTER, VIKINGASSAULT, \
                        LIBERATOR, LIBERATORAG, BANSHEE, BATTLECRUISER]
    
    MARINE.attacks_ground = 1*1.5
    MARINE.attacks_air = 1*1.5
    MARINE.dmg_ground = 6
    MARINE.dmg_air = 6
    MARINE.bonus_dmg_ground = 0
    MARINE.bonus_dmg_air = 0
    MARINE.bonus_attr_ground = None
    MARINE.bonus_attr_air = None
    MARINE.attack_speed_ground = 0.61
    MARINE.attack_speed_air = 0.61
    MARINE.attack_point_ground = 0.0357
    MARINE.attack_point_air = 0.0357
    MARINE.hp = 45 
    MARINE.shields = 0
    MARINE.armor = 0
    MARINE.shield_armor = 0
    MARINE.range_ground = 5
    MARINE.range_air = 5
    MARINE.leash_range = 0
    MARINE.movement_speed = 3.15*1.5
    MARINE.splash_area_air = 0
    MARINE.splash_area_ground = 0
    MARINE.size = 0.75 # Size is in diameter
    MARINE.attribute = ['Light', 'Biological']
    MARINE.is_air = False
    MARINE.is_ground = True
    MARINE.minerals = self.calculate_unit_value(MARINE).minerals
    MARINE.vespene = self.calculate_unit_value(MARINE).vespene
    MARINE.supply = self.calculate_supply_cost(MARINE) # Training/morph cost, so upgraded units must count their base units!
    MARINE.build_time = 18
    
    MARAUDER.attacks_ground = 1*1.5
    MARAUDER.attacks_air = 0
    MARAUDER.dmg_ground = 10
    MARAUDER.dmg_air = 0
    MARAUDER.bonus_dmg_ground = 10
    MARAUDER.bonus_dmg_air = 0
    MARAUDER.bonus_attr_ground = 'Armored'
    MARAUDER.bonus_attr_air = None
    MARAUDER.attack_speed_ground = 1.07
    MARAUDER.attack_speed_air = 1.07
    MARAUDER.attack_point_ground = 0
    MARAUDER.attack_point_air = 0
    MARAUDER.hp = 125-20
    MARAUDER.shields = 0
    MARAUDER.armor = 1
    MARAUDER.shield_armor = 0
    MARAUDER.range_ground = 6
    MARAUDER.range_air = 0
    MARAUDER.leash_range = 0
    MARAUDER.movement_speed = 3.15*1.5
    MARAUDER.splash_area_air = 0
    MARAUDER.splash_area_ground = 0
    MARAUDER.size = 1.125 # Size is in diameter
    MARAUDER.attribute = ['Psionic', 'Biological']
    MARAUDER.is_air = False
    MARAUDER.is_ground = True
    MARAUDER.minerals = self.calculate_unit_value(MARAUDER).minerals
    MARAUDER.vespene = self.calculate_unit_value(MARAUDER).vespene
    MARAUDER.supply = self.calculate_supply_cost(MARAUDER) # Training/morph cost, so upgraded units must count their base units!
    MARAUDER.build_time = 21
		
    REAPER.attacks_ground = 2
    REAPER.attacks_air = 0
    REAPER.dmg_ground = 4
    REAPER.dmg_air = 0
    REAPER.bonus_dmg_ground = 0
    REAPER.bonus_dmg_air = 0
    REAPER.bonus_attr_ground = None
    REAPER.bonus_attr_air = None
    REAPER.attack_speed_ground = 0.79
    REAPER.attack_speed_air = 0.79
    REAPER.attack_point_ground = 0
    REAPER.attack_point_air = 0
    REAPER.hp = 60
    REAPER.shields = 0
    REAPER.armor = 0
    REAPER.shield_armor = 0
    REAPER.range_ground = 5
    REAPER.range_air = 0
    REAPER.leash_range = 0
    REAPER.movement_speed = 5.25
    REAPER.splash_area_air = 0
    REAPER.splash_area_ground = 0
    REAPER.size = 0.75 # Size is in diameter
    REAPER.attribute = ['Light', 'Biological']
    REAPER.is_air = False
    REAPER.is_ground = True
    REAPER.minerals = self.calculate_unit_value(REAPER).minerals
    REAPER.vespene = self.calculate_unit_value(REAPER).vespene
    REAPER.supply = self.calculate_supply_cost(REAPER) # Training/morph cost, so upgraded units must count their base units!
    REAPER.build_time = 32
    
    GHOST.attacks_ground = 1
    GHOST.attacks_air = 1
    GHOST.dmg_ground = 10
    GHOST.dmg_air = 10
    GHOST.bonus_dmg_ground = 10
    GHOST.bonus_dmg_air = 10
    GHOST.bonus_attr_ground = 'Light'
    GHOST.bonus_attr_air = 'Light'
    GHOST.attack_speed_ground = 1.07
    GHOST.attack_speed_air = 1.07
    GHOST.attack_point_ground = 0.0593
    GHOST.attack_point_air = 0.0593
    GHOST.hp = 100 
    GHOST.shields = 0
    GHOST.armor = 0
    GHOST.shield_armor = 0
    GHOST.range_ground = 6
    GHOST.range_air = 6
    GHOST.leash_range = 0
    GHOST.movement_speed = 3.94
    GHOST.splash_area_air = 0
    GHOST.splash_area_ground = 0
    GHOST.size = 0.75 # Size is in diameter
    GHOST.attribute = ['Psionic', 'Biological']
    GHOST.is_air = False
    GHOST.is_ground = True
    GHOST.minerals = self.calculate_unit_value(GHOST).minerals
    GHOST.vespene = self.calculate_unit_value(GHOST).vespene
    GHOST.supply = self.calculate_supply_cost(GHOST) # Training/morph cost, so upgraded units must count their base units!
    GHOST.build_time = 29
		
    HELLION.attacks_ground = 1
    HELLION.attacks_air = 0
    HELLION.dmg_ground = 8
    HELLION.dmg_air = 0
    HELLION.bonus_dmg_ground = 6+5
    HELLION.bonus_dmg_air = 0
    HELLION.bonus_attr_ground = 'Light'
    HELLION.bonus_attr_air = None
    HELLION.attack_speed_ground = 1.79
    HELLION.attack_speed_air = 1.79
    HELLION.attack_point_ground = 0.1786
    HELLION.attack_point_air = 0.1786
    HELLION.hp = 90
    HELLION.shields = 0
    HELLION.armor = 0
    HELLION.shield_armor = 0
    HELLION.range_ground = 5
    HELLION.range_air = 0
    HELLION.leash_range = 0
    HELLION.movement_speed = 5.95
    HELLION.splash_area_air = 0
    HELLION.splash_area_ground = 2
    HELLION.size = 1.25 # Size is in diameter
    HELLION.attribute = ['Light', 'Mechanical']
    HELLION.is_air = False
    HELLION.is_ground = True
    HELLION.minerals = self.calculate_unit_value(HELLION).minerals
    HELLION.vespene = self.calculate_unit_value(HELLION).vespene
    HELLION.supply = self.calculate_supply_cost(HELLION) # Training/morph cost, so upgraded units must count their base units!
    HELLION.build_time = 21
    
    HELLIONTANK.attacks_ground = 1
    HELLIONTANK.attacks_air = 0
    HELLIONTANK.dmg_ground = 18
    HELLIONTANK.dmg_air = 0
    HELLIONTANK.bonus_dmg_ground = 0+12
    HELLIONTANK.bonus_dmg_air = 0
    HELLIONTANK.bonus_attr_ground = 'Light'
    HELLIONTANK.bonus_attr_air = None
    HELLIONTANK.attack_speed_ground = 1.43
    HELLIONTANK.attack_speed_air = 1.43
    HELLIONTANK.attack_point_ground = 0.1193
    HELLIONTANK.attack_point_air = 0.1193
    HELLIONTANK.hp = 135
    HELLIONTANK.shields = 0
    HELLIONTANK.armor = 0
    HELLIONTANK.shield_armor = 0
    HELLIONTANK.range_ground = 2
    HELLIONTANK.range_air = 0
    HELLIONTANK.leash_range = 0
    HELLIONTANK.movement_speed = 3.15
    HELLIONTANK.splash_area_air = 0
    HELLIONTANK.splash_area_ground = 2.5
    HELLIONTANK.size = 1.25 # Size is in diameter
    HELLIONTANK.attribute = ['Light', 'Mechanical', 'Biological']
    HELLIONTANK.is_air = False
    HELLIONTANK.is_ground = True
    HELLIONTANK.minerals = self.calculate_unit_value(HELLIONTANK).minerals
    HELLIONTANK.vespene = self.calculate_unit_value(HELLIONTANK).vespene
    HELLIONTANK.supply = self.calculate_supply_cost(HELLIONTANK) # Training/morph cost, so upgraded units must count their base units!
    HELLIONTANK.build_time = 21
    
    WIDOWMINE.attacks_ground = 1
    WIDOWMINE.attacks_air = 1
    WIDOWMINE.dmg_ground = 125
    WIDOWMINE.dmg_air = 125
    WIDOWMINE.bonus_dmg_ground = 0
    WIDOWMINE.bonus_dmg_air = 0
    WIDOWMINE.bonus_attr_ground = None 
    WIDOWMINE.bonus_attr_air = None
    WIDOWMINE.attack_speed_ground = 29
    WIDOWMINE.attack_speed_air = 29
    WIDOWMINE.attack_point_ground = 1.07 + 3
    WIDOWMINE.attack_point_air = 1.07 + 3
    WIDOWMINE.hp = 90
    WIDOWMINE.shields = 0
    WIDOWMINE.armor = 0
    WIDOWMINE.shield_armor = 0
    WIDOWMINE.range_ground = 5
    WIDOWMINE.range_air = 5
    WIDOWMINE.leash_range = 0
    WIDOWMINE.movement_speed = 3.94
    WIDOWMINE.splash_area_air = self.PI*(1.75**2)*40/125
    WIDOWMINE.splash_area_ground = self.PI*(1.75**2)*40/125
    WIDOWMINE.size = 1 # Size is in diameter
    WIDOWMINE.attribute = ['Light', 'Mechanical']
    WIDOWMINE.is_air = False
    WIDOWMINE.is_ground = True
    WIDOWMINE.minerals = self.calculate_unit_value(WIDOWMINE).minerals
    WIDOWMINE.vespene = self.calculate_unit_value(WIDOWMINE).vespene
    WIDOWMINE.supply = self.calculate_supply_cost(WIDOWMINE) # Training/morph cost, so upgraded units must count their base units!
    WIDOWMINE.build_time = 21
    
    SIEGETANK.attacks_ground = 1
    SIEGETANK.attacks_air = 0
    SIEGETANK.dmg_ground = 15
    SIEGETANK.dmg_air = 0
    SIEGETANK.bonus_dmg_ground = 10
    SIEGETANK.bonus_dmg_air = 0
    SIEGETANK.bonus_attr_ground = 'Armored'
    SIEGETANK.bonus_attr_air = None
    SIEGETANK.attack_speed_ground = 0.74
    SIEGETANK.attack_speed_air = 0.74
    SIEGETANK.attack_point_ground = 0.1193
    SIEGETANK.attack_point_air = 0.1193
    SIEGETANK.hp = 175
    SIEGETANK.shields = 0
    SIEGETANK.armor = 1
    SIEGETANK.shield_armor = 0
    SIEGETANK.range_ground = 7
    SIEGETANK.range_air = 0
    SIEGETANK.leash_range = 0
    SIEGETANK.movement_speed = 3.15
    SIEGETANK.splash_area_air = 0
    SIEGETANK.splash_area_ground = 0
    SIEGETANK.size = 1.75 # Size is in diameter
    SIEGETANK.attribute = ['Armored', 'Mechanical']
    SIEGETANK.is_air = False
    SIEGETANK.is_ground = True
    SIEGETANK.minerals = self.calculate_unit_value(SIEGETANK).minerals
    SIEGETANK.vespene = self.calculate_unit_value(SIEGETANK).vespene
    SIEGETANK.supply = self.calculate_supply_cost(SIEGETANK) # Training/morph cost, so upgraded units must count their base units!
    SIEGETANK.build_time = 32
    
    SIEGETANKSIEGED.attacks_ground = 1
    SIEGETANKSIEGED.attacks_air = 0
    SIEGETANKSIEGED.dmg_ground = 40
    SIEGETANKSIEGED.dmg_air = 0
    SIEGETANKSIEGED.bonus_dmg_ground = 30
    SIEGETANKSIEGED.bonus_dmg_air = 0
    SIEGETANKSIEGED.bonus_attr_ground = 'Armored'
    SIEGETANKSIEGED.bonus_attr_air = None
    SIEGETANKSIEGED.attack_speed_ground = 2.14
    SIEGETANKSIEGED.attack_speed_air = 2.14
    SIEGETANKSIEGED.attack_point_ground = 2.14
    SIEGETANKSIEGED.attack_point_air = 2.14
    SIEGETANKSIEGED.hp = 175
    SIEGETANKSIEGED.shields = 0
    SIEGETANKSIEGED.armor = 1
    SIEGETANKSIEGED.shield_armor = 0
    SIEGETANKSIEGED.range_ground = 13
    SIEGETANKSIEGED.range_air = 0
    SIEGETANKSIEGED.leash_range = 0
    SIEGETANKSIEGED.movement_speed = 0
    SIEGETANKSIEGED.splash_area_air = 0
    SIEGETANKSIEGED.splash_area_ground = self.PI*(0.4687**2 + (0.7812**2-0.4687**2)*0.5 + (1.25**2-0.7812**2)*0.25)
    SIEGETANKSIEGED.size = 1.75 # Size is in diameter
    SIEGETANKSIEGED.attribute = ['Armored', 'Mechanical']
    SIEGETANKSIEGED.is_air = False
    SIEGETANKSIEGED.is_ground = True
    SIEGETANKSIEGED.minerals = self.calculate_unit_value(SIEGETANKSIEGED).minerals
    SIEGETANKSIEGED.vespene = self.calculate_unit_value(SIEGETANKSIEGED).vespene
    SIEGETANKSIEGED.supply = self.calculate_supply_cost(SIEGETANKSIEGED) # Training/morph cost, so upgraded units must count their base units!
    SIEGETANKSIEGED.build_time = 32

    CYCLONE.attacks_ground = 1
    CYCLONE.attacks_air = 1
    CYCLONE.dmg_ground = 20
    CYCLONE.dmg_air = 20
    CYCLONE.bonus_dmg_ground = 0+20
    CYCLONE.bonus_dmg_air = 0+20
    CYCLONE.bonus_attr_ground = 'Armored'
    CYCLONE.bonus_attr_air = 'Armored'
    CYCLONE.attack_speed_ground = 0.71
    CYCLONE.attack_speed_air = 0.71
    CYCLONE.attack_point_ground = 0
    CYCLONE.attack_point_air = 0
    CYCLONE.hp = 120
    CYCLONE.shields = 0
    CYCLONE.armor = 1
    CYCLONE.shield_armor = 0
    CYCLONE.range_ground = 7
    CYCLONE.range_air = 7
    CYCLONE.leash_range = 15
    CYCLONE.movement_speed = 4.73
    CYCLONE.splash_area_air = 0
    CYCLONE.splash_area_ground = 0
    CYCLONE.size = 1.5 # Size is in diameter
    CYCLONE.attribute = ['Armored', 'Mechanical']
    CYCLONE.is_air = False
    CYCLONE.is_ground = True
    CYCLONE.minerals = self.calculate_unit_value(CYCLONE).minerals
    CYCLONE.vespene = self.calculate_unit_value(CYCLONE).vespene
    CYCLONE.supply = self.calculate_supply_cost(CYCLONE) # Training/morph cost, so upgraded units must count their base units!
    CYCLONE.build_time = 32
    
    THOR.attacks_ground = 2
    THOR.attacks_air = 4
    THOR.dmg_ground = 30
    THOR.dmg_air = 6
    THOR.bonus_dmg_ground = 0
    THOR.bonus_dmg_air = 6
    THOR.bonus_attr_ground = None
    THOR.bonus_attr_air = 'Light'
    THOR.attack_speed_ground = 0.91
    THOR.attack_speed_air = 2.14
    THOR.attack_point_ground = 0.5936
    THOR.attack_point_air = 0.1193
    THOR.hp = 400
    THOR.shields = 0
    THOR.armor = 1
    THOR.shield_armor = 0
    THOR.range_ground = 7
    THOR.range_air = 10
    THOR.leash_range = 0
    THOR.movement_speed = 2.62
    THOR.splash_area_air = self.PI*0.5**2
    THOR.splash_area_ground = 0
    THOR.size = 2 # Size is in diameter
    THOR.attribute = ['Armored', 'Mechanical','Massive']
    THOR.is_air = False
    THOR.is_ground = True
    THOR.minerals = self.calculate_unit_value(THOR).minerals
    THOR.vespene = self.calculate_unit_value(THOR).vespene
    THOR.supply = self.calculate_supply_cost(THOR) # Training/morph cost, so upgraded units must count their base units!
    THOR.build_time = 43
            
    THORAP.attacks_ground = 2
    THORAP.attacks_air = 1
    THORAP.dmg_ground = 30
    THORAP.dmg_air = 25
    THORAP.bonus_dmg_ground = 0
    THORAP.bonus_dmg_air = 10
    THORAP.bonus_attr_ground = None
    THORAP.bonus_attr_air = 'Massive'
    THORAP.attack_speed_ground = 0.91
    THORAP.attack_speed_air = 0.91
    THORAP.attack_point_ground = 0.5936
    THORAP.attack_point_air = 0.1193
    THORAP.hp = 400
    THORAP.shields = 0
    THORAP.armor = 1
    THORAP.shield_armor = 0
    THORAP.range_ground = 7
    THORAP.range_air = 11
    THORAP.leash_range = 0
    THORAP.movement_speed = 2.62
    THORAP.splash_area_air = 0
    THORAP.splash_area_ground = 0
    THORAP.size = 2 # Size is in diameter
    THORAP.attribute = ['Armored', 'Mechanical','Massive']
    THORAP.is_air = False
    THORAP.is_ground = True
    THORAP.minerals = self.calculate_unit_value(THORAP).minerals
    THORAP.vespene = self.calculate_unit_value(THORAP).vespene
    THORAP.supply = self.calculate_supply_cost(THORAP) # Training/morph cost, so upgraded units must count their base units!
    THORAP.build_time = 43
    
    VIKINGFIGHTER.attacks_ground = 0
    VIKINGFIGHTER.attacks_air = 2
    VIKINGFIGHTER.dmg_ground = 0
    VIKINGFIGHTER.dmg_air = 10
    VIKINGFIGHTER.bonus_dmg_ground = 0
    VIKINGFIGHTER.bonus_dmg_air = 4
    VIKINGFIGHTER.bonus_attr_ground = None
    VIKINGFIGHTER.bonus_attr_air = 'Armored'
    VIKINGFIGHTER.attack_speed_ground = 1.43
    VIKINGFIGHTER.attack_speed_air = 1.43
    VIKINGFIGHTER.attack_point_ground = 0.1193
    VIKINGFIGHTER.attack_point_air = 0.1193
    VIKINGFIGHTER.hp = 125
    VIKINGFIGHTER.shields = 0
    VIKINGFIGHTER.armor = 0
    VIKINGFIGHTER.shield_armor = 0
    VIKINGFIGHTER.range_ground = 0
    VIKINGFIGHTER.range_air = 9
    VIKINGFIGHTER.leash_range = 0
    VIKINGFIGHTER.movement_speed = 3.85
    VIKINGFIGHTER.splash_area_air = 0
    VIKINGFIGHTER.splash_area_ground = 0
    VIKINGFIGHTER.size = 1.5 # Size is in diameter
    VIKINGFIGHTER.attribute = ['Armored', 'Mechanical']
    VIKINGFIGHTER.is_air = True
    VIKINGFIGHTER.is_ground = False
    VIKINGFIGHTER.minerals = self.calculate_unit_value(VIKINGFIGHTER).minerals
    VIKINGFIGHTER.vespene = self.calculate_unit_value(VIKINGFIGHTER).vespene
    VIKINGFIGHTER.supply = self.calculate_supply_cost(VIKINGFIGHTER) # Training/morph cost, so upgraded units must count their base units!
    VIKINGFIGHTER.build_time = 30
    
    VIKINGASSAULT.attacks_ground = 1
    VIKINGASSAULT.attacks_air = 0
    VIKINGASSAULT.dmg_ground = 12
    VIKINGASSAULT.dmg_air = 0
    VIKINGASSAULT.bonus_dmg_ground = 8
    VIKINGASSAULT.bonus_dmg_air = 0
    VIKINGASSAULT.bonus_attr_ground = 'Mechanical'
    VIKINGASSAULT.bonus_attr_air = None
    VIKINGASSAULT.attack_speed_ground = 0.71
    VIKINGASSAULT.attack_speed_air = 0.71
    VIKINGASSAULT.attack_point_ground = 0.1193
    VIKINGASSAULT.attack_point_air = 0.1193
    VIKINGASSAULT.hp = 125
    VIKINGASSAULT.shields = 0
    VIKINGASSAULT.armor = 0
    VIKINGASSAULT.shield_armor = 0
    VIKINGASSAULT.range_ground = 6
    VIKINGASSAULT.range_air = 0
    VIKINGASSAULT.leash_range = 0
    VIKINGASSAULT.movement_speed = 3.85
    VIKINGASSAULT.splash_area_air = 0
    VIKINGASSAULT.splash_area_ground = 0
    VIKINGASSAULT.size = 1.5 # Size is in diameter
    VIKINGASSAULT.attribute = ['Armored', 'Mechanical']
    VIKINGASSAULT.is_air = False
    VIKINGASSAULT.is_ground = True
    VIKINGASSAULT.minerals = self.calculate_unit_value(VIKINGASSAULT).minerals
    VIKINGASSAULT.vespene = self.calculate_unit_value(VIKINGASSAULT).vespene
    VIKINGASSAULT.supply = self.calculate_supply_cost(VIKINGASSAULT) # Training/morph cost, so upgraded units must count their base units!
    VIKINGASSAULT.build_time = 30
    
    LIBERATOR.attacks_ground = 0
    LIBERATOR.attacks_air = 2
    LIBERATOR.dmg_ground = 0
    LIBERATOR.dmg_air = 5
    LIBERATOR.bonus_dmg_ground = 0
    LIBERATOR.bonus_dmg_air = 0
    LIBERATOR.bonus_attr_ground = None
    LIBERATOR.bonus_attr_air = None
    LIBERATOR.attack_speed_ground = 1.29
    LIBERATOR.attack_speed_air = 1.29
    LIBERATOR.attack_point_ground = 0.1193
    LIBERATOR.attack_point_air = 0.1193
    LIBERATOR.hp = 180
    LIBERATOR.shields = 0
    LIBERATOR.armor = 0
    LIBERATOR.shield_armor = 0
    LIBERATOR.range_ground = 0
    LIBERATOR.range_air = 5
    LIBERATOR.leash_range = 0
    LIBERATOR.movement_speed = 4.72
    LIBERATOR.splash_area_air = self.PI*1.5**2
    LIBERATOR.splash_area_ground = 0
    LIBERATOR.size = 1.5 # Size is in diameter
    LIBERATOR.attribute = ['Armored', 'Mechanical']
    LIBERATOR.is_air = True
    LIBERATOR.is_ground = False
    LIBERATOR.minerals = self.calculate_unit_value(LIBERATOR).minerals
    LIBERATOR.vespene = self.calculate_unit_value(LIBERATOR).vespene
    LIBERATOR.supply = self.calculate_supply_cost(LIBERATOR) # Training/morph cost, so upgraded units must count their base units!
    LIBERATOR.build_time = 43
    
    LIBERATORAG.attacks_ground = 1
    LIBERATORAG.attacks_air = 0
    LIBERATORAG.dmg_ground = 75
    LIBERATORAG.dmg_air = 0
    LIBERATORAG.bonus_dmg_ground = 0
    LIBERATORAG.bonus_dmg_air = 0
    LIBERATORAG.bonus_attr_ground = None
    LIBERATORAG.bonus_attr_air = None
    LIBERATORAG.attack_speed_ground = 1.14
    LIBERATORAG.attack_speed_air = 1.14
    LIBERATORAG.attack_point_ground = 1.14
    LIBERATORAG.attack_point_air = 1.14
    LIBERATORAG.hp = 180
    LIBERATORAG.shields = 0
    LIBERATORAG.armor = 0
    LIBERATORAG.shield_armor = 0
    LIBERATORAG.range_ground = 10+3
    LIBERATORAG.range_air = 0
    LIBERATORAG.leash_range = 0
    LIBERATORAG.movement_speed = 0
    LIBERATORAG.splash_area_air = 0
    LIBERATORAG.splash_area_ground = 0
    LIBERATORAG.size = 1.5 # Size is in diameter
    LIBERATORAG.attribute = ['Armored', 'Mechanical']
    LIBERATORAG.is_air = True
    LIBERATORAG.is_ground = False
    LIBERATORAG.minerals = self.calculate_unit_value(LIBERATORAG).minerals
    LIBERATORAG.vespene = self.calculate_unit_value(LIBERATORAG).vespene
    LIBERATORAG.supply = self.calculate_supply_cost(LIBERATORAG) # Training/morph cost, so upgraded units must count their base units!
    LIBERATORAG.build_time = 43
    
    BANSHEE.attacks_ground = 2
    BANSHEE.attacks_air = 0
    BANSHEE.dmg_ground = 12
    BANSHEE.dmg_air = 0
    BANSHEE.bonus_dmg_ground = 0
    BANSHEE.bonus_dmg_air = 0
    BANSHEE.bonus_attr_ground = None
    BANSHEE.bonus_attr_air = None
    BANSHEE.attack_speed_ground = 0.89
    BANSHEE.attack_speed_air = 0
    BANSHEE.attack_point_ground = 0.1193
    BANSHEE.attack_point_air = 0
    BANSHEE.hp = 140
    BANSHEE.shields = 0
    BANSHEE.armor = 0
    BANSHEE.shield_armor = 0
    BANSHEE.range_ground = 6
    BANSHEE.range_air = 0
    BANSHEE.leash_range = 0
    BANSHEE.movement_speed = 3.85+1.4
    BANSHEE.splash_area_air = 0
    BANSHEE.splash_area_ground = 0
    BANSHEE.size = 1.5 # Size is in diameter
    BANSHEE.attribute = ['Light', 'Mechanical']
    BANSHEE.is_air = True
    BANSHEE.is_ground = False
    BANSHEE.minerals = self.calculate_unit_value(BANSHEE).minerals
    BANSHEE.vespene = self.calculate_unit_value(BANSHEE).vespene
    BANSHEE.supply = self.calculate_supply_cost(BANSHEE) # Training/morph cost, so upgraded units must count their base units!
    BANSHEE.build_time = 43
    
    BATTLECRUISER.attacks_ground = 1
    BATTLECRUISER.attacks_air = 1
    BATTLECRUISER.dmg_ground = 8
    BATTLECRUISER.dmg_air = 5
    BATTLECRUISER.bonus_dmg_ground = 0
    BATTLECRUISER.bonus_dmg_air = 0
    BATTLECRUISER.bonus_attr_ground = None
    BATTLECRUISER.bonus_attr_air = None
    BATTLECRUISER.attack_speed_ground = 0.16
    BATTLECRUISER.attack_speed_air = 0.16
    BATTLECRUISER.attack_point_ground = 0
    BATTLECRUISER.attack_point_air = 0
    BATTLECRUISER.hp = 550
    BATTLECRUISER.shields = 0
    BATTLECRUISER.armor = 3
    BATTLECRUISER.shield_armor = 0
    BATTLECRUISER.range_ground = 6
    BATTLECRUISER.range_air = 6
    BATTLECRUISER.leash_range = 0
    BATTLECRUISER.movement_speed = 2.62
    BATTLECRUISER.splash_area_air = 0
    BATTLECRUISER.splash_area_ground = 0
    BATTLECRUISER.size = 1.5 # Size is in diameter
    BATTLECRUISER.attribute = ['Armored', 'Mechanical', 'Massive']
    BATTLECRUISER.is_air = True
    BATTLECRUISER.is_ground = False
    BATTLECRUISER.minerals = self.calculate_unit_value(BATTLECRUISER).minerals
    BATTLECRUISER.vespene = self.calculate_unit_value(BATTLECRUISER).vespene
    BATTLECRUISER.supply = self.calculate_supply_cost(BATTLECRUISER) # Training/morph cost, so upgraded units must count their base units!
    BATTLECRUISER.build_time = 64
    
    
    # Protoss: Note that warp prism and observers have different forms with different names! 
    # Excluded units: High Templar, Observer, Warp Prism, Interceptor
    self.protoss_army = [ZEALOT, STALKER, SENTRY, ADEPT, DARKTEMPLAR, ARCHON, IMMORTAL, COLOSSUS, DISRUPTOR, PHOENIX, ORACLE, VOIDRAY, TEMPEST, CARRIER, MOTHERSHIP]
    
    ZEALOT.attacks_ground = 2
    ZEALOT.attacks_air = 0
    ZEALOT.dmg_ground = 8
    ZEALOT.dmg_air = 0
    ZEALOT.bonus_dmg_ground = 0
    ZEALOT.bonus_dmg_air = 0
    ZEALOT.bonus_attr_ground = None
    ZEALOT.bonus_attr_air = None
    ZEALOT.attack_speed_ground = 0.86
    ZEALOT.attack_speed_air = 0.86
    ZEALOT.attack_point_ground = 0
    ZEALOT.attack_point_air = 0
    ZEALOT.hp = 100
    ZEALOT.shields = 50
    ZEALOT.armor = 1
    ZEALOT.shield_armor = 0
    ZEALOT.range_ground = 0.1
    ZEALOT.range_air = 0
    ZEALOT.leash_range = 0
    ZEALOT.movement_speed = 3.15 + (4.725 - 3.15)
    ZEALOT.splash_area_air = 0
    ZEALOT.splash_area_ground = 0
    ZEALOT.size = 1 # Size is in diameter
    ZEALOT.attribute = ['Light', 'Biological']
    ZEALOT.is_air = False
    ZEALOT.is_ground = True
    ZEALOT.minerals = self.calculate_unit_value(ZEALOT).minerals
    ZEALOT.vespene = self.calculate_unit_value(ZEALOT).vespene
    ZEALOT.supply = self.calculate_supply_cost(ZEALOT) # Training/morph cost, so upgraded units must count their base units!
    ZEALOT.build_time = 20
    
    STALKER.attacks_ground = 1
    STALKER.attacks_air = 1
    STALKER.dmg_ground = 13
    STALKER.dmg_air = 13
    STALKER.bonus_dmg_ground = 5
    STALKER.bonus_dmg_air = 5
    STALKER.bonus_attr_ground = 'Armored'
    STALKER.bonus_attr_air = 'Armored'
    STALKER.attack_speed_ground = 1.34
    STALKER.attack_speed_air = 1.34
    STALKER.attack_point_ground = 0.1193
    STALKER.attack_point_air = 0.1193
    STALKER.hp = 80
    STALKER.shields = 80
    STALKER.armor = 1
    STALKER.shield_armor = 0
    STALKER.range_ground = 6
    STALKER.range_air = 6
    STALKER.leash_range = 0
    STALKER.movement_speed = 4.13
    STALKER.splash_area_air = 0
    STALKER.splash_area_ground = 0
    STALKER.size = 1.25 # Size is in diameter
    STALKER.attribute = ['Armored', 'Mechanical']
    STALKER.is_air = False
    STALKER.is_ground = True
    STALKER.minerals = self.calculate_unit_value(STALKER).minerals
    STALKER.vespene = self.calculate_unit_value(STALKER).vespene
    STALKER.supply = self.calculate_supply_cost(STALKER) # Training/morph cost, so upgraded units must count their base units!
    STALKER.build_time = 23
    
    SENTRY.attacks_ground = 1
    SENTRY.attacks_air = 1
    SENTRY.dmg_ground = 6
    SENTRY.dmg_air = 6
    SENTRY.bonus_dmg_ground = 0
    SENTRY.bonus_dmg_air = 0
    SENTRY.bonus_attr_ground = None
    SENTRY.bonus_attr_air = None
    SENTRY.attack_speed_ground = 0.71
    SENTRY.attack_speed_air = 0.71
    SENTRY.attack_point_ground = 0.71#0.1193
    SENTRY.attack_point_air = 0.71#0.1193
    SENTRY.hp = 40
    SENTRY.shields = 40
    SENTRY.armor = 1
    SENTRY.shield_armor = 0
    SENTRY.range_ground = 5
    SENTRY.range_air = 5
    SENTRY.leash_range = 0
    SENTRY.movement_speed = 3.15
    SENTRY.splash_area_air = 0
    SENTRY.splash_area_ground = 0
    SENTRY.size = 1 # Size is in diameter
    SENTRY.attribute = ['Light', 'Mechanical', 'Psionic']
    SENTRY.is_air = False
    SENTRY.is_ground = True
    SENTRY.minerals = self.calculate_unit_value(SENTRY).minerals
    SENTRY.vespene = self.calculate_unit_value(SENTRY).vespene
    SENTRY.supply = self.calculate_supply_cost(SENTRY) # Training/morph cost, so upgraded units must count their base units!
    SENTRY.build_time = 23
    
    ADEPT.attacks_ground = 1*1.45
    ADEPT.attacks_air = 0
    ADEPT.dmg_ground = 10
    ADEPT.dmg_air = 0
    ADEPT.bonus_dmg_ground = 12
    ADEPT.bonus_dmg_air = 0
    ADEPT.bonus_attr_ground = 'Light'
    ADEPT.bonus_attr_air = None
    ADEPT.attack_speed_ground = 1.61
    ADEPT.attack_speed_air = 1.61
    ADEPT.attack_point_ground = 0.1193
    ADEPT.attack_point_air = 0.1193
    ADEPT.hp = 70
    ADEPT.shields = 70
    ADEPT.armor = 1
    ADEPT.shield_armor = 0
    ADEPT.range_ground = 4
    ADEPT.range_air = 0
    ADEPT.leash_range = 0
    ADEPT.movement_speed = 3.5
    ADEPT.splash_area_air = 0
    ADEPT.splash_area_ground = 0
    ADEPT.size = 1 # Size is in diameter
    ADEPT.attribute = ['Light', 'Biological']
    ADEPT.is_air = False
    ADEPT.is_ground = True
    ADEPT.minerals = self.calculate_unit_value(ADEPT).minerals
    ADEPT.vespene = self.calculate_unit_value(ADEPT).vespene
    ADEPT.supply = self.calculate_supply_cost(ADEPT) # Training/morph cost, so upgraded units must count their base units!
    ADEPT.build_time = 20
    
    DARKTEMPLAR.attacks_ground = 1
    DARKTEMPLAR.attacks_air = 0
    DARKTEMPLAR.dmg_ground = 45
    DARKTEMPLAR.dmg_air = 0
    DARKTEMPLAR.bonus_dmg_ground = 0
    DARKTEMPLAR.bonus_dmg_air = 0
    DARKTEMPLAR.bonus_attr_ground = None
    DARKTEMPLAR.bonus_attr_air = None
    DARKTEMPLAR.attack_speed_ground = 1.21
    DARKTEMPLAR.attack_speed_air = 0
    DARKTEMPLAR.attack_point_ground = 0.2579
    DARKTEMPLAR.attack_point_air = 0.2579
    DARKTEMPLAR.hp = 40
    DARKTEMPLAR.shields = 80
    DARKTEMPLAR.armor = 1
    DARKTEMPLAR.shield_armor = 0
    DARKTEMPLAR.range_ground = 0.1
    DARKTEMPLAR.range_air = 0
    DARKTEMPLAR.leash_range = 0
    DARKTEMPLAR.movement_speed = 3.94
    DARKTEMPLAR.splash_area_air = 0
    DARKTEMPLAR.splash_area_ground = 0
    DARKTEMPLAR.size = 0.75 # Size is in diameter
    DARKTEMPLAR.attribute = ['Light', 'Biological']
    DARKTEMPLAR.is_air = False
    DARKTEMPLAR.is_ground = True
    DARKTEMPLAR.minerals = self.calculate_unit_value(DARKTEMPLAR).minerals
    DARKTEMPLAR.vespene = self.calculate_unit_value(DARKTEMPLAR).vespene
    DARKTEMPLAR.supply = self.calculate_supply_cost(DARKTEMPLAR) # Training/morph cost, so upgraded units must count their base units!
    DARKTEMPLAR.build_time = 32
    
    ARCHON.attacks_ground = 1
    ARCHON.attacks_air = 1
    ARCHON.dmg_ground = 25
    ARCHON.dmg_air = 25
    ARCHON.bonus_dmg_ground = 10
    ARCHON.bonus_dmg_air = 10
    ARCHON.bonus_attr_ground = 'Biological'
    ARCHON.bonus_attr_air = 'Biological'
    ARCHON.attack_speed_ground = 1.25
    ARCHON.attack_speed_air = 1.25
    ARCHON.attack_point_ground = 0.1193
    ARCHON.attack_point_air = 0.1193
    ARCHON.hp = 10
    ARCHON.shields = 350
    ARCHON.armor = 1
    ARCHON.shield_armor = 0
    ARCHON.range_ground = 3
    ARCHON.range_air = 3
    ARCHON.leash_range = 0
    ARCHON.movement_speed = 3.94
    ARCHON.splash_area_air = self.PI*(0.25**2 + (0.5**2-0.25**2)*0.5 + (1**2-0.5**2)*0.25)
    ARCHON.splash_area_ground = self.PI*(0.25**2 + (0.5**2-0.25**2)*0.5 + (1**2-0.5**2)*0.25)
    ARCHON.size = 2 # Size is in diameter
    ARCHON.attribute = ['Massive', 'Psionic']
    ARCHON.is_air = False
    ARCHON.is_ground = True
    ARCHON.minerals = self.calculate_unit_value(HIGHTEMPLAR).minerals*2 # If we want to make archons, we will use HTs not DTs.
    ARCHON.vespene = self.calculate_unit_value(HIGHTEMPLAR).vespene*2
    ARCHON.supply = self.calculate_supply_cost(ARCHON) # Training/morph cost, so upgraded units must count their base units!
    ARCHON.build_time = 32*2
    
    IMMORTAL.attacks_ground = 1
    IMMORTAL.attacks_air = 0
    IMMORTAL.dmg_ground = 20
    IMMORTAL.dmg_air = 0
    IMMORTAL.bonus_dmg_ground = 30
    IMMORTAL.bonus_dmg_air = 0
    IMMORTAL.bonus_attr_ground = 'Armored'
    IMMORTAL.bonus_attr_air = None
    IMMORTAL.attack_speed_ground = 1.04
    IMMORTAL.attack_speed_air = 1.04
    IMMORTAL.attack_point_ground = 0.1193
    IMMORTAL.attack_point_air = 0.1193
    IMMORTAL.hp = 200
    IMMORTAL.shields = 100 + 100 # We will count barrier as +100 shields
    IMMORTAL.armor = 1
    IMMORTAL.shield_armor = 0
    IMMORTAL.range_ground = 6
    IMMORTAL.range_air = 0
    IMMORTAL.leash_range = 0
    IMMORTAL.movement_speed = 3.15
    IMMORTAL.splash_area_air = 0
    IMMORTAL.splash_area_ground = 0
    IMMORTAL.size = 1.5 # Size is in diameter
    IMMORTAL.attribute = ['Armored', 'Mechanical']
    IMMORTAL.is_air = False
    IMMORTAL.is_ground = True
    IMMORTAL.minerals = self.calculate_unit_value(IMMORTAL).minerals
    IMMORTAL.vespene = self.calculate_unit_value(IMMORTAL).vespene
    IMMORTAL.supply = self.calculate_supply_cost(IMMORTAL) # Training/morph cost, so upgraded units must count their base units!
    IMMORTAL.build_time = 39
    
    COLOSSUS.attacks_ground = 2
    COLOSSUS.attacks_air = 0
    COLOSSUS.dmg_ground = 10
    COLOSSUS.dmg_air = 0
    COLOSSUS.bonus_dmg_ground = 5
    COLOSSUS.bonus_dmg_air = 0
    COLOSSUS.bonus_attr_ground = 'Light'
    COLOSSUS.bonus_attr_air = None
    COLOSSUS.attack_speed_ground = 1.07
    COLOSSUS.attack_speed_air = 1.07
    COLOSSUS.attack_point_ground = 0.0594
    COLOSSUS.attack_point_air = 0.0594
    COLOSSUS.hp = 200
    COLOSSUS.shields = 150
    COLOSSUS.armor = 1
    COLOSSUS.shield_armor = 0
    COLOSSUS.range_ground = 7+2
    COLOSSUS.range_air = 0
    COLOSSUS.leash_range = 0
    COLOSSUS.movement_speed = 3.15
    COLOSSUS.splash_area_air = 0
    COLOSSUS.splash_area_ground = 2.8
    COLOSSUS.size = 2 # Size is in diameter
    COLOSSUS.attribute = ['Armored', 'Mechanical', 'Massive']
    COLOSSUS.is_air = True
    COLOSSUS.is_ground = True
    COLOSSUS.minerals = self.calculate_unit_value(COLOSSUS).minerals
    COLOSSUS.vespene = self.calculate_unit_value(COLOSSUS).vespene
    COLOSSUS.supply = self.calculate_supply_cost(COLOSSUS) # Training/morph cost, so upgraded units must count their base units!
    COLOSSUS.build_time = 54
    
    DISRUPTOR.attacks_ground = 1
    DISRUPTOR.attacks_air = 0
    DISRUPTOR.dmg_ground = 145
    DISRUPTOR.dmg_air = 0
    DISRUPTOR.bonus_dmg_ground = 0
    DISRUPTOR.bonus_dmg_air = 0
    DISRUPTOR.bonus_attr_ground = None
    DISRUPTOR.bonus_attr_air = None
    DISRUPTOR.attack_speed_ground = 21.4
    DISRUPTOR.attack_speed_air = 21.4
    DISRUPTOR.attack_point_ground = 2.1
    DISRUPTOR.attack_point_air = 2.1
    DISRUPTOR.hp = 100
    DISRUPTOR.shields = 100
    DISRUPTOR.armor = 1
    DISRUPTOR.shield_armor = 0
    DISRUPTOR.range_ground = 11
    DISRUPTOR.range_air = 0
    DISRUPTOR.leash_range = 0
    DISRUPTOR.movement_speed = 3.15
    DISRUPTOR.splash_area_air = 0
    DISRUPTOR.splash_area_ground = self.PI*1.5**2
    DISRUPTOR.size = 1 # Size is in diameter
    DISRUPTOR.attribute = ['Armored', 'Mechanical']
    DISRUPTOR.is_air = False
    DISRUPTOR.is_ground = True
    DISRUPTOR.minerals = self.calculate_unit_value(DISRUPTOR).minerals
    DISRUPTOR.vespene = self.calculate_unit_value(DISRUPTOR).vespene
    DISRUPTOR.supply = self.calculate_supply_cost(DISRUPTOR) # Training/morph cost, so upgraded units must count their base units!
    DISRUPTOR.build_time = 36
    
    PHOENIX.attacks_ground = 0
    PHOENIX.attacks_air = 2
    PHOENIX.dmg_ground = 0
    PHOENIX.dmg_air = 5
    PHOENIX.bonus_dmg_ground = 0
    PHOENIX.bonus_dmg_air = 5
    PHOENIX.bonus_attr_ground = None
    PHOENIX.bonus_attr_air = 'Light'
    PHOENIX.attack_speed_ground = 0.79
    PHOENIX.attack_speed_air = 0.79
    PHOENIX.attack_point_ground = 0
    PHOENIX.attack_point_air = 0
    PHOENIX.hp = 120
    PHOENIX.shields = 60
    PHOENIX.armor = 0
    PHOENIX.shield_armor = 0
    PHOENIX.range_ground = 0
    PHOENIX.range_air = 5+2
    PHOENIX.leash_range = 0
    PHOENIX.movement_speed = 5.95
    PHOENIX.splash_area_air = 0
    PHOENIX.splash_area_ground = 0
    PHOENIX.size = 1.5 # Size is in diameter
    PHOENIX.attribute = ['Light', 'Mechanical']
    PHOENIX.is_air = True
    PHOENIX.is_ground = False
    PHOENIX.minerals = self.calculate_unit_value(PHOENIX).minerals
    PHOENIX.vespene = self.calculate_unit_value(PHOENIX).vespene
    PHOENIX.supply = self.calculate_supply_cost(PHOENIX) # Training/morph cost, so upgraded units must count their base units!
    PHOENIX.build_time = 25
    
    ORACLE.attacks_ground = 1
    ORACLE.attacks_air = 0
    ORACLE.dmg_ground = 15
    ORACLE.dmg_air = 0
    ORACLE.bonus_dmg_ground = 7
    ORACLE.bonus_dmg_air = 0
    ORACLE.bonus_attr_ground = 'Light'
    ORACLE.bonus_attr_air = None
    ORACLE.attack_speed_ground = 0.61
    ORACLE.attack_speed_air = 0.61
    ORACLE.attack_point_ground = 0.1193
    ORACLE.attack_point_air = 0.1193
    ORACLE.hp = 100 
    ORACLE.shields = 60
    ORACLE.armor = 0
    ORACLE.shield_armor = 0
    ORACLE.range_ground = 4
    ORACLE.range_air = 0
    ORACLE.leash_range = 0
    ORACLE.movement_speed = 5.6
    ORACLE.splash_area_air = 0
    ORACLE.splash_area_ground = 0
    ORACLE.size = 1.5 # Size is in diameter
    ORACLE.attribute = ['Armored', 'Mechanical']
    ORACLE.is_air = True
    ORACLE.is_ground = False
    ORACLE.minerals = self.calculate_unit_value(ORACLE).minerals
    ORACLE.vespene = self.calculate_unit_value(ORACLE).vespene
    ORACLE.supply = self.calculate_supply_cost(ORACLE) # Training/morph cost, so upgraded units must count their base units!
    ORACLE.build_time = 37
    
    VOIDRAY.attacks_ground = 1
    VOIDRAY.attacks_air = 1
    VOIDRAY.dmg_ground = 6
    VOIDRAY.dmg_air = 6
    VOIDRAY.bonus_dmg_ground = 4+6
    VOIDRAY.bonus_dmg_air = 4+6
    VOIDRAY.bonus_attr_ground = 'Armored'
    VOIDRAY.bonus_attr_air = 'Armored'
    VOIDRAY.attack_speed_ground = 0.36
    VOIDRAY.attack_speed_air = 0.36
    VOIDRAY.attack_point_ground = 0.36#0.1193
    VOIDRAY.attack_point_air = 0.36#0.1193
    VOIDRAY.hp = 150 
    VOIDRAY.shields = 100
    VOIDRAY.armor = 0
    VOIDRAY.shield_armor = 0
    VOIDRAY.range_ground = 6
    VOIDRAY.range_air = 6
    VOIDRAY.leash_range = 0
    VOIDRAY.movement_speed = 3.5
    VOIDRAY.splash_area_air = 0
    VOIDRAY.splash_area_ground = 0
    VOIDRAY.size = 2 # Size is in diameter
    VOIDRAY.attribute = ['Armored', 'Mechanical']
    VOIDRAY.is_air = True
    VOIDRAY.is_ground = False
    VOIDRAY.minerals = self.calculate_unit_value(VOIDRAY).minerals
    VOIDRAY.vespene = self.calculate_unit_value(VOIDRAY).vespene
    VOIDRAY.supply = self.calculate_supply_cost(VOIDRAY) # Training/morph cost, so upgraded units must count their base units!
    VOIDRAY.build_time = 43
    
    TEMPEST.attacks_ground = 1
    TEMPEST.attacks_air = 1
    TEMPEST.dmg_ground = 40
    TEMPEST.dmg_air = 30
    TEMPEST.bonus_dmg_ground = 0
    TEMPEST.bonus_dmg_air = 22
    TEMPEST.bonus_attr_ground = None
    TEMPEST.bonus_attr_air = 'Massive'
    TEMPEST.attack_speed_ground = 2.36
    TEMPEST.attack_speed_air = 2.36
    TEMPEST.attack_point_ground = 0.1193
    TEMPEST.attack_point_air = 0.1193
    TEMPEST.hp = 200 
    TEMPEST.shields = 100
    TEMPEST.armor = 2
    TEMPEST.shield_armor = 0
    TEMPEST.range_ground = 10
    TEMPEST.range_air = 14
    TEMPEST.leash_range = 0
    TEMPEST.movement_speed = 3.15
    TEMPEST.splash_area_air = 0
    TEMPEST.splash_area_ground = 0
    TEMPEST.size = 2.5 # Size is in diameter
    TEMPEST.attribute = ['Armored', 'Mechanical', 'Massive']
    TEMPEST.is_air = True
    TEMPEST.is_ground = False
    TEMPEST.minerals = self.calculate_unit_value(TEMPEST).minerals
    TEMPEST.vespene = self.calculate_unit_value(TEMPEST).vespene
    TEMPEST.supply = self.calculate_supply_cost(TEMPEST) # Training/morph cost, so upgraded units must count their base units!
    TEMPEST.build_time = 43
    
    INTERCEPTOR.attacks_ground = 2
    INTERCEPTOR.attacks_air = 2
    INTERCEPTOR.dmg_ground = 5
    INTERCEPTOR.dmg_air = 5
    INTERCEPTOR.bonus_dmg_ground = 0
    INTERCEPTOR.bonus_dmg_air = 0
    INTERCEPTOR.bonus_attr_ground = None
    INTERCEPTOR.bonus_attr_air = None
    INTERCEPTOR.attack_speed_ground = 2.14
    INTERCEPTOR.attack_speed_air = 2.14
    INTERCEPTOR.attack_point_ground = 0.27
    INTERCEPTOR.attack_point_air = 0.27
    INTERCEPTOR.hp = 40
    INTERCEPTOR.shields = 40
    INTERCEPTOR.armor = 0
    INTERCEPTOR.shield_armor = 0
    INTERCEPTOR.range_ground = 8
    INTERCEPTOR.range_air = 8
    INTERCEPTOR.leash_range = 14
    INTERCEPTOR.movement_speed = 2.62
    INTERCEPTOR.splash_area_air = 0
    INTERCEPTOR.splash_area_ground = 0
    INTERCEPTOR.size = 0.5 # Size is in diameter
    INTERCEPTOR.attribute = ['Light', 'Mechanical']
    INTERCEPTOR.is_air = True
    INTERCEPTOR.is_ground = False
    INTERCEPTOR.minerals = self.calculate_unit_value(INTERCEPTOR).minerals
    INTERCEPTOR.vespene = self.calculate_unit_value(INTERCEPTOR).vespene
    INTERCEPTOR.supply = self.calculate_supply_cost(INTERCEPTOR) # Training/morph cost, so upgraded units must count their base units!
    INTERCEPTOR.build_time = 9
    
    CARRIER.attacks_ground = 2*8
    CARRIER.attacks_air = 2*8
    CARRIER.dmg_ground = 5
    CARRIER.dmg_air = 5
    CARRIER.bonus_dmg_ground = 0
    CARRIER.bonus_dmg_air = 0
    CARRIER.bonus_attr_ground = None
    CARRIER.bonus_attr_air = None
    CARRIER.attack_speed_ground = 2.14
    CARRIER.attack_speed_air = 2.14
    CARRIER.attack_point_ground = 0
    CARRIER.attack_point_air = 0
    CARRIER.hp = 300
    CARRIER.shields = 150
    CARRIER.armor = 2
    CARRIER.shield_armor = 0
    CARRIER.range_ground = 8
    CARRIER.range_air = 8
    CARRIER.leash_range = 14
    CARRIER.movement_speed = 2.62
    CARRIER.splash_area_air = 0
    CARRIER.splash_area_ground = 0
    CARRIER.size = 2.5 # Size is in diameter
    CARRIER.attribute = ['Armored', 'Mechanical', 'Massive']
    CARRIER.is_air = True
    CARRIER.is_ground = False
    CARRIER.minerals = self.calculate_unit_value(CARRIER).minerals
    CARRIER.vespene = self.calculate_unit_value(CARRIER).vespene
    CARRIER.supply = self.calculate_supply_cost(CARRIER) # Training/morph cost, so upgraded units must count their base units!
    CARRIER.build_time = 64
    
    MOTHERSHIP.attacks_ground = 6
    MOTHERSHIP.attacks_air = 6
    MOTHERSHIP.dmg_ground = 6
    MOTHERSHIP.dmg_air = 6
    MOTHERSHIP.bonus_dmg_ground = 0
    MOTHERSHIP.bonus_dmg_air = 0
    MOTHERSHIP.bonus_attr_ground = None
    MOTHERSHIP.bonus_attr_air = None
    MOTHERSHIP.attack_speed_ground = 1.58
    MOTHERSHIP.attack_speed_air = 1.58
    MOTHERSHIP.attack_point_ground = 0
    MOTHERSHIP.attack_point_air = 0
    MOTHERSHIP.hp = 350
    MOTHERSHIP.shields = 350
    MOTHERSHIP.armor = 2
    MOTHERSHIP.shield_armor = 0
    MOTHERSHIP.range_ground = 7
    MOTHERSHIP.range_air = 7
    MOTHERSHIP.leash_range = 0
    MOTHERSHIP.movement_speed = 2.62
    MOTHERSHIP.splash_area_air = 0
    MOTHERSHIP.splash_area_ground = 0
    MOTHERSHIP.size = 2.75 # Size is in diameter
    MOTHERSHIP.attribute = ['Armored', 'Mechanical', 'Psionic', 'Massive', 'Heroic']
    MOTHERSHIP.is_air = True
    MOTHERSHIP.is_ground = False
    MOTHERSHIP.minerals = self.calculate_unit_value(MOTHERSHIP).minerals
    MOTHERSHIP.vespene = self.calculate_unit_value(MOTHERSHIP).vespene
    MOTHERSHIP.supply = self.calculate_supply_cost(MOTHERSHIP) # Training/morph cost, so upgraded units must count their base units!
    MOTHERSHIP.build_time = 114
    
    # Zerg: Note that all zerg ground units can burrow! 
    # Excluded units: Vipers, Infestors, Swarm hosts, Overseers, Overlords, Broodlings, Locusts, Banelings
    # How do we count the combat strength of swarm hosts and brood lords? What about spellcasters? What about banelings?
    self.zerg_army = [ZERGLING, ROACH, RAVAGER, HYDRALISK, LURKERMP, QUEEN, MUTALISK, CORRUPTOR, BROODLORD, ULTRALISK]
    
    ZERGLING.attacks_ground = 1*1.4
    ZERGLING.attacks_air = 0
    ZERGLING.dmg_ground = 5
    ZERGLING.dmg_air = 0
    ZERGLING.bonus_dmg_ground = 0
    ZERGLING.bonus_dmg_air = 0
    ZERGLING.bonus_attr_ground = None
    ZERGLING.bonus_attr_air = None
    ZERGLING.attack_speed_ground = 0.497
    ZERGLING.attack_speed_air = 0.497
    ZERGLING.attack_point_ground = 0.1193
    ZERGLING.attack_point_air = 0.1193
    ZERGLING.hp = 35
    ZERGLING.shields = 0
    ZERGLING.armor = 0
    ZERGLING.shield_armor = 0
    ZERGLING.range_ground = 0.1
    ZERGLING.range_air = 0
    ZERGLING.leash_range = 0
    ZERGLING.movement_speed = 4.13*1.6
    ZERGLING.splash_area_air = 0
    ZERGLING.splash_area_ground = 0
    ZERGLING.size = 0.75 # Size is in diameter
    ZERGLING.attribute = ['Light', 'Biological']
    ZERGLING.is_air = False
    ZERGLING.is_ground = True
    ZERGLING.minerals = self.calculate_unit_value(ZERGLING).minerals
    ZERGLING.vespene = self.calculate_unit_value(ZERGLING).vespene
    ZERGLING.supply = self.calculate_supply_cost(ZERGLING) # Training/morph cost, so upgraded units must count their base units!
    ZERGLING.build_time = 17
    
    ROACH.attacks_ground = 1
    ROACH.attacks_air = 0
    ROACH.dmg_ground = 16
    ROACH.dmg_air = 0
    ROACH.bonus_dmg_ground = 0
    ROACH.bonus_dmg_air = 0
    ROACH.bonus_attr_ground = None
    ROACH.bonus_attr_air = None
    ROACH.attack_speed_ground = 1.43
    ROACH.attack_speed_air = 1.43
    ROACH.attack_point_ground = 0.1193
    ROACH.attack_point_air = 0.1193
    ROACH.hp = 145
    ROACH.shields = 0
    ROACH.armor = 1
    ROACH.shield_armor = 0
    ROACH.range_ground = 4
    ROACH.range_air = 0
    ROACH.leash_range = 0
    ROACH.movement_speed = 3.15+1.05
    ROACH.splash_area_air = 0
    ROACH.splash_area_ground = 0
    ROACH.size = 1 # Size is in diameter
    ROACH.attribute = ['Armored', 'Biological']
    ROACH.is_air = False
    ROACH.is_ground = True
    ROACH.minerals = self.calculate_unit_value(ROACH).minerals
    ROACH.vespene = self.calculate_unit_value(ROACH).vespene
    ROACH.supply = self.calculate_supply_cost(ROACH) # Training/morph cost, so upgraded units must count their base units!
    ROACH.build_time = 19
    
    # Does not include bile!
    RAVAGER.attacks_ground = 1
    RAVAGER.attacks_air = 0
    RAVAGER.dmg_ground = 16
    RAVAGER.dmg_air = 0
    RAVAGER.bonus_dmg_ground = 0
    RAVAGER.bonus_dmg_air = 0
    RAVAGER.bonus_attr_ground = None
    RAVAGER.bonus_attr_air = None
    RAVAGER.attack_speed_ground = 1.14
    RAVAGER.attack_speed_air = 1.14
    RAVAGER.attack_point_ground = 0.1429
    RAVAGER.attack_point_air = 0.1429
    RAVAGER.hp = 120
    RAVAGER.shields = 0
    RAVAGER.armor = 1
    RAVAGER.shield_armor = 0
    RAVAGER.range_ground = 6
    RAVAGER.range_air = 0
    RAVAGER.leash_range = 0
    RAVAGER.movement_speed = 3.85
    RAVAGER.splash_area_air = 0
    RAVAGER.splash_area_ground = 0
    RAVAGER.size = 1.5 # Size is in diameter
    RAVAGER.attribute = ['Biological']
    RAVAGER.is_air = False
    RAVAGER.is_ground = True
    RAVAGER.minerals = self.calculate_unit_value(RAVAGER).minerals
    RAVAGER.vespene = self.calculate_unit_value(RAVAGER).vespene
    RAVAGER.supply = self.calculate_supply_cost(RAVAGER) + self.calculate_supply_cost(ROACH) # Training/morph cost, so upgraded units must count their base units!
    RAVAGER.build_time = 19 + 9
    
    HYDRALISK.attacks_ground = 1
    HYDRALISK.attacks_air = 1
    HYDRALISK.dmg_ground = 12
    HYDRALISK.dmg_air = 12
    HYDRALISK.bonus_dmg_ground = 0
    HYDRALISK.bonus_dmg_air = 0
    HYDRALISK.bonus_attr_ground = None
    HYDRALISK.bonus_attr_air = None
    HYDRALISK.attack_speed_ground = 0.54
    HYDRALISK.attack_speed_air = 0.54
    HYDRALISK.attack_point_ground = 0.1486
    HYDRALISK.attack_point_air = 0.1486
    HYDRALISK.hp = 90
    HYDRALISK.shields = 0
    HYDRALISK.armor = 0
    HYDRALISK.shield_armor = 0
    HYDRALISK.range_ground = 5+1
    HYDRALISK.range_air = 5+1
    HYDRALISK.leash_range = 0
    HYDRALISK.movement_speed = 3.15+0.7875
    HYDRALISK.splash_area_air = 0
    HYDRALISK.splash_area_ground = 0
    HYDRALISK.size = 1.25 # Size is in diameter
    HYDRALISK.attribute = ['Light', 'Biological']
    HYDRALISK.is_air = False
    HYDRALISK.is_ground = True
    HYDRALISK.minerals = self.calculate_unit_value(HYDRALISK).minerals
    HYDRALISK.vespene = self.calculate_unit_value(HYDRALISK).vespene
    HYDRALISK.supply = self.calculate_supply_cost(HYDRALISK) # Training/morph cost, so upgraded units must count their base units!
    HYDRALISK.build_time = 24
    
    # Models splash as radius of 3 of the spikes. 10 spikes are shot, but we assume only 3 are useful!
    LURKERMP.attacks_ground = 1
    LURKERMP.attacks_air = 0
    LURKERMP.dmg_ground = 20
    LURKERMP.dmg_air = 0
    LURKERMP.bonus_dmg_ground = 10
    LURKERMP.bonus_dmg_air = 0
    LURKERMP.bonus_attr_ground = 'Armored'
    LURKERMP.bonus_attr_air = None
    LURKERMP.attack_speed_ground = 1.43
    LURKERMP.attack_speed_air = 1.43
    LURKERMP.attack_point_ground = 1.43
    LURKERMP.attack_point_air = 1.43
    LURKERMP.hp = 200
    LURKERMP.shields = 0
    LURKERMP.armor = 1
    LURKERMP.shield_armor = 0
    LURKERMP.range_ground = 8+2
    LURKERMP.range_air = 0
    LURKERMP.leash_range = 0
    LURKERMP.movement_speed = 4.13
    LURKERMP.splash_area_air = 0
    LURKERMP.splash_area_ground = 3*self.PI*0.5**2
    LURKERMP.size = 1.5 # Size is in diameter
    LURKERMP.attribute = ['Armored', 'Biological']
    LURKERMP.is_air = False
    LURKERMP.is_ground = True
    LURKERMP.minerals = self.calculate_unit_value(LURKERMP).minerals
    LURKERMP.vespene = self.calculate_unit_value(LURKERMP).vespene
    LURKERMP.supply = self.calculate_supply_cost(LURKERMP) + self.calculate_supply_cost(HYDRALISK) # Training/morph cost, so upgraded units must count their base units!
    LURKERMP.build_time = 24 + 18
    
    QUEEN.attacks_ground = 2
    QUEEN.attacks_air = 1
    QUEEN.dmg_ground = 4
    QUEEN.dmg_air = 9
    QUEEN.bonus_dmg_ground = 0
    QUEEN.bonus_dmg_air = 0
    QUEEN.bonus_attr_ground = None
    QUEEN.bonus_attr_air = None
    QUEEN.attack_speed_ground = 0.71
    QUEEN.attack_speed_air = 0.71
    QUEEN.attack_point_ground = 0.1193
    QUEEN.attack_point_air = 0.1193
    QUEEN.hp = 175
    QUEEN.shields = 0
    QUEEN.armor = 1
    QUEEN.shield_armor = 0
    QUEEN.range_ground = 5
    QUEEN.range_air = 8
    QUEEN.leash_range = 0
    QUEEN.movement_speed = 1.31
    QUEEN.splash_area_air = 0
    QUEEN.splash_area_ground = 0
    QUEEN.size = 1.75 # Size is in diameter
    QUEEN.attribute = ['Psionic', 'Biological']
    QUEEN.is_air = False
    QUEEN.is_ground = True
    QUEEN.minerals = self.calculate_unit_value(QUEEN).minerals
    QUEEN.vespene = self.calculate_unit_value(QUEEN).vespene
    QUEEN.supply = self.calculate_supply_cost(QUEEN) # Training/morph cost, so upgraded units must count their base units!
    QUEEN.build_time = 36
    
    # Models bounce damage as 3 hits of average damage (6). Does not reflect the poor scaling of the bounce with upgrades!
    MUTALISK.attacks_ground = 3
    MUTALISK.attacks_air = 3
    MUTALISK.dmg_ground = 6
    MUTALISK.dmg_air = 6
    MUTALISK.bonus_dmg_ground = 0
    MUTALISK.bonus_dmg_air = 0
    MUTALISK.bonus_attr_ground = None
    MUTALISK.bonus_attr_air = None
    MUTALISK.attack_speed_ground = 1.09
    MUTALISK.attack_speed_air = 1.09
    MUTALISK.attack_point_ground = 0
    MUTALISK.attack_point_air = 0
    MUTALISK.hp = 120
    MUTALISK.shields = 0
    MUTALISK.armor = 0
    MUTALISK.shield_armor = 0
    MUTALISK.range_ground = 3
    MUTALISK.range_air = 3
    MUTALISK.leash_range = 0
    MUTALISK.movement_speed = 5.6
    MUTALISK.splash_area_air = 0
    MUTALISK.splash_area_ground = 0
    MUTALISK.size = 1 # Size is in diameter
    MUTALISK.attribute = ['Light', 'Biological']
    MUTALISK.is_air = True
    MUTALISK.is_ground = False
    MUTALISK.minerals = self.calculate_unit_value(MUTALISK).minerals
    MUTALISK.vespene = self.calculate_unit_value(MUTALISK).vespene
    MUTALISK.supply = self.calculate_supply_cost(MUTALISK) # Training/morph cost, so upgraded units must count their base units!
    MUTALISK.build_time = 24
    
    CORRUPTOR.attacks_ground = 0
    CORRUPTOR.attacks_air = 1
    CORRUPTOR.dmg_ground = 0
    CORRUPTOR.dmg_air = 14
    CORRUPTOR.bonus_dmg_ground = 0
    CORRUPTOR.bonus_dmg_air = 6
    CORRUPTOR.bonus_attr_ground = None
    CORRUPTOR.bonus_attr_air = 'Massive'
    CORRUPTOR.attack_speed_ground = 1.36
    CORRUPTOR.attack_speed_air = 1.36
    CORRUPTOR.attack_point_ground = 0.0446
    CORRUPTOR.attack_point_air = 0.0446
    CORRUPTOR.hp = 200
    CORRUPTOR.shields = 0
    CORRUPTOR.armor = 2
    CORRUPTOR.shield_armor = 0
    CORRUPTOR.range_ground = 0
    CORRUPTOR.range_air = 6
    CORRUPTOR.leash_range = 0
    CORRUPTOR.movement_speed = 4.725
    CORRUPTOR.splash_area_air = 0
    CORRUPTOR.splash_area_ground = 0
    CORRUPTOR.size = 1.25 # Size is in diameter
    CORRUPTOR.attribute = ['Armored', 'Biological']
    CORRUPTOR.is_air = True
    CORRUPTOR.is_ground = False
    CORRUPTOR.minerals = self.calculate_unit_value(CORRUPTOR).minerals
    CORRUPTOR.vespene = self.calculate_unit_value(CORRUPTOR).vespene
    CORRUPTOR.supply = self.calculate_supply_cost(CORRUPTOR) # Training/morph cost, so upgraded units must count their base units!
    CORRUPTOR.build_time = 29
    
    # Assumes that broodlings hit twice each. Does not take into account hp of broodlings, broodlings getting multiple hits, or pathblocking!
    BROODLORD.attacks_ground = 6
    BROODLORD.attacks_air = 0
    BROODLORD.dmg_ground = (20+4*2)/3
    BROODLORD.dmg_air = 0
    BROODLORD.bonus_dmg_ground = 0
    BROODLORD.bonus_dmg_air = 0
    BROODLORD.bonus_attr_ground = None
    BROODLORD.bonus_attr_air = None
    BROODLORD.attack_speed_ground = 1.79*2
    BROODLORD.attack_speed_air = 1.79*2
    BROODLORD.attack_point_ground = 0.1193
    BROODLORD.attack_point_air = 0.1193
    BROODLORD.hp = 225
    BROODLORD.shields = 0
    BROODLORD.armor = 1
    BROODLORD.shield_armor = 0
    BROODLORD.range_ground = 10
    BROODLORD.range_air = 0
    BROODLORD.leash_range = 0
    BROODLORD.movement_speed = 1.97
    BROODLORD.splash_area_air = 0
    BROODLORD.splash_area_ground = 0
    BROODLORD.size = 1.25 # Size is in diameter
    BROODLORD.attribute = ['Armored', 'Biological', 'Massive']
    BROODLORD.is_air = True
    BROODLORD.is_ground = False
    BROODLORD.minerals = self.calculate_unit_value(BROODLORD).minerals
    BROODLORD.vespene = self.calculate_unit_value(BROODLORD).vespene
    BROODLORD.supply = self.calculate_supply_cost(BROODLORD) + self.calculate_supply_cost(CORRUPTOR) # Training/morph cost, so upgraded units must count their base units!
    BROODLORD.build_time = 24
    
    ULTRALISK.attacks_ground = 1
    ULTRALISK.attacks_air = 0
    ULTRALISK.dmg_ground = 35
    ULTRALISK.dmg_air = 0
    ULTRALISK.bonus_dmg_ground = 0
    ULTRALISK.bonus_dmg_air = 0
    ULTRALISK.bonus_attr_ground = None
    ULTRALISK.bonus_attr_air = None
    ULTRALISK.attack_speed_ground = 0.61
    ULTRALISK.attack_speed_air = 0.61
    ULTRALISK.attack_point_ground = 0.238
    ULTRALISK.attack_point_air = 0.238
    ULTRALISK.hp = 500
    ULTRALISK.shields = 0
    ULTRALISK.armor = 2+2
    ULTRALISK.shield_armor = 0
    ULTRALISK.range_ground = 10
    ULTRALISK.range_air = 0
    ULTRALISK.leash_range = 0
    ULTRALISK.movement_speed = 4.13+0.82
    ULTRALISK.splash_area_air = 0
    ULTRALISK.splash_area_ground = 0.33*(self.PI*2**2)/2
    ULTRALISK.size = 2 # Size is in diameter
    ULTRALISK.attribute = ['Armored', 'Biological', 'Massive']
    ULTRALISK.is_air = False
    ULTRALISK.is_ground = True
    ULTRALISK.minerals = self.calculate_unit_value(ULTRALISK).minerals
    ULTRALISK.vespene = self.calculate_unit_value(ULTRALISK).vespene
    ULTRALISK.supply = self.calculate_supply_cost(ULTRALISK) # Training/morph cost, so upgraded units must count their base units!
    ULTRALISK.build_time = 39
