/* 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: Christoph Renner co-programmer: */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY #include "loading/factory.h" #include "debug.h" #include "loading/load_param.h" #include "util/loading/load_param_xml.h" #include "state.h" #include "player.h" #include "playable.h" #include "actionbox_enemy.h" ObjectListDefinition(ActionboxEnemy); CREATE_FACTORY(ActionboxEnemy); ActionboxEnemy::ActionboxEnemy(const TiXmlElement* root) { PRINTF(0)("ActionboxEnemy\n"); this->registerObject(this, ActionboxEnemy::_objectList); this->toList(OM_GROUP_00); this->isActive = true; this->pitch = 0.0f; this->dPitch = 0.0; this->maxSpeed = 10; this->acceleration = 3; this->speed = 0; if ( root ) this->loadParams( root ); } ActionboxEnemy::~ActionboxEnemy() { } void ActionboxEnemy::loadParams(const TiXmlElement* root) { WorldEntity::loadParams( root ); } void ActionboxEnemy::tick( float dt ) { myDir = this->getAbsDir(); myCoor = this->getAbsCoor(); this->pitch += this->dPitch*dt; while ( pitch > 2*PI ) pitch -= 2*PI; while ( pitch < 0 ) pitch += 2*PI; myDir *= qPitch.inverse(); qPitch = Quaternion( pitch, Vector( 1, 0, 0 ) ); moveTowardsBox( NULL, dt ); if ( isActive && State::getActionBox() ) { ActionBox* box = State::getActionBox(); if ( box->isPointInBox( this->getAbsCoor() ) ) { attackPlayer( box, dt ); } else { moveTowardsBox( box, dt ); } } myDir *= qPitch; this->setAbsDir( myDir ); this->setAbsCoor( myCoor ); } void ActionboxEnemy::attackPlayer( ActionBox * box, float dt ) { } void ActionboxEnemy::moveTowardsBox( ActionBox * box, float dt ) { //Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor(); static float time = 0; time += dt; Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor() + State::getPlayer()->getPlayable()->getAbsDir().apply(Vector(1, 0, 0))*50*(1.5 + sin(time/5)); Vector targetDir = targetPos - myCoor; Quaternion cur = myDir; Quaternion rx( dt, Vector( 0, 0, 1 ) ); Quaternion tmp1 = cur * rx; Quaternion tmp2 = cur * rx.inverse(); Quaternion dec; if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) ) dec = tmp1; else dec = tmp2; float dp = dec.apply( Vector(1, 0, 0) ).dot(Vector(0, 1, 0)); if ( dp > -0.9 && dp < 0.9 ) { cur = dec; } Quaternion ry( dt, cur.inverse().apply( Vector( 0, 1, 0 ) ) ); tmp1 = cur * ry; tmp2 = cur * ry.inverse(); if ( tmp1.apply( Vector(1, 0, 0) ).dot(targetDir) > tmp2.apply( Vector(1, 0, 0)).dot(targetDir) ) cur = tmp1; else cur = tmp2; myDir = cur; Vector fw = cur.apply( Vector(1, 0, 0) ); this->speed += this->acceleration*dt; if ( this->speed > this->maxSpeed ) this->speed = this->maxSpeed; this->myCoor += fw*speed*dt; } void ActionboxEnemy::draw( ) const { #if 0 Vector fw = this->getAbsDir().apply( Vector( 1, 0, 0 ) ); fw.normalize(); fw = fw * 100; Vector mp = this->getAbsCoor(); Vector op = mp + fw; Vector targetPos = State::getPlayer()->getPlayable()->getAbsCoor(); Vector dv = targetPos - this->getAbsCoor(); dv.normalize(); dv *= 100; dv += mp; Vector spUp = this->getAbsDir().inverse().apply( this->getAbsDir().apply( Vector( 0, 1, 0 ) ) ); spUp.normalize(); spUp *= 100; spUp += mp; Vector up = fw.cross( dv ); up += mp; //PRINTF(0)("DEBUG\n"); //mp.debug(); //op.debug(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glLineWidth(2.0); glColor3f(1.0, 0.0, 0.0 ); glBegin(GL_LINE_STRIP); glVertex3f(mp.x, mp.y, mp.z); glVertex3f(op.x, op.y, op.z); glEnd(); glColor3f(0.0, 1.0, 0.0 ); glBegin(GL_LINE_STRIP); glVertex3f(mp.x, mp.y, mp.z); glVertex3f(dv.x, dv.y, dv.z); glEnd(); glColor3f(0.0, 0.0, 1.0 ); glBegin(GL_LINE_STRIP); glVertex3f(mp.x, mp.y, mp.z); glVertex3f(up.x, up.y, up.z); glEnd(); glColor3f(1.0, 1.0, 1.0 ); glBegin(GL_LINE_STRIP); glVertex3f(mp.x, mp.y, mp.z); glVertex3f(spUp.x, spUp.y, spUp.z); glEnd(); glPopMatrix(); #endif WorldEntity::draw(); }