/* 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: Thomas Fahrni co-programmer: */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_AI #include "attack_module.h" #include "ai_engine.h" #include "state.h" #include "debug.h" #include "player.h" #include "playable.h" #include "npcs/npc_test.h" #include "weapons/weapon.h" #include "projectiles/projectile.h" #include "shell_command.h" SHELL_COMMAND(setDistanceToPlayer, AttackModule, setDistanceToPlayer); SHELL_COMMAND(setDistanceToNPC, AttackModule, setDistanceToNPC); SHELL_COMMAND(setMaxAccleartion, AttackModule, setMaxAccleartion); SHELL_COMMAND(setTestValue, AttackModule, setTestValue); SHELL_COMMAND(setTestValue2, AttackModule, setTestValue2); float AttackModule::distanceToPlayer=15; float AttackModule::distanceToNPC=2; float AttackModule::maxAccleration=300.0f; float AttackModule::testValue=2; float AttackModule::testValue2=40; void AttackModule::setDistanceToPlayer(float newValue){ distanceToPlayer=newValue; } void AttackModule::setDistanceToNPC(float newValue){ distanceToNPC=newValue; } void AttackModule::setMaxAccleartion(float newValue){ maxAccleration=newValue; } void AttackModule::setTestValue(float newValue){ testValue=newValue; } void AttackModule::setTestValue2(float newValue){ testValue2=newValue; } AttackModule::AttackModule() { tickCount=0; randomFreq=40; fireTimeout=1; } void AttackModule::process(float dt) { if(npc == NULL)return; Vector tmpVector; float tmpFloat; Vector npcCollision; Vector playerCollision; weight=1; //get information about player Player* pl = State::getPlayer(); if( pl == NULL)return; Vector playerPosition = pl->getPlayable()->getAbsCoor(); float playerRadius=getRadius( pl->getPlayable() ); //get information about myself Vector myPosition = npc->getAbsCoor(); float myRadius = getRadius(npc); //float vMax=1000.0f/myRadius; float vMax=maxSpeed; float aMax=1000/myRadius; //anti player collision Vector vectorToPlayer = playerPosition - myPosition; tmpFloat=vectorToPlayer.len()-playerRadius-myRadius-distanceToPlayer; if(tmpFloat<0.1)tmpFloat=0.1; playerCollision=vectorToPlayer/(tmpFloat*tmpFloat)*(-1); //anti NPC collision for(ObjectList::const_iterator it = WorldEntity::objectList().begin(); it != WorldEntity::objectList().end(); ++it) { if((*it)->isA(Weapon::staticClassID()) )continue; if((*it)->isA(Projectile::staticClassID()) )continue; if(*it==npc)continue; tmpVector=myPosition-(*it)->getAbsCoor(); tmpFloat=tmpVector.len()-myRadius-distanceToNPC-getRadius(*it); if(tmpFloat<0.1)tmpFloat=0.1; tmpVector=tmpVector/(tmpFloat*tmpFloat); npcCollision=npcCollision+tmpVector; } //random movement //randomFreq=testValue2; if(++tickCount>=randomFreq){ tickCount=0; int x = (rand()%101)-50; //-50-50 int z = (rand()%101)-50; //-50-50 randomVector=Vector(x,0,z); randomFreq=(rand()%81)+70; //70-150 Ticks } //calculate correction vector Vector vectorToDestination=destination-myPosition; Vector correction= playerCollision*50*3 *6/myRadius + npcCollision*50*3 *6/myRadius + destinationMovement*2//-movement + (vectorToDestination-movement)*3 + (randomVector * testValue); correction.y=0; //limit accleration float correctionLen=correction.len(); if(correctionLen>maxAccleration*dt)correction=correction/correctionLen*maxAccleration*dt; movement+=correction; //limit speed float movementLen=movement.len(); if(movementLen>vMax)movement=movement/movementLen*vMax; //move NPC... npc->shiftCoor(movement * dt); //rotate NPC view = target->getAbsCoor()-myPosition; Vector randomView=view.cross(Vector(0,1,0)).getNormalized(); randomView=randomView*((rand()%4)-2); view = target->getAbsCoor()+randomView-myPosition; view = view.cross( Vector(0,1,0) ).getNormalized(); npc->setAbsDirSoft( Quaternion( view, Vector(0,1,0)),8/myRadius); if(npc->isA(NPC::staticClassID()) ){ fireTimeout-=dt; if(fireTimeout<=0){ fireTimeout=(rand()%21)/10+1; //std::cout << "Fiiiiirrreee!\n"; NPC* npc2 = static_cast(npc); npc2->fire(); } } }