Index: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	(revision 10374)
+++ trunk/src/Makefile.am	(revision 10376)
@@ -25,4 +25,5 @@
 orxonox_LDADD = \
 		world_entities/libORXwe.a \
+		ai/libORXai.a \
 		util/libORXutils.a \
 		$(libORXlibs_a_LIBRARIES_) \
@@ -81,4 +82,5 @@
 		lib \
 		util \
+		ai \
 		world_entities \
 		. \
Index: trunk/src/ai/Makefile.am
===================================================================
--- trunk/src/ai/Makefile.am	(revision 10376)
+++ trunk/src/ai/Makefile.am	(revision 10376)
@@ -0,0 +1,30 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXai.a
+
+libORXai_a_SOURCES = \
+			ai_engine.cc \
+			ai_module.cc \
+			ai_team.cc \
+			ai_team_member.cc \
+			movement_module.cc \
+			shooting_module.cc \
+			attack_module.cc\
+			swarm_module.cc\
+			swarm_wait.cc\
+			swarm_gorel.cc\
+			swarm_attack.cc
+
+noinst_HEADERS =        \
+			ai_engine.h \
+			ai_module.h \
+			ai_team.h \
+			ai_team_member.h \
+			movement_module.h \
+			shooting_module.h \
+			attack_module.h\
+			swarm_module.h\
+			swarm_wait.h\
+			swarm_gorel.h\
+			swarm_attack.h
Index: trunk/src/ai/ai_engine.cc
===================================================================
--- trunk/src/ai/ai_engine.cc	(revision 10376)
+++ trunk/src/ai/ai_engine.cc	(revision 10376)
@@ -0,0 +1,71 @@
+/*
+   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_engine.h"
+#include "debug.h"
+#include "npcs/npc_test.h"
+#include "player.h"
+#include "playable.h"
+#include "state.h"
+
+AIEngine* AIEngine::singletonRef = NULL;
+
+void AIEngine::tick(float dt)
+{
+	std::map<int,AITeam*>::iterator it;
+	std::vector<WorldEntity*>* enemyList=new std::vector<WorldEntity*>;
+
+	for (it=teams.begin(); it!= teams.end(); it++ )
+	{
+		//add player to enemys (player belongs to team 0)
+		if(it->first!=0){
+			Player* pl = State::getPlayer();
+			if( pl!=NULL && pl->getPlayable()!=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
+		it->second->setEnemyList(enemyList);
+		it->second->process(dt);
+		enemyList->clear();
+	}
+
+	delete enemyList;
+}
+
+void AIEngine::addAI(int teamNumber, int swarmNumber, WorldEntity* npc, float maxSpeed, float attackDistance)
+{
+	std::pair<std::map<int,AITeam*>::iterator,bool> p;
+	AITeam* newTeam=new AITeam();
+	p=teams.insert(std::make_pair(teamNumber,newTeam));
+	if(!p.second)delete newTeam;
+	p.first->second->addAI(swarmNumber, npc, maxSpeed, attackDistance);
+}
+
+void AIEngine::removeAI(int teamNumber, int swarmNumber, WorldEntity* npc)
+{
+	std::map<int,AITeam*>::iterator it = teams.find(teamNumber);
+	if(it==teams.end())return;
+	it->second->removeAI(swarmNumber,npc);
+	if(it->second->getTeamSize()==0){
+		delete it->second;
+		teams.erase(it);
+	}
+}
+
Index: trunk/src/ai/ai_engine.h
===================================================================
--- trunk/src/ai/ai_engine.h	(revision 10376)
+++ trunk/src/ai/ai_engine.h	(revision 10376)
@@ -0,0 +1,25 @@
+
+#ifndef _AI_ENGINE_H
+#define _AI_ENGINE_H
+
+
+#include "ai_team.h"
+
+
+class AIEngine{
+ public:
+	~AIEngine(){}
+
+   static AIEngine* getInstance() { if( singletonRef == NULL) singletonRef = new AIEngine(); return singletonRef; }
+
+   void tick(float dt);
+	void addAI(int teamNumber, int swarmNumber, WorldEntity* npc, float maxSpeed, float attackDistance);
+	void removeAI(int teamNumber, int swarmNumber, WorldEntity* npc);
+
+ private:
+	AIEngine(){}
+	static AIEngine* singletonRef;
+	std::map<int,AITeam*> teams;
+};
+
+#endif /* _AI_ENGINE_H */
Index: trunk/src/ai/ai_module.cc
===================================================================
--- trunk/src/ai/ai_module.cc	(revision 10376)
+++ trunk/src/ai/ai_module.cc	(revision 10376)
@@ -0,0 +1,48 @@
+
+
+/*
+   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_module.h"
+#include "debug.h"
+#include "aabb.h"
+
+float AIModule::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 AIModule::getAttributesFrom(AIModule* other)
+{
+	this->view = other->getView();
+	this->movement = other->getMovement();
+	this->npc = other->getNPC();
+	this->target = other->getTarget();
+	this->weight = other->getWeight();
+	this->maxSpeed = other->getMaxSpeed();
+	this->attackDistance = other->getAttackDistance();
+	this->accelerationMax = other->getMaxAcceleration();
+}
Index: trunk/src/ai/ai_module.h
===================================================================
--- trunk/src/ai/ai_module.h	(revision 10376)
+++ trunk/src/ai/ai_module.h	(revision 10376)
@@ -0,0 +1,56 @@
+
+#ifndef _AI_MODULE_H
+#define _AI_MODULE_H
+#include "world_entity.h"
+class NPC2;
+
+class AIModule {
+ public:
+	inline AIModule(){taskComplete=false;}
+   virtual ~AIModule(){}
+   virtual void process(float dt){}
+
+	inline void setDestination(Vector destination){this->destination=destination;}
+	inline void setDestinationMovement(Vector destinationMovement){this->destinationMovement=destinationMovement;}
+	inline void setWeight(int weight){this->weight=weight;}
+	inline void setTarget(WorldEntity* target){this->target=target;}
+	inline void setNPC(WorldEntity* npc){this->npc=npc;}
+	inline void setMaxSpeed(float maxSpeed){this->maxSpeed=maxSpeed;}
+	inline void setAttackDistance(float attackDistance){this->attackDistance=attackDistance;}
+
+	inline Vector getPosition(){return npc->getAbsCoor();}
+	inline Vector getMovement(){return movement;}
+	inline Vector getView(){return view;}
+	inline WorldEntity* getNPC(){return npc;}
+	inline WorldEntity* getTarget(){return target;}
+	inline float getWeight(){return weight;}
+	inline float getMaxAcceleration(){return accelerationMax;}
+	inline float getMaxSpeed(){return maxSpeed;}
+	inline float getAttackDistance(){return attackDistance;}
+	inline float getNPCRadius(){return getRadius(npc);}
+
+	inline bool done(){return taskComplete;}
+
+	void getAttributesFrom(AIModule* oldModule);
+
+ protected:
+	float getRadius(WorldEntity* object);
+
+	Vector destination;
+	Vector destinationMovement;
+	Vector destinationView;
+
+	bool taskComplete;
+	Vector movement;
+	Vector view;
+
+	WorldEntity* npc;
+	WorldEntity* target;
+
+	float weight;
+	float maxSpeed;
+	float attackDistance;
+	float accelerationMax;
+};
+
+#endif /* _AI_MODULE_H */
Index: trunk/src/ai/ai_swarm.cc
===================================================================
--- trunk/src/ai/ai_swarm.cc	(revision 10376)
+++ trunk/src/ai/ai_swarm.cc	(revision 10376)
@@ -0,0 +1,104 @@
+/*
+   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"
+#include "attack_module.h"
+#include "debug.h"
+#include <stdio.h>
+#include "aabb.h"
+
+AISwarm::AISwarm()
+{
+	tickCount=0;
+	randomFreq=100;
+}
+
+
+void AISwarm::process(float dt)
+{
+	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();
+	float distanceToTarget=(swarmPosition-targetPosition).len();
+
+	float aMax=70.0f;
+	float vMax=1000.0f;
+	float deltaDistance=30;
+	float attackDistance=100;
+
+
+
+	if(distanceToTarget+deltaDistance<=attackDistance && status!=ATTACKING){
+		for (it= members.begin(); it!= members.end(); it++ ){
+			AIModule* oldAI = it->second;
+			AIModule* newAI = new AttackModule();
+			newAI->getAttributesFrom(oldAI);
+			it->second=newAI;
+			delete oldAI;
+			status=ATTACKING;
+		}
+	}else if(distanceToTarget-deltaDistance>=attackDistance && status!=MOVING){
+		for (it= members.begin(); it!= members.end(); it++ ){
+			AIModule* oldAI = it->second;
+			AIModule* newAI = new MovementModule();
+			newAI->getAttributesFrom(oldAI);
+			it->second=newAI;
+			delete oldAI;
+			status=MOVING;
+		}
+	}
+
+
+
+	if(status!=ATTACKING && tickCount>=randomFreq){
+		tickCount=0;
+		//int x = (rand()%141)+10;				//10-150
+		int x = (rand()%241)-120;			//-120-120
+		int z = (rand()%241)-120;			//-120-120
+		randomVector=Vector(x,0,z);
+
+		//std::cout << "change to: ||" << randomVector.x << "   ==" << randomVector.z << "\n";
+	}
+	tickCount++;
+
+
+	destination=taskRelObject->getAbsCoor()+taskRelPos;
+	Vector correction=(destination+randomVector-swarmPosition)-movement;
+	correction.y=0;
+
+	float correctionLen=correction.len();
+	if(correctionLen>aMax*dt)correction=correction/correctionLen*aMax*dt;
+
+	//std::cout << angleRad(correction,movement) << "\n";
+	movement+=correction;
+
+	float movementLen=movement.len();
+	if(movementLen>vMax)movement=movement/movementLen*vMax;
+
+
+
+	for (it= members.begin(); it!= members.end(); it++ ){
+		it->second->setDestination(swarmPosition);
+		it->second->setDestinationMovement(movement);
+		it->second->setTarget(target);
+		it->second->process(dt);
+	}
+}
Index: trunk/src/ai/ai_swarm.h
===================================================================
--- trunk/src/ai/ai_swarm.h	(revision 10376)
+++ trunk/src/ai/ai_swarm.h	(revision 10376)
@@ -0,0 +1,32 @@
+
+#ifndef _AI_SWARM_H
+#define _AI_SWARM_H
+
+#include "world_entity.h"
+#include "ai_module.h"
+#include "swarm_module.h"
+
+
+class AISwarm : public SwarmModule{
+	public:
+		AISwarm();
+		virtual ~AISwarm(){}
+		virtual void process(float dt);
+
+		inline void setDestination(Vector destination){this->destination=destination;}
+		inline void setTarget(WorldEntity* target){this->target=target;}
+
+		enum statusType{ATTACKING,MOVING,WAITING};
+
+	private:
+		Vector destination;
+		Vector movement;
+		WorldEntity* target;
+		statusType status;
+
+		int tickCount;
+		int randomFreq;
+		Vector randomVector;
+};
+
+#endif /* _AI_SWARM_H */
Index: trunk/src/ai/ai_team.cc
===================================================================
--- trunk/src/ai/ai_team.cc	(revision 10376)
+++ trunk/src/ai/ai_team.cc	(revision 10376)
@@ -0,0 +1,129 @@
+/*
+   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_team.h"
+#include "swarm_gorel.h"
+#include "swarm_module.h"
+#include "swarm_wait.h"
+#include "swarm_attack.h"
+#include "debug.h"
+#include "player.h"
+#include "playable.h"
+#include "state.h"
+
+void AITeam::process(float dt)
+{
+	std::map<int,SwarmModule*>::iterator it;
+	for (it= swarms.begin(); it!= swarms.end(); it++ ){
+
+		if(it->second->taskDone()){
+			//std::cout << "Swarm Task Complete!\n";
+
+			if(enemyList->size()==0){
+				changeSwarmModule(it, new SwarmWait);
+				it->second->orderMaxTime(2);	//sleep 2 seconds..
+				it->second->process(dt);
+				continue;
+			}
+
+			Vector position=it->second->getPosition();
+			Vector newPosition;
+			WorldEntity* target=enemyList->at(0);
+
+			//check if enemy is the player..
+			bool isPlayer=(State::getPlayer()->getPlayable()==target);
+			float speed;
+			float maxTime=10;
+
+
+			//find new Position
+			if(isPlayer){
+				float attackDistance=it->second->getAttackDistance();
+
+				Vector targetPos=target->getAbsCoor();
+				int zNorm=(position.z>targetPos.z)?1:-1;
+
+				if((position.z-targetPos.z)*zNorm>60){	//go to start position
+					//std::cout << "Go Start Position\n";
+					changeSwarmModule(it, new SwarmGoRel);
+					zNorm=1-(rand()%2)*2;	//1 or -1
+					newPosition=Vector(attackDistance+60,0,zNorm*10);
+					speed=60;
+				}else if(position.x > targetPos.x+attackDistance+40){	//go to attack position
+					//std::cout << "Go Attack Position\n";
+					changeSwarmModule(it, new SwarmGoRel);
+					newPosition=Vector(attackDistance+30,0,0);
+					speed=60;
+				}else if(position.x > targetPos.x+attackDistance+20){	//go to attack mode
+					//std::cout << "Go Attack Mode\n";
+					changeSwarmModule(it, new SwarmAttack);
+					newPosition=Vector(attackDistance,0,0);
+					speed=60;
+					maxTime=(rand()%11)+4;//4-14 Sekunden
+				}else{												//go to fallback point
+					//std::cout << "Go  Fallback Point\n";
+					changeSwarmModule(it, new SwarmGoRel);
+					newPosition=Vector(80,0,zNorm*90);
+					speed=80;
+				}
+			}else{
+
+			}
+
+			speed=0;
+
+			if(enemyList->size()>0){
+				it->second->setEnemyList(enemyList);
+				it->second->orderRelObject(target);
+				it->second->orderRelPos(newPosition);
+				it->second->orderSpeed(speed);
+				//it->second->orderView(Vector(0,0,1));
+				it->second->orderMaxTime(maxTime); //5-10
+				//it->second->newOrder();
+			}
+		}
+		it->second->process(dt);
+	}
+}
+
+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, float maxSpeed, float attackDistance)
+{
+	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;
+	p.first->second->addAI(npc, maxSpeed, attackDistance);
+}
+
+
+void AITeam::removeAI(int swarmNumber, WorldEntity* npc)
+{
+	std::map<int,SwarmModule*>::iterator it = swarms.find(swarmNumber);
+	if(it==swarms.end())return;
+	it->second->removeAI(npc);
+	if(it->second->getSwarmSize()==0){
+		delete it->second;
+		swarms.erase(it);
+	}
+}
Index: trunk/src/ai/ai_team.h
===================================================================
--- trunk/src/ai/ai_team.h	(revision 10376)
+++ trunk/src/ai/ai_team.h	(revision 10376)
@@ -0,0 +1,23 @@
+
+#ifndef _AI_TEAM_H
+#define _AI_TEAM_H
+
+#include "swarm_module.h"
+
+class AITeam{
+ public:
+	~AITeam(){}
+	AITeam(){}
+	std::vector<WorldEntity*>* getEnemyList();
+	void process(float dt);
+	void addAI(int swarmNumber, WorldEntity* npc, float maxSpeed, float attackDistance);
+	void removeAI(int swarmNumber, WorldEntity* npc);
+	inline int getTeamSize(){ return swarms.size(); }
+	inline void setEnemyList(std::vector<WorldEntity*>* enemyList){this->enemyList=enemyList;}
+ private:
+	std::vector<WorldEntity*>* enemyList;
+	std::map<int,SwarmModule*> swarms;
+	void changeSwarmModule(std::map<int,SwarmModule*>::iterator it,SwarmModule* newAI);
+};
+
+#endif /* _AI_TEAM_H */
Index: trunk/src/ai/ai_team_member.cc
===================================================================
--- trunk/src/ai/ai_team_member.cc	(revision 10376)
+++ trunk/src/ai/ai_team_member.cc	(revision 10376)
@@ -0,0 +1,57 @@
+/*
+   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_team_member.h"
+// #include "movement_module.h"
+// #include "ai_engine.h"
+// #include "debug.h"
+//
+//
+//
+// void AITeamMember::process()
+// {
+// 	int moduleCount=modules.size();
+// 	for(int i=0; i < moduleCount; i++ )
+// 	{
+//    	//std::cout << "Processing AIModule " << i << " (" << moduleCount << ")\n";
+//    	modules.at(i)->process();
+// 	}
+// }
+//
+//
+//
+//
+// void AITeamMember::addToTeam(int aiTeamNumber)
+// {
+// 	//macht nicht so ganz das was es eigntlich machen sollte..
+// 	AIEngine* aiEngine=AIEngine::getInstance();
+// 	int teamNumber=aiEngine->newTeam();
+// 	aiEngine->getTeam(teamNumber)->addMember(this);
+//
+// 	MovementModule* nMod=new MovementModule;
+// 	addModule(nMod);
+// 	//nMod->testModule=nMod;
+// }
+//
+//
+//
+//
+// void AITeamMember::addModule(AIModule* newModule)
+// {
+// 		std::cout << "AIModule added\n";
+// 		modules.push_back(newModule);
+// 		newModule->setOwner(this);
+// }
Index: trunk/src/ai/ai_team_member.h
===================================================================
--- trunk/src/ai/ai_team_member.h	(revision 10376)
+++ trunk/src/ai/ai_team_member.h	(revision 10376)
@@ -0,0 +1,31 @@
+
+#ifndef _AI_TEAM_MEMBER_H
+#define _AI_TEAM_MEMBER_H
+
+#include "world_entity.h"
+#include "ai_module.h"
+
+//class AIModule;
+
+class AITeamMember : public WorldEntity {
+//  public:
+// 	AITeamMember(){};
+// 	~AITeamMember(){};
+//
+//    void process();
+//    void addToTeam(int);
+//    void addModule(AIModule*);
+//
+// 	inline void setTeamNumber(int teamNumber){this->teamNumber=teamNumber;}
+// 	inline int getTeamNumber(){return this->teamNumber;}
+// 	inline void setSwarmNumber(int swarmNumber){this->swarmNumber=swarmNumber;}
+// 	inline int getSwarmNumber(){return this->swarmNumber;}
+//
+//  private:
+// 	 AIModule* aiModule;
+// 	 int teamNumber;
+// 	 int swarmNumber;
+// 	 int difficulty;
+};
+
+#endif /* _AI_TEAM_MEMBER_H */
Index: trunk/src/ai/attack_module.cc
===================================================================
--- trunk/src/ai/attack_module.cc	(revision 10376)
+++ trunk/src/ai/attack_module.cc	(revision 10376)
@@ -0,0 +1,165 @@
+/*
+   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<WorldEntity>::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*>(npc);
+			npc2->fire();
+		}
+	}
+}
+
+
Index: trunk/src/ai/attack_module.h
===================================================================
--- trunk/src/ai/attack_module.h	(revision 10376)
+++ trunk/src/ai/attack_module.h	(revision 10376)
@@ -0,0 +1,42 @@
+
+#ifndef _ATTACK_MODULE_H
+#define _ATTACK_MODULE_H
+
+#include "ai_module.h"
+#include "player.h"
+#include "playable.h"
+//#include "npcs/npc_test.h"
+class NPC2;
+
+
+class AttackModule : public AIModule{
+
+	public:
+		AttackModule();
+		virtual ~AttackModule(){}
+		virtual void process(float dt);
+
+		static void setDistanceToPlayer(float newValue);
+		static void setDistanceToNPC(float newValue);
+		static void setMaxAccleartion(float newValue);
+		static void setTestValue(float newValue);
+		static void setTestValue2(float newValue);
+
+	private:
+		Vector myATTACK;
+		float myMaxAccleration;
+		float myMaxSpeed;
+
+		static float maxAccleration;
+		static float distanceToPlayer;
+		static float distanceToNPC;
+		static float testValue;
+		static float testValue2;
+
+		int tickCount;
+		int randomFreq;
+		float fireTimeout;
+		Vector randomVector;
+};
+
+#endif /* _ATTACK_MODULE_H */
Index: trunk/src/ai/movement_module.cc
===================================================================
--- trunk/src/ai/movement_module.cc	(revision 10376)
+++ trunk/src/ai/movement_module.cc	(revision 10376)
@@ -0,0 +1,147 @@
+/*
+   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 "weapons/weapon.h"
+#include "projectiles/projectile.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=30;
+float MovementModule::distanceToNPC=2;
+float MovementModule::maxAccleration=250.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;
+}
+
+MovementModule::MovementModule(WorldEntity* object)
+{
+	this->npc=object;
+}
+
+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;
+	WorldEntity* playable = pl->getPlayable();
+	if( playable == 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=1000.0f/myRadius;
+	float vMax=maxSpeed;
+
+	//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<WorldEntity>::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;
+	}
+
+
+
+	//calculate correction vector
+	Vector vectorToDestination=destination-myPosition;
+
+	Vector correction=		playerCollision*50*3 *6/myRadius
+								+	npcCollision*50*3 *6/myRadius
+								+	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)),10/myRadius);
+
+}
+
+
Index: trunk/src/ai/movement_module.h
===================================================================
--- trunk/src/ai/movement_module.h	(revision 10376)
+++ trunk/src/ai/movement_module.h	(revision 10376)
@@ -0,0 +1,42 @@
+
+#ifndef _MOVEMENT_MODULE_H
+#define _MOVEMENT_MODULE_H
+
+#include "ai_module.h"
+#include "player.h"
+#include "playable.h"
+//#include "npcs/npc_test.h"
+class NPC2;
+
+
+class MovementModule : public AIModule{
+
+	public:
+		MovementModule();
+		MovementModule(WorldEntity* object);
+		virtual ~MovementModule(){}
+		virtual void process(float dt);
+
+		static void setDistanceToPlayer(float newValue);
+		static void setDistanceToNPC(float newValue);
+		static void setMaxAccleartion(float newValue);
+		static void setTestValue(float newValue);
+		static void setTestValue2(float newValue);
+
+	private:
+		Vector myMovement;
+		float myMaxAccleration;
+		float myMaxSpeed;
+
+		static float maxAccleration;
+		static float distanceToPlayer;
+		static float distanceToNPC;
+		static float testValue;
+		static float testValue2;
+
+		int tickCount;
+		int randomFreq;
+		Vector randomVector;
+};
+
+#endif /* _MOVEMENT_MODULE_H */
Index: trunk/src/ai/shooting_module.cc
===================================================================
--- trunk/src/ai/shooting_module.cc	(revision 10376)
+++ trunk/src/ai/shooting_module.cc	(revision 10376)
@@ -0,0 +1,36 @@
+
+
+/*
+   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 "debug.h"
+#include "shooting_module.h"
+
+
+ShootingModule::ShootingModule()
+{}
+
+
+ShootingModule::~ShootingModule()
+{}
+
+
+void ShootingModule::process()
+{
+	//std::cout << "Processing Shooting Module...\n";
+	return;
+}
+
+
Index: trunk/src/ai/shooting_module.h
===================================================================
--- trunk/src/ai/shooting_module.h	(revision 10376)
+++ trunk/src/ai/shooting_module.h	(revision 10376)
@@ -0,0 +1,15 @@
+
+#ifndef _SHOOTING_MODULE_H
+#define _SHOOTING_MODULE_H
+
+#include "ai_module.h"
+
+class ShootingModule : public AIModule{
+ public:
+   ShootingModule();
+   virtual ~ShootingModule();
+   virtual void process();
+ private:
+};
+
+#endif /* _SHOOTING_MODULE_H */
Index: trunk/src/ai/swarm_attack.cc
===================================================================
--- trunk/src/ai/swarm_attack.cc	(revision 10376)
+++ trunk/src/ai/swarm_attack.cc	(revision 10376)
@@ -0,0 +1,66 @@
+/*
+   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_attack.h"
+#include "ai_module.h"
+#include "attack_module.h"
+
+void SwarmAttack::initialize()
+{
+	std::map<WorldEntity*,AIModule*>::iterator it;
+
+	//load correct ai-module..
+	for (it= members.begin(); it!= members.end(); it++ ){
+		changeAIModule(it, new AttackModule());
+	}
+}
+
+void SwarmAttack::process(float dt)
+{
+	std::map<WorldEntity*,AIModule*>::iterator it;
+
+	Vector sideL=taskRelPos.cross(Vector(0,1,0)).getNormalized();
+	Vector sideR=sideL*-1;
+	Vector posL=Vector(0,0,0);
+	Vector posR=Vector(0,0,0);
+
+	//tell positions to swarm-members...
+	float radius;
+	Vector objectPos=taskRelObject->getAbsCoor();
+
+	for (it=members.begin(); it!= members.end(); it++ ){
+		radius=it->second->getNPCRadius();
+		posR=posR+sideR*radius*1.5;
+		it->second->setDestination(objectPos+taskRelPos+posR);
+		it->second->setDestinationMovement(Vector(0,0,0));
+		it->second->setTarget(taskRelObject);
+		it->second->process(dt);
+		posR=posR+sideR*radius*1.5;
+
+		it++;
+		if(it==members.end())break;
+		radius=it->second->getNPCRadius();
+		posL=posL+sideL*radius*1.5;
+		it->second->setDestination(objectPos+taskRelPos+posL);
+		it->second->setDestinationMovement(Vector(0,0,0));
+		it->second->setTarget(taskRelObject);
+		it->second->process(dt);
+		posL=posL+sideL*radius*1.5;
+	}
+
+	//check time..
+	taskMaxTime-=dt;
+	if(taskMaxTime<0)taskComplete=true;
+}
Index: trunk/src/ai/swarm_attack.h
===================================================================
--- trunk/src/ai/swarm_attack.h	(revision 10376)
+++ trunk/src/ai/swarm_attack.h	(revision 10376)
@@ -0,0 +1,17 @@
+
+#ifndef _SWARM_ATTACK_H
+#define _SWARM_ATTACK_H
+
+#include "swarm_module.h"
+
+
+
+class SwarmAttack : public SwarmModule{
+	public:
+		SwarmAttack(){}
+		virtual ~SwarmAttack(){}
+		virtual void process(float dt);
+		virtual void initialize();
+};
+
+#endif /* _SWARM_ATTACK_H */
Index: trunk/src/ai/swarm_gorel.cc
===================================================================
--- trunk/src/ai/swarm_gorel.cc	(revision 10376)
+++ trunk/src/ai/swarm_gorel.cc	(revision 10376)
@@ -0,0 +1,100 @@
+/*
+   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=80;//400/averageRadius;
+	vMax=maxSpeed;//1000/averageRadius;//300/averageRadius;
+	viewChangeMax=90/averageRadius;
+
+	//load correct ai-module..
+	for (it= members.begin(); it!= members.end(); it++ ){
+		changeAIModule(it, new MovementModule());
+	}
+
+	//get swarm position..
+	//position=this->getPosition();
+}
+
+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-position)-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;
+
+	float newSpeed=movement.len();
+	Vector newView=movement.getNormalized();
+
+	/*if((newSpeed<=taskSpeed && speed>=taskSpeed)||(newSpeed>=taskSpeed && speed<=taskSpeed)){
+		newSpeed=taskSpeed;
+	}else if((newSpeed>speed && speed<taskSpeed) || (newSpeed < speed && speed < taskSpeed)){
+		newSpeed=taskSpeed;
+	}*/
+
+	/*if(angleDeg(view,newView)>viewChangeMax){
+		std::cout << "alarm\n";
+	}*/
+	if(newSpeed<40)newSpeed=40;
+	if(newSpeed>vMax)newSpeed=vMax;
+
+	speed=newSpeed;
+	view=newView;
+	position=position+view*speed*dt;
+
+	//tell orders to swarm-members...
+	for (it= members.begin(); it!= members.end(); it++ ){
+		it->second->setDestination(position);
+		it->second->setDestinationMovement(view*speed);
+		it->second->process(dt);
+	}
+
+	//check if destination reached
+	if(!taskComplete){
+		//swarmPosition=this->getPosition();
+		if((destination-position).len()<10)taskComplete=true;
+	}
+}
Index: trunk/src/ai/swarm_gorel.h
===================================================================
--- trunk/src/ai/swarm_gorel.h	(revision 10376)
+++ trunk/src/ai/swarm_gorel.h	(revision 10376)
@@ -0,0 +1,22 @@
+
+#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;
+		float viewChangeMax;
+};
+
+#endif /* _SWARM_GOREL_H */
Index: trunk/src/ai/swarm_module.cc
===================================================================
--- trunk/src/ai/swarm_module.cc	(revision 10376)
+++ trunk/src/ai/swarm_module.cc	(revision 10376)
@@ -0,0 +1,95 @@
+/*
+   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, float maxSpeed, float attackDistance)
+{
+	std::pair< std::map<WorldEntity*,AIModule*>::iterator , bool > p;
+	AIModule* newAIModule=new MovementModule(npc);
+	newAIModule->setAttackDistance(attackDistance);
+	newAIModule->setMaxSpeed(maxSpeed);
+	this->attackDistance=attackDistance;
+	this->maxSpeed=maxSpeed;
+	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::getSwarmPosition()
+{
+	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->position=other->getPosition();
+	this->maxSpeed=other->getMaxSpeed();
+	this->attackDistance=other->getAttackDistance();
+
+	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: trunk/src/ai/swarm_module.h
===================================================================
--- trunk/src/ai/swarm_module.h	(revision 10376)
+++ trunk/src/ai/swarm_module.h	(revision 10376)
@@ -0,0 +1,62 @@
+
+#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*, float maxSpeed, float attackDistance);
+	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 newOrder(){this->taskComplete=false;}
+	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 getSwarmPosition();
+	inline Vector getPosition(){return position;}
+	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;}
+	inline float getMaxSpeed(){return maxSpeed;}
+	inline float getAttackDistance(){return attackDistance;}
+
+ 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;
+	Vector position;
+	float speed;
+
+	float maxSpeed;
+	float attackDistance;
+
+	std::map<WorldEntity*,AIModule*> members;
+	std::vector<WorldEntity*>* enemys;
+};
+
+
+#endif /* _SWARM_MODULE_H */
Index: trunk/src/ai/swarm_wait.cc
===================================================================
--- trunk/src/ai/swarm_wait.cc	(revision 10376)
+++ trunk/src/ai/swarm_wait.cc	(revision 10376)
@@ -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: trunk/src/ai/swarm_wait.h
===================================================================
--- trunk/src/ai/swarm_wait.h	(revision 10376)
+++ trunk/src/ai/swarm_wait.h	(revision 10376)
@@ -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 */
Index: trunk/src/defs/include_paths.am
===================================================================
--- trunk/src/defs/include_paths.am	(revision 10374)
+++ trunk/src/defs/include_paths.am	(revision 10376)
@@ -1,3 +1,4 @@
 AM_CXXFLAGS=-I$(MAINSRCDIR)
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/ai
 AM_CXXFLAGS+=-I$(MAINSRCDIR)/world_entities
 AM_CXXFLAGS+=-I$(MAINSRCDIR)/story_entities
Index: trunk/src/lib/math/vector.h
===================================================================
--- trunk/src/lib/math/vector.h	(revision 10374)
+++ trunk/src/lib/math/vector.h	(revision 10376)
@@ -124,5 +124,5 @@
  * @return the angle between the vectors in radians
 */
-inline float angleDeg (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())); };
+inline float angleRad (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())); };
 /**
  *  calculate the angle between two vectors in degrees
@@ -131,5 +131,5 @@
  * @return the angle between the vectors in degrees
 */
-inline float angleRad (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())) * 180/M_PI; };
+inline float angleDeg (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())) * 180/M_PI; };
 
 /** an easy way to create a Random Vector @param sideLength the length of the Vector (x not sqrt(x^2...)) */
Index: trunk/src/lib/util/debug.h
===================================================================
--- trunk/src/lib/util/debug.h	(revision 10374)
+++ trunk/src/lib/util/debug.h	(revision 10376)
@@ -82,4 +82,5 @@
   #define DEBUG_MODULE_GUI                   2
   #define DEBUG_MODULE_SOUND                 2
+  #define DEBUG_MODULE_AI                    2
 
   // MISC
Index: trunk/src/story_entities/game_world.cc
===================================================================
--- trunk/src/story_entities/game_world.cc	(revision 10374)
+++ trunk/src/story_entities/game_world.cc	(revision 10376)
@@ -55,4 +55,5 @@
 #include "ogg_player.h"
 #include "shader.h"
+#include "ai_engine.h"
 
 #include "animation_player.h"
@@ -337,4 +338,7 @@
     this->collisionReaction ();
 
+    /* perform ai check*/
+    this->checkAI();
+
     /* check the game rules */
     this->checkGameRules();
@@ -511,4 +515,12 @@
 
 
+
+void GameWorld::checkAI()
+{
+  AIEngine::getInstance()->tick(this->dtS);
+  //AIEngine::getInstance()->tick();
+}
+
+
 /**
  *  check the game rules: winning conditions, etc.
Index: trunk/src/story_entities/game_world.h
===================================================================
--- trunk/src/story_entities/game_world.h	(revision 10374)
+++ trunk/src/story_entities/game_world.h	(revision 10376)
@@ -74,4 +74,5 @@
   virtual void tick();
   virtual void update();
+  virtual void checkAI();
   virtual void checkGameRules();
   virtual void collisionDetection();
Index: trunk/src/world_entities/npcs/npc.cc
===================================================================
--- trunk/src/world_entities/npcs/npc.cc	(revision 10374)
+++ trunk/src/world_entities/npcs/npc.cc	(revision 10376)
@@ -18,26 +18,101 @@
 
 
+#include "movement_module.h"
+#include "ai_module.h"
+#include "ai_team.h"
+#include "ai_swarm.h"
+#include "ai_engine.h"
+
+#include "player.h"
+#include "playable.h"
+
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "loading/factory.h"
+#include "debug.h"
+#include "loading/load_param.h"
+
+
 #include "npc.h"
 
 ObjectListDefinition(NPC);
+CREATE_FACTORY(NPC);
+
 
 NPC::NPC(const TiXmlElement* root)
+  : weaponMan(this)
 {
   this->registerObject(this, NPC::_objectList);
 
-  this->toList(OM_GROUP_00);
-
-}
-
-
-NPC::~NPC () {}
-
-
-
-/**
- * adds an AI to this NPC
- */
-void NPC::addAI(AI* ai)
-{}
+  this->toList(OM_GROUP_01);
+
+  if( root != NULL)
+	  this->loadParams(root);
+
+  std::cout << "Team Number: " << teamNumber << "\n";
+  std::cout << "Swarm Number:" << swarmNumber << "\n";
+
+  AIEngine::getInstance()->addAI(teamNumber,swarmNumber,(WorldEntity*)this,maxSpeed,attackDistance);
+
+  this->bFire = false;
+
+
+    // create the weapons and their manager
+
+
+  this->getWeaponManager().changeWeaponConfig(1);
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+
+  wpRight->toList( this->getOMListNumber());
+  wpLeft->toList( this->getOMListNumber());
+
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+
+  wpLeft->increaseEnergy( 100);
+  wpRight->increaseEnergy( 100);
+
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  this->getWeaponManager().setSlotCount(7);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-2.6, .1, -3.0));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-2.6, .1, 3.0));
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
+  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().getFixedTarget()->setParent(this);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0);
+
+}
+
+
+NPC::~NPC ()
+{
+  AIEngine::getInstance()->removeAI(teamNumber,swarmNumber,(WorldEntity*)this);
+}
 
 
@@ -50,4 +125,89 @@
 {
    WorldEntity::loadParams(root);
-}
-
+
+  LoadParam(root, "team", this, NPC, setTeamNumber)
+  .describe("this sets the team number")
+  .defaultValues(0);
+
+  LoadParam(root, "swarm", this, NPC, setSwarmNumber)
+  .describe("this sets the swarm number")
+  .defaultValues(0);
+
+  LoadParam(root, "maxSpeed", this, NPC, setMaxSpeed)
+  .describe("this sets the NPC max Speed")
+  .defaultValues(0);
+
+  LoadParam(root, "attackDistance", this, NPC, setAttackDistance)
+  .describe("this sets the NPC distance to target")
+  .defaultValues(0);
+}
+
+
+/**
+ * @brief adds a Weapon to the NPC.
+ * @param weapon the Weapon to add.
+ * @param configID the Configuration ID to add this weapon to.
+ * @param slotID the slotID to add the Weapon to.
+ */
+bool NPC::addWeapon(Weapon* weapon, int configID, int slotID)
+{
+  weapon->setOwner(this->getOwner());
+
+
+  if(this->weaponMan.addWeapon(weapon, configID, slotID))
+  {
+    return true;
+  }
+  else
+  {
+    if (weapon != NULL)
+      PRINTF(2)("Unable to add Weapon (%s::%s) to %s::%s\n",
+                weapon->getClassCName(), weapon->getCName(), this->getClassCName(), this->getCName());
+    else
+      PRINTF(2)("No weapon defined\n");
+    return false;
+
+  }
+}
+
+/**
+ * @brief removes a Weapon.
+ * @param weapon the Weapon to remove.
+ */
+void NPC::removeWeapon(Weapon* weapon)
+{
+  this->weaponMan.removeWeapon(weapon);
+
+}
+
+/**
+ * @brief jumps to the next WeaponConfiguration
+ */
+void NPC::nextWeaponConfig()
+{
+  this->weaponMan.nextWeaponConfig();
+}
+
+/**
+ * @brief moves to the last WeaponConfiguration
+ */
+void NPC::previousWeaponConfig()
+{
+  this->weaponMan.previousWeaponConfig();
+}
+
+
+
+
+/**
+ * ticking
+ * @param dt  time since last tick
+ */
+void NPC::tick(float dt)
+{
+	//std::cout << "fire..\n";
+  this->weaponMan.tick(dt);
+  if (this->bFire)
+    weaponMan.fire();
+  this->bFire = false;
+}
Index: trunk/src/world_entities/npcs/npc.h
===================================================================
--- trunk/src/world_entities/npcs/npc.h	(revision 10374)
+++ trunk/src/world_entities/npcs/npc.h	(revision 10376)
@@ -4,20 +4,51 @@
 
 #include "world_entity.h"
+#include "ai_module.h"
+#include "world_entities/weapons/weapon_manager.h"
 
 class AI;
 
-class NPC : public WorldEntity {
+class NPC : public WorldEntity
+{
   ObjectListDeclaration(NPC);
- public:
-   NPC (const TiXmlElement* root);
+
+public:
+  NPC(const TiXmlElement* root = NULL);
   virtual ~NPC ();
 
-  virtual void loadParams(const TiXmlElement* root = NULL);
+  virtual void loadParams(const TiXmlElement* root);
 
-  void addAI(AI* ai);
 
+  bool addWeapon(Weapon* weapon, int configID = -1, int slotID = -1);
+  void removeWeapon(Weapon* weapon);
+  void nextWeaponConfig();
+  void previousWeaponConfig();
+  inline WeaponManager& getWeaponManager() { return this->weaponMan; };
+
+
+  virtual void tick(float dt);
+  inline int getTeam()  { return teamNumber; }
+  inline void fire(){ this->bFire=true;}
+
+
+
+private:
+  inline void setTeamNumber(int number) { teamNumber=number; }
+  inline void setSwarmNumber(int number) { swarmNumber=number; }
+  inline void setMaxSpeed(float number) { maxSpeed=number; }
+  inline void setAttackDistance(float number) { attackDistance=number; }
 
  private:
 
+  int                   teamNumber;   //!< number of the team
+  int                   swarmNumber;  //!< number of the swarm
+  int                   difficulty;   //!< difficulty
+  float						maxSpeed;
+  float						attackDistance;
+
+  WeaponManager         weaponMan;    //!< weapon manager
+  bool                  bFire;        //!< fire
+
+  AIModule*             aiModule;
 };
 
Index: trunk/src/world_entities/npcs/npc_test.cc
===================================================================
--- trunk/src/world_entities/npcs/npc_test.cc	(revision 10374)
+++ trunk/src/world_entities/npcs/npc_test.cc	(revision 10376)
@@ -19,7 +19,6 @@
 
 #include "npc_test.h"
-#include "obb_tree.h"
+#include <stdio.h>
 
-#include "shader.h"
 #include "state.h"
 #include "debug.h"
@@ -28,5 +27,11 @@
 #include "loading/load_param.h"
 
-#include "effects/explosion.h"
+#include "md2/md2Model.h"
+#include "player.h"
+#include "playable.h"
+
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
 
 
@@ -34,31 +39,59 @@
 CREATE_FACTORY(NPC2);
 
+
 NPC2::NPC2(const TiXmlElement* root)
-  : NPC(NULL)
 {
   this->registerObject(this, NPC2::_objectList);
 
-//   if ((float)rand()/RAND_MAX > .5f)
-//     this->loadModel("models/ships/bolido.obj", 6);
-//   else
-//     this->loadModel("models/ships/gobblin.obj", 6);
+  if (root != NULL)
+    this->loadParams(root);
 
 
+  // create the weapons and their manager
 
 
-  this->shader = NULL;
-//  if (likely(Shader::checkShaderAbility()))
-    //this->shader = Shader::getShader("shaders/toon.vert", "shaders/toon.frag");
+  this->getWeaponManager().changeWeaponConfig(1);
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
 
-  this->randomRotAxis = VECTOR_RAND(1);
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
 
-  if (root != NULL)
-    this->loadParams(root);
+  this->setHealthMax(100);
+  this->setHealth(80);
+
+  this->getWeaponManager().setSlotCount(7);
+
+  this->getWeaponManager().setSlotPosition(0, Vector(-2.6, .1, -3.0));
+  this->getWeaponManager().setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(1, Vector(-2.6, .1, 3.0));
+  this->getWeaponManager().setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager().setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager().setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager().setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager().setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager().setSlotPosition(6, Vector(-1, 0.0, 0));
+  this->getWeaponManager().setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager().getFixedTarget()->setParent(this);
+  this->getWeaponManager().getFixedTarget()->setRelCoor(100000,0,0);
+
 }
 
-
-NPC2::~NPC2 ()
-{}
-
+NPC2::~NPC2()
+{
+}
 
 void NPC2::loadParams(const TiXmlElement* root)
@@ -69,57 +102,16 @@
 
 
-void NPC2::destroy(WorldEntity* killer)
+
+void NPC2::tick(float dt)
 {
-  Explosion::explode(this, Vector(10,10,10));
-  this->toList(OM_DEAD);
 
+
+
+
+  // animating the md2 model
+  if( likely(this->getModel(0) != NULL) && this->getModel(0)->isA(MD2Model::staticClassID()))
+    ((MD2Model*)this->getModel(0))->tick(dt);
 }
 
 
 
-/**
- *  the entity is drawn onto the screen with this function
- *
- * This is a central function of an entity: call it to let the entity painted to the screen.
- * Just override this function with whatever you want to be drawn.
- */
-// void NPC2::draw() const
-// {
-//   glMatrixMode(GL_MODELVIEW);
-//   glPushMatrix();
-//   float matrix[4][4];
-//
-//   /* translate */
-//   glTranslatef (this->getAbsCoor ().x,
-//                 this->getAbsCoor ().y,
-//                 this->getAbsCoor ().z);
-//   /* rotate */
-//   this->getAbsDir ().matrix (matrix);
-//   glMultMatrixf((float*)matrix);
-//
-// //   if (this->shader != NULL && this->shader != Shader::getActiveShader())
-// //     shader->activateShader();
-//
-//   if( this->getModel())
-//     this->getModel()->draw();
-// //   shader->deactivateShader();
-//
-//
-// /*  if (this->model)
-//     this->model->draw();*/
-//   glPopMatrix();
-// }
-
-
-void NPC2::tick(float dt)
-{
-//  Vector direction = (State::getCameraTarget()->getAbsCoor() - this->getAbsCoor());
-
-  //if (directin.len() < 100)
-//  this->shiftCoor(direction *dt * 5 * exp(-direction.len() / 30.0));
-//  this->shiftDir(Quaternion(dt, this->randomRotAxis));
-
-}
-
-
-
Index: trunk/src/world_entities/npcs/npc_test.h
===================================================================
--- trunk/src/world_entities/npcs/npc_test.h	(revision 10374)
+++ trunk/src/world_entities/npcs/npc_test.h	(revision 10376)
@@ -5,26 +5,25 @@
 #include "npc.h"
 
+
+
 class AI;
 class Shader;
+class AIModule;
 
-class NPC2 : public NPC {
+class NPC2 : public NPC
+{
   ObjectListDeclaration(NPC2);
 
- public:
+public:
   NPC2 (const TiXmlElement* root);
   virtual ~NPC2 ();
+  virtual void loadParams(const TiXmlElement* root);
+  virtual void tick(float dt);
 
-  virtual void loadParams(const TiXmlElement* root);
 
-  void addAI(AI* ai);
 
-  virtual void destroy(WorldEntity* killer);
 
-  virtual void tick(float dt);
-//   virtual void draw() const;
+private:
 
- private:
-   Vector   randomRotAxis;
-   Shader*  shader;
 };
 
