/* 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: */ #include "world.h" #include using namespace std; /** \brief Create a new World This creates a new empty world! */ World::World () { lastPlayer = null; lastNPC = null; lastEnv = null; primitiveMove = 0; step = 0; } World::~World () {} /** \brief Add Player \param player A reference to the new player object Add a new Player to the game. Player has to be initialised previously */ bool World::addPlayer(Player* player) { playerList* listMember = new playerList; listMember->player = player; if ( lastPlayer != null ) { listMember->number = lastPlayer->number + 1; listMember->next = lastPlayer; } else { listMember->number = 0; listMember->next = null; } lastPlayer = listMember; } /** \brief Remove Player \param player A reference to the new npc object Remove a new Player to the game. */ bool World::removePlayer(Player* player) { cout << "World::removeNPC not implemented yet" << endl; } Player* World::getLocalPlayer() { return localPlayer; } /** \brief Add Non-Player-Character \param player A reference to the new npc object Add a new Non-Player-Character to the game. Player has to be initialised previously */ bool World::addNPC(NPC* npc) { npcList* listMember = new npcList; listMember->npc = npc; if ( lastNPC != null ) { listMember->number = lastNPC->number + 1; listMember->next = lastNPC; } else { listMember->number = 0; listMember->next = null; } lastNPC = listMember; } /** \brief Remove Non-Player Character \param player A reference to the new npc object Remove a new Non-Player-Character to the game. */ bool World::removeNPC(NPC* npc) { npcList* npcRef = lastNPC; npcList* lastRef = lastNPC; while ( npcRef != null ) { if ( npcRef->npc == npc ) { cout << "found" << endl; if ( npcRef == lastRef ) { lastNPC = lastNPC->next; delete npcRef; npcRef = lastNPC; lastRef = lastNPC; } else { lastRef->next = npcRef->next; delete npcRef; npcRef = lastRef->next; } cout << "killed ..." << endl; } else { lastRef = npcRef; npcRef = npcRef->next; } } cout << "npc left" << endl; } /** \brief Add environmental object \param player A reference to the new env object Add a new Environment to the world. Env has to be initialised before. */ bool World::addEnv(Environment* env) { envList* listMember = new envList; listMember->env = env; if ( lastEnv != null ) { listMember->number = lastEnv->number + 1; listMember->next = lastEnv; } else { listMember->number = 0; listMember->next = null; } lastEnv = listMember; } /** \brief Draws the World and all Objects contained Calls the draw function of all: Objects, Players, Environement. This is the core of all graphics here. */ void World::drawWorld(void) { glLoadIdentity(); gluLookAt(0.0, -14.0 + DataTank::yOffset, 15.0, 0.0, 0.0 + DataTank::yOffset, 0.0, 0.0, 1.0, 0.0); /* first draw all players */ playerList* tmpPlayer = lastPlayer; Player* player = tmpPlayer->player; while( tmpPlayer != null ) { (*tmpPlayer->player).drawPlayer(); tmpPlayer = tmpPlayer->next; } /* second draw all npcs */ npcList* tmpNPC = lastNPC; while( tmpNPC != null ) { (*tmpNPC->npc).drawNPC(); tmpNPC = tmpNPC->next; } /* now draw the rest of the world: environement */ envList* tmpEnv = lastEnv; while( tmpEnv != null ) { (*tmpEnv->env).drawEnvironment(); tmpEnv = tmpEnv->next; } /* draw the ground grid */ glColor3f(0.0, 1.0, 0.0); glBegin(GL_LINES); /* for the moment, we've got only pseudo moving ground */ for (int y = 0; y < 60; y += 2) { for (int x = 0; x < 60; x += 2) { glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]); glVertex3f((float)(x - 28), (float)(y - 30), surface[x+2][y]); } } glEnd(); glBegin(GL_LINES); for (int x = 0; x < 60; x += 2) { for (int y = 0; y < 60; y += 2) { glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]); glVertex3f((float)(x - 30), (float)(y - 28), surface[x][y+2]); } } glEnd(); //primitiveMove+=0.07; DataTank::yOffset += step; tmpPlayer = lastPlayer; while( tmpPlayer != null ) { tmpPlayer->player->yCor += step; tmpPlayer = tmpPlayer->next; } } void World::initEnvironement() { for (int x = 0; x < 60; x += 2) { for (int y = 0; y < 60; y += 2) { surface[x][y] = 0; } } } void World::setWorldStep(float step) { this->step = step; cout << "setting speed to " << step << endl; } /** \brief Updates the world and all its objects Calculates the new state of the world. User-input and AI of the enemies are accounted for. */ void World::updateWorld(void) { } /* collision detection */ /* fix: bad efficency: stupid brute force */ void World::detectCollision() { //cout << "World::detectCollision" << endl; float xOff, yOff, zOff, radius; npcList* tmpNPC, *tmpRef; //cout << "World::detectCollsions" << endl; /* first: check if any player's shoots trigger a collision */ playerList* tmpPlayer = lastPlayer; Player* player = tmpPlayer->player; int state; while( tmpPlayer != null ) { tmpNPC = lastNPC; while( tmpNPC != null ) { //cout << "npc != null" << endl; radius = tmpNPC->npc->collisionRadius; //cout << "worki" << endl; ShootLaser::shoot* shoota = tmpPlayer->player->shootLaser->lastShoot; while( shoota != null ) { xOff = shoota->xCor - tmpNPC->npc->xCor; yOff = shoota->yCor - tmpNPC->npc->yCor; zOff = shoota->zCor - tmpNPC->npc->zCor; if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) { //cout << "COLLISION " << endl; int state = tmpNPC->npc->hit(); /* state is a value that marks if the ship dies or not */ /* if state == 0 the ship dies and we have to remove it */ /* if ( state == 0 ) { tmpRef = tmpNPC; tmpNPC = tmpNPC->next; removeNPC(tmpRef->npc); break; } */ } shoota = shoota->next; } //cout << "changing npc..." << endl; tmpNPC = tmpNPC->next; //cout << "..changing npc done" << endl; } //cout << "changing play..." << endl; tmpPlayer = tmpPlayer->next; //cout << "changing play done" << endl; } //cout << "World::detectCollisions middle" << endl; /* second: check if any player hits an enemy */ tmpPlayer = lastPlayer; while( tmpPlayer != null ) { tmpNPC = lastNPC; while( tmpNPC != null ) { radius = tmpNPC->npc->collisionRadius + tmpPlayer->player->collisionRadius; xOff = tmpPlayer->player->xCor - tmpNPC->npc->xCor; yOff = tmpPlayer->player->yCor - tmpNPC->npc->yCor; zOff = tmpPlayer->player->zCor - tmpNPC->npc->zCor; if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) { //cout << "COLLISION " << endl; tmpNPC->npc->hit(); } tmpNPC = tmpNPC->next; } tmpPlayer = tmpPlayer->next; } /* third: check if any enemy shoots a player */ //cout << "World::detectCollisions end" << endl; } /** \brief Routine for testing purposes. testing, testing, testing... */ void World::testThaTest(void) { cout << "World::testThaTest() called" << endl; /* test addPlayer */ cout << "addPlayer test..." << endl; playerList* pl = lastPlayer; while ( pl != null ) { cout << "player " << pl->number << " was found" << endl; pl = pl->next; } /* test addNPC */ cout << "addNPC test..." << endl; npcList* nl = lastNPC; while ( nl != null ) { cout << "npc " << nl->number << " was found" << endl; nl = nl->next; } /* test addEnv */ cout << "addEnv test..." << endl; envList* en = lastEnv; while ( en != null ) { cout << "env " << en->number << " was found" << endl; en = en->next; } /* test drawWorld() */ }