/* 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 "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; } void AttackModule::process(float dt) { if(npc == NULL)return; Vector tmpVector; float tmpFloat; Vector npcCollision; Vector playerCollision; bool autoRotate=true; weight=1; speedMax=1000.0f; //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); //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==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 + npcCollision*50*3 + 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>speedMax)movement=movement/movementLen*speedMax; //move NPC... npc->shiftCoor(movement * dt); //rotate NPC view = target->getAbsCoor()-myPosition; view = view.cross( Vector(0,1,0) ).getNormalized(); npc->setAbsDirSoft( Quaternion( view, Vector(0,1,0)),1); }