import es
import random
import gamethread
import playerlib
import popuplib

import wcs
from wcs import wcs

raceName = 'Warden'
race     = wcs.Race(raceName)

""" Load the strings into the variable text """
text     = race.loadStrings()

""" ############################### """
""" ### Begin the configuration ### """
""" ############################### """

config   = race.config()

raceMinLevel      = config.addVar('wardenMinLevel', 100, 'The level required to player the Warden Race.')

config.addComment('')
config.addComment('******************************')
config.addComment('Hide')
config.addComment('   This skill allows the player to')
config.addComment('   become more invisible whilst')
config.addComment('   standing still.')
config.addComment('******************************')
config.addComment('')
hideMaxLevel      = config.addVar('hideMaxLevel',       2, 'The maximum level of the hide skill') 
hideLevelInterval = config.addVar('hideLevelInterval',  5, 'The intervals between the abilities to upgrade their Hide skill')

config.addComment('')
config.addComment('******************************')
config.addComment('Shadow Strike')
config.addComment('    This skill has a random chance')
config.addComment('    to poision a player when damaged.')
config.addComment('******************************')
config.addComment('')
shadowMaxLevel      = config.addVar('shadowMaxLevel',       3, 'The maximum level of the Shadow Strike skill') 
shadowLevelInterval = config.addVar('shadowLevelInterval',  1, 'The intervals between the abilities to upgrade their Shadow Strike skill')
shadowPercentage    = config.addVar('shadowPercentage',    10, 'The chance the attacker will poision the victim multiplied via their Shadow Strike skill')

config.addComment('')
config.addComment('******************************')
config.addComment('Blink')
config.addComment('    This skill teleports a player')
config.addComment('    to the position he his looking.')
config.addComment('******************************')
config.addComment('')
blinkMaxLevel      = config.addVar('blinkMaxLevel',       3, 'The maximum level of the blink skill') 
blinkLevelInterval = config.addVar('blinkLevelInterval',  2, 'The intervals between the abilities to upgrade their Blink skill')

config.addComment('')
config.addComment('******************************')
config.addComment('Fan of Knives')
config.addComment('    This skill damages all nearby')
config.addComment('    enemies when the player presses')
config.addComment('    ability key.')
config.addComment('******************************')
config.addComment('')
fanMaxLevel      = config.addVar('fanMaxLevel',       3, 'The maximum level of the Fan of Knives skill') 
fanLevelInterval = config.addVar('fanLevelInterval',  1, 'The intervals between the abilities to upgrade their Fan of Knives skill')
fanCoolDown      = config.addVar('fanCoolDown',       8, 'The amount of seconds after a player has used their Fan of Knives skill until they can use it again')

config.addComment('')
config.addComment('******************************')
config.addComment('Avatar of Vengance')
config.addComment('    This ultimate creates a sprite')
config.addComment('    on top of all the dead players')
config.addComment('    which Damage enemies.')
config.addComment('******************************')
config.addComment('')
avatarMinLevel      = config.addVar('avatarMinLevel',       6, 'The level required before a player can acquire level 1 of the Avatar of Vengance skill.')
avatarMaxLevel      = config.addVar('avatarMaxLevel',       1, 'The maximum level of the Avatar of Vengance skill') 
avatarLevelInterval = config.addVar('avatarLevelInterval',  1, 'The intervals between the abilities to upgrade their Avatar of Vengance skill')
avatarCoolDown      = config.addVar('avatarCoolDown',      30, 'The amount of seconds after a player has used their Avatar of Vengance skill until they can use it again')

config.load(True)

""" ##################### """
""" ### END OF CONFIG ### """
""" ##################### """

race.registerSkill('Hide',                  int(hideMaxLevel),   int(hideLevelInterval),   'You become hard to see when standing still.')
race.registerSkill('Shadow Strike',         int(shadowMaxLevel), int(shadowLevelInterval), 'Your attacks deal extra damage over time.')
race.registerSkill('Fan of Knives',         int(fanMaxLevel),    int(fanLevelInterval),    'Use your +ability key to deal damage to all oppents near you.')
race.registerSkill('Blink',                 int(blinkMaxLevel),  int(blinkLevelInterval),  'Use your +ability2 key to jump to the postion you are looking at.')
race.registerUltimate('Avatar of Vengance', int(avatarMinLevel), int(avatarMaxLevel),      int(avatarLevelInterval), 'Creates an avatar that summon\'s spirit allies from near by corpses.')
race.registerMinLevel(int(raceMinLevel))

delaylist = []
def player_ultimate_on(event_var):
    userid = int(event_var['userid'])
    if wcs.GetLevel(userid, raceName, 'Avatar of Vengance'):
        if wcs.isEst:
            x,y,z = es.getplayerlocation(userid)
            es.server.queuecmd('est_effect 3 #a 0 sprites/lgtning.vmt %s %s %s %s %s %s %s 40 10 %s %s %s 255'%(x, y, z + 100, x, y, z, 20, 255, 255, 255) )
            es.server.queuecmd('est_effect 10 #a 0 effects/tp_eyefx/tpeye3.vmt %s %s %s 9 0 %s 66 1 0 255 255 255 255 1'%(x, y, z + 75, 20) )
        wcs.Command(userid).SetCoolDown('Avatar of Vengance', int(avatarCoolDown))
        create_spirit(userid, x, y, z, 0, [])
		
def create_spirit(userid, x, y, z, count, bannedlist):
    if count < 20:
        nearlist = filter(lambda x: x not in bannedlist, deadnear(x,y,z))
        if nearlist:
            post = random.choice(nearlist)
            bannedlist.append(post)
            spirit_loop(userid, post[0], post[1], post[2] + 30, 0)
            gamethread.delayedname(1, '%sulti' % userid, create_spirit,(userid, x, y, z, count + 1, bannedlist) )
            delaylist.append('%sulti' % userid)
            
def spirit_loop(userid,x,y,z,count):
    if count <= 10:
        gamethread.delayedname(.5, '%sspirit%s' % (userid, count), spirit_loop,(userid, x, y, z, count + 1) )
        delaylist.append('%sspirit%s' % (userid, count) )
        if wcs.isEst:
            es.server.queuecmd('est_effect 10 #a 0 sprites/lgtning.vmt %s %s %s %s %s %s 5 0 2 %s %s %s 128 10' % (x, y, z, 40, 60, .5, 255, 0, 0) )
        userlist = wcs.Command(userid).GetNearCoordList(x, y, z, 800, 800, 800, '#ct' if es.getplayerteam(userid) == 2 else '#t')
        if len(userlist):
            target     = random.choice(userlist)
            if wcs.isEst:
                x1, y1, z1 = es.getplayerlocation(target)
                es.server.queuecmd('est_effect 3 #a 0 effects/tp_eyefx/tpeye3.vmt %s %s %s %s %s %s %s 7 3 %s %s %s 180'%(x, y, z, x1, y1, z1 + 30, .5, 0, 0, 0) )
            wcs.Command(target).Damage(15, 32, userid)
            
def deadnear(x,y,z):
    nearlist = []
    for player in playerlib.getPlayerList('#all'):
        location = wcs.Command(player).ReturnDict('death location')
        if location is not None:
            qx, qy, qz = location
            if qx or qy or qz:
                qx -= x
                qy -= y
                qz -= z
                if abs(qx) <= 1000 and abs(qy) <= 1000 and abs(qz) <= 1000:
                    nearlist.append(tuple(qx, qy, qz))
    return nearlist
    
def player_death(event_var):
    userid = int(event_var['userid'])
    wcs.Command(userid).UpdateDict('death location', es.getplayerlocation(userid))
	
def player_hurt(event_var):
    userid   = int(event_var['userid'])
    attacker = int(event_var['attacker'])
    damage   = int(event_var['dmg_health'])
    strike   = wcs.GetLevel(attacker, raceName, 'Shadow Strike') * int(shadowPercentage)
    if strike >= random.randint(1,100):
        if not wcs.Command(userid).ReturnDict('poisoned'):
            wcs.Effect().Beam1(attacker,userid,1.5,0,255,0)
            wcs.Command(userid).UpdateDict('poisoned',1)
            wcs.Command(userid).SpeedAdd(-.2)
            gamethread.delayedname(2,'%spoison1'%userid,wcs.Command(userid).Damage,(damage/10,32,attacker))
            gamethread.delayedname(4,'%spoison2'%userid,wcs.Command(userid).Damage,(damage/10,32,attacker))
            gamethread.delayedname(6,'%spoison3'%userid,wcs.Command(userid).Damage,(damage/10,32,attacker))
            gamethread.delayedname(8,'%spoison4'%userid,wcs.Command(userid).Damage,(damage/10,32,attacker))
            gamethread.delayedname(10,'%spoison5'%userid,wcs.Command(userid).Damage,(damage/10,32,attacker))
            gamethread.delayedname(10,'%spoisonspeed'%userid,wcs.Command(userid).SpeedAdd,.2)
            gamethread.delayed(10,wcs.Command(userid).UpdateDict,('poisoned',0))
            delaylist.append('%spoison1'%userid)
            delaylist.append('%spoison2'%userid)
            delaylist.append('%spoison3'%userid)
            delaylist.append('%spoison4'%userid)
            delaylist.append('%spoison5'%userid)
            delaylist.append('%spoisonspeed'%userid)
            
def round_end(event_var):
    global delaylist
    for d in delaylist:
        gamethread.cancelDelayed(d)
    delaylist = []
	
def player_spawn(event_var):
    userid = int(event_var['userid'])
    wcs.Command(userid).UpdateDict('death location', (0,0,0))
    hide = wcs.GetLevel(userid, raceName, 'Hide') * 30
    if hide:
        wcs.Command(userid).UpdateDict('location', es.getplayerlocation(userid))
        if not wcs.Command(userid).ReturnDict('looping'):
            hide_loop(userid, hide + 165)
            
def player_ability_on(event_var):
    userid = int(event_var['userid'])
    fan    = wcs.GetLevel(userid, raceName, 'Fan of Knives')
    if fan:
        cooldown = wcs.Command(userid).GetCoolDown('Fan of Knives')
        if not cooldown:
            fan_skill(userid)
        else:
            es.tell(userid, '#multi', text('cooldown', {'time': cooldown, 'skill' : 'Fan of Knives'}, playerlib.getPlayer(userid).get("lang") ) )
            
def player_ability_on2(event_var):
    userid = int(event_var['userid'])
    blink  = wcs.GetLevel(userid, raceName, 'Blink')
    if blink:
        cooldown = wcs.Command(userid).GetCoolDown('Blink') 
        if not cooldown:
            wcs.Command(userid).GetViewCoord(blink_skill)
        else:
            es.tell(userid, '#multi', text('cooldown', {'time': cooldown, 'skill' : 'Blink'}, playerlib.getPlayer(userid).get("lang") ) )
        
def blink_skill(userid, x, y, z):
    wcs.effect.Smoke(userid)
    if isEst:
        wcs.Command(userid).PushTo(x, y, z, 5)
    else:
        # Okay there's no EST, so chance it and just teleport them there -.-
        es.server.queuecmd('es_xsetpos %s %s %s %s' % (userid, x, y, z) )
    wcs.Command(userid).SetCoolDown('Blink', 30 / wcs.GetLevel(userid, raceName, 'Blink') )
		
def fan_skill(userid):
    wcs.effect.Ring3(userid, 360, 1, 128, 128, 128)
    team = es.getplayerteam(userid)
    wcs.Command(userid).SetCoolDown('Fan of Knives', int(fanCoolDown))
    wcs.Command(userid).Near(360, Knives, '#ct' if team == 2 else '#t')
	
def Knives(userid, attacker):
    wcs.Command(userid).Damage(wcs.GetLevel(attacker, raceName, 'Fan of Knives') * 35, 32, attacker)
    
def hide_loop(userid,al):
    if not playerlib.getPlayer(userid).get('isdead') and es.exists('userid', userid):
        wcs.Command(userid).UpdateDict('looping', 1)
        location = es.getplayerlocation(userid)
        if location == wcs.Command(userid).ReturnDict('location'):
            wcs.Command(userid).Fade(al, 2)
        else:
            wcs.Command(userid).Color(alpha = 255)
            wcs.Command(userid).UpdateDict('location', location)
        gamethread.delayed(1, hide_loop, (userid, al) )
    else:
        wcs.Command(userid).UpdateDict('looping', 0)
