# Balazar
# Copyright (C) 2005 Jean-Baptiste LAMY
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


import random

import soya, tofu
from soya import Point, Vector

from balazar.controller import StackController, Goto, GotoXZ, Gotoward, LookAt, GrabItem, Fly, Wait, Wander
from balazar.character  import *
from balazar.character  import _P, _V
from balazar.item       import Item, Food, Key, Axe
import balazar.globdef    as globdef

import balazar.base  as base
import balazar.sound

import balazar.npc as npc


class AIController(npc.AIController):
  aggressivity  = 0.8
  dodge         = 0.3
  
  def __init__(self, mobile):
    npc.AIController.__init__(self, mobile)
    
  def attack(self, enemy):
    h = random.random()
    if   h < 0.75: yield self.attack_basic(enemy)
    else:         yield self.attack_jump (enemy)
    
  def check(self): # Don't move
    self.append_and_cancel(Wait  (self.mobile, 200))
    

class Wiseman(npc.NPC, base.Discutable):
  Controller = AIController
  
  race           = "wiseman"
  die_duration1  = 84
  die_duration2  = 108
  
  def __init__(self):
    npc.NPC.__init__(self)
    
    self.perso = soya.Cal3dVolume(self, soya.Cal3dShape.get("sage"), ["perso"])
    #self.perso.animate_blend_cycle("attente")
    
    #self.perso.set_shape(soya.Cal3dShape.get("sage"), ["perso"])
    
    self.fighting   = 5.0
    self.resistance = 7.0
    
    self.auto_equip_items()
    
  def hurt(self, *arg, **kargs): pass
  
  def discussion_is_valid___sage_pompon_0__0_1_0(self, hero):
    return hero.get_item(balazar.item.PomponScepter)
    
  def start_discussion(self, hero):
    from balazar.game_interface import AutoDiscussion
    AutoDiscussion(hero, self, u"", u"__sage_pompon_0__0").activate(0)
    return
  
    from balazar.game_interface import Discussion
    Discussion(self, u"", _(u"__sage_pompon_1__0"), choices = [
      Discussion(self, _(u"__sage_pompon_1__0_0"), _(u"__sage_pompon_1__0_0_0"), choices = [
        Discussion(self, _(u"__sage_pompon_1__0_0_0_0"), _(u"__sage_pompon_1__0_0_0_0_0"), choices = [
          Discussion(self, _(u"__sage_pompon_1__0_0_0_0_0_0"), _(u"__sage_pompon_1__0_0_0_0_0_0_0")),
          ]),
        ]),
      Discussion(self, _(u"__sage_pompon_1__0_1"), _(u"__sage_pompon_1__0_1_0"), condition = lambda : hero.get_item(balazar.item.PomponScepter)),
      ]).activate(0)
    
  def get_relation(self, other):
    return 1.0
  
  def strike_left(self, target):
    yield FightAction(ACTION_FIGHT_LEFT, target)
    yield Action(ACTION_WAIT)
    for i in range(26): yield None
    
  def strike_right(self, target):
    yield FightAction(ACTION_FIGHT_RIGHT, target)
    yield Action(ACTION_WAIT)
    for i in range(26): yield None
    
  def strike_charge(self, target):
    yield FightAction(ACTION_FIGHT_CHARGE, target)
    yield Action(ACTION_WAIT)
    for i in range(26): yield None
    
  def strike_sagittal(self, target):
    yield FightAction(ACTION_FIGHT_SAGITTAL, target)
    yield Action(ACTION_WAIT)
    for i in range(29): yield None
    
  def do_action_31(self, action, state): # ACTION_FIGHT_LEFT
    state.animation = "combat1"
    target = (action.target_uid and tofu.Unique.hasuid(action.target_uid) and tofu.Unique.getbyuid(action.target_uid)) or None
    if target:
      _P.clone(target)
      _P.convert_to(self)
      if _P.x > 0.1: state.rotate_lateral(-2.0)
      else: state.rotate_lateral(4.0)
    else: state.rotate_lateral(4.0)
    
    if   action.duration == 0: self.kill_rays = self.weapon.kill_rays
    elif action.duration == 8: self.striking = 1; self.doer.action_done(SoundState(self, "strike2.wav", 4.0))
    action.duration += 1
    if action.duration > 19: self.striking = 0; self.current_action = None
    
  def do_action_32(self, action, state): # ACTION_FIGHT_RIGHT
    state.animation = "combat0"
    target = (action.target_uid and tofu.Unique.hasuid(action.target_uid) and tofu.Unique.getbyuid(action.target_uid)) or None
    if target:
      _P.clone(target)
      _P.convert_to(self)
      if _P.x > -0.1: state.rotate_lateral(-4.0)
      else: state.rotate_lateral(2.0)
    else: state.rotate_lateral(-4.0)

    if   action.duration == 0: self.kill_rays = self.weapon.kill_rays
    elif action.duration == 8: self.striking = 1; self.doer.action_done(SoundState(self, "strike2.wav", 4.0))
    action.duration += 1
    if action.duration > 19: self.striking = 0; self.current_action = None
    
  def do_action_33(self, action, state): # ACTION_FIGHT_SAGITTAL
    state.animation = "combat3"
    target = (action.target_uid and tofu.Unique.hasuid(action.target_uid) and tofu.Unique.getbyuid(action.target_uid)) or None
    if target: self.strike_rot(target, state)
    
    if   action.duration ==  0: self.kill_rays = self.weapon.kill_rays
    elif action.duration == 8: self.striking = 1; self.doer.action_done(SoundState(self, "strike3.wav", 4.0))
    action.duration += 1
    if action.duration > 21: self.striking = 0; self.current_action = None
    
  def do_action_34(self, action, state): # ACTION_FIGHT_CHARGE
    state.animation = "combat2"
    target = (action.target_uid and tofu.Unique.hasuid(action.target_uid) and tofu.Unique.getbyuid(action.target_uid)) or None
    if target: self.strike_rot(target, state)
    
    if   action.duration ==  0: self.kill_rays = self.spc_kill_rays
    elif action.duration == 10: self.striking = 1; self.doer.action_done(SoundState(self, "strike1.wav", 2.0))
    elif action.duration < 10: pass
    elif action.duration < 15: state.shift(0.0, 0.0, -0.2 )
    elif action.duration < 30: state.shift(0.0, 0.0, -0.3 )
    else                     : state.shift(0.0, 0.0, -0.05)
    action.duration += 1
    if action.duration > 36:
      self.striking = 0
      self.current_action = None
      self.kill_rays = self.weapon.kill_rays
