Index: /branches/ai/src/ai/Makefile.am
===================================================================
--- /branches/ai/src/ai/Makefile.am	(revision 10243)
+++ /branches/ai/src/ai/Makefile.am	(revision 10244)
@@ -8,9 +8,11 @@
 			ai_module.cc \
 			ai_team.cc \
-			ai_swarm.cc \
 			ai_team_member.cc \
 			movement_module.cc \
 			shooting_module.cc \
-			attack_module.cc
+			attack_module.cc\
+			swarm_module.cc\
+			swarm_wait.cc\
+			swarm_gorel.cc
 
 noinst_HEADERS =        \
@@ -18,7 +20,9 @@
 			ai_module.h \
 			ai_team.h \
-			ai_swarm.h \
 			ai_team_member.h \
 			movement_module.h \
 			shooting_module.h \
-			attack_module.h
+			attack_module.h\
+			swarm_module.h\
+			swarm_wait.h\
+			swarm_gorel.h
Index: /branches/ai/src/ai/ai_engine.cc
===================================================================
--- /branches/ai/src/ai/ai_engine.cc	(revision 10243)
+++ /branches/ai/src/ai/ai_engine.cc	(revision 10244)
@@ -30,14 +30,13 @@
 	for (it=teams.begin(); it!= teams.end(); it++ )
 	{
-		//find enemys for the team
-		for(ObjectList<NPC2>::const_iterator npc = NPC2::objectList().begin(); npc != NPC2::objectList().end(); ++npc)
-			if((*npc)->getTeam() != it->first)enemyList->push_back(*npc);
-
 		//add player to enemys (player belongs to team 0)
 		if(it->first!=0){
-			//std::cout << "adding player to enemyList\n";
 			Player* pl = State::getPlayer();
 			if(pl != NULL)enemyList->push_back(pl->getPlayable());
 		}
+	
+		//find other enemys for this team
+		for(ObjectList<NPC2>::const_iterator npc = NPC2::objectList().begin(); npc != NPC2::objectList().end(); ++npc)
+			if((*npc)->getTeam() != it->first)enemyList->push_back(*npc);
 
 		//process the team
Index: /branches/ai/src/ai/ai_module.h
===================================================================
--- /branches/ai/src/ai/ai_module.h	(revision 10243)
+++ /branches/ai/src/ai/ai_module.h	(revision 10244)
@@ -7,5 +7,5 @@
 class AIModule {
  public:
-	AIModule(){}
+	inline AIModule(){taskComplete=false;}
    virtual ~AIModule(){}
    virtual void process(float dt){}
@@ -25,4 +25,7 @@
 	inline float getMaxAcceleration(){return accelerationMax;}
 	inline float getMaxSpeed(){return speedMax;}
+	inline float getNPCRadius(){return getRadius(npc);}
+
+	inline bool done(){return taskComplete;}
 
 	void getAttributesFrom(AIModule* oldModule);
@@ -35,5 +38,5 @@
 	Vector destinationView;
 
-
+	bool taskComplete;
 	Vector movement;
 	Vector view;
Index: /branches/ai/src/ai/ai_swarm.cc
===================================================================
--- /branches/ai/src/ai/ai_swarm.cc	(revision 10243)
+++ /branches/ai/src/ai/ai_swarm.cc	(revision 10244)
@@ -14,5 +14,5 @@
 */
 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_AI
-#include "ai_swarm.h"
+#include "swarm_gorel.h"
 #include "ai_module.h"
 #include "movement_module.h"
@@ -33,4 +33,7 @@
 	std::map<WorldEntity*,AIModule*>::iterator it;
 
+	if(enemys==NULL || enemys->size()<1)return;
+	target=enemys->at(0);
+	
 	Vector swarmPosition=this->getPosition();
 	Vector targetPosition=target->getAbsCoor();
@@ -78,5 +81,5 @@
 
 
-
+	destination=taskRelObject->getAbsCoor()+taskRelPos;
 	Vector correction=(destination+randomVector-swarmPosition)-movement;
 	correction.y=0;
@@ -100,48 +103,2 @@
 	}
 }
-
-
-
-void AISwarm::addAI(WorldEntity* npc)
-{
-	std::pair< std::map<WorldEntity*,AIModule*>::iterator , bool > p;
-	AIModule* newAIModule=new MovementModule(npc);
-	p=members.insert(std::make_pair(npc,newAIModule));
-	if(!p.second)delete newAIModule;
-}
-
-
-void AISwarm::removeAI(WorldEntity* npc)
-{
-	std::map<WorldEntity*,AIModule*>::iterator it = members.find(npc);
-	if(it==members.end())return; 		//npc not found
-	delete it->second; 					//delete AIModule
-	members.erase(it); 					//remove AIModule from members
-}
-
-
-Vector AISwarm::getPosition()
-{
-	Vector center=Vector(0,0,0);
-	std::map<WorldEntity*,AIModule*>::iterator it;
-	for (it= members.begin(); it!= members.end(); it++ )
-		center=center+it->second->getPosition();
-
-	return center/members.size();
-}
-
-float AISwarm::getRadius(WorldEntity* object)
-{
-	AABB* aabb = object->getModelAABB();
-	if( aabb == NULL)return -1;
-
-	float a = aabb->halfLength[0];
-	float b = aabb->halfLength[1];
-	float c = aabb->halfLength[2];
-
-	if(a>b){
-		return (c>a)?c:a;
-	}else{
-		return (c>b)?c:b;
-	}
-}
Index: /branches/ai/src/ai/ai_swarm.h
===================================================================
--- /branches/ai/src/ai/ai_swarm.h	(revision 10243)
+++ /branches/ai/src/ai/ai_swarm.h	(revision 10244)
@@ -5,32 +5,23 @@
 #include "world_entity.h"
 #include "ai_module.h"
+#include "swarm_module.h"
 
 
-
-class AISwarm{
+class AISwarm : public SwarmModule{
 	public:
 		AISwarm();
-		~AISwarm(){}
-		void process(float dt);
-		void addAI(WorldEntity*);
-		void removeAI(WorldEntity*);
+		virtual ~AISwarm(){}
+		virtual void process(float dt);
 
-		inline int getSwarmSize(){return members.size();}
 		inline void setDestination(Vector destination){this->destination=destination;}
 		inline void setTarget(WorldEntity* target){this->target=target;}
-		Vector getPosition();
 
 		enum statusType{ATTACKING,MOVING,WAITING};
 
 	private:
-		float getRadius(WorldEntity* object);
-
-
 		Vector destination;
 		Vector movement;
 		WorldEntity* target;
 		statusType status;
-
-		std::map<WorldEntity*,AIModule*> members;
 
 		int tickCount;
Index: /branches/ai/src/ai/ai_team.cc
===================================================================
--- /branches/ai/src/ai/ai_team.cc	(revision 10243)
+++ /branches/ai/src/ai/ai_team.cc	(revision 10244)
@@ -15,13 +15,25 @@
 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_AI
 #include "ai_team.h"
+#include "swarm_gorel.h"
+#include "swarm_module.h"
 #include "debug.h"
 
 void AITeam::process(float dt)
 {
-	std::map<int,AISwarm*>::iterator it;
+	std::map<int,SwarmModule*>::iterator it;
 	for (it= swarms.begin(); it!= swarms.end(); it++ ){
-		if(enemyList->size()>0){
-			it->second->setTarget(enemyList->at(0));
-			it->second->setDestination(enemyList->at(0)->getAbsCoor());
+	
+		if(it->second->taskDone()){
+			std::cout << "Task Done!\n";
+			changeSwarmModule(it, new SwarmGoRel);
+		
+			if(enemyList->size()>0){
+				it->second->setEnemyList(enemyList);
+				it->second->orderRelObject(enemyList->at(0));
+				it->second->orderRelPos(Vector(60,0,0));
+				it->second->orderSpeed(50);
+				it->second->orderView(Vector(0,0,1));
+				it->second->orderMaxTime(5);
+			}
 		}
 		it->second->process(dt);
@@ -29,9 +41,17 @@
 }
 
+void AITeam::changeSwarmModule(std::map<int,SwarmModule*>::iterator it,SwarmModule* newAI)
+{
+			SwarmModule* oldAI = it->second;
+			newAI->getAttributesFrom(oldAI);
+			it->second=newAI;
+			delete oldAI;
+}
+
 
 void AITeam::addAI(int swarmNumber, WorldEntity* npc)
 {
-	std::pair<std::map<int,AISwarm*>::iterator,bool> p;
-	AISwarm* newSwarm=new AISwarm();
+	std::pair<std::map<int,SwarmModule*>::iterator,bool> p;
+	SwarmModule* newSwarm=new SwarmGoRel();
 	p=swarms.insert(std::make_pair(swarmNumber,newSwarm));
 	if(!p.second)delete newSwarm;
@@ -42,5 +62,5 @@
 void AITeam::removeAI(int swarmNumber, WorldEntity* npc)
 {
-	std::map<int,AISwarm*>::iterator it = swarms.find(swarmNumber);
+	std::map<int,SwarmModule*>::iterator it = swarms.find(swarmNumber);
 	if(it==swarms.end())return;
 	it->second->removeAI(npc);
Index: /branches/ai/src/ai/ai_team.h
===================================================================
--- /branches/ai/src/ai/ai_team.h	(revision 10243)
+++ /branches/ai/src/ai/ai_team.h	(revision 10244)
@@ -3,5 +3,5 @@
 #define _AI_TEAM_H
 
-#include "ai_swarm.h"
+#include "swarm_module.h"
 
 class AITeam{
@@ -17,5 +17,6 @@
  private:
 	std::vector<WorldEntity*>* enemyList;
-	std::map<int,AISwarm*> swarms;
+	std::map<int,SwarmModule*> swarms;
+	void changeSwarmModule(std::map<int,SwarmModule*>::iterator it,SwarmModule* newAI);
 };
 
Index: /branches/ai/src/ai/attack_module.cc
===================================================================
--- /branches/ai/src/ai/attack_module.cc	(revision 10243)
+++ /branches/ai/src/ai/attack_module.cc	(revision 10244)
@@ -45,5 +45,5 @@
 {
 	tickCount=0;
-	randomFreq=60;
+	randomFreq=40;
 }
 
@@ -100,5 +100,5 @@
 	//random movement
 	//randomFreq=testValue2;
-	if(++tickCount>=randomFreq && movement.len()<60){
+	if(++tickCount>=randomFreq){
 		tickCount=0;
 		int x = (rand()%101)-50;			//-50-50
Index: /branches/ai/src/ai/movement_module.cc
===================================================================
--- /branches/ai/src/ai/movement_module.cc	(revision 10243)
+++ /branches/ai/src/ai/movement_module.cc	(revision 10244)
@@ -32,5 +32,5 @@
 float MovementModule::distanceToPlayer=15;
 float MovementModule::distanceToNPC=2;
-float MovementModule::maxAccleration=300.0f;
+float MovementModule::maxAccleration=250.0f;
 float MovementModule::testValue=2;
 float MovementModule::testValue2=40;
Index: /branches/ai/src/ai/swarm_gorel.cc
===================================================================
--- /branches/ai/src/ai/swarm_gorel.cc	(revision 10244)
+++ /branches/ai/src/ai/swarm_gorel.cc	(revision 10244)
@@ -0,0 +1,81 @@
+/*
+   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 "swarm_gorel.h"
+#include "ai_module.h"
+#include "movement_module.h"
+
+void SwarmGoRel::initialize()
+{
+	std::map<WorldEntity*,AIModule*>::iterator it;
+	
+	//calculate  movement parameters..
+	float averageRadius;
+	for (it=members.begin(); it!= members.end(); it++ ){
+		averageRadius+=it->second->getNPCRadius();
+	}
+	averageRadius=averageRadius/members.size();
+	aMax=1000/averageRadius;
+	vMax=1000/averageRadius;
+	
+	//load correct ai-module..
+	for (it= members.begin(); it!= members.end(); it++ ){
+		changeAIModule(it, new MovementModule());
+	}
+	
+}
+
+void SwarmGoRel::process(float dt)
+{
+	std::map<WorldEntity*,AIModule*>::iterator it;
+
+	Vector swarmPosition=this->getPosition();
+	Vector correction=Vector(0,0,0);
+	Vector destination;
+	
+	if(taskRelObject!=NULL && taskMaxTime>0){
+		destination=taskRelObject->getAbsCoor()+taskRelPos;
+		correction=(destination-swarmPosition)-view*speed;
+		correction.y=0;
+		taskMaxTime-=dt;
+	}else{
+		taskComplete=true;
+	}
+	
+	float correctionLen=correction.len();
+	if(correctionLen>aMax*dt)correction=correction/correctionLen*aMax*dt;
+
+	//std::cout << angleRad(correction,movement) << "\n";
+	Vector movement=view*speed+correction;
+
+	float movementLen=movement.len();
+	if(movementLen>vMax)movement=movement/movementLen*vMax;
+	
+	speed=movement.len();
+	view=movement.getNormalized();
+
+	//tell orders to swarm-members...
+	for (it= members.begin(); it!= members.end(); it++ ){
+		it->second->setDestination(swarmPosition);
+		it->second->setDestinationMovement(movement);
+		it->second->process(dt);
+	}
+	
+	//check if destination reached
+	if(!taskComplete){
+		swarmPosition=this->getPosition();
+		if((destination-swarmPosition).len()<10)taskComplete=true;
+	}
+}
Index: /branches/ai/src/ai/swarm_gorel.h
===================================================================
--- /branches/ai/src/ai/swarm_gorel.h	(revision 10244)
+++ /branches/ai/src/ai/swarm_gorel.h	(revision 10244)
@@ -0,0 +1,21 @@
+
+#ifndef _SWARM_GOREL_H
+#define _SWARM_GOREL_H
+
+#include "swarm_module.h"
+
+
+
+class SwarmGoRel : public SwarmModule{
+	public:
+		SwarmGoRel(){}
+		virtual ~SwarmGoRel(){}
+		virtual void process(float dt);
+		virtual void initialize();
+		
+	private:
+		float vMax;
+		float aMax;
+};
+
+#endif /* _SWARM_GOREL_H */
Index: /branches/ai/src/ai/swarm_module.cc
===================================================================
--- /branches/ai/src/ai/swarm_module.cc	(revision 10244)
+++ /branches/ai/src/ai/swarm_module.cc	(revision 10244)
@@ -0,0 +1,88 @@
+/*
+   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 "ai_swarm.h"
+#include "ai_module.h"
+#include "movement_module.h"
+#include "swarm_module.h"
+#include "debug.h"
+#include <stdio.h>
+#include "aabb.h"
+
+
+
+void SwarmModule::addAI(WorldEntity* npc)
+{
+	std::pair< std::map<WorldEntity*,AIModule*>::iterator , bool > p;
+	AIModule* newAIModule=new MovementModule(npc);
+	p=members.insert(std::make_pair(npc,newAIModule));
+	if(!p.second)delete newAIModule;
+	
+	this->initialize();
+}
+
+void SwarmModule::removeAI(WorldEntity* npc)
+{
+	std::map<WorldEntity*,AIModule*>::iterator it = members.find(npc);
+	if(it==members.end())return; 		//npc not found
+	delete it->second; 					//delete AIModule
+	members.erase(it); 					//remove AIModule from members
+	
+	this->initialize();
+}
+
+Vector SwarmModule::getPosition()
+{
+	Vector center=Vector(0,0,0);
+	std::map<WorldEntity*,AIModule*>::iterator it;
+	for (it= members.begin(); it!= members.end(); it++ )
+		center=center+it->second->getPosition();
+
+	return center/members.size();
+}
+
+float SwarmModule::getRadius(WorldEntity* object)
+{
+	AABB* aabb = object->getModelAABB();
+	if( aabb == NULL)return -1;
+
+	float a = aabb->halfLength[0];
+	float b = aabb->halfLength[1];
+	float c = aabb->halfLength[2];
+
+	if(a>b){
+		return (c>a)?c:a;
+	}else{
+		return (c>b)?c:b;
+	}
+}
+
+void SwarmModule::getAttributesFrom(SwarmModule* other)
+{
+	this->members=other->getMembers();
+	this->speed=other->getSpeed();
+	this->view=other->getView();
+	this->enemys=other->getEnemyList();
+	
+	this->initialize();
+}
+
+void SwarmModule::changeAIModule(std::map<WorldEntity*,AIModule*>::iterator it,AIModule* newAI)
+{
+		AIModule* oldAI = it->second;
+		newAI->getAttributesFrom(oldAI);
+		it->second=newAI;
+		delete oldAI;
+}
Index: /branches/ai/src/ai/swarm_module.h
===================================================================
--- /branches/ai/src/ai/swarm_module.h	(revision 10244)
+++ /branches/ai/src/ai/swarm_module.h	(revision 10244)
@@ -0,0 +1,54 @@
+
+#ifndef _SWARM_MODULE_H
+#define _SWARM_MODULE_H
+#include "world_entity.h"
+#include "ai_module.h"
+
+class SwarmModule {
+ public:
+	inline SwarmModule(){taskComplete=false;}
+	virtual ~SwarmModule(){}
+	virtual void process(float dt){}
+	
+	void addAI(WorldEntity*);
+	void removeAI(WorldEntity*);
+	void getAttributesFrom(SwarmModule* oldModule);
+	virtual void initialize(){}
+	inline bool taskDone(){return taskComplete;}
+	
+	inline void setEnemyList(std::vector<WorldEntity*>* enemys){this->enemys=enemys;}	
+	
+	inline void orderRelPos(Vector taskRelPos){this->taskRelPos=taskRelPos;}
+	inline void orderAbsPos(Vector taskAbsPos){this->taskAbsPos=taskAbsPos;}
+	inline void orderView(Vector taskView){this->taskView=taskView;}
+	inline void orderSpeed(float taskSpeed){this->taskSpeed=taskSpeed;}
+	inline void orderRelObject(WorldEntity* taskRelObject){this->taskRelObject=taskRelObject;}
+	inline void orderMaxTime(float taskMaxTime){this->taskMaxTime=taskMaxTime;}
+
+	Vector getPosition();
+	inline float getSpeed(){return speed;}
+	inline Vector getView(){return view;}
+	inline int getSwarmSize(){return members.size();}
+	inline std::vector<WorldEntity*>* getEnemyList(){return enemys;}
+	inline std::map<WorldEntity*,AIModule*> getMembers(){return members;}
+	
+ protected:
+	float getRadius(WorldEntity* object);
+	void changeAIModule(std::map<WorldEntity*,AIModule*>::iterator it,AIModule* newAI);
+	Vector taskRelPos;
+	Vector taskAbsPos;
+	Vector taskView;
+	float taskSpeed;
+	WorldEntity* taskRelObject;
+	bool taskComplete;
+	float taskMaxTime;
+	
+	Vector view;
+	float speed;
+	
+	std::map<WorldEntity*,AIModule*> members;	
+	std::vector<WorldEntity*>* enemys;
+};
+
+
+#endif /* _SWARM_MODULE_H */
Index: /branches/ai/src/ai/swarm_wait.cc
===================================================================
--- /branches/ai/src/ai/swarm_wait.cc	(revision 10244)
+++ /branches/ai/src/ai/swarm_wait.cc	(revision 10244)
@@ -0,0 +1,23 @@
+/*
+   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 "swarm_wait.h"
+
+
+void SwarmWait::process(float dt)
+{
+	taskMaxTime-=dt;
+	if(taskMaxTime<=0)taskComplete=true;
+}
Index: /branches/ai/src/ai/swarm_wait.h
===================================================================
--- /branches/ai/src/ai/swarm_wait.h	(revision 10244)
+++ /branches/ai/src/ai/swarm_wait.h	(revision 10244)
@@ -0,0 +1,15 @@
+
+#ifndef _SWARM_WAIT_H
+#define _SWARM_WAIT_H
+
+#include "swarm_module.h"
+
+
+class SwarmWait : public SwarmModule{
+	public:
+		SwarmWait();
+		virtual ~SwarmWait(){}
+		virtual void process(float dt);
+};
+
+#endif /* _SWARM_WAIT_H */
