from __future__ import generators
import plus
import Arenas
import random
import Hazards
import math

import HazardsBlueRay
from random import randint


class BBEANS_Bot_Flame(Arenas.SuperArena):
    "The official arena for BBEANS AI tournaments.  This arena features low boundary walls and a walled spinning blade in the center.  After 90 seconds, the walls around the blade will retract into the floor."
    name = "BBEANS Tournament Arena"
    preview = "bbeans/bbeans_preview.bmp"
    game_types = ['DEATHMATCH', 'BATTLE ROYAL', 'TEAM MATCH']
    extent = (-11, 11, 11, -11)

    def __init__(self):
        Arenas.SuperArena.__init__(self, "Arenas/bbeans/bbeans.gmf")
        plus.setBackColor(0,0,0)
        degrad = 0.01745
        self.AddStaticCamera("                Overview", (0, 7.8, -17.5), (35*degrad,0), 68*degrad)
        self.AddStaticCamera("                Corner Cam 1", (4, 0, 4), (10*degrad,45*degrad),72*degrad)
        self.AddStaticCamera("                Corner Cam 2", (4, 0, -4), (10*degrad,135*degrad), 72*degrad)
        self.AddStaticCamera("                Corner Cam 3", (-4, 0, -4), (10*degrad,225*degrad), 72*degrad)
        self.AddStaticCamera("                Corner Cam 4", (-4, 0, 4), (10*degrad,315*degrad), 72*degrad)
        self.AddWatchCamera("                Watch Cam 1", (15, 7.8, -15), (6, 37, 40*degrad, 15*degrad))
        self.AddWatchCamera("                Watch Cam 2", (-15, 7.8, 15), (6, 37, 40*degrad, 15*degrad))
        self.AddWatchCamera("                Blade Cam", (0, 2, 0), (5, 25, 65*degrad, 45*degrad))
        self.AddWatchCamera("                Overhead Cam", (0, 7.8, 0), (10, 15, 68*degrad, 58*degrad))
        self.AddWatchCamera("                Audience Cam", (0, 3, -30), (19, 41, 30*degrad, 20*degrad))
        self.players = ()
        self.SetPinned ("bladewall", True)
        self.wallmaster = 0

            ##################  BotFlame ##################-------------
        self.SetDefaultstimer = 0  
        self.RI_OffOrOn = 0
        self.RI_1 = 0
        self.RI_2 = 0
        self.RI_3 = 0
        self.RI_4 = 0
        self.RI_5 = 0
        self.RI_6 = 0
        self.BOT_0 = False
        self.BOT_1 = False
        self.BOT_2 = False
        self.BOT_3 = False

       ## ----------- ADJUSTABLE SETTINGS ----------- ##
        self.FrequencyOfBotFire = 9999 # Determines how often Bot Fires will occur:   '0' = BotFlames off.     '1' = every game.     '2' = 1 out of every 2 games (average).    Etc......
        self.DamageUntilFlame_a = .2  # Parameters are above 0(dead) and below 1(no damage).  Negative number turns Bot flame 'a' Off.
        self.DamageUntilFlame_b = .1   # Another flame in case of greater damage. Parameters are above 0(dead) and below 1(no damage).  Negative number turns Bot flame 'b' Off.
        self.FireDamageON = False  # 'True' causes fire to damage bot itself.  'False' turns off.
        self.FireDamageAmount = 5  # Determines how much damage the fire does each Tick.
        self.FireSoundON = False  # 'True' turns on 'crackling fire' sound.  'False' turns off.
       ## ----------- ADJUSTABLE SETTINGS ----------- ##
            ##################  BotFlame ##################-------------



    def Activate(self, on):
        if on:
            self.players = plus.getPlayers()

        Arenas.SuperArena.Activate(self, on)
        

    def HazardsOn(self, on):
        self.spinner = self.GetHinge("Hinge01")
        self.spinner.SetAutoLocks(False, False)
        self.spinner.Lock(False)

        self.prism = self.AddPrismatic("floor", "bladewall", 0, -1, 0, 0, 3, 0)
        self.prism.SetAutoLock(False)

        if on:
            self.SetSubMaterialSound("blade", "metal", 1.2, "Sounds\\bbeans\\spinnerhit.wav")
            self.spinner.SetPowerSettings(200,68)
            self.spinner.SetDirection(100)
        else:
            self.wallmaster = 370

        #box off spinner
        self.AddCollisionLine((2, 2), (2, -2))
        self.AddCollisionLine((2, -2), (-2, -2))
        self.AddCollisionLine((-2, -2), (-2, 2))
        self.AddCollisionLine((-2, 2), (2, 2))
        #outer walls
        self.AddCollisionLine((11, 11), (11, -11))
        self.AddCollisionLine((11, -11), (-11, -11))
        self.AddCollisionLine((-11, -11), (-11, 11))
        self.AddCollisionLine((-11, 11), (11, 11))
        #spinner ai guide
        self.AddPOV(0, (5, 5), (0, 1))
        self.AddPOV(1, (5, -5), (1, 2))
        self.AddPOV(2, (-5, -5), (2, 3))
        self.AddPOV(3, (-5, 5), (3, 0))

            ##################  BotFlame ##################-------------
        self.flame0a = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame0a)                                                                    
        self.flame1a = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame1a)                                                                    
        self.flame2a = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame2a)
        self.flame3a = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame3a)                                                                    

        self.flame0b = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame0b)
        self.flame1b = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame1b)
        self.flame2b = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame2b)
        self.flame3b = HazardsBlueRay.BotFlame((0, 0, 0), (0, 1, 0), (.2, .4, .2), .8) 
        self.AddHazard(self.flame3b)            

        #self.Crackle = plus.createSound("Sounds/Crackling-short.wav", True, (0,0,0)) # Indicator.
        self.Crackle = plus.createSound("Sounds/Crackling-short-quiet.wav", True, (0,0,0)) # Indicator.
            ##################  BotFlame ##################-------------

        return Arenas.SuperArena.HazardsOn(self, on)

    def __del__(self):
        plus.removeSound(self.Crackle)
        Arenas.SuperArena.__del__(self)


            ##################  BotFlame ##################-------------
    def Introduction(self):  
        players = plus.getPlayers()
        pcount = len(players)
        if 0 in players: self.BOT_0 = True
        if 1 in players: self.BOT_1 = True
        if 2 in players: self.BOT_2 = True
        if 3 in players: self.BOT_3 = True
        # done
        yield 0            
            ##################  BotFlame ##################-------------





    def Tick(self):
        self.wallmaster += 1

        for each in self.players:
            if plus.getLocation(each)[1] < -0.6 and (abs(plus.getLocation(each)[0]) > 11.3 or abs(plus.getLocation(each)[2]) > 11.3):
                plus.eliminatePlayer(each)
            if abs(plus.getLocation(each)[0]) < 1.8 and abs(plus.getLocation(each)[2]) < 1.8 and plus.getLocation(each)[1] < -0.5 and self.wallmaster < 370:
                self.wallmaster = 370

        if self.wallmaster == 370:
            self.retractsound = plus.createSound("Sounds/liftmotor.wav", False, (0, 0, 0))
            plus.playSound(self.retractsound)
        if self.wallmaster > 370 and self.wallmaster < 390:
            self.SetPinned ("bladewall", False)
            self.prism.Lock(False)
            self.prism.ApplyForce(50)

            ##################  BotFlame ##################-------------
        if self.SetDefaultstimer == 0: #### Set these random values at start. 
            self.RI_OffOrOn = randint(1, self.FrequencyOfBotFire) # @@ Turns Bot flames "On" average of parameter set above (_init_) . @@@@@@
            self.RI_1 = randint(-2, 2) # For flame angle (x, z).
            self.RI_2 = randint(-2, 2)
            self.RI_3 = randint(-2, 2)
            self.RI_4 = randint(-2, 2)
            self.RI_5 = randint(1, 2) # For flame height (y).
            self.RI_6 = randint(1, 2) 
            self.SetDefaultstimer +=1 #### Valid only for 1st Tick, then effectively "OFF".

        #----- Damage = Fire -----
        if self.BOT_0 == True:
            if plus.getHealth(0,0) < self.DamageUntilFlame_a and self.RI_OffOrOn == 1:
                self.flame0a.BotFlameOff()
                self.flame0a = HazardsBlueRay.BotFlame(plus.getLocation(0), (self.RI_1, self.RI_5, self.RI_2), (.2, .4, .2), .8)
                if self.FireDamageON == True:
                    plus.damage(0, 0, self.FireDamageAmount, plus.getLocation(0)) #  damage to bot-0
                if self.FireSoundON == True:
                    plus.playSound(self.Crackle)
                self.flame0a.BotFlameOn()

        if self.BOT_1 == True:
            if plus.getHealth(1,0) < self.DamageUntilFlame_a and self.RI_OffOrOn == 1:
                self.flame1a.BotFlameOff()
                self.flame1a = HazardsBlueRay.BotFlame(plus.getLocation(1), (self.RI_2, self.RI_6, self.RI_3), (.2, .4, .2), .8)
                if self.FireDamageON == True:
                    plus.damage(1, 0, self.FireDamageAmount, plus.getLocation(1)) #  damage to bot-1
                if self.FireSoundON == True:
                    plus.playSound(self.Crackle)
                self.flame1a.BotFlameOn()

        if self.BOT_2 ==True:
            if plus.getHealth(2,0) < self.DamageUntilFlame_a and self.RI_OffOrOn == 1:
                self.flame2a.BotFlameOff()
                self.flame2a = HazardsBlueRay.BotFlame(plus.getLocation(2), (self.RI_3, self.RI_5, self.RI_4), (.2, .4, .2), .8)
                if self.FireDamageON == True:
                    plus.damage(2, 0, self.FireDamageAmount, plus.getLocation(2)) #  damage to bot-2
                if self.FireSoundON == True:
                    plus.playSound(self.Crackle)
                self.flame2a.BotFlameOn()

        if self.BOT_3 == True:
            if plus.getHealth(3,0) < self.DamageUntilFlame_a and self.RI_OffOrOn == 1:
                self.flame3a.BotFlameOff()
                self.flame3a = HazardsBlueRay.BotFlame(plus.getLocation(3), (self.RI_4, self.RI_6, self.RI_1), (.2, .4, .2), .8)
                if self.FireDamageON == True:
                    plus.damage(3, 0, self.FireDamageAmount, plus.getLocation(3)) #  damage to bot-3
                if self.FireSoundON == True:
                    plus.playSound(self.Crackle)
                self.flame3a.BotFlameOn()

        #----- If More Damage, then More Fire -----
        if self.BOT_0 == True:
            if plus.getHealth(0,0) < self.DamageUntilFlame_b and self.RI_OffOrOn == 1:
                self.flame0b.BotFlameOff()
                self.flame0b = HazardsBlueRay.BotFlame(plus.getLocation(0), (self.RI_2, self.RI_6, self.RI_1), (.2, .4, .2), .8)
                self.flame0b.BotFlameOn()

        if self.BOT_1 == True:
            if plus.getHealth(1,0) < self.DamageUntilFlame_b and self.RI_OffOrOn == 1:
                self.flame1b.BotFlameOff()
                self.flame1b = HazardsBlueRay.BotFlame(plus.getLocation(1), (self.RI_3, self.RI_5, self.RI_2), (.2, .4, .2), .8)
                self.flame1b.BotFlameOn()

        if self.BOT_2 == True:
            if plus.getHealth(2,0) < self.DamageUntilFlame_b and self.RI_OffOrOn == 1:
                self.flame2b.BotFlameOff()
                self.flame2b = HazardsBlueRay.BotFlame(plus.getLocation(2), (self.RI_4, self.RI_6, self.RI_3), (.2, .4, .2), .8)
                self.flame2b.BotFlameOn()

        if self.BOT_3 == True:
            if plus.getHealth(3,0) < self.DamageUntilFlame_b and self.RI_OffOrOn == 1:
                self.flame3b.BotFlameOff()
                self.flame3b = HazardsBlueRay.BotFlame(plus.getLocation(3), (self.RI_1, self.RI_5, self.RI_4), (.2, .4, .2), .8)
                self.flame3b.BotFlameOn()
            ##################  BotFlame ##################-------------

            
        return Arenas.SuperArena.Tick(self)



        
Arenas.register(BBEANS_Bot_Flame)
