~ubuntu-branches/ubuntu/precise/supertuxkart/precise

« back to all changes in this revision

Viewing changes to src/World.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Gonéri Le Bouder, Gonéri Le Bouder, Eddy Petrişor
  • Date: 2006-09-08 22:59:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060908225925-3spug0pnh9ekwlpw
Tags: 0.2-1
[ Gonéri Le Bouder ]
* new upstream release candidate
 + Closes: #388021
 + remove supertuxkart.sh
 + add supertuxkart(|-data).install
 + clean up
 + remove deps on ${shlibs:Depends}, ${misc:Depends} for supertuxkart-data
* fix French comment was tagged de_DE
* fix not-binnmuable-any-depends-all
* fix FTBFS on 64bit arch
 + Closes: #370810

[ Eddy Petrişor ]
* added Romanian translation to desktop file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//  $Id: World.cxx 498 2004-12-22 06:55:12Z grumbel $
2
 
//
3
 
//  SuperTuxKart - a fun racing game with go-kart
4
 
//  Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
5
 
//
6
 
//  This program is free software; you can redistribute it and/or
7
 
//  modify it under the terms of the GNU General Public License
8
 
//  as published by the Free Software Foundation; either version 2
9
 
//  of the License, or (at your option) any later version.
10
 
//
11
 
//  This program is distributed in the hope that it will be useful,
12
 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
//  GNU General Public License for more details.
15
 
//
16
 
//  You should have received a copy of the GNU General Public License
17
 
//  along with this program; if not, write to the Free Software
18
 
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
 
 
20
 
#include <assert.h>
21
 
#include <iostream>
22
 
#include <sstream>
23
 
#include <stdexcept>
24
 
#include <algorithm>
25
 
#include "preprocessor.h"
26
 
#include "Explosion.h"
27
 
#include "Herring.h"
28
 
#include "Projectile.h"
29
 
#include "KartDriver.h"
30
 
#include "WidgetSet.h"
31
 
#include "tuxkart.h"
32
 
#include "Loader.h"
33
 
#include "material.h"
34
 
#include "World.h"
35
 
#include "Camera.h"
36
 
#include "RaceSetup.h"
37
 
#include "WorldLoader.h"
38
 
#include "PlayerDriver.h"
39
 
#include "AutoDriver.h"
40
 
#include "isect.h"
41
 
#include "Track.h"
42
 
#include "KartManager.h"
43
 
#include "TrackManager.h"
44
 
 
45
 
World* world = 0;
46
 
 
47
 
World::World(const RaceSetup& raceSetup_)
48
 
  : raceSetup(raceSetup_)
49
 
{
50
 
  phase = START_PHASE;
51
 
 
52
 
  scene = NULL;
53
 
  track = NULL;
54
 
 
55
 
  clock           = 0.0f;
56
 
  
57
 
  // Grab the track centerline file
58
 
  track = track_manager->getTrack(raceSetup.track) ;
59
 
 
60
 
  // Start building the scene graph
61
 
  scene       = new ssgRoot   ;
62
 
  trackBranch = new ssgBranch ;
63
 
  scene -> addKid ( trackBranch ) ;
64
 
 
65
 
  /* Load the Herring */
66
 
  sgVec3 yellow = { 1.0, 1.0, 0.4 } ;
67
 
 
68
 
  gold_h    = new Herring ( yellow ) ; 
69
 
  silver_h  = new Herring ( ssgLoad ( "coin.ac", loader )   ) ;
70
 
  red_h     = new Herring ( ssgLoad ( "bonusblock.ac", loader )   ) ; 
71
 
  green_h   = new Herring ( ssgLoad ( "banana.ac", loader )   ) ; 
72
 
 
73
 
  preProcessObj ( gold_h -> getRoot());
74
 
  preProcessObj ( silver_h -> getRoot());
75
 
  preProcessObj ( red_h -> getRoot());
76
 
  preProcessObj ( green_h -> getRoot());
77
 
 
78
 
  // Create the karts and fill the kart vector with them
79
 
 
80
 
  assert(raceSetup.karts.size() > 0);
81
 
 
82
 
  for (RaceSetup::Karts::iterator i = raceSetup.karts.begin() ; i != raceSetup.karts.end() ; ++i )
83
 
  {
84
 
    KartDriver* newkart;
85
 
    int pos = kart.size();
86
 
 
87
 
    if (std::find(raceSetup.players.begin(), raceSetup.players.end(), pos) != raceSetup.players.end())
88
 
      { // the given position belongs to a player
89
 
        newkart = new KartDriver ( this, kart_manager.getKart(*i), pos, new PlayerDriver ) ;
90
 
      }
91
 
    else
92
 
      newkart = new KartDriver ( this, kart_manager.getKart(*i), pos, new AutoDriver ) ;
93
 
    
94
 
    sgCoord init_pos = { { 0, 0, 0 }, { 0, 0, 0 } } ;
95
 
 
96
 
    init_pos.xyz [ 0 ] = (pos % 2 == 0) ? 1.5f : -1.5f ;
97
 
    init_pos.xyz [ 1 ] = -pos * 1.5f ;
98
 
 
99
 
    newkart -> setReset ( & init_pos ) ;
100
 
    newkart -> reset    () ;
101
 
    newkart -> getModel () -> clrTraversalMaskBits(SSGTRAV_ISECT|SSGTRAV_HOT);
102
 
 
103
 
    scene -> addKid ( newkart -> getRoot() ) ;
104
 
 
105
 
    kart.push_back(newkart);
106
 
  }
107
 
 
108
 
  // Load the track models
109
 
  loadTrack   ( ) ;
110
 
  loadPlayers ( ) ;
111
 
 
112
 
  preProcessObj ( scene ) ;
113
 
 
114
 
#ifdef SSG_BACKFACE_COLLISIONS_SUPPORTED
115
 
  //ssgSetBackFaceCollisions ( raceSetup.mirror ) ;
116
 
#endif
117
 
        
118
 
  guiStack.push_back(GUIS_RACE);
119
 
 
120
 
  std::string music = track_manager->getTrack(raceSetup.track)->music_filename;
121
 
  
122
 
  if (!music.empty())
123
 
    sound -> change_track ( music.c_str() );
124
 
 
125
 
  ready_set_go = 3;
126
 
}
127
 
 
128
 
World::~World()
129
 
{  
130
 
  for ( unsigned int i = 0 ; i < kart.size() ; i++ )
131
 
    delete kart[i];
132
 
 
133
 
  kart.clear();
134
 
 
135
 
  for(Projectiles::iterator i = projectiles.begin();
136
 
      i != projectiles.end(); ++i)
137
 
    delete *i;
138
 
  for(Explosions::iterator i = explosions.begin(); i != explosions.end(); ++i)
139
 
    delete *i;
140
 
 
141
 
  ssgDeRefDelete(projectile_spark);
142
 
  ssgDeRefDelete(projectile_missle);
143
 
  ssgDeRefDelete(projectile_flamemissle);
144
 
  ssgDeRefDelete(explode);
145
 
    
146
 
  delete gold_h;
147
 
  delete silver_h;
148
 
  delete red_h;
149
 
  delete green_h;
150
 
 
151
 
  delete scene ; 
152
 
}
153
 
 
154
 
void
155
 
World::draw()
156
 
{
157
 
  for ( Karts::size_type i = 0 ; i < kart.size(); ++i) kart[ i ] -> placeModel() ;
158
 
 
159
 
  ssgGetLight ( 0 ) -> setPosition ( track->sun_position ) ;
160
 
  ssgGetLight ( 0 ) -> setColour ( GL_AMBIENT , track->ambientcol  ) ;
161
 
  ssgGetLight ( 0 ) -> setColour ( GL_DIFFUSE , track->diffusecol  ) ;
162
 
  ssgGetLight ( 0 ) -> setColour ( GL_SPECULAR, track->specularcol ) ;
163
 
 
164
 
  ssgCullAndDraw ( world->scene ) ;
165
 
}
166
 
 
167
 
void
168
 
World::update(float delta)
169
 
{
170
 
  clock += delta;
171
 
 
172
 
  checkRaceStatus();
173
 
 
174
 
  for ( Karts::size_type i = 0 ; i < kart.size(); ++i) kart[ i ] -> update (delta) ;
175
 
  for(Projectiles::iterator i = projectiles.begin();
176
 
      i != projectiles.end(); ++i)
177
 
    (*i)->update(delta);
178
 
  for(Explosions::iterator i = explosions.begin(); i != explosions.end(); ++i)
179
 
      (*i)->update(delta);
180
 
  for ( int i = 0 ; i < MAX_HERRING     ; i++ ) herring    [ i ] .  update () ;
181
 
  for ( Karts::size_type i = 0 ; i < kart.size(); ++i) updateLapCounter ( i ) ;
182
 
 
183
 
  /* Routine stuff we do even when paused */
184
 
  silver_h -> update () ;
185
 
  gold_h   -> update () ;
186
 
  red_h    -> update () ;
187
 
  green_h  -> update () ;
188
 
}
189
 
 
190
 
void
191
 
World::checkRaceStatus()
192
 
{
193
 
  if (clock > 1.0 && ready_set_go == 0)
194
 
    {
195
 
      ready_set_go = -1;
196
 
    }
197
 
  else if (clock > 2.0 && ready_set_go == 1)
198
 
    {
199
 
      ready_set_go = 0;
200
 
      phase = RACE_PHASE;
201
 
      clock = 0.0f;
202
 
    }
203
 
  else if (clock > 1.0 && ready_set_go == 2)
204
 
    {
205
 
      ready_set_go = 1;
206
 
    }
207
 
  else if (clock > 0.0 && ready_set_go == 3)
208
 
    {
209
 
      ready_set_go = 2;
210
 
    }
211
 
 
212
 
  if ( world->kart[0]->getLap () >= raceSetup.numLaps )
213
 
    {
214
 
      phase = FINISH_PHASE;
215
 
    }
216
 
}
217
 
 
218
 
void
219
 
World::updateLapCounter ( int k )
220
 
{
221
 
  int p = 1 ;
222
 
 
223
 
  /* Find position of kart 'k' */
224
 
 
225
 
  for ( Karts::size_type j = 0 ; j < kart.size() ; ++j )
226
 
  {
227
 
    if ( int(j) == k ) continue ;
228
 
 
229
 
    if ( kart[j]->getLap() >  kart[k]->getLap() ||
230
 
         ( kart[j]->getLap() == kart[k]->getLap() && 
231
 
           kart[j]->getDistanceDownTrack() >
232
 
                            kart[k]->getDistanceDownTrack() ))
233
 
      p++ ;      
234
 
  }
235
 
 
236
 
  kart [ k ] -> setPosition ( p ) ;
237
 
}
238
 
 
239
 
void
240
 
World::loadPlayers()
241
 
{
242
 
  for ( Karts::size_type i = 0 ; i < kart.size() ; ++i )
243
 
    {
244
 
      kart[i]->load_data();
245
 
    }
246
 
 
247
 
  projectile_spark = ssgLoad("spark.ac");
248
 
  projectile_spark->ref();
249
 
  projectile_missle = ssgLoad("missile.ac");
250
 
  projectile_missle->ref();
251
 
  projectile_flamemissle = ssgLoad("flamemissile.ac");
252
 
  projectile_flamemissle->ref();
253
 
  explode = ssgLoad("explode.ac");
254
 
  explode->ref();
255
 
}
256
 
 
257
 
void
258
 
World::herring_command (char *s, char *str )
259
 
{
260
 
  if ( num_herring >= MAX_HERRING )
261
 
  {
262
 
    fprintf ( stderr, "Too many herring\n" ) ;
263
 
    return ;
264
 
  }
265
 
 
266
 
  HerringInstance *h = & herring[num_herring] ;
267
 
  sgVec3 xyz ;
268
 
 
269
 
  sscanf ( s, "%f,%f", &xyz[0], &xyz[1] ) ;
270
 
 
271
 
  xyz[2] = 1000000.0f ;
272
 
  xyz[2] = getHeight ( trackBranch, xyz ) + 0.06 ;
273
 
 
274
 
  sgCoord c ;
275
 
 
276
 
  sgSetVec3  ( c.hpr, 0.0f, 0.0f, 0.0f ) ;
277
 
  sgCopyVec3 ( c.xyz, xyz ) ;
278
 
 
279
 
  if ( str[0]=='Y' || str[0]=='y' ){ h->her = gold_h   ; h->type = HE_GOLD   ;}
280
 
  if ( str[0]=='G' || str[0]=='g' ){ h->her = green_h  ; h->type = HE_GREEN  ;}
281
 
  if ( str[0]=='R' || str[0]=='r' ){ h->her = red_h    ; h->type = HE_RED    ;}
282
 
  if ( str[0]=='S' || str[0]=='s' ){ h->her = silver_h ; h->type = HE_SILVER ;}
283
 
 
284
 
  sgCopyVec3 ( h->xyz, xyz ) ;
285
 
  h->eaten = FALSE ;
286
 
  h->scs   = new ssgTransform ;
287
 
  h->scs -> setTransform ( &c ) ;
288
 
  h->scs -> addKid ( h->her->getRoot () ) ;
289
 
  scene  -> addKid ( h->scs ) ;
290
 
 
291
 
  num_herring++ ;
292
 
}
293
 
 
294
 
 
295
 
void
296
 
World::loadTrack()
297
 
{
298
 
  std::string path = "data/";
299
 
  path += track->getIdent();
300
 
  path += ".loc";
301
 
  path = loader->getPath(path);
302
 
  FILE *fd = fopen (path.c_str(), "r" ) ;
303
 
 
304
 
  if ( fd == NULL )
305
 
  {
306
 
    std::stringstream msg;
307
 
    msg << "Can't open track location file '" << path << "'.";
308
 
    throw std::runtime_error(msg.str());
309
 
  }
310
 
 
311
 
  initWorld () ;
312
 
 
313
 
  char s [ 1024 ] ;
314
 
 
315
 
  while ( fgets ( s, 1023, fd ) != NULL )
316
 
  {
317
 
    if ( *s == '#' || *s < ' ' )
318
 
      continue ;
319
 
 
320
 
    int need_hat = FALSE ;
321
 
    int fit_skin = FALSE ;
322
 
    char fname [ 1024 ] ;
323
 
    sgCoord loc ;
324
 
    sgZeroVec3 ( loc.xyz ) ;
325
 
    sgZeroVec3 ( loc.hpr ) ;
326
 
 
327
 
    char htype = '\0' ;
328
 
 
329
 
    if ( sscanf ( s, "%cHERRING,%f,%f", &htype,
330
 
                     &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
331
 
    {
332
 
      herring_command ( & s [ strlen ( "*HERRING," ) ], s ) ;
333
 
    }
334
 
    else
335
 
    if ( s[0] == '\"' )
336
 
    {
337
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f,%f,%f",
338
 
                 fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
339
 
                        &(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2]) ) == 7 )
340
 
      {
341
 
        /* All 6 DOF specified */
342
 
        need_hat = FALSE ;
343
 
      }
344
 
      else 
345
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,%f,%f",
346
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]),
347
 
                          &(loc.hpr[0]), &(loc.hpr[1]), &(loc.hpr[2]) ) == 6 )
348
 
      {
349
 
        /* All 6 DOF specified - but need height */
350
 
        need_hat = TRUE ;
351
 
      }
352
 
      else 
353
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f",
354
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]),
355
 
                          &(loc.hpr[0]) ) == 5 )
356
 
      {
357
 
        /* No Roll/Pitch specified - assumed zero */
358
 
        need_hat = FALSE ;
359
 
      }
360
 
      else 
361
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f,{},{}",
362
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.hpr[0]) ) == 3 )
363
 
      {
364
 
        /* All 6 DOF specified - but need height, roll, pitch */
365
 
        need_hat = TRUE ;
366
 
        fit_skin = TRUE ;
367
 
      }
368
 
      else 
369
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,{},%f",
370
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]),
371
 
                          &(loc.hpr[0]) ) == 4 )
372
 
      {
373
 
        /* No Roll/Pitch specified - but need height */
374
 
        need_hat = TRUE ;
375
 
      }
376
 
      else 
377
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f",
378
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 4 )
379
 
      {
380
 
        /* No Heading/Roll/Pitch specified - but need height */
381
 
        need_hat = FALSE ;
382
 
      }
383
 
      else 
384
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f,{}",
385
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
386
 
      {
387
 
        /* No Roll/Pitch specified - but need height */
388
 
        need_hat = TRUE ;
389
 
      }
390
 
      else 
391
 
      if ( sscanf ( s, "\"%[^\"]\",%f,%f",
392
 
                   fname, &(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
393
 
      {
394
 
        /* No Z/Heading/Roll/Pitch specified */
395
 
        need_hat = FALSE ;
396
 
      }
397
 
      else 
398
 
      if ( sscanf ( s, "\"%[^\"]\"", fname ) == 1 )
399
 
      {
400
 
        /* Nothing specified */
401
 
        need_hat = FALSE ;
402
 
      }
403
 
      else
404
 
      {
405
 
        fclose(fd);
406
 
        std::stringstream msg;
407
 
        msg << "Syntax error in '" << path << "': " << s;
408
 
        throw std::runtime_error(msg.str());
409
 
      }
410
 
 
411
 
      if ( need_hat )
412
 
      {
413
 
        sgVec3 nrm ;
414
 
 
415
 
        loc.xyz[2] = 1000.0f ;
416
 
        loc.xyz[2] = getHeightAndNormal ( trackBranch, loc.xyz, nrm ) ;
417
 
 
418
 
        if ( fit_skin )
419
 
        {
420
 
          float sy = sin ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
421
 
          float cy = cos ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
422
 
   
423
 
          loc.hpr[2] =  SG_RADIANS_TO_DEGREES * atan2 ( nrm[0] * cy -
424
 
                                                        nrm[1] * sy, nrm[2] ) ;
425
 
          loc.hpr[1] = -SG_RADIANS_TO_DEGREES * atan2 ( nrm[1] * cy +
426
 
                                                        nrm[0] * sy, nrm[2] ) ; 
427
 
        }
428
 
      }
429
 
 
430
 
      ssgEntity        *obj   = ssgLoad ( fname, loader ) ;
431
 
      ssgRangeSelector *lod   = new ssgRangeSelector ;
432
 
      ssgTransform     *trans = new ssgTransform ( & loc ) ;
433
 
 
434
 
      float r [ 2 ] = { -10.0f, 2000.0f } ;
435
 
 
436
 
      lod         -> addKid    ( obj   ) ;
437
 
      trans       -> addKid    ( lod   ) ;
438
 
      trackBranch -> addKid    ( trans ) ;
439
 
      lod         -> setRanges ( r, 2  ) ;
440
 
    }
441
 
    else
442
 
    {
443
 
      fclose(fd);
444
 
      std::stringstream msg;
445
 
      msg << "Syntax error in '" << path << "': " << s;
446
 
      throw std::runtime_error(msg.str());
447
 
    }
448
 
  }
449
 
 
450
 
  fclose ( fd ) ;
451
 
}
452
 
 
453
 
void
454
 
World::restartRace()
455
 
{
456
 
  ready_set_go = 3;
457
 
  finishing_position = -1 ;
458
 
  clock = 0.0f;
459
 
  phase = START_PHASE;
460
 
 
461
 
  for ( Karts::iterator i = kart.begin(); i != kart.end() ; ++i )
462
 
    (*i)->reset() ;
463
 
}
464
 
 
465
 
KartDriver*
466
 
World::getKart(int kartId)
467
 
{
468
 
  assert(kartId >= 0 && kartId < int(kart.size()));
469
 
  return kart[kartId];
470
 
}
471
 
 
472
 
KartDriver*
473
 
World::getPlayerKart(int player)
474
 
{
475
 
  return kart[raceSetup.players[player]];
476
 
}
477
 
 
478
 
/* EOF */