/* 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: */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY #include "executor/executor.h" #include "md2_creature.h" #include "objModel.h" #include "md2/md2Model.h" #include "util/loading/resource_manager.h" #include "state.h" #include "weapons/weapon_manager.h" #include "weapons/test_gun.h" #include "weapons/turret.h" #include "weapons/cannon.h" #include "util/loading/factory.h" #include "key_mapper.h" #include "graphics_engine.h" #include "debug.h" CREATE_FACTORY(MD2Creature, CL_MD2_CREATURE); /** * destructs the MD2Creature, deletes alocated memory */ MD2Creature::~MD2Creature () { this->setPlayer(NULL); } /** * loads a MD2Creatures information from a specified file. * @param fileName the name of the File to load the MD2Creature from (absolute path) */ MD2Creature::MD2Creature(const std::string& fileName) { this->init(); TiXmlDocument doc(fileName); if(!doc.LoadFile()) { PRINTF(2)("Loading file %s failed for md2 creature.\n", fileName.c_str()); return; } this->loadParams(doc.RootElement()); } /** * creates a new MD2Creature from Xml Data * @param root the xml element containing MD2Creature data @todo add more parameters to load */ MD2Creature::MD2Creature(const TiXmlElement* root) { this->init(); if (root != NULL) this->loadParams(root); } /** * initializes a MD2Creature */ void MD2Creature::init() { PRINTF(4)("MD2CREATURE INIT\n"); // this->setRelDir(Quaternion(M_PI, Vector(1,0,0))); this->setClassID(CL_MD2_CREATURE, "MD2Creature"); this->toList(OM_GROUP_01); //weapons: Weapon* wpRight = new TestGun(0); wpRight->setName("testGun Right"); Weapon* wpLeft = new TestGun(1); wpLeft->setName("testGun Left"); Weapon* cannon = dynamic_cast(Factory::fabricate(CL_CANNON)); cannon->setName("BFG"); this->addWeapon(wpLeft, 1, 0); this->addWeapon(wpRight,1 ,1); this->getWeaponManager().changeWeaponConfig(0); // pnode camera issue this->cameraConnNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT); this->cameraConnNode.addNodeFlags(PNODE_PROHIBIT_CHILD_DELETE); this->cameraConnNode.setName("CameraConnectorNode"); this->addChild(&this->cameraConnNode); this->cameraConnNode.addChild(State::getCameraTargetNode()); this->cameraConnNode.addChild(State::getCameraNode()); State::getCameraTargetNode()->setRelCoor(10,0,0); // control initialisation this->mouseDirX *= Quaternion( M_PI * 0.75f, Vector(0,1,0)); bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bStrafeL = bStrafeR = bJump = false; bFire = false; xMouse = yMouse = 0; mouseSensitivity = 0.003; airViscosity = 0.0; cycle = 0.0; travelSpeed = 15.0; this->velocity = Vector(0.0,0.0,0.0); //add events to the eventlist //add events to the eventlist registerEvent(KeyMapper::PEV_FORWARD); registerEvent(KeyMapper::PEV_BACKWARD); registerEvent(KeyMapper::PEV_LEFT); registerEvent(KeyMapper::PEV_RIGHT); registerEvent(KeyMapper::PEV_UP); registerEvent(KeyMapper::PEV_DOWN); registerEvent(KeyMapper::PEV_FIRE1); registerEvent(KeyMapper::PEV_NEXT_WEAPON); registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON); registerEvent(EV_MOUSE_MOTION); this->registerEvent(SDLK_SPACE); this->getWeaponManager().setSlotCount(7); this->getWeaponManager().setSlotPosition(0, Vector(-0.5, .2, -1.9)); this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); this->getWeaponManager().setSlotPosition(1, Vector(-0.5, .2, 1.9)); this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5)); this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0))); this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5)); this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0))); this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5)); this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0))); this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5)); this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0))); // this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0)); this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL); // this->cameraConnNode.addChild(this->getWeaponManager().getFixedTarget()); dynamic_cast(this->getWeaponManager().getFixedTarget())->setVisibility( false); this->getWeaponManager().getFixedTarget()->setRelCoor(10,0,0); } /** * loads the Settings of a MD2Creature from an XML-element. * @param root the XML-element to load the MD2Creature's properties from */ void MD2Creature::loadParams(const TiXmlElement* root) { WorldEntity::loadParams(root); } void MD2Creature::enter() { dynamic_cast(this->getWeaponManager().getFixedTarget())->setVisibility( true); State::getCameraNode()->setParentSoft(&this->cameraConnNode); State::getCameraNode()->setRelCoorSoft(-10, 0,0); State::getCameraTargetNode()->setParentSoft(&this->cameraConnNode); } void MD2Creature::leave() { dynamic_cast(this->getWeaponManager().getFixedTarget())->setVisibility( false); this->detachCamera(); } /** * effect that occurs after the MD2Creature is spawned */ void MD2Creature::postSpawn () {} /** * the action occuring if the MD2Creature left the game */ void MD2Creature::leftWorld () {} /** * this function is called, when two entities collide * @param entity: the world entity with whom it collides * * Implement behaviour like damage application or other miscellaneous collision stuff in this function */ void MD2Creature::collidesWith(WorldEntity* entity, const Vector& location) { PRINTF(0)("Collided with the md2 model\n"); } /** * draws the MD2Creature after transforming it. */ void MD2Creature::draw () const { if (this->getCurrentPlayer() != NULL) WorldEntity::draw(); this->cameraConnNode.debugDraw(0); } /** * the function called for each passing timeSnap * @param time The timespan passed since last update */ void MD2Creature::tick (float time) { Playable::tick(time); if( likely(this->getModel(0) != NULL)) ((MD2Model*)this->getModel(0))->tick(time); // MD2Creature controlled movement this->calculateVelocity(time); Vector move = this->velocity * time; this->shiftCoor (move); // handle animations differently if( this->bJump && likely(this->getModel(0) != NULL)) { ((MD2Model*)this->getModel(0))->setAnimation(JUMP); } else if( this->bFire && likely(this->getModel(0) != NULL)) { if( ((MD2Model*)this->getModel(0))->getAnim() != ATTACK) ((MD2Model*)this->getModel(0))->setAnimation(ATTACK); } else if( fabs(move.len()) > 0.0f && likely(this->getModel(0) != NULL)) { if( ((MD2Model*)this->getModel(0))->getAnim() != RUN) ((MD2Model*)this->getModel(0))->setAnimation(RUN); } else if (likely(this->getModel(0) != NULL)) { if( ((MD2Model*)this->getModel(0))->getAnim() != STAND) ((MD2Model*)this->getModel(0))->setAnimation(STAND); } //orient the MD2Creature in direction of the mouse // this->setAbsDir(mouseDirX); // this->cameraConnNode.setRelDir(mouseDirY); this->setAbsDir(this->mouseDirX); } /** * calculate the velocity * @param time the timeslice since the last frame */ void MD2Creature::calculateVelocity (float time) { Vector accel(0.0, 0.0, 0.0); /* Vector rot(0.0, 0.0, 0.0); // wird benötigt für Helicopter */ //float rotVal = 0.0; /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */ /* calculate the direction in which the craft is heading */ if( bMouseMotion) { PRINTF(0)("motion\n"); this->mouseDirX *= Quaternion(-M_PI / 4.0f * this->xMouse*mouseSensitivity, Vector(0,1,0)); this->mouseDirY *= Quaternion(-M_PI / 4.0f * this->yMouse*mouseSensitivity, Vector(0,0,1)); this->bMouseMotion = false; } if( this->bUp ) { accel += (this->getAbsDirX())*2; } if( this->bDown ) { accel -= (this->getAbsDirX())*2; } if( this->bLeft/* > -this->getRelCoor().z*2*/) { this->shiftDir(Quaternion(time, Vector(0,1,0))); } if( this->bRight /* > this->getRelCoor().z*2*/) { this->shiftDir(Quaternion(-time, Vector(0,1,0))); } if( this->bStrafeL /* > -this->getRelCoor().z*2*/) { accel -= this->getAbsDirZ() * 2.0f; } if( this->bStrafeR /* > this->getRelCoor().z*2*/) { accel += this->getAbsDirZ() * 2.0f; } if (this->bAscend ) { this->shiftDir(Quaternion(time, Vector(0,0,1))); } if (this->bDescend ) { this->shiftDir(Quaternion(-time, Vector(0,0,1))); } velocity = accel * 20.0f; //rot.normalize(); //this->setRelDirSoft(Quaternion(rotVal, rot), 5); } /** * @todo switch statement ?? */ void MD2Creature::process(const Event &event) { Playable::process(event); if( event.type == KeyMapper::PEV_LEFT) this->bStrafeL = event.bPressed; else if( event.type == KeyMapper::PEV_RIGHT) this->bStrafeR = event.bPressed; else if( event.type == KeyMapper::PEV_FORWARD) this->bUp = event.bPressed; else if( event.type == KeyMapper::PEV_BACKWARD) this->bDown = event.bPressed; else if( event.type == SDLK_SPACE) this->bJump = event.bPressed; else if( event.type == EV_MOUSE_MOTION) { this->bMouseMotion = true; this->xMouse = event.xRel; this->yMouse = event.yRel; } }