Logo Search packages:      
Sourcecode: race version File versions

ai.cpp

/*
 This Game is distributed under the GNU GENERAL PUBLIC LICENSE 
 version 2. See COPYING for details.                           
                                                               
 Copyright (C) 1999-2002 Harry Storbacka                            
                                                               
 ai.cpp                                                      */

// TODO: AARGH... so ugly code :( 
//   - hs, 04.01.2002

#include <ClanLib/core.h>
#include <ClanLib/application.h>
#include <ClanLib/display.h>
#include <ClanLib/gl.h>
#include <cmath>
#include <iostream>

#include "config.h"

#include "tile_enums.h"

#include "track.h"
#include "map.h"
#include "car.h"
#include "attractor.h"
#include "season.h"
#include "game_config.h"
#include "car_config.h"
#include "object_3d.h"
#include "debug.h"

#include "graphics.h"
#include "ai.h"

bool road( float, float );
bool rotate_dir( int, int );


Car_AI::Car_AI(float x, float y, char id, char _ai_id )
: Car(x, y, id)
{
      RaceDebug::print( "Car_AI: constructor", 5 );
      
      ai_id = _ai_id;
      
      atr_num = 0;
      
      collision_timer = 0;
      collision_counter = 0;
      
      RaceDebug::print( "Car_AI: constructor -- done", 5 );
}

Car_AI::~Car_AI()
{
      RaceDebug::print( "Car_AI: destructor", 5 );
}


void Car_AI::show(int center_x, int center_y )
{
      glPushMatrix();
            
            glTranslatef( x, y, z );
            
            // legacy... Frame is a int (0->31) => 11.25 degrees/step
            // angle is the move direction, frame is the cars rotation :)
            glRotatef( Frame*11.25, 0.0f, 0.0f, 1.0f );
            
            // rotate car so it follows terrain
            glRotatef( rot_x, 1.0f, 0.0f, 0.0f );
            glRotatef( rot_y, 0.0f, 1.0f, 0.0f );
            
            Gfx::CarGfx->texture[id].bind();
            Gfx::CarGfx->car[id]->draw();

      glPopMatrix();
}

void Car_AI::update(float move_time )
{
      time_elapsed = move_time;
      
      if( angle >= 32 ) angle -= 32;
      if( angle < 0 ) angle += 32;

      dx = move_time * speed*(cos( angle*(M_PI/16)));
      dy = move_time * speed*(sin( angle*(M_PI/16)));
}

void Car_AI::update_frame(int num)
{
      if( Frame != wanted_angle )
      {
            if( abs(wanted_angle - Frame) == 1 )
                  num = 1;
      
            if( get_rotate_dir(Frame, wanted_angle) == 1 )
            {
                  Frame += num;
            }
            if( get_rotate_dir(Frame, wanted_angle) == 0 )
            {
                  Frame -= num;
            }
      
            if( Frame > 31 ) Frame -= 32;
            if( Frame < 0 ) Frame += 32;
      }

      if( angle == wanted_angle )
            Frame = angle;
}

void Car_AI::update_object_speed()
{
      if( Config::difficulty_level < 1 )
            max_speed = Config::road_speed * (Config::difficulty_level -0.1f);
      
      if( Config::difficulty_level == 1 )
            max_speed = Config::road_speed * Config::difficulty_level;
      
      if( Config::difficulty_level > 1 )
            max_speed = Config::road_speed * (Config::difficulty_level +0.1f);
      
      // TODO: does this work at all?
      
      // limit AI:s speeds in curves so that they will _better_ stay on track  
      if( angleDifference > 3 )
            max_speed -= 0.2f * time_elapsed;
      
      if( speed < max_speed && !sliding )
      {
            accel = time_elapsed * (1.0f/(speed+2.0f)) * 15.0f;
            speed+=accel;
      }
}

void Car_AI::update_wanted_dir()
{
      int   atr_x = Track::track->attractors[atr_num].x;
      int   atr_y = Track::track->attractors[atr_num].y;
      
      if( Track::track->attractors[atr_num].on_attractor( x, y ))
      {
            atr_num++;
            if( (unsigned)atr_num == Track::track->attractors.size())
                  atr_num = 0;
            // cout << "changed attractor " << (int)atr_num << endl;
      }

      //  o 1
      // a   
      if( atr_x < (int)(x+0.0) && atr_y > (int)(y+0.0) )
      {
            tmp_wa = 12;
      }

      // o  2
      //  a 
      if( atr_x > (int)(x+0.0) && atr_y > (int)(y+0.0) )
      {
            tmp_wa = 4;
      }

      //  a 3
      // o  
      if( (atr_x > (int)(x+0.0)) && (atr_y < ((int)(y+0.0))) )
      {
            tmp_wa = 28;
      }

      // a  4
      //  o  
      if( atr_x < (int)(x+0.0) && atr_y < (int)(y+0.0) )
      {
            tmp_wa = 20;
      }

      // o a 5
      if( atr_x > (int)x && atr_y == (int)y )
      {
            tmp_wa = 0;
      }
      // a o 6
      if( atr_x < (int)(x+0.0) && atr_y == (int)(y+0.0) )
      {
            tmp_wa = 16;
      }
      // a 7
      // o  
      if( atr_x == (int)(x+0.0) && atr_y < (int)(y+0.0) )
      {
            tmp_wa = 24;
      }
      // o 8
      // a  
      if( atr_x == (int)(x+0.0) && atr_y > (int)(y+0.0) )
      {
            tmp_wa = 8;
      }

      if( stays_on_road() )
            wanted_angle = tmp_wa;
}

bool Car_AI::stays_on_road()
{
      // TODO: ai turns the wrong way (level2.track)

      int atr_y = Track::track->attractors[atr_num].y;

      if( tmp_wa == 4 )
            if( road( x +1, y +1 ) == false )
            {
                  if( atr_y >= (int)y )
                  {
                        if( road( x +1, y )) wanted_angle = 0;
                        else if( road( x , y+1 )) wanted_angle = 8;
                  }
                  return false;
            }

      if( tmp_wa == 12 )
            if( road(x -1, (int)y +1 ) == false )
            {
                  if( atr_y >= (int)y )
                  {
                        if( road( x -1, y )) wanted_angle = 16;
                        else if( road( x , y+1 )) wanted_angle = 8;
                  }
                  return false;
            }
 
      if( tmp_wa == 20 )
            if( road(x -1, (int)y -1 ) == false )
            {
                  if( atr_y <= (int)y )
                  {
                        if( road( x -1, y )) wanted_angle = 16;
                        else if( road( x , y-1 )) wanted_angle = 24;
                  }
                  return false;
            }


      if( tmp_wa == 28 )
            if( road(x -1, y +1 ) == false )
            {
                  if( atr_y <= (int)y )
                  {
                        if( road( x +1, y ))
                                    wanted_angle = 0;
                        else if( road( x , y-1 ))
                                    wanted_angle = 24;
                  }
                  return false;
            }
      return true;
}

void Car_AI::reset_special()
{
      atr_num = 0;
}

bool Car_AI::road( float x, float y )
{
/*    if( Track::track->get_tmp_map( int(x + 0.5), int(y +0.5) ) > 0 ) 
            return true;*/
      
      if( Track::track->get_tmp_map( (int)x, (int)y ) == '#' )
            return true;

      return false;
}

void Car_AI::avoid_collisions()
{
      // actually I'm not sure if this would be such a good idea...
      //  More collisions make the game more interesting :)
}

void Car_AI::update_extras()
{
      //
}


Generated by  Doxygen 1.6.0   Back to index