# 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

from balazar.character import *
from balazar.character import _P, _V
from balazar.item      import KillRay


class Hero(Character):
  race              = "hero"
  discussion_radius = 5.0
  
  def big_round(self):
    Character.big_round(self)
    
    if tofu.GAME_INTERFACE and self is tofu.GAME_INTERFACE.hero:
      discutables = [(self.distance_to(i), i)
                     for i in self.level
                     if isinstance(i, base.Discutable)
                     ]
      if discutables: distance, nearest_discutable = min(discutables)
      else:           distance, nearest_discutable = 10000.0, None
      
      previous = tofu.GAME_INTERFACE.current_discussion
      if previous:
        if ((not previous.character is self) and (not previous.character is nearest_discutable)) or not previous.check():
          previous.destroy()
          previous = None
          
      if nearest_discutable and (not previous) and (distance < nearest_discutable.discussion_radius):
        nearest_discutable.start_discussion(self)
        if isinstance(nearest_discutable, Character):
          self.doer.do_action(DiscussionAction(ACTION_DISCUSSING, nearest_discutable))
          
      
      
class Balazar(Hero):
  die_duration1  = 84
  die_duration2  = 155
  
  def __init__(self):
    Hero.__init__(self)
    
    self.perso = soya.Cal3dVolume(self, soya.Cal3dShape.get("balazar"), ["perso"])
    #self.perso = soya.Cal3dVolume(self, soya.Cal3dShape.get("echassien2@vert"), ["perso"])
    self.perso.animate_blend_cycle("attente")
    
    self.right_foot = soya.World(self)
    self.perso.attach_to_bone(self.right_foot, "piedD")
    self.spc_kill_rays = [
      KillRay(self.right_foot, -1.0, 0.1, -0.2, 2.0, 0.0,  0.0),
      KillRay(self.right_foot,  0.0, 0.1,  0.2, 0.0, 0.0, -1.5),
      ]
    
    self.fight_skill = 2.0
    self.resistance  = 3.0
    
    sword = balazar.item.Knife()
    sword = balazar.item.Sword()
    self.add_item(sword)
    sword.set_equiped(1)

    sword = balazar.item.LargeSword()
    self.add_item(sword)
    
    #sword = balazar.item.Map("foret_pompon")
    #self.add_item(sword)
    
    #sword = balazar.item.MorkulKillerKnife()
    #self.add_item(sword)
    
    sword = balazar.item.TuryleSword()
    self.add_item(sword)
    
    #sword = balazar.item.PomponScepter()
    #self.add_item(sword)
    
    
  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)
    
    max_dz = 0.4 - math.sqrt((self.x - state.x) ** 2 + (self.z - state.z) ** 2)
    
    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, -min(0.2 , max_dz))
    elif action.duration < 30: state.shift(0.0, 0.0, -min(0.4 , max_dz))
    else                     : state.shift(0.0, 0.0, -min(0.05, max_dz))
    action.duration += 1
    if action.duration > 36:
      self.striking = 0
      self.current_action = None
      self.kill_rays = self.weapon.kill_rays
    

