import plus
import Arenas
import AI
import math
import random

class BlackHoleArena(Arenas.SuperArena):
    "Designed by the famous scientist Jonzu, this space station represents the cutting edge of Black Hole technology."
    name = "Black Hole Space Station"
    preview = "BlackHole/BlackHole_Preview.bmp"
    game_types = ['DEATHMATCH', 'BATTLE ROYAL', 'TEAM MATCH']
    extent = (-30, 30, 31, -31)

    def __init__(self):
        Arenas.SuperArena.__init__(self, "Arenas/BlackHole/BlackHole.gmf")
        plus.setBackColor(0,0,0)
        self.Inferno1 = []
        self.Inferno2 = []
        self.Inferno3 = []
        self.Inferno4 = []
        self.FireOn1 = 0
        self.FireOn2 = 0
        self.FireOn3 = 0
        self.FireOn4 = 0

        self.AddStaticCamera("\t\tOuter View 1", (35, 8, 35), (0.5148, -2.3562), 0.675)
        self.AddStaticCamera("\t\tOuter View 2", (-35, 8, 35), (0.5148, 2.3562), 0.675)
        self.AddStaticCamera("\t\tOuter View 3", (35, 8, -35), (0.5148, -0.7854), 0.675)
        self.AddStaticCamera("\t\tOuter View 4", (-35, 8, -35), (0.5148, 0.7854), 0.675)

        self.AddStaticCamera("\t\tInner View 1", (14.5, 4, 14.5), (0.5833, -2.3562), 0.7854)
        self.AddStaticCamera("\t\tInner View 2", (-14.5, 4, 14.5), (0.5833, 2.3562), 0.7854)
        self.AddStaticCamera("\t\tInner View 3", (14.5, 4, -14.5), (0.5833, -0.7854), 0.7854)
        self.AddStaticCamera("\t\tInner View 4", (-14.5, 4, -14.5), (0.5833, 0.7854), 0.7854)

        self.AddStaticCamera("\t\tCenter View 1", (0, 20, 0), (1.5708, 1.5708), 0.675)
        self.AddStaticCamera("\t\tCenter View 2", (0, 40, 0), (1.5708, 1.5708), 0.675)
        self.AddStaticCamera("\t\tCenter View 3", (0, 60.67, 0), (1.5708, 1.5708), 0.675)
        self.AddStaticCamera("\t\tCenter View 4", (0, 80, 0), (1.5708, 1.5708), 0.675)

        self.AddWatchCamera("\t\tWatch Cam 1", (10, 16, 10), (6, 37, 0.5236, 0.3491))
        self.AddWatchCamera("\t\tWatch Cam 2", (-10, 16, 10), (6, 37, 0.5236, 0.3491))
        self.AddWatchCamera("\t\tWatch Cam 3", (10, 16, -10), (6, 37, 0.5236, 0.3491))
        self.AddWatchCamera("\t\tWatch Cam 4", (-10, 16, -10), (6, 37, 0.5236, 0.3491))

    def __del__(self):
        self.__setattr__tickInterval__(0.25)
        Arenas.SuperArena.__del__(self)

    def Activate(self, starting): #Loaded at beginning and end of battle
        if starting:
            self.players = list(plus.getPlayers())

            self.RegisterZone("FireZone1", 1)
            self.RegisterZone("FireZone2", 2)
            self.RegisterZone("FireZone3", 3)
            self.RegisterZone("FireZone4", 4)

        Arenas.SuperArena.Activate(self, starting)

    def HazardsOn(self, on):
        if on:
            for x in xrange(12,20):
                x -= 0.2
                for y in xrange(12,20):
                    y -= 0.2
                    if (x + y) % 2:
                        self.Inferno1.append(plus.AddParticleEmitter((x,-7.5,y), (0,2.5,0), (5, 15, 5)))#.SetEmitting(True)
                        self.Inferno2.append(plus.AddParticleEmitter((-x,-7.5,y), (0,2.5,0), (5, 15, 5)))#.SetEmitting(True)
                        self.Inferno3.append(plus.AddParticleEmitter((x,-7.5,-y), (0,2.5,0), (5, 15, 5)))#.SetEmitting(True)
                        self.Inferno4.append(plus.AddParticleEmitter((-x,-7.5,-y), (0,2.5,0), (5, 15, 5)))#.SetEmitting(True)
            random.shuffle(self.Inferno1)
            random.shuffle(self.Inferno2)
            random.shuffle(self.Inferno3)
            random.shuffle(self.Inferno4)

        #FireZone1
        self.AddCollisionLine((6, 12), (12, 6))
        self.AddCollisionLine((12, 6), (18, 12))
        self.AddCollisionLine((18, 12), (12, 18))
        self.AddCollisionLine((12, 18), (6, 12))

        #FireZone2
        self.AddCollisionLine((-6, 12), (-12, 6))
        self.AddCollisionLine((-12, 6), (-18, 12))
        self.AddCollisionLine((-18, 12), (-12, 18))
        self.AddCollisionLine((-12, 18), (-6, 12))

        #FireZone3
        self.AddCollisionLine((6, -12), (12, -6))
        self.AddCollisionLine((12, -6), (18, -12))
        self.AddCollisionLine((18, -12), (12, -18))
        self.AddCollisionLine((12, -18), (6, -12))

        #FireZone4
        self.AddCollisionLine((-6, -12), (-12, -6))
        self.AddCollisionLine((-12, -6), (-18, -12))
        self.AddCollisionLine((-18, -12), (-12, -18))
        self.AddCollisionLine((-12, -18), (-6, -12))

        #Movement Around Hazards
        self.AddPOV(0, (25, 25), (0, 1, 2, 4, 6))
        self.AddPOV(1, (-25, 25), (0, 1, 3, 5, 6))
        self.AddPOV(2, (25, -25), (0, 2, 3, 4, 7))
        self.AddPOV(3, (-25, -25), (1, 2, 3, 5, 7))
        self.AddPOV(4, (25, 0), (0, 2, 4, 5, 8))
        self.AddPOV(5, (-25, 0), (1, 3, 4, 5, 8))
        self.AddPOV(6, (0, 25), (0, 1, 6, 7, 8))
        self.AddPOV(7, (0, -25), (2, 3, 6, 7, 8))
        self.AddPOV(8, (0, 0), (4, 5, 6, 7, 8))

        return Arenas.SuperArena.HazardsOn(self, on)

    def Tick(self):
        if self.FireOn1 > 0:
            if plus.getFPS() > 40:
                for fire in self.Inferno1:
                    if plus.getFPS() > 40:
                        fire.SetEmitting(True)
                    else: break
            else:
                for fire in self.Inferno1: fire.SetEmitting(False)

            self.FireOn1 -= self.tickInterval
            burnbot = self.GetRobotsInPhantom("FireZone1")
            if len(burnbot):
                self.FireOn1 = 3
                for bot in burnbot:
                    plus.force(bot-1, 0, plus.getWeight(bot-1)*600, 0)
                    if plus.getHealth(bot-1, 0) <= 0:
                        plus.damage(bot-1, 0, 41, (15,3.8,15))
                    plus.damage(bot-1, 0, 15, (15,3.8,15))
        else:
            for fire in self.Inferno1: fire.SetEmitting(False)

        if self.FireOn2 > 0:
            if plus.getFPS() > 40:
                for fire in self.Inferno2:
                    if plus.getFPS() > 40:
                        fire.SetEmitting(True)
                    else: break
            else:
                for fire in self.Inferno2: fire.SetEmitting(False)

            self.FireOn2 -= self.tickInterval
            burnbot = self.GetRobotsInPhantom("FireZone2")
            if len(burnbot):
                self.FireOn2 = 3
                for bot in burnbot:
                    plus.force(bot-1, 0, plus.getWeight(bot-1)*600, 0)
                    if plus.getHealth(bot-1, 0) <= 0:
                        plus.damage(bot-1, 0, 41, (-15,3.8,15))
                    plus.damage(bot-1, 0, 15, (-15,3.8,15))
        else:
            for fire in self.Inferno2: fire.SetEmitting(False)

        if self.FireOn3 > 0:
            if plus.getFPS() > 40:
                for fire in self.Inferno3:
                    if plus.getFPS() > 40:
                        fire.SetEmitting(True)
                    else: break
            else:
                for fire in self.Inferno3: fire.SetEmitting(False)

            self.FireOn3 -= self.tickInterval
            burnbot = self.GetRobotsInPhantom("FireZone3")
            if len(burnbot):
                self.FireOn3 = 3
                for bot in burnbot:
                    plus.force(bot-1, 0, plus.getWeight(bot-1)*600, 0)
                    if plus.getHealth(bot-1, 0) <= 0:
                        plus.damage(bot-1, 0, 41, (15,3.8,-15))
                    plus.damage(bot-1, 0, 15, (15,3.8,-15))
        else:
            for fire in self.Inferno3: fire.SetEmitting(False)

        if self.FireOn4 > 0:
            if plus.getFPS() > 40:
                for fire in self.Inferno4:
                    if plus.getFPS() > 40:
                        fire.SetEmitting(True)
                    else: break
            else:
                for fire in self.Inferno4: fire.SetEmitting(False)

            self.FireOn4 -= self.tickInterval
            burnbot = self.GetRobotsInPhantom("FireZone4")
            if len(burnbot):
                self.FireOn4 = 3
                for bot in burnbot:
                    plus.force(bot-1, 0, plus.getWeight(bot-1)*600, 0)
                    if plus.getHealth(bot-1, 0) <= 0:
                        plus.damage(bot-1, 0, 41, (-15,0,-15))
                    plus.damage(bot-1, 0, 15, (-15,0,-15))
        else:
            for fire in self.Inferno4: fire.SetEmitting(False)

        for each in plus.getPlayers():
            Where = plus.getLocation(each)
            if Where[1] < -12: plus.eliminatePlayer(each)

        return Arenas.SuperArena.Tick(self)

    def ZoneEvent(self, direction, id, robot, chassis):
        #print "robot:", robot
        if id == 1:
            self.FireOn1 = 3
        elif id == 2:
            self.FireOn2 = 3
        elif id == 3:
            self.FireOn3 = 3
        elif id == 4:
            self.FireOn4 = 3
        return True

    def GetPath(self, start, end, ignore_hazards):
        # overridden to stay in bounds

        if ignore_hazards:
            return Arenas.SuperArena.GetPath(self, start, end, ignore_hazards)

        if 10 < abs(end[0]) < 20 and 10 < abs(end[2]) < 20:
            self.TargetingSystem = [(math.sqrt((start[0]-plus.getLocation(x)[0])**2+(start[1]-plus.getLocation(x)[1])**2+(start[2]-plus.getLocation(x)[2])**2), (10 < abs(plus.getLocation(x)[0]) < 20 and 10 < abs(plus.getLocation(x)[2]) < 20), x) for x in plus.getPlayers()]
            #[(DistanceFromStart, InHazard, BotID)] #After sorting, the first bot is the AI loading this and the second bot is its target
            if self.TargetingSystem != []:
                self.TargetingSystem.sort()
                self.TargetingSystem.reverse()
                self.StatusOfAI = self.TargetingSystem.pop() #Don't target self unless you want to hold still (I'm not using the variable 'start' because future AI might use GetPath for other things besides driving right away)

                AI_Index = 0
                self.NewTargetID = -1

                for target in self.TargetingSystem:
                    if target[2] < self.StatusOfAI[2]:
                        if not plus.isHuman(target[2]):
                            AI_Index += 1
                for index in xrange(0, len(self.TargetingSystem)):
                    if not self.TargetingSystem[index][1] and (self.TargetingSystem[index][2] in AI.running_ai[AI_Index].GetEnemies()):
                        self.NewTargetID = self.TargetingSystem[index][2] #Keeps replacing the ID as it gets closer to the bot

                if self.NewTargetID == -1:
                    AI.running_ai[AI_Index].AimToHeading(AI.running_ai[AI_Index].GetHeadingTo(end,0), 0)
                    return Arenas.SuperArena.GetPath(self, start, start, ignore_hazards)

                return Arenas.SuperArena.GetPath(self, start, plus.getLocation(self.NewTargetID), ignore_hazards)

        return Arenas.SuperArena.GetPath(self, start, end, ignore_hazards)

Arenas.register(BlackHoleArena)
