#!/usr/bin/env python
# $Id: game_pony.py,v 1.11 2006/07/10 00:11:38 devel Exp $
# @file
# @author   Jim E. Brooks  http://www.jimbrooks.org
# @brief    Python component of game module.  Integrated with C++.
#
# @verbatim
#
# Naming convention:
# s         self
# m*        Class member
# cptr      Pointer to a C/C++ object.
# mCm[]     member that is a const matrix
#
# @endverbatim
################################################################################

import sys, random

# Import modules from Palomino.
import ceng, ceng2, cworld, cgame, cgame2

# Import constants from Palomino modules whose values originate from C++.
# This is why variables such as AXIS_X,Xx,etc seem to magically appear.
from ceng2 import *
from cgame2 import *

# Include eng.py.
# C++ has appended sys.path with path to Python scripts.
from eng import *

################################################################################
# Dyna class based on its C++ counterpart.

class CraftF14(Dyna):

    def __init__( s, quadrant, x, y, z ):
        s.mCptr = cgame.CraftF14TomcatNew( quadrant, x, y, z )
        return

################################################################################
# Dyna class based on its C++ counterpart.

class DynaModelTarget(Dyna):

    def __init__( s, quadrant, x, y, z, modelName ):
        s.mCptr = cgame.DynaModelTargetNew( quadrant, x, y, z, modelName )
        return

################################################################################
# Hangar.
#
#----------------------------------------
#  
#              .....0.... 
#          ....          ...
#        ...                ...
#       1   2..............3   4
#       .   .              .   .
#       .   .              .   .
#       .   .              .   .
#       5...6              7...8 
#  
#----------------------------------------

class Hangar(Fixed):

    def __init__( s, quadrantCptr, position ):
        """ position: tuple """
        Fixed.__init__( s, quadrantCptr, position )

        # Construct world vertexs.
        HANGAR_HEIGHT = WORLD(70.0)
        HANGAR_WIDTH  = WORLD(70.0)
        HANGAR_LENGTH = WORLD(500.0)
        wv = []  # [ (x,y,z), ... ]
        (cx,cy,cz) = position
        wv.append( ( 0.00*HANGAR_WIDTH+cx, 1.00*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 0
        wv.append( (-1.00*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 1
        wv.append( (-0.75*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 2
        wv.append( ( 0.75*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 3
        wv.append( ( 1.00*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 4
        wv.append( (-1.00*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 5
        wv.append( (-0.75*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 6
        wv.append( ( 0.75*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 7
        wv.append( ( 1.00*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, HANGAR_LENGTH+cz) )  # 8
        wv.append( (0.0, 0.0, 0.0) )                                                   # 9
        wv.append( ( 0.00*HANGAR_WIDTH+cx, 1.00*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 10
        wv.append( (-1.00*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 11
        wv.append( (-0.75*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 12
        wv.append( ( 0.75*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 13
        wv.append( ( 1.00*HANGAR_WIDTH+cx, 0.75*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 14
        wv.append( (-1.00*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 15
        wv.append( (-0.75*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 16
        wv.append( ( 0.75*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 17
        wv.append( ( 1.00*HANGAR_WIDTH+cx, 0.00*HANGAR_HEIGHT+cy, -HANGAR_LENGTH+cz) ) # 18
        s.SetWorldVertexs( wv )

        # Construct a list of texture data.
        TEX1 = 6.0
        TEX2 = 10.0
        TEX3 = 2.0
        tex = []
        # triangle
        tex.append( Polytex( "hangar1.tga", [ (TEX1/2,0.0), (0.0,0.0), (0.0,TEX1) ] ) )
        # quad #1
        tex.append( Polytex( "hangar1.tga", [ (0.0,0.0), (0.0,TEX2), (TEX2,TEX2), (TEX2,0.0) ] ) )
        # quad #2
        tex.append( Polytex( "hangar1.tga", [ (0.0,0.0), (0.0,TEX3), (TEX3,TEX3), (TEX3,0.0) ] ) )

        # Construct polygons.
        pl = PolygonList( s.GetPolygonList() )
        pl.EnableCull( False )
        pl.SetRgba( RGBA( (192, 192, 192, 230) ) )
        pl.SetPolytexList( tex )
        # front
        pl.SetPolytexIdx( 0 ); pl.AddPolygon( (0, 1, 4) )
        pl.SetPolytexIdx( 2 ); pl.AddPolygon( (1, 5, 6, 2) )
        pl.SetPolytexIdx( 2 ); pl.AddPolygon( (3, 7, 8, 4) )
        # left
        pl.SetPolytexIdx( 1 ); pl.AddPolygon( (1, 0, 10, 11) )
        pl.SetPolytexIdx( 1 ); pl.AddPolygon( (5, 1, 11, 15) )
        # rear
        pl.SetPolytexIdx( 0 ); pl.AddPolygon( (10, 11, 14) )
        pl.SetPolytexIdx( 2 ); pl.AddPolygon( (11, 15, 16, 12) )
        pl.SetPolytexIdx( 2 ); pl.AddPolygon( (13, 17, 18, 14) )
        # right
        pl.SetPolytexIdx( 1 ); pl.AddPolygon( (0, 4, 14, 10) )
        pl.SetPolytexIdx( 1 ); pl.AddPolygon( (4, 8, 18, 14) )
        pl.Optimize( len(wv) )
        return

################################################################################
# Top-level class of game module.

class GamePony(object):

    def __init__( s ):

        s.mEye     = Dyna( ceng.GetEye() )
        s.mPlayer1 = Dyna( cgame.GetPlayer( 1 ) )
        s.mPlayer2 = Dyna( cgame.GetPlayer( 2 ) )
        s.mTurkeyCnt = 0

    def StartTurkeyShoot( s ):

        quadrantCenter = cworld.GetCenterQuadrant()
        
        # Spawn turkeys.
        for i in range(0,50):
            s.SpawnTurkey( s.mPlayer1 )

        # Set player #1,#2 for demo mode.
        s.mPlayer1.SetOrigin( Oy, WORLD(500.0) )
        s.mPlayer2.SetOrigin( Ox, s.mPlayer1.mCm[Ox] + WORLD(30.0) )
        s.mPlayer2.SetOrigin( Oy, WORLD(500.0) )
        s.mPlayer2.SetOrigin( Oz, s.mPlayer1.mCm[Oz] + WORLD(200.0) )
        s.mPlayer1.SetThrottle( 50 )
        s.mPlayer2.SetThrottle( 50 )
        s.mPlayer1.SetAnimation( eAnimate_PILOT_PURSUE )
        s.mPlayer2.SetAnimation( eAnimate_AUTO_TRANSLATE )
        s.mPlayer1.PilotSelectTarget()
        s.mPlayer1.ChaseIncDistance( 50 )

        # Randomly position and rotate tanks.
        tankCnt = 150
        modelNameTank = cgame.GetModelDir() + "tank.pal"  # no slash
        for i in range(0,tankCnt):
            (tx,ty,tz) = cworld.QuadrantRandomPosition( quadrantCenter )
            ty = WORLD(10.0)
            tank = DynaModelTarget( quadrantCenter, tx,ty,tz, modelNameTank )
            tank.Rotate( AXIS_Y, random_f(359.0) )
            tank.SetThrottle( 0 )
            tank.SetAnimation( eAnimate_NONE )

        return

    def SpawnTurkey( s, pursuer ):
        """ Spawn a turkey near the pursuer. """
        (cx,cy,cz) = pursuer.GetPosition()
        cx += WORLD( 900.0) + WORLD(random_f(3000.0))
        cy += WORLD(2000.0) + WORLD(random_f(300.0))
        cz += WORLD( 900.0) + WORLD(random_f(3000.0))
        turkey = CraftF14( cworld.GetCenterQuadrant(), cx, cy, cz )
        cgame.CraftListAppend( turkey.mCptr )
        turkey.Rotate( AXIS_Y, -10.0 )
        turkey.SetAnimation( eAnimate_AUTO_TRANSLATE )
        turkey.SetThrottle( 10 )
        
        s.mTurkeyCnt += 1
        if (s.mTurkeyCnt & 7) == 7:
            turkey.SetAnimation( eAnimate_PILOT_PURSUE )
            turkey.PilotSelectTarget()

################################################################################
# Execute.

if not ceng2.QUIET:
    print "[run] Python module."

# Get the center of the simulated World.
(cx,cy,cz) = cworld.GetCenter(); cy = cworld.GetGroundY( (cx,cy,cz) )

# Create Hangar.
# -- disabled, plan to replace with improved hangar --
#(x,y,z) = (cx,cy,cz)
#z = z - WORLD(500.0)
#Hangar( cworld.GetCenterQuadrant(), (x,y,z) )

# Exit.
# C++ may or may not start the game module.  See GamePony::StartPython().
