/* 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 "movement_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, MovementModule, setDistanceToPlayer); SHELL_COMMAND(setDistanceToNPC, MovementModule, setDistanceToNPC); SHELL_COMMAND(setMaxAccleartion, MovementModule, setMaxAccleartion); SHELL_COMMAND(setTestValue, MovementModule, setTestValue); SHELL_COMMAND(setTestValue2, MovementModule, setTestValue2); float MovementModule::distanceToPlayer=15; float MovementModule::distanceToNPC=2; float MovementModule::maxAccleration=300.0f; float MovementModule::testValue=2; float MovementModule::testValue2=40; void MovementModule::setDistanceToPlayer(float newValue){ distanceToPlayer=newValue; } void MovementModule::setDistanceToNPC(float newValue){ distanceToNPC=newValue; } void MovementModule::setMaxAccleartion(float newValue){ maxAccleration=newValue; } void MovementModule::setTestValue(float newValue){ testValue=newValue; } void MovementModule::setTestValue2(float newValue){ testValue2=newValue; } MovementModule::MovementModule() { tickCount=0; randomFreq=100; } void MovementModule::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 aMax=maxAccleration; float vMax=800.0f/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==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; } //calculate correction vector Vector vectorToDestination=destination-myPosition; Vector correction= playerCollision*50*3 + npcCollision*50*3 + Vector(0,0,0) + destinationMovement*2//-movement + (vectorToDestination-movement)*3; correction.y=0; //limit accleration float correctionLen=correction.len(); if(correctionLen>aMax*dt)correction=correction/correctionLen*aMax*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 = movement.cross( Vector(0,1,0) ).getNormalized(); npc->setAbsDirSoft( Quaternion( view, Vector(0,1,0)),3); }