| 1 | /* | 
|---|
| 2 |    orxonox - the future of 3D-vertical-scrollers | 
|---|
| 3 |  | 
|---|
| 4 |    Copyright (C) 2004 orx | 
|---|
| 5 |  | 
|---|
| 6 |    This program is free software; you can redistribute it and/or modify | 
|---|
| 7 |    it under the terms of the GNU General Public License as published by | 
|---|
| 8 |    the Free Software Foundation; either version 2, or (at your option) | 
|---|
| 9 |    any later version. | 
|---|
| 10 |  | 
|---|
| 11 | ### File Specific: | 
|---|
| 12 |    main-programmer: Benjamin Knecht | 
|---|
| 13 |    co-programmer: Silvan Nellen | 
|---|
| 14 |  | 
|---|
| 15 | */ | 
|---|
| 16 |  | 
|---|
| 17 | #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY | 
|---|
| 18 |  | 
|---|
| 19 | #include "executor/executor.h" | 
|---|
| 20 | #include "space_ship.h" | 
|---|
| 21 |  | 
|---|
| 22 | #include "util/loading/resource_manager.h" | 
|---|
| 23 |  | 
|---|
| 24 | #include "weapons/test_gun.h" | 
|---|
| 25 | #include "weapons/turret.h" | 
|---|
| 26 | #include "weapons/cannon.h" | 
|---|
| 27 |  | 
|---|
| 28 | #include "dot_emitter.h" | 
|---|
| 29 | #include "sprite_particles.h" | 
|---|
| 30 |  | 
|---|
| 31 | #include "util/loading/factory.h" | 
|---|
| 32 | #include "key_mapper.h" | 
|---|
| 33 | #include "event_handler.h" | 
|---|
| 34 |  | 
|---|
| 35 | #include "network_game_manager.h" | 
|---|
| 36 |  | 
|---|
| 37 | #include "power_ups/weapon_power_up.h" | 
|---|
| 38 | #include "power_ups/param_power_up.h" | 
|---|
| 39 |  | 
|---|
| 40 | #include "graphics_engine.h" | 
|---|
| 41 |  | 
|---|
| 42 | #include "plane.h" | 
|---|
| 43 |  | 
|---|
| 44 | #include "state.h" | 
|---|
| 45 | #include "player.h" | 
|---|
| 46 |  | 
|---|
| 47 | #include "util/loading/load_param.h" | 
|---|
| 48 |  | 
|---|
| 49 |  | 
|---|
| 50 | // #include "lib/gui/gl_gui/glgui_bar.h" | 
|---|
| 51 | // #include "lib/gui/gl_gui/glgui_pushbutton.h" | 
|---|
| 52 |  | 
|---|
| 53 |  | 
|---|
| 54 | using namespace std; | 
|---|
| 55 |  | 
|---|
| 56 | CREATE_FACTORY(SpaceShip, CL_SPACE_SHIP); | 
|---|
| 57 |  | 
|---|
| 58 |  | 
|---|
| 59 | /** | 
|---|
| 60 |  *  destructs the spaceship, deletes alocated memory | 
|---|
| 61 |  */ | 
|---|
| 62 | SpaceShip::~SpaceShip () | 
|---|
| 63 | { | 
|---|
| 64 |   this->setPlayer(NULL); | 
|---|
| 65 | } | 
|---|
| 66 |  | 
|---|
| 67 | /** | 
|---|
| 68 |  * loads a Spaceships information from a specified file. | 
|---|
| 69 |  * @param fileName the name of the File to load the spaceship from (absolute path) | 
|---|
| 70 |  */ | 
|---|
| 71 | SpaceShip::SpaceShip(const std::string& fileName) | 
|---|
| 72 | { | 
|---|
| 73 |   this->init(); | 
|---|
| 74 |   TiXmlDocument doc(fileName); | 
|---|
| 75 |  | 
|---|
| 76 |   if(!doc.LoadFile()) | 
|---|
| 77 |   { | 
|---|
| 78 |     PRINTF(2)("Loading file %s failed for spaceship.\n", fileName.c_str()); | 
|---|
| 79 |     return; | 
|---|
| 80 |   } | 
|---|
| 81 |  | 
|---|
| 82 |   this->loadParams(doc.RootElement()); | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | /** | 
|---|
| 86 |  *  creates a new Spaceship from Xml Data | 
|---|
| 87 |  * @param root the xml element containing spaceship data | 
|---|
| 88 |  | 
|---|
| 89 |    @todo add more parameters to load | 
|---|
| 90 | */ | 
|---|
| 91 | SpaceShip::SpaceShip(const TiXmlElement* root) | 
|---|
| 92 | { | 
|---|
| 93 |   this->init(); | 
|---|
| 94 |   if (root != NULL) | 
|---|
| 95 |     this->loadParams(root); | 
|---|
| 96 |   else | 
|---|
| 97 |   { | 
|---|
| 98 |     //this->loadModel("models/ships/reap_#.obj"); | 
|---|
| 99 |     //TODO HACK this is only for network multiplayer games. | 
|---|
| 100 |     if( this->getOwner()%2 == 0) | 
|---|
| 101 |     { | 
|---|
| 102 |       this->loadModel("models/ships/reap_#.obj"); | 
|---|
| 103 |       this->toList(OM_GROUP_00); | 
|---|
| 104 |     } | 
|---|
| 105 |     else | 
|---|
| 106 |     { | 
|---|
| 107 |       this->loadModel( "models/ships/fighter.obj" ); | 
|---|
| 108 |       this->toList(OM_GROUP_01); | 
|---|
| 109 |     } | 
|---|
| 110 |   } | 
|---|
| 111 |  | 
|---|
| 112 | } | 
|---|
| 113 |  | 
|---|
| 114 |  | 
|---|
| 115 | /** | 
|---|
| 116 |  * initializes a Spaceship | 
|---|
| 117 |  */ | 
|---|
| 118 | void SpaceShip::init() | 
|---|
| 119 | { | 
|---|
| 120 | //  this->setRelDir(Quaternion(M_PI, Vector(1,0,0))); | 
|---|
| 121 |   this->setClassID(CL_SPACE_SHIP, "SpaceShip"); | 
|---|
| 122 |  | 
|---|
| 123 |   PRINTF(4)("SPACESHIP INIT\n"); | 
|---|
| 124 |  | 
|---|
| 125 |   //weapons: | 
|---|
| 126 |   Weapon* wpRight = new TestGun(0); | 
|---|
| 127 |   wpRight->setName("testGun Right"); | 
|---|
| 128 |   Weapon* wpLeft = new TestGun(1); | 
|---|
| 129 |   wpLeft->setName("testGun Left"); | 
|---|
| 130 |   //Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_CANNON)); | 
|---|
| 131 |  | 
|---|
| 132 |   //cannon->setName("BFG"); | 
|---|
| 133 |  | 
|---|
| 134 |   this->addWeapon(wpLeft, 1, 0); | 
|---|
| 135 |   this->addWeapon(wpRight,1 ,1); | 
|---|
| 136 |   //this->addWeapon(cannon, 0, 6); | 
|---|
| 137 |  | 
|---|
| 138 |   this->getWeaponManager().changeWeaponConfig(1); | 
|---|
| 139 |  | 
|---|
| 140 |   bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false; | 
|---|
| 141 |  | 
|---|
| 142 |   xMouse = yMouse = 0; | 
|---|
| 143 |   yInvert = 1; | 
|---|
| 144 |   mouseSensitivity = 0.001; | 
|---|
| 145 |   airViscosity = 0.9; | 
|---|
| 146 |   controlVelocityX = 25; | 
|---|
| 147 |   controlVelocityY = 150; | 
|---|
| 148 |   shipInertia = 1.5; | 
|---|
| 149 | //  cycle = 0.0; | 
|---|
| 150 |  | 
|---|
| 151 |   this->setHealthMax(100); | 
|---|
| 152 |   this->setHealth(80); | 
|---|
| 153 |  | 
|---|
| 154 |   travelSpeed = 0.0; | 
|---|
| 155 |   acceleration = 3; | 
|---|
| 156 |   this->velocity = this->getAbsDirX()*travelSpeed; | 
|---|
| 157 |   this->mouseDir = this->getAbsDir(); | 
|---|
| 158 |   this->pitchDir = this->getAbsDir(); | 
|---|
| 159 |  | 
|---|
| 160 | //   GLGuiButton* button = new GLGuiPushButton(); | 
|---|
| 161 | //    button->show(); | 
|---|
| 162 | //    button->setLabel("orxonox"); | 
|---|
| 163 | //    button->setBindNode(this); | 
|---|
| 164 | //     GLGuiBar* bar = new GLGuiBar(); | 
|---|
| 165 | //     bar->show(); | 
|---|
| 166 | //     bar->setValue(7.0); | 
|---|
| 167 | //     bar->setMaximum(10); | 
|---|
| 168 | //     bar->setSize2D( 20, 100); | 
|---|
| 169 | //     bar->setAbsCoor2D( 10, 200); | 
|---|
| 170 |  | 
|---|
| 171 |   //add events to the eventlist | 
|---|
| 172 |   registerEvent(KeyMapper::PEV_FORWARD); | 
|---|
| 173 |   registerEvent(KeyMapper::PEV_BACKWARD); | 
|---|
| 174 |   registerEvent(KeyMapper::PEV_LEFT); | 
|---|
| 175 |   registerEvent(KeyMapper::PEV_RIGHT); | 
|---|
| 176 |   //registerEvent(SDLK_q); | 
|---|
| 177 |   //registerEvent(SDLK_e); | 
|---|
| 178 |   registerEvent(KeyMapper::PEV_FIRE1); | 
|---|
| 179 |   registerEvent(KeyMapper::PEV_NEXT_WEAPON); | 
|---|
| 180 |   registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON); | 
|---|
| 181 |   //registerEvent(SDLK_PAGEUP); | 
|---|
| 182 |   //registerEvent(SDLK_PAGEDOWN); | 
|---|
| 183 |   registerEvent(EV_MOUSE_MOTION); | 
|---|
| 184 |  | 
|---|
| 185 |   this->getWeaponManager().setSlotCount(7); | 
|---|
| 186 |  | 
|---|
| 187 |   this->getWeaponManager().setSlotPosition(0, Vector(-2.6, .1, -3.0)); | 
|---|
| 188 |   this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); | 
|---|
| 189 |  | 
|---|
| 190 |   this->getWeaponManager().setSlotPosition(1, Vector(-2.6, .1, 3.0)); | 
|---|
| 191 |   this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); | 
|---|
| 192 |  | 
|---|
| 193 |   this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5)); | 
|---|
| 194 |   this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0))); | 
|---|
| 195 |  | 
|---|
| 196 |   this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5)); | 
|---|
| 197 |   this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0))); | 
|---|
| 198 |  | 
|---|
| 199 |   this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5)); | 
|---|
| 200 |   this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0))); | 
|---|
| 201 |  | 
|---|
| 202 |   this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5)); | 
|---|
| 203 |   this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0))); | 
|---|
| 204 | // | 
|---|
| 205 |    this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0)); | 
|---|
| 206 |    this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); | 
|---|
| 207 |    // | 
|---|
| 208 | //   this->getWeaponManager().setSlotPosition(8, Vector(-2.5, -0.3, -2.0)); | 
|---|
| 209 | //   this->getWeaponManager().setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0))); | 
|---|
| 210 | // | 
|---|
| 211 | //   this->getWeaponManager().setSlotPosition(9, Vector(-2.5, -0.3, 2.0)); | 
|---|
| 212 | //   this->getWeaponManager().setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));: | 
|---|
| 213 |  | 
|---|
| 214 |   this->getWeaponManager().getFixedTarget()->setParent(this); | 
|---|
| 215 |   this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0); | 
|---|
| 216 |  | 
|---|
| 217 |   dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false); | 
|---|
| 218 |  | 
|---|
| 219 |   this->burstEmitter = new DotEmitter(200, 0.0, .01); | 
|---|
| 220 |   this->burstEmitter->setParent(this); | 
|---|
| 221 |   this->burstEmitter->setRelCoor(-1, .5, 0); | 
|---|
| 222 |   this->burstEmitter->setName("SpaceShip_Burst_emitter"); | 
|---|
| 223 |  | 
|---|
| 224 |   this->burstSystem = new SpriteParticles(1000); | 
|---|
| 225 |   this->burstSystem->addEmitter(this->burstEmitter); | 
|---|
| 226 |   this->burstSystem->setName("SpaceShip_Burst_System"); | 
|---|
| 227 |   ((SpriteParticles*)this->burstSystem)->setMaterialTexture("maps/radial-trans-noise.png"); | 
|---|
| 228 |   this->burstSystem->setLifeSpan(1.0, .3); | 
|---|
| 229 |   this->burstSystem->setRadius(0.0, 1.0); | 
|---|
| 230 |   this->burstSystem->setRadius(0.05, 1.0); | 
|---|
| 231 |   this->burstSystem->setRadius(.5, .8); | 
|---|
| 232 |   this->burstSystem->setRadius(1.0, 0); | 
|---|
| 233 |   this->burstSystem->setColor(0.0, .7,.7,1,.7); | 
|---|
| 234 |   this->burstSystem->setColor(0.2, 0,0,0.8,.5); | 
|---|
| 235 |   this->burstSystem->setColor(0.5, .5,.5,.8,.8); | 
|---|
| 236 |   this->burstSystem->setColor(1.0, .8,.8,.8,.0); | 
|---|
| 237 |  | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 |  | 
|---|
| 241 | /** | 
|---|
| 242 |  * loads the Settings of a SpaceShip from an XML-element. | 
|---|
| 243 |  * @param root the XML-element to load the Spaceship's properties from | 
|---|
| 244 |  */ | 
|---|
| 245 | void SpaceShip::loadParams(const TiXmlElement* root) | 
|---|
| 246 | { | 
|---|
| 247 |   Playable::loadParams(root); | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | void SpaceShip::setPlayDirection(const Quaternion& quat, float speed) | 
|---|
| 251 | { | 
|---|
| 252 |   this->mouseDir = quat; | 
|---|
| 253 | } | 
|---|
| 254 |  | 
|---|
| 255 |  | 
|---|
| 256 | void SpaceShip::reset() | 
|---|
| 257 | { | 
|---|
| 258 |   bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false; | 
|---|
| 259 |  | 
|---|
| 260 |   xMouse = yMouse = 0; | 
|---|
| 261 |  | 
|---|
| 262 |   this->setHealth(80); | 
|---|
| 263 |   this->velocity = Vector(0.0, 0.0, 0.0); | 
|---|
| 264 | } | 
|---|
| 265 |  | 
|---|
| 266 |  | 
|---|
| 267 | void SpaceShip::enter() | 
|---|
| 268 | { | 
|---|
| 269 |   dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( true); | 
|---|
| 270 |   this->attachCamera(); | 
|---|
| 271 | } | 
|---|
| 272 |  | 
|---|
| 273 | void SpaceShip::leave() | 
|---|
| 274 | { | 
|---|
| 275 |   dynamic_cast<Element2D*>(this->getWeaponManager().getFixedTarget())->setVisibility( false); | 
|---|
| 276 |   this->detachCamera(); | 
|---|
| 277 | } | 
|---|
| 278 |  | 
|---|
| 279 |  | 
|---|
| 280 | /** | 
|---|
| 281 |  *  effect that occurs after the SpaceShip is spawned | 
|---|
| 282 | */ | 
|---|
| 283 | void SpaceShip::postSpawn () | 
|---|
| 284 | { | 
|---|
| 285 |   //setCollision(new CollisionCluster(1.0, Vector(0,0,0))); | 
|---|
| 286 | } | 
|---|
| 287 |  | 
|---|
| 288 | /** | 
|---|
| 289 |  *  the action occuring if the spaceship left the game | 
|---|
| 290 | */ | 
|---|
| 291 | void SpaceShip::leftWorld () | 
|---|
| 292 | {} | 
|---|
| 293 |  | 
|---|
| 294 | WorldEntity* ref = NULL; | 
|---|
| 295 | /** | 
|---|
| 296 |  *  this function is called, when two entities collide | 
|---|
| 297 |  * @param entity: the world entity with whom it collides | 
|---|
| 298 |  * | 
|---|
| 299 |  * Implement behaviour like damage application or other miscellaneous collision stuff in this function | 
|---|
| 300 |  */ | 
|---|
| 301 | void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location) | 
|---|
| 302 | { | 
|---|
| 303 |   Playable::collidesWith(entity, location); | 
|---|
| 304 |  | 
|---|
| 305 |   if( entity->isA(CL_PROJECTILE) && entity != ref) | 
|---|
| 306 |   { | 
|---|
| 307 |     if ( isServer() ) | 
|---|
| 308 |     { | 
|---|
| 309 |       networkCollisionList.push_back( entity->getHealth() ); | 
|---|
| 310 |       doCollideNetwork( entity->getHealth() ); | 
|---|
| 311 |     } | 
|---|
| 312 |   } | 
|---|
| 313 | //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z); | 
|---|
| 314 | } | 
|---|
| 315 |  | 
|---|
| 316 | /** | 
|---|
| 317 |  *  draws the spaceship after transforming it. | 
|---|
| 318 | */ | 
|---|
| 319 | void SpaceShip::draw () const | 
|---|
| 320 | { | 
|---|
| 321 |   WorldEntity::draw(); | 
|---|
| 322 |  | 
|---|
| 323 |   //this->debug(0); | 
|---|
| 324 | } | 
|---|
| 325 |  | 
|---|
| 326 | /** | 
|---|
| 327 |  *  the function called for each passing timeSnap | 
|---|
| 328 |  * @param time The timespan passed since last update | 
|---|
| 329 | */ | 
|---|
| 330 | void SpaceShip::tick (float time) | 
|---|
| 331 | { | 
|---|
| 332 |   Playable::tick(time); | 
|---|
| 333 |  | 
|---|
| 334 |   if( ( xMouse != 0 || yMouse != 0 ) && this->getOwner() == this->getHostID() ) | 
|---|
| 335 |    { | 
|---|
| 336 |     if (xMouse > controlVelocityX) xMouse = controlVelocityX; | 
|---|
| 337 |     else if (xMouse < -controlVelocityX) xMouse = -controlVelocityX; | 
|---|
| 338 |     if (yMouse > controlVelocityY) yMouse = controlVelocityY; | 
|---|
| 339 |     else if (yMouse < -controlVelocityY) yMouse = -controlVelocityY; | 
|---|
| 340 |  | 
|---|
| 341 |     pitchDir = (Quaternion(xMouse*mouseSensitivity*0.5, Vector(1,0,0))); | 
|---|
| 342 |  | 
|---|
| 343 |     mouseDir *= (Quaternion(-M_PI/4*xMouse*mouseSensitivity, Vector(0,1,0))*Quaternion(-M_PI/4*yMouse*mouseSensitivity*yInvert, Vector(0,0,1))*pitchDir); | 
|---|
| 344 |     xMouse = yMouse = 0; | 
|---|
| 345 |    } | 
|---|
| 346 |  | 
|---|
| 347 |  | 
|---|
| 348 | //   if( this != State::getPlayer()->getControllable()) | 
|---|
| 349 | //     return; | 
|---|
| 350 |  | 
|---|
| 351 |   // spaceship controlled movement | 
|---|
| 352 |   if (this->getOwner() == this->getHostID()) | 
|---|
| 353 |     this->calculateVelocity(time); | 
|---|
| 354 |  | 
|---|
| 355 |  | 
|---|
| 356 |   Vector move = velocity*time; | 
|---|
| 357 |  | 
|---|
| 358 |   //orient the velocity in the direction of the spaceship. | 
|---|
| 359 |   travelSpeed = velocity.len(); | 
|---|
| 360 |   velocity += ((this->getAbsDirX())*travelSpeed-velocity)*airViscosity; | 
|---|
| 361 |   velocity = (velocity.getNormalized())*travelSpeed; | 
|---|
| 362 |   this->burstEmitter->setEmissionRate(travelSpeed); | 
|---|
| 363 |   this->burstEmitter->setEmissionVelocity(travelSpeed*.5, travelSpeed *.1); | 
|---|
| 364 |  | 
|---|
| 365 |   //orient the spaceship in direction of the mouse | 
|---|
| 366 |    rotQuat = Quaternion::quatSlerp( this->getAbsDir(), mouseDir, 0.5);//fabsf(time)*shipInertia); | 
|---|
| 367 |    if (this->getAbsDir().distance(rotQuat) > 0.00000000000001) | 
|---|
| 368 |     this->setAbsDir( rotQuat); | 
|---|
| 369 |    //this->setAbsDirSoft(mouseDir,5); | 
|---|
| 370 |  | 
|---|
| 371 |   // this is the air friction (necessary for a smooth control) | 
|---|
| 372 |   if(travelSpeed >= 120) velocity -= velocity.getNormalized()*travelSpeed*travelSpeed*0.0001; | 
|---|
| 373 |   else if (travelSpeed <= 80) velocity -= velocity.getNormalized()*travelSpeed*0.001; | 
|---|
| 374 |  | 
|---|
| 375 |   //other physics (gravity) | 
|---|
| 376 |   //if(travelSpeed < 120) | 
|---|
| 377 |   //move += Vector(0,-1,0)*60*time + Vector(0,1,0)*travelSpeed/2*time; | 
|---|
| 378 |  | 
|---|
| 379 |   //hoover effect | 
|---|
| 380 |   //cycle += time; | 
|---|
| 381 |   //this->shiftCoor(Vector(0,1,0)*cos(this->cycle*2.0)*0.02); | 
|---|
| 382 |  | 
|---|
| 383 |   //readjust | 
|---|
| 384 |   //if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0))); | 
|---|
| 385 |   //else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0))); | 
|---|
| 386 |  | 
|---|
| 387 |   //SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2); | 
|---|
| 388 |  | 
|---|
| 389 |   this->shiftCoor(move); | 
|---|
| 390 |  | 
|---|
| 391 |  | 
|---|
| 392 | } | 
|---|
| 393 |  | 
|---|
| 394 | /** | 
|---|
| 395 |  *  calculate the velocity | 
|---|
| 396 |  * @param time the timeslice since the last frame | 
|---|
| 397 | */ | 
|---|
| 398 | void SpaceShip::calculateVelocity (float time) | 
|---|
| 399 | { | 
|---|
| 400 |   Vector accel(0.0, 0.0, 0.0); | 
|---|
| 401 |   /* | 
|---|
| 402 |   Vector rot(0.0, 0.0, 0.0); // wird benötigt für Helicopter | 
|---|
| 403 |   */ | 
|---|
| 404 |   //float rotVal = 0.0; | 
|---|
| 405 |   /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */ | 
|---|
| 406 |   /* calculate the direction in which the craft is heading  */ | 
|---|
| 407 |  | 
|---|
| 408 |   //Plane plane(Vector(0,1,0), Vector(0,0,0)); | 
|---|
| 409 |  | 
|---|
| 410 |   if( this->bUp ) | 
|---|
| 411 |    { | 
|---|
| 412 |      //this->shiftCoor(this->getAbsDirX()); | 
|---|
| 413 |       //accel += (this->getAbsDirX())*2; | 
|---|
| 414 |       accel += (this->getAbsDirX())*acceleration; | 
|---|
| 415 |  | 
|---|
| 416 |    } | 
|---|
| 417 |  | 
|---|
| 418 |   if( this->bDown ) | 
|---|
| 419 |    { | 
|---|
| 420 |      //this->shiftCoor((this->getAbsDirX())*-1); | 
|---|
| 421 |      //accel -= (this->getAbsDirX())*2; | 
|---|
| 422 |     //if(velocity.len() > 50) | 
|---|
| 423 |      accel -= (this->getAbsDirX())*0.5*acceleration; | 
|---|
| 424 |  | 
|---|
| 425 |  | 
|---|
| 426 |  | 
|---|
| 427 |    } | 
|---|
| 428 |  | 
|---|
| 429 |   if( this->bLeft/* > -this->getRelCoor().z*2*/) | 
|---|
| 430 |   { | 
|---|
| 431 |     this->shiftDir(Quaternion(time, Vector(0,1,0))); | 
|---|
| 432 | //    accel -= rightDirection; | 
|---|
| 433 |     //velocityDir.normalize(); | 
|---|
| 434 |     //rot +=Vector(1,0,0); | 
|---|
| 435 |     //rotVal -= .4; | 
|---|
| 436 |   } | 
|---|
| 437 |   if( this->bRight /* > this->getRelCoor().z*2*/) | 
|---|
| 438 |   { | 
|---|
| 439 |     this->shiftDir(Quaternion(-time, Vector(0,1,0))); | 
|---|
| 440 |  | 
|---|
| 441 |     //    accel += rightDirection; | 
|---|
| 442 |     //velocityDir.normalize(); | 
|---|
| 443 |     //rot += Vector(1,0,0); | 
|---|
| 444 |     //rotVal += .4; | 
|---|
| 445 |   } | 
|---|
| 446 |  | 
|---|
| 447 |  | 
|---|
| 448 |   if( this->bRollL /* > -this->getRelCoor().z*2*/) | 
|---|
| 449 |   { | 
|---|
| 450 |     mouseDir *= Quaternion(-time*2, Vector(1,0,0)); | 
|---|
| 451 | //    accel -= rightDirection; | 
|---|
| 452 |     //velocityDir.normalize(); | 
|---|
| 453 |     //rot +=Vector(1,0,0); | 
|---|
| 454 |     //rotVal -= .4; | 
|---|
| 455 |   } | 
|---|
| 456 |   if( this->bRollR /* > this->getRelCoor().z*2*/) | 
|---|
| 457 |   { | 
|---|
| 458 |     mouseDir *= Quaternion(time*2, Vector(1,0,0)); | 
|---|
| 459 |  | 
|---|
| 460 |     //    accel += rightDirection; | 
|---|
| 461 |     //velocityDir.normalize(); | 
|---|
| 462 |     //rot += Vector(1,0,0); | 
|---|
| 463 |     //rotVal += .4; | 
|---|
| 464 |   } | 
|---|
| 465 |   if (this->bAscend ) | 
|---|
| 466 |   { | 
|---|
| 467 |     this->shiftDir(Quaternion(time, Vector(0,0,1))); | 
|---|
| 468 |  | 
|---|
| 469 | //    accel += upDirection; | 
|---|
| 470 |     //velocityDir.normalize(); | 
|---|
| 471 |     //rot += Vector(0,0,1); | 
|---|
| 472 |     //rotVal += .4; | 
|---|
| 473 |   } | 
|---|
| 474 |   if (this->bDescend ) | 
|---|
| 475 |   { | 
|---|
| 476 |     this->shiftDir(Quaternion(-time, Vector(0,0,1))); | 
|---|
| 477 |  | 
|---|
| 478 |     //    accel -= upDirection; | 
|---|
| 479 |     //velocityDir.normalize(); | 
|---|
| 480 |     //rot += Vector(0,0,1); | 
|---|
| 481 |     //rotVal -= .4; | 
|---|
| 482 |   } | 
|---|
| 483 |  | 
|---|
| 484 |   velocity += accel*time*10; | 
|---|
| 485 |   //rot.normalize(); | 
|---|
| 486 |   //this->setRelDirSoft(Quaternion(rotVal, rot), 5); | 
|---|
| 487 | } | 
|---|
| 488 |  | 
|---|
| 489 | /** | 
|---|
| 490 |  * @todo switch statement ?? | 
|---|
| 491 |  */ | 
|---|
| 492 | void SpaceShip::process(const Event &event) | 
|---|
| 493 | { | 
|---|
| 494 |   Playable::process(event); | 
|---|
| 495 |  | 
|---|
| 496 |   if( event.type == KeyMapper::PEV_LEFT) | 
|---|
| 497 |       this->bRollL = event.bPressed; | 
|---|
| 498 |   else if( event.type == KeyMapper::PEV_RIGHT) | 
|---|
| 499 |       this->bRollR = event.bPressed; | 
|---|
| 500 |   else if( event.type == KeyMapper::PEV_FORWARD) | 
|---|
| 501 |     this->bUp = event.bPressed; //this->shiftCoor(0,.1,0); | 
|---|
| 502 |   else if( event.type == KeyMapper::PEV_BACKWARD) | 
|---|
| 503 |     this->bDown = event.bPressed; //this->shiftCoor(0,-.1,0); | 
|---|
| 504 |   else if( event.type == EV_MOUSE_MOTION) | 
|---|
| 505 |   { | 
|---|
| 506 |     this->xMouse += event.xRel; | 
|---|
| 507 |     this->yMouse += event.yRel; | 
|---|
| 508 |   } | 
|---|
| 509 | } | 
|---|
| 510 |  | 
|---|
| 511 |  | 
|---|
| 512 | #define MASK_bUp         1 | 
|---|
| 513 | #define MASK_bDown       2 | 
|---|
| 514 | #define MASK_bLeft       4 | 
|---|
| 515 | #define MASK_bRight      8 | 
|---|
| 516 | #define MASK_bAscend    16 | 
|---|
| 517 | #define MASK_bDescend   32 | 
|---|
| 518 | #define MASK_bRollL     64 | 
|---|
| 519 | #define MASK_bRollR    128 | 
|---|
| 520 |  | 
|---|
| 521 | #define DATA_state       1 | 
|---|
| 522 | #define DATA_flags       2 | 
|---|
| 523 | #define DATA_mouse       3 | 
|---|
| 524 | #define DATA_sync        4 | 
|---|
| 525 | #define DATA_velocity    5 | 
|---|
| 526 | #define DATA_playables   6 | 
|---|
| 527 | #define DATA_collision   7 | 
|---|
| 528 |  | 
|---|
| 529 | int SpaceShip::writeBytes( const byte * data, int length, int sender ) | 
|---|
| 530 | { | 
|---|
| 531 |   SYNCHELP_READ_BEGIN(); | 
|---|
| 532 |  | 
|---|
| 533 |   byte b; | 
|---|
| 534 |  | 
|---|
| 535 |   while ( SYNCHELP_READ_REMAINING()>0 ) | 
|---|
| 536 |   { | 
|---|
| 537 |     SYNCHELP_READ_BYTE( b, NWT_SS_B ); | 
|---|
| 538 |  | 
|---|
| 539 |     if ( b == DATA_state ) | 
|---|
| 540 |     { | 
|---|
| 541 |       setRequestedSync( false ); | 
|---|
| 542 |       setIsOutOfSync( false ); | 
|---|
| 543 |       SYNCHELP_READ_FKT( WorldEntity::writeState, NWT_SS_WE_STATE ); | 
|---|
| 544 |  | 
|---|
| 545 |       continue; | 
|---|
| 546 |     } | 
|---|
| 547 |  | 
|---|
| 548 |     if ( b == DATA_flags ) | 
|---|
| 549 |     { | 
|---|
| 550 |       if ( this->getOwner() != this->getHostID() ) | 
|---|
| 551 |       { | 
|---|
| 552 |         byte flags = 0; | 
|---|
| 553 |         SYNCHELP_READ_BYTE( flags, NWT_SS_FLAGS ); | 
|---|
| 554 |  | 
|---|
| 555 |         bUp = (flags & MASK_bUp) != 0; | 
|---|
| 556 |         bDown = (flags & MASK_bDown) != 0; | 
|---|
| 557 |         bLeft = (flags & MASK_bLeft) != 0; | 
|---|
| 558 |         bRight = (flags & MASK_bRight) != 0; | 
|---|
| 559 |         bAscend = (flags & MASK_bAscend) != 0; | 
|---|
| 560 |         bDescend = (flags & MASK_bDescend) != 0; | 
|---|
| 561 |         bRollL = (flags & MASK_bRollL) != 0; | 
|---|
| 562 |         bRollR = (flags & MASK_bRollR) != 0; | 
|---|
| 563 |  | 
|---|
| 564 |       } | 
|---|
| 565 |       else | 
|---|
| 566 |         assert(false); | 
|---|
| 567 |  | 
|---|
| 568 |       continue; | 
|---|
| 569 |     } | 
|---|
| 570 |  | 
|---|
| 571 |     if ( b == DATA_mouse ) | 
|---|
| 572 |     { | 
|---|
| 573 |       if ( this->getOwner() != this->getHostID() ) | 
|---|
| 574 |       { | 
|---|
| 575 |         SYNCHELP_READ_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW ); | 
|---|
| 576 |         SYNCHELP_READ_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX ); | 
|---|
| 577 |         SYNCHELP_READ_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY ); | 
|---|
| 578 |         SYNCHELP_READ_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ ); | 
|---|
| 579 |       } | 
|---|
| 580 |       else | 
|---|
| 581 |         assert(false); | 
|---|
| 582 |  | 
|---|
| 583 |       continue; | 
|---|
| 584 |     } | 
|---|
| 585 |  | 
|---|
| 586 |     if ( b == DATA_sync ) | 
|---|
| 587 |     { | 
|---|
| 588 |       if ( this->getOwner() != this->getHostID() ) | 
|---|
| 589 |       { | 
|---|
| 590 |         SYNCHELP_READ_FKT( PNode::writeSync, NWT_SS_PN_SYNC ); | 
|---|
| 591 |       } | 
|---|
| 592 |       else | 
|---|
| 593 |         assert(false); | 
|---|
| 594 |  | 
|---|
| 595 |       continue; | 
|---|
| 596 |     } | 
|---|
| 597 |  | 
|---|
| 598 |     if ( b == DATA_velocity ) | 
|---|
| 599 |     { | 
|---|
| 600 |       if ( this->getOwner() != this->getHostID() ) | 
|---|
| 601 |       { | 
|---|
| 602 |         SYNCHELP_READ_FLOAT( velocity.x, NWT_SS_VELX ); | 
|---|
| 603 |         SYNCHELP_READ_FLOAT( velocity.y, NWT_SS_VELY ); | 
|---|
| 604 |         SYNCHELP_READ_FLOAT( velocity.z, NWT_SS_VELZ ); | 
|---|
| 605 |       } | 
|---|
| 606 |       else | 
|---|
| 607 |         assert(false); | 
|---|
| 608 |  | 
|---|
| 609 |       continue; | 
|---|
| 610 |     } | 
|---|
| 611 |  | 
|---|
| 612 |     if ( b == DATA_playables ) | 
|---|
| 613 |     { | 
|---|
| 614 |       if ( this->getOwner() != this->getHostID() ) | 
|---|
| 615 |       { | 
|---|
| 616 |         SYNCHELP_READ_FKT( Playable::writeSync, NWT_SS_PL_SYNC ); | 
|---|
| 617 |       } | 
|---|
| 618 |       else | 
|---|
| 619 |         assert(false); | 
|---|
| 620 |     } | 
|---|
| 621 |  | 
|---|
| 622 |     if ( b == DATA_collision ) | 
|---|
| 623 |     { | 
|---|
| 624 |       int n; | 
|---|
| 625 |       float energy; | 
|---|
| 626 |       SYNCHELP_READ_INT( n, NWT_SS_CO_N ); | 
|---|
| 627 |  | 
|---|
| 628 |       for ( int i = 0; i<n; i++ ) | 
|---|
| 629 |       { | 
|---|
| 630 |         SYNCHELP_READ_FLOAT( energy, NWT_SS_CO_CLID ); | 
|---|
| 631 |         doCollideNetwork( energy ); | 
|---|
| 632 |       } | 
|---|
| 633 |     } | 
|---|
| 634 |   } | 
|---|
| 635 |  | 
|---|
| 636 |   return SYNCHELP_READ_N; | 
|---|
| 637 | } | 
|---|
| 638 |  | 
|---|
| 639 |  | 
|---|
| 640 |  | 
|---|
| 641 | int SpaceShip::readBytes( byte * data, int maxLength, int * reciever ) | 
|---|
| 642 | { | 
|---|
| 643 |   SYNCHELP_WRITE_BEGIN(); | 
|---|
| 644 |  | 
|---|
| 645 |   if ( isOutOfSync() && !requestedSync() /*&& this->getHostID()!=this->getOwner()*/ ) | 
|---|
| 646 |   { | 
|---|
| 647 |     (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() ); | 
|---|
| 648 |     setRequestedSync( true ); | 
|---|
| 649 |     PRINTF(0)("REQUESTED STATE %d\n", this->getUniqueID()); | 
|---|
| 650 |   } | 
|---|
| 651 |  | 
|---|
| 652 |   int rec = this->getRequestSync(); | 
|---|
| 653 |   if ( rec > 0 ) | 
|---|
| 654 |   { | 
|---|
| 655 |     *reciever = rec; | 
|---|
| 656 |  | 
|---|
| 657 |     PRINTF(0)("SEND STATE %d %d\n", this->getUniqueID(), rec); | 
|---|
| 658 |  | 
|---|
| 659 |     SYNCHELP_WRITE_BYTE( (byte)DATA_state, NWT_SS_B ); | 
|---|
| 660 |  | 
|---|
| 661 |     SYNCHELP_WRITE_FKT( WorldEntity::readState, NWT_SS_WE_STATE ); | 
|---|
| 662 |  | 
|---|
| 663 |     return SYNCHELP_WRITE_N; | 
|---|
| 664 |   } | 
|---|
| 665 |  | 
|---|
| 666 |   *reciever = 0 - this->getOwner(); | 
|---|
| 667 |   //TODO: implement with SYNCHELP_WRITE_SENT() | 
|---|
| 668 |   bool sentSomething = false; | 
|---|
| 669 |  | 
|---|
| 670 |   if ( PNode::needsReadSync() && ( this->getHostID()==0 || this->getOwner() == this->getHostID() ) ) | 
|---|
| 671 |   { | 
|---|
| 672 |     PRINTF(0)("sending PNode::readSync\n"); | 
|---|
| 673 |     SYNCHELP_WRITE_BYTE( DATA_sync, NWT_SS_B ); | 
|---|
| 674 |     SYNCHELP_WRITE_FKT( PNode::readSync, NWT_SS_PN_SYNC ); | 
|---|
| 675 |     sentSomething = true; | 
|---|
| 676 |   } | 
|---|
| 677 |  | 
|---|
| 678 |   if ( this->getHostID()==0 || this->getHostID()==this->getOwner() ) | 
|---|
| 679 |   { | 
|---|
| 680 |     byte mask = 0; | 
|---|
| 681 |  | 
|---|
| 682 |     if ( bUp ) | 
|---|
| 683 |       mask |= MASK_bUp; | 
|---|
| 684 |     if ( bDown ) | 
|---|
| 685 |       mask |= MASK_bDown; | 
|---|
| 686 |     if ( bLeft ) | 
|---|
| 687 |       mask |= MASK_bLeft; | 
|---|
| 688 |     if ( bRight ) | 
|---|
| 689 |       mask |= MASK_bRight; | 
|---|
| 690 |     if ( bAscend ) | 
|---|
| 691 |       mask |= MASK_bAscend; | 
|---|
| 692 |     if ( bRollL ) | 
|---|
| 693 |       mask |= MASK_bRollL; | 
|---|
| 694 |     if ( bRollR ) | 
|---|
| 695 |       mask |= MASK_bRollR; | 
|---|
| 696 |  | 
|---|
| 697 |  | 
|---|
| 698 |     if ( mask != oldMask ) | 
|---|
| 699 |     { | 
|---|
| 700 |       oldMask = mask; | 
|---|
| 701 |       PRINTF(0)("sending mask\n"); | 
|---|
| 702 |       sentSomething = true; | 
|---|
| 703 |       SYNCHELP_WRITE_BYTE( DATA_flags, NWT_SS_B ); | 
|---|
| 704 |       SYNCHELP_WRITE_BYTE( mask, NWT_SS_FLAGS ); | 
|---|
| 705 |     } | 
|---|
| 706 | #define __OFFSET_MDIR_W 0.01 | 
|---|
| 707 | #define __OFFSET_MDIR_V 0.01 | 
|---|
| 708 |     if ( fabs( oldMouseDir.w - mouseDir.w ) > __OFFSET_MDIR_W || | 
|---|
| 709 |          fabs( oldMouseDir.v.x - mouseDir.v.x ) > __OFFSET_MDIR_V || | 
|---|
| 710 |          fabs( oldMouseDir.v.y - mouseDir.v.y ) > __OFFSET_MDIR_V || | 
|---|
| 711 |          fabs( oldMouseDir.v.z - mouseDir.v.z ) > __OFFSET_MDIR_V ) | 
|---|
| 712 |     { | 
|---|
| 713 |       oldMouseDir = mouseDir; | 
|---|
| 714 |  | 
|---|
| 715 |       SYNCHELP_WRITE_BYTE( DATA_mouse, NWT_SS_B ); | 
|---|
| 716 |       PRINTF(0)("SENDING mousedir\n"); | 
|---|
| 717 |       sentSomething = true; | 
|---|
| 718 |       SYNCHELP_WRITE_FLOAT( mouseDir.w, NWT_SS_MOUSEDIRW ); | 
|---|
| 719 |       SYNCHELP_WRITE_FLOAT( mouseDir.v.x, NWT_SS_MOUSEDIRX ); | 
|---|
| 720 |       SYNCHELP_WRITE_FLOAT( mouseDir.v.y, NWT_SS_MOUSEDIRY ); | 
|---|
| 721 |       SYNCHELP_WRITE_FLOAT( mouseDir.v.z, NWT_SS_MOUSEDIRZ ); | 
|---|
| 722 |     } | 
|---|
| 723 | #define __OFFSET_VEL 0.05 | 
|---|
| 724 |     if ( fabs( oldVelocity.x - velocity.x ) > __OFFSET_VEL*fabs(oldVelocity.x)+0.1 || | 
|---|
| 725 |          fabs( oldVelocity.y - velocity.y ) > __OFFSET_VEL*fabs(oldVelocity.y)+0.1 || | 
|---|
| 726 |          fabs( oldVelocity.z - velocity.z ) > __OFFSET_VEL*fabs(oldVelocity.z)+0.1 ) | 
|---|
| 727 |     { | 
|---|
| 728 |       oldVelocity.x = velocity.x; | 
|---|
| 729 |       oldVelocity.y = velocity.y; | 
|---|
| 730 |       oldVelocity.z = velocity.z; | 
|---|
| 731 |       PRINTF(0)("SENDING velocity\n"); | 
|---|
| 732 |       sentSomething = true; | 
|---|
| 733 |       SYNCHELP_WRITE_BYTE( DATA_velocity, NWT_SS_B ); | 
|---|
| 734 |       SYNCHELP_WRITE_FLOAT( velocity.x, NWT_SS_VELX ); | 
|---|
| 735 |       SYNCHELP_WRITE_FLOAT( velocity.y, NWT_SS_VELY ); | 
|---|
| 736 |       SYNCHELP_WRITE_FLOAT( velocity.z, NWT_SS_VELZ ); | 
|---|
| 737 |     } | 
|---|
| 738 |  | 
|---|
| 739 |     while ( Playable::needsReadSync() ) | 
|---|
| 740 |     { | 
|---|
| 741 |       sentSomething = true; | 
|---|
| 742 |       PRINTF(0)("SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC )\n"); | 
|---|
| 743 |       SYNCHELP_WRITE_BYTE( DATA_playables, NWT_SS_B ); | 
|---|
| 744 |       SYNCHELP_WRITE_FKT( Playable::readSync, NWT_SS_PL_SYNC ); | 
|---|
| 745 |     } | 
|---|
| 746 |  | 
|---|
| 747 |   } | 
|---|
| 748 |  | 
|---|
| 749 |   if ( !sentSomething ) | 
|---|
| 750 |   { | 
|---|
| 751 |     *reciever = 0; | 
|---|
| 752 |  | 
|---|
| 753 |     if ( networkCollisionList.size()>0 ) | 
|---|
| 754 |     { | 
|---|
| 755 |       SYNCHELP_WRITE_BYTE( DATA_collision, NWT_SS_B ); | 
|---|
| 756 |  | 
|---|
| 757 |       SYNCHELP_WRITE_INT( networkCollisionList.size(), NWT_SS_CO_N ); | 
|---|
| 758 |  | 
|---|
| 759 |       for ( std::list<float>::iterator it = networkCollisionList.begin(); it!=networkCollisionList.end(); it++ ) | 
|---|
| 760 |       { | 
|---|
| 761 |         SYNCHELP_WRITE_FLOAT( *it, NWT_SS_CO_CLID ); | 
|---|
| 762 |       } | 
|---|
| 763 |  | 
|---|
| 764 |       networkCollisionList.clear(); | 
|---|
| 765 |     } | 
|---|
| 766 |   } | 
|---|
| 767 |  | 
|---|
| 768 |   return SYNCHELP_WRITE_N; | 
|---|
| 769 | } | 
|---|
| 770 |  | 
|---|
| 771 |  | 
|---|
| 772 | void SpaceShip::doCollideNetwork( float energy ) | 
|---|
| 773 | { | 
|---|
| 774 |   this->decreaseHealth( energy ); | 
|---|
| 775 |   if( this->getHealth() <= 0) | 
|---|
| 776 |   { | 
|---|
| 777 |     this->die(); | 
|---|
| 778 |   } | 
|---|
| 779 | } | 
|---|
| 780 |  | 
|---|
| 781 |  | 
|---|
| 782 |  | 
|---|