# Free for all script written by Yourself
# With scripts from: Jail.py and arena.py
# And btw I doubt this works; Ninja Pig
# fixed by thepolm3
 
 
from random import randint
from twisted.internet.reactor import callLater
from pyspades.common import to_coordinates, coordinates
from commands import add, admin, get_player, join_arguments, name, alias, get_team
from pyspades.constants import *
 
jail_location = 0, 0, 0 # x, y, z of the spectator room
jail_coords   = [ ] # e.g. ["B4", "B5"]
 
# If ALWAYS_ENABLED is False, free for all can still be enabled in the map
# metadata by setting the key 'free_for_all' to True in the extensions dictionary
ALWAYS_ENABLED = True
 
# If WATER_SPANS is True, then players can spawn in water
WATER_SPAWNS = False
 
HIDE_POS = (0, 0, 63)
 
def apply_script(protocol, connection, config):
    class SurvivorProtocol(protocol):
        game_mode=CTF_MODE
        free_for_all=None
        
        def on_map_change(self, map):
            extensions = self.map_info.extensions
            if ALWAYS_ENABLED:
                self.free_for_all = True
            else:
                if extensions.has_key('free_for_all'):
                    self.free_for_all = extensions['free_for_all']
                else:
                    self.free_for_all = False
            if self.free_for_all:
                self.friendly_fire = True
            return protocol.on_map_change(self, map)
        
        def on_base_spawn(self, x, y, z, base, entity_id):
            if self.free_for_all:
                return HIDE_POS
            return protocol.on_base_spawn(self, x, y, z, base, entity_id)
 
        def on_flag_spawn(self, x, y, z, flag, entity_id):
            if self.free_for_all:
                return HIDE_POS
            return protocol.on_flag_spawn(self, x, y, z, flag, entity_id)
 
    class SurvivorConnection(connection):
        score_hack = False
        def on_spawn_location(self, pos):
            if not self.score_hack and self.protocol.free_for_all:
                while True:
                    x = randint(0, 511)
                    y = randint(0, 511)
                    z = self.protocol.map.get_z(x, y)
                    if z != 63 or WATER_SPAWNS:
                        break
                # Magic numbers taken from server.py spawn function
                z -= 2.4
                x += 0.5
                y += 0.5
                return (x, y, z)
            return connection.on_spawn_location(self, pos)

        def on_connect(self):
            if self.protocol.free_for_all and not get_team(self, "green").locked:
                get_team(self, "green").locked = True
            return connection.on_connect(self)

        def on_refill(self):
            if self.protocol.free_for_all:
                return False
            return connection.on_refill(self)
 
        def on_flag_take(self):
            if self.protocol.free_for_all:
                return False
            return connection.on_flag_take(self)
        
        def on_kill(self, by, type, grenade):
            # Switch teams to add score hack
            if by is not None and by.team is self.team and self is not by:
                self.switch_team()
                a=callLater(0.01,self.switch_team)
                return connection.on_kill(self, by, type, grenade)

        def switch_team(self):
            pos = self.world_object.position
            self.set_team(self.team.other)
            self.spawn((pos.x, pos.y, pos.z))
 
 
    return SurvivorProtocol, SurvivorConnection
