from pyspades.server import *                                           # ooh god no
from commands import name, add, admin, alias                            # i wont comment
import commands                                                         # everything
from pyspades.constants import *                                        # here there are
from pyspades.collision import vector_collision, distance_3d_vector     # just too many lines

class point():   # couldnt find any more boring name
    x = None     
    y = None
    z = None


@alias('pr')
@name('piercingrounds')
def switch_rounds(self):
    if self.pierce and self.weapon == RIFLE_WEAPON:
        self.pierce = False
        weapon_reload.player_id = self.player_id
        weapon_reload.clip_ammo = self.weapon_object.current_ammo
        weapon_reload.reserve_ammo = self.weapon_object.current_stock * 2
        self.weapon_object.current_stock *= 2
        self.send_contained(weapon_reload)
        return 'You return to use normal ammunition.' 
    elif self.pierce == False and self.weapon == RIFLE_WEAPON:
    	self.pierce = True
        weapon_reload.player_id = self.player_id
        weapon_reload.clip_ammo = self.weapon_object.current_ammo
        weapon_reload.reserve_ammo = self.weapon_object.current_stock / 2
        self.weapon_object.current_stock /= 2
        self.send_contained(weapon_reload)
        self.send_chat('Keep in mind that they will not work when you keep the mouse button pressed.')
        return 'Your Bullets can pierce through blocks now'
    else: 
    	return 'This option is only available for the Rifle.'
commands.add(switch_rounds)

@alias('pd')
@admin
@name('piercedistance')
def pierce_distance(self, value):
    self.protocol.piercing_distance = int(value)
    annoyance = 'Your bullets can only pierce through blocks that are not farther than %i blocks!' % (self.protocol.piercing_distance)
    self.protocol.send_chat(annoyance)
    return annoyance
commands.add(pierce_distance)

@alias('pv')
@admin
@name('piercevalid')
def pierce_valid(self, value):
    self.protocol.piercing_valid = int(value)
    fuckthis = 'Piercing rounds hit only when the targit is standing %i blocks away from a wall.' % (self.protocol.piercing_valid)
    self.protocol.send_chat(fuckthis)
    return fuckthis
commands.add(pierce_valid)

@alias('pt')
@admin
@name('piercetolerance')
def pierce_tolerance(self, value):
    self.protocol.piercing_tolerance = float(value)
    omgkillme = 'Piercingtolerance set to %f.' % (self.protocol.piercing_tolerance)
    return omgkillme
commands.add(pierce_tolerance)

@alias('pdm')
@admin
@name('piercedamagemultiplier')
def pierce_damage_multiplier(self, value):
    self.protocol.piercing_damage_multiplier = float(value)
    ithasnoend = 'Pierce damage multiplier set to %f.' % (self.protocol.piercing_damage_multiplier)
    self.protocol.send_chat(ithasnoend)
    return ithasnoend
commands.add(pierce_damage_multiplier)

@alias('tpc')
@admin
@name('togglepierce')
def set_pierce(self):
    if self.protocol.pierce_on == True:
        self.protocol.pierce_on = False
        aaarghstahp = 'NOOOO YOU LOST THE ABILITY TO USE PIERCING ROUNDS!'
        self.protocol.send_chat(aaarghstahp)
        return aaarghstahp
    else:
        self.protocol.pierce_on = True
        aaarghstahp = 'HALEJUYA YOU ARE ABLE TO USE PIERCING ROUNDS NOW!'
        self.protocol.send_chat(aaarghstahp)
        return aaarghstahp
commands.add(set_pierce)


def apply_script(protocol, connection, config): # but i cant stop Y_Y

    class piercingprotocol(protocol):

        piercing_distance = 126          # aah my lovely included
        piercing_valid = 3               # customization possibilities
        piercing_tolerance = 0.3         # hackers will be in awe bout
        piercing_damage_multiplier = 1   # that script i suppose
        piercing_on = True               # it will be cool though
    
    class piercingconnection(connection):

        pierce = False

        def on_shoot_set(self, fire):  # why is there no actual function for a normal shot?

                if self.protocol.piercing_on:

                    if self.pierce == True and fire == True and self.weapon == RIFLE_WEAPON and self.tool != BLOCK_TOOL and self.tool != SPADE_TOOL: # geez 

                        hoho = self.world_object.cast_ray(self.protocol.piercing_distance)
                        if hoho == None: hoho = (0,0,0) # hohohohohohoh
                        point.x = hoho[0]  # ooohohohoho
                        point.y = hoho[1]  # ohoohoohoo
                        point.z = hoho[2]  # hoho hoooo

                        for unicorn in self.protocol.players.values():

                            if unicorn.team != self.team and unicorn.team != 2: # spectators ruin every script of mine

                                if distance_3d_vector(self.world_object.position, unicorn.world_object.position) <= self.protocol.piercing_distance and distance_3d_vector(point, unicorn.world_object.position) <= self.protocol.piercing_valid: # again a monsterline

                                    if self.world_object.validate_hit(unicorn.world_object, TORSO, self.protocol.piercing_tolerance):
                                        unicorn.hit(self.weapon_object.damage[0] * self.protocol.piercing_damage_multiplier, self, WEAPON_KILL)
                                        connection.on_hit(self, self.weapon_object.damage[0] * self.protocol.piercing_damage_multiplier, unicorn, WEAPON_KILL, None)

                                    elif self.world_object.validate_hit(unicorn.world_object, HEAD, self.protocol.piercing_tolerance):
                                        unicorn.hit(self.weapon_object.damage[1] * self.protocol.piercing_damage_multiplier, self, HEADSHOT_KILL)
                                        connection.on_hit(self, self.weapon_object.damage[1] * self.protocol.piercing_damage_multiplier, unicorn, HEADSHOT_KILL, None)

                                    elif self.world_object.validate_hit(unicorn.world_object, ARMS, self.protocol.piercing_tolerance):
                                        unicorn.hit(self.weapon_object.damage[2] * self.protocol.piercing_damage_multiplier, self, WEAPON_KILL)
                                        connection.on_hit(self, self.weapon_object.damage[2] * self.protocol.piercing_damage_multiplier, unicorn, WEAPON_KILL, None)

                                    elif self.world_object.validate_hit(unicorn.world_object, LEGS, self.protocol.piercing_tolerance):
                                        unicorn.hit(self.weapon_object.damage[3] * self.protocol.piercing_damage_multiplier, self, WEAPON_KILL)
                                        connection.on_hit(self, self.weapon_object.damage[3] * self.protocol.piercing_damage_multiplier, unicorn, WEAPON_KILL, None)

                        fire = False # i dunno why but i guess it has some use

                return connection.on_shoot_set(self, False)

        def on_spawn(self, pos): # just to make sure nobody doubles his ammo

            if self.pierce and self.weapon == RIFLE_WEAPON:
            	weapon_reload.player_id = self.player_id
                weapon_reload.clip_ammo = self.weapon_object.current_ammo
                weapon_reload.reserve_ammo = self.weapon_object.current_stock / 2
                self.weapon_object.current_stock /= 2
                self.send_contained(weapon_reload)

            return connection.on_spawn(self, pos)


    return piercingprotocol, piercingconnection