import random, math
class enemy:
    def __init__(self, name, hp, speed, evasion, element, moves, physicalArmor, magicArmor, mana, ability, status):
        self.name = name
        self.hp = hp
        self.speed = speed
        self.evasion = evasion
        self.element = element
        self.moves = moves
        self.physicalArmor = physicalArmor
        self.magicArmor = magicArmor
        self.mana = mana
        self.ability = ability
        self.status = status
        self.cooldowns = cooldownsetup(self.moves)

    def attack(self, target):
        global curent_move
        final_target = ""
        #Check to see if self is alive
        if self.hp > 0:
            self.cooldowns = cooldowncount(self.cooldowns)
            #Check to see if there is more than one target
            print(self.cooldowns)
            if multiple(target) == True:
                #Check to see if targets are alive
                targets = get_target_alive(target)
                #Check to see if self has more than one move
                if multiple(targets) == True:
                    if multiple(self.moves) == True:
                        #Counter varable to slice cooldowns list with
                        count = -1
                        curent_move = 0
                        for move in self.moves:
                            count = count + 1
                            d = 0
                            for move in self.moves:
                                best_move = move
                            #Check to see if move is off cool down and self has enough mana
                            if avalable(move.manacost, self.mana, self.cooldowns, count) == True:
                                for target in targets:
                                    d = move_calc(move,target, d, count)
                                if best_move.damage < d:
                                    best_move = move
                                    final_target = target
                                elif best_move.damage == d:
                                    if best_move.manacost > move.manacost:
                                        best_move = move
                                        final_target = target
                    else:
                        if type(self.moves) == list:
                            self.moves = self.moves[0]
                        best_move = self.moves
                else:
                    final_target = targets
            else:
                final_target = target
        else:
            death()
            print("Your dead")
            best_move = Dead
        if best_move.area == True:
            if random.randrange(0,100) < (best_move.accuracy):
                for target in targets:
                    target.hp = target.hp - damage_calc(best_move, target)
        else:
            if random.randrange(0,100) < (best_move.accuracy):
                target.hp = target.hp - damage_calc(best_move, target)
        print(best_move.name, best_move.damage, final_target, target.hp)


def death():
    pass

def damage_calc(move, target):
    return math.ceil((move.damage*aElements[move.element][target.element])*((100-target.physicalArmor)/100))

def move_calc(move,target, d, count):
    global curent_move
    if move.area == True:
        if random.randrange(0,100) < (move.accuracy):
            if move.element == "Physical":
                d = d + damage_calc(move, target)
            else:
                d = d + damage_calc(move, target)
        else:
            d = 0
    else:
        if curent_move == count:
            if random.randrange(0,100) < (move.accuracy):
                if move.element == "Physical":
                    if damage_calc(move, target) > d:
                        d = damage_calc(move, target)
                else:
                    if damage_calc(move, target) > d:
                        d = damage_calc(move, target)
            else:
                d = 0
        else:
            if random.randrange(0,100) < (move.accuracy):
                if move.element == "Physical":
                    d = damage_calc(move, target)
                else:
                    d = damage_calc(move, target)
            else:
                d = 0
    curent_move = count
    return d

def cooldownsetup(moves):
    cooldowns = []
    #Sets up a list of 0's to store cool down times in self.cooldowns unless there is only move in which case self.cooldowns is a single varable
    if multiple(moves) == True:
        for move in moves:
            cooldowns.append(0)
        return cooldowns
    else:
        return 0
        
def cooldowncount(cooldowns):
    #Checks to see if there is more than one cool down
    if multiple(cooldowns) == True:
        #lowers all values in cooldowns list by one unless its already 0
        cooldowns[:] = [(x - 1)  if (x>0) else (x) for x in cooldowns]
        return cooldowns
    else:
        return cooldowns - 1

#for (move, cooldown) in zip(moves, cooldowns):
        
                      
def avalable(cost, mana, cooldowns, count):
    #checks if self will have more than or = to mana after the cost of the spell is subtracted
    if (mana - cost) >= 0:
        if cooldowns[count] <= 0:
            return True
    return False

def multiple(target):
    #checks to see if input is a list and if so it checks to see if that list has more than one value if so it returns True otherwise it returns False
    if type(target) == list:
        if len(target) > 1:
            return True
    return False

def get_target_alive(target):
    alive_target = []
    #Filters throgh target list and removes any targets that dont have more than 0 health
    for targets in target:
        if targets.hp > 0:
            alive_target.append(targets)
    return alive_target


class Moves:
    def __init__(self, name, damage, element, accuracy, cooldown, manacost, area):
        self.name = name
        self.damage = damage
        self.element = element
        self.accuracy = accuracy
        self.cooldown = cooldown
        self.manacost = manacost
        self.area = area


#Type chart attacking element is on the left and defending element is on the right will return damage multiplyer
aElements = {
    "Fire" : {"Water" : 0.5, "Earth" : 0.5, "Nature" : 2, "Air" : 2, "Fire" : 0.5, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Water" : {"Water" : 0.5, "Earth" : 2, "Nature" : -0.5, "Air" : 1, "Fire" : 2, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Earth" : {"Water" : 1, "Earth" : 1, "Nature" : 0.5, "Air" : 0, "Fire" : 2, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Nature" : {"Water" : 2, "Earth" : 2, "Nature" : 1, "Air" : 0.2, "Fire" : 0, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Air" : {"Water" : 1, "Earth" : 2, "Nature" : 1, "Air" : 0.5, "Fire" : 2, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Physical" : {"Water" : 1, "Earth" : 1, "Nature" : 1, "Air" : 1, "Fire" : 1, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Dark" : {"Water" : 1, "Earth" : 1, "Nature" : 1, "Air" : 1, "Fire" : 1, "Physical" : 1, "Dark" : 1, "Light" : 1},
    "Light" : {"Water" : 1, "Earth" : 1, "Nature" : 1, "Air" : 1, "Fire" : 1, "Physical" : 1, "Dark" : 1, "Light" : 1}
}


#Move objects
Fireblast = Moves("Fireblast", 5, "Fire", 80, 2, 2, True)
Fireball = Moves("Fireball", 4, "Fire", 95, 2, 2, True)
Fireshot = Moves("Fireshot", 4, "Fire", 90, 2, 1, False)
Jump = Moves("Jump", 2, "Physical", 100, 1, 0, False)
Dead = Moves("ded", 0, "Physical", 0, 0, 0, False)

#Enemy objects
#name, hp, speed, evasion, element, moves, physicalArmor, magicArmor, mana, ability, status
slime = enemy("Slime", 8, 1, 5, "Water", [Fireball, Fireshot, Jump], 5, 15, 3, "mana_absorbe", "nada")
wolf = enemy("Wolf", 3, 1, 5, "Physical", [Fireshot, Jump, Fireball], 5, 15, 10, "hunter", "nada")
rat = enemy("Rat", 8, 1, 5, "Physical", [Fireball, Jump, Fireshot], 5, 15, 10, "sworm", "nada")
rat.attack([wolf, slime])
rat.attack([wolf, slime])
rat.attack([wolf, slime])
[0, 0, 0]
Fireshot 4  6
[0, 0, 0]
Fireshot 4  4
[0, 0, 0]
Fireshot 4  2