"""
MOBA by thepolm3

Idea by Jdrew
Use this script with the "mobapowers" script for best effects
"""

from twisted.internet.reactor import callLater
from random import randint
from pyspades.server import Territory
from pyspades.collision import vector_collision

PER_LANE=2
LANES=3
BLUE_BASE=20,492
GREEN_BASE=492,20
NOCP=max(0,min(16,PER_LANE*LANES*2+2))
LANEMIDDLES=[(20,20),(255,255),(492,492)]

class MOBACP(Territory):
    lane=0
    position=0
    start_team=None
    per_lane=PER_LANE
    lanes=LANES
    def reset(self):
        self.team=self.start_team
        self.update()

    def add_player(self, player):
        if self.position==0:
            for i in range(LANES):
                cp=self.protocol.find_cp(i,1,self.team)
                if cp and cp.team!=self.team:
                    return Territory.add_player(self,player)
            if player.team!=self.team:
                player.kill()
                return
        elif player.team!= self.start_team and self.position<PER_LANE:
            cp=self.protocol.find_cp(self.lane,self.position+1,self.start_team)
            if cp:
                if cp.team==self.start_team: #if the lane hasn't been captured yet
                    player.hit(10)
                    return
        Territory.add_player(self,player)
            

def apply_script(protocol,connection,config):
    class MOBAConnection(connection):

        def on_spawn_location(self,pos):
            x,y=[BLUE_BASE,GREEN_BASE][self.team==self.protocol.green_team]
            x+=randint(-20,20)
            y+=randint(-20,20)
            connection.on_spawn_location(self,pos)
            return (x,y,self.protocol.map.get_z(x,y)-3)

        def get_cp_standing_in(self):
            if self.world_object:
                for cp in self.protocol.cps:
                    if vector_collision(self.world_object.position, cp):
                        return cp

        def on_refill(self):
            cp=self.get_cp_standing_in()
            if cp:
                if cp.team==self.team.other:
                    return False
            return connection.on_refill(self)
                

    class MOBAProtocol(protocol):
        game_mode=1
        cps=[]

        def on_cp_capture(self,cp):
            if cp.position==0:
                for player in cp.players:
                    if player.team!=cp.start_team:
                        self.reset_game(player)
                        callLater(0.1,cp.reset)
                        return protocol.on_cp_capture(self,cp)
            return protocol.on_cp_capture(self,cp)
            
        def on_map_change(self,map):
            global PER_LANE,LANES,BLUE_BASE,GREEN_BASE,NOCP,LANEMIDDLES
            extensions=self.map_info.extensions
            if extensions.has_key('per_lane'):
                PER_LANE = extensions['per_lane']
            if extensions.has_key('lanes'):
                LANEMIDDLES = extensions['lanes']
                LANES=len(LANEMIDDLES)
            if extensions.has_key('blue_base'):
                BLUE_BASE = extensions['blue_base']
            if extensions.has_key('green_base'):
                GREEN_BASE = extensions['green_base']
            NOCP=max(0,min(16,PER_LANE*LANES*2+2))
            return protocol.on_map_change(self,map)

        def find_cp(self,lane=None,position=None,team=None):
            max_count=[1,0][lane==None]+[1,0][position==None]+[1,0][team==None]
            for cp in self.cps:
                count=0
                if lane!=None and cp.lane==lane:
                    count+=1
                if position!=None and cp.position==position:
                    count+=1
                if team!=None and cp.start_team==team:
                    count+=1
                if count>=max_count:
                    return cp

        def get_cp(self,index):
            #magic function
            if index>=NOCP/2:
                team=self.green_team
                index-=NOCP/2
            else:
                team=self.blue_team
            if index+1==NOCP/2:
                x,y=[BLUE_BASE,GREEN_BASE][team==self.green_team]
                lane=0
                position=0
            else:
                position=index % PER_LANE+1
                lane=((index-(position-1))/PER_LANE)
                if team==self.blue_team:
                    xa,ya=LANEMIDDLES[lane]
                    xb,yb=BLUE_BASE
                    xa,ya=xa-xb,ya-yb
                    xa,ya=xa/(PER_LANE+1),ya/(PER_LANE+1)
                    x,y=(xa*(position))+BLUE_BASE[0],(ya*(position))+BLUE_BASE[1]
                else:
                    xa,ya=LANEMIDDLES[lane]
                    xb,yb=GREEN_BASE
                    xa,ya=xa-xb,ya-yb
                    xa,ya=xa/(PER_LANE+1),ya/(PER_LANE+1)
                    x,y=(xa*(position))+GREEN_BASE[0],(ya*(position))+GREEN_BASE[1]
            return lane,position,team,x,y,self.map.get_z(x,y)
                    

        def get_cp_entities(self):
            cps = []
            for i in xrange(NOCP):
                l,p,t,x,y,z = self.get_cp(i)
                cp = MOBACP(i, self, x,y,z)
                cp.team = t
                cp.position = p
                cp.lane = l
                cp.start_team = t
                cps.append(cp)
            self.cps=cps
            return cps

    return MOBAProtocol,MOBAConnection
