/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx 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, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli co-programmer: Christian Meyer */ #include #include #include #include "world.h" using namespace std; /** \brief Create a new World This creates a new empty world! */ World::World () { entities = new List(); } World::~World () { unload (); delete entities; } template T* World::spawn(Location* loc = NULL, WorldEntity* owner = NULL) { Location zeroloc; T* entity = new T(); entities->add ((WorldEntity*)entity, LIST_ADD_NEXT); if( loc == NULL) { zeroloc.dist = 0; zeroloc.part = 0; zeroloc.pos = Vector(); zeroloc.rot = Rotation(); loc = &zeroloc; } entity->init (loc, owner); if (entity->bFree) { track[loc->part].map_coords( loc, entity->get_placement()) } entity->post_spawn (); return entity; } template T* World::spawn(Placement* plc, WorldEntity* owner = NULL) { T* entity = new T(); entities->add ((WorldEntity*)entity, LIST_ADD_NEXT); entity->init (plc, owner); if (!entity->bFree) { printf("Can't spawn unfree entity with placement\n"); entities->remove( (WorldEntity*)entity, LIST_FIND_FW); return NULL; } entity->post_spawn (); return entity; } World::collide () { List *a, *b; WorldEntity *aobj, *bobj; a = entities->get_next(); while( a != NULL) { aobj = a->get_object(); if( aobj->bCollide && aobj->collisioncluster != NULL) { b = a->get_next(); while( b != NULL) { bobj = b->get_object(); if( bobj->bCollide && bobj->collisioncluster != NULL) { Uint32 ahitflg, bhitflg; if check_collision ( aobj->place, aobj->collisioncluster, &ahitflg, bobj->place, bobj->collisioncluster, &bhitflg); { aobj->collide (bobj, ahitflg, bhitflg); bobj->collide (aobj, bhitflg, ahitflg); } } b = b->get_next(); } } a = a->get_next(); } } void World::draw () { // draw geometry // draw entities List *l; WorldEntity* entity; l = entities->get_next(); while( l != NULL) { entity = l->get_object(); if( entity->bDraw) entity->draw(); l = l->get_next(); } } void World::update () { List *l; WorldEntity* entity; Location* loc; Placement* plc; Uint32 t; l = entities->get_next(); while( l != NULL) { entity = l->get_object(); if( entity != bFree) { loc = entity->get_location(); plc = entity->get_placement(); t = loc->part; if( t >= tracklen) { printf("An entity is out of the game area\n"); entity->left_world (); } else { while( track[t].map_coords( loc, plc)) { track[t]->post_leave (entity); if( loc->part >= tracklen) { printf("An entity has left the game area\n"); entity->left_world (); break; } track[loc->part]->post_enter (entity); } } } else { // TO DO: implement check whether this particular free entity is out of the game area // TO DO: call function to notify the entity that it left the game area } l = l->get_next(); } } void World::time_slice (Uint32 deltaT) { List *l; WorldEntity* entity; float seconds = deltaT; seconds /= 1000; l = entities->get_next(); while( l != NULL) { entity = l->get_object(); entity->tick (seconds); l = l->get_next(); } for( int i = 0; i < tracklen) track[i].tick (seconds); } void World::unload() { if( pathnodes) delete []pathnodes; if( track) delete []pathnodes; } void World::load_debug_level() { // create some path nodes pathnodes = new Vector[6]; pathnodes[0] = Vector(0, 0, 0); pathnodes[1] = Vector(-100, 40, 0); pathnodes[2] = Vector(-100, 140, 0); pathnodes[3] = Vector(0, 180, 0); pathnodes[4] = Vector(100, 140, 0); pathnodes[5] = Vector(100, 40, 0); // create the tracks tracklen = 6; track = new Track[6]; for( int i = 0; i < tracklen; i++) { track[i] = Track( i, (i+1)%tracklen, &pathnodes[i], &pathnodes[(i+1)%tracklen]); } // create a player // bind input // bind camera }