Index: GTP/trunk/App/Demos/Illum/Ogre/src/Moria/include/Moria.h
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/src/Moria/include/Moria.h	(revision 2446)
+++ GTP/trunk/App/Demos/Illum/Ogre/src/Moria/include/Moria.h	(revision 2459)
@@ -64,4 +64,7 @@
 		this->sysNode = sysNode;
 
+		mStatsOn = false;
+		showDebugOverlay(mStatsOn);
+
     }
 
@@ -82,5 +85,5 @@
 
 		//sysNode->setPosition(mCamera->getPosition() - Vector3(0,1.5,0));
-		sysNode->setPosition(FPSPlayer::thePlayer->getPosition() - Vector3(0,1.5,0));
+		//sysNode->setPosition(FPSPlayer::thePlayer->getPosition() - Vector3(0,1.5,0));
 
         return ExampleFrameListener::frameStarted(evt);     
@@ -259,4 +262,8 @@
 	void createPostproc()
 	{		
+		CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0),
+														"FireHeatCompositor");
+		CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0),
+														"FireHeatCompositor", false);
 		
 		CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0),
@@ -275,15 +282,9 @@
 		CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0),
 														"GTP/PostProc/ToneMap", true);	
-
-
-
-	
-		
-
-		/*
+				
 		CompositorManager::getSingleton().addCompositor(mWindow->getViewport(0),
 														"GTP/PostProc/MotionBlur");
 		CompositorManager::getSingleton().setCompositorEnabled(mWindow->getViewport(0),
-														"GTP/PostProc/MotionBlur", true);	*/
+														"GTP/PostProc/MotionBlur", false);
 		
 	}
@@ -291,6 +292,6 @@
 	void chooseSceneManager()
 	{
-		mSceneMgr = mRoot->createSceneManager("OctreeSceneManager");
-		//mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
+		//mSceneMgr = mRoot->createSceneManager("OctreeSceneManager");
+		mSceneMgr = mRoot->createSceneManager("OcclusionCullingSceneManager");
 	}
 
@@ -298,6 +299,9 @@
     {
 		std::string occlusion_cfg("OcclusionCulling.cfg");
-		//mSceneMgr->setWorldGeometry(occlusion_cfg);
-		
+		mSceneMgr->setWorldGeometry(occlusion_cfg);
+		
+		Overlay* mainOverlay = OverlayManager::getSingleton().getByName("MORIA/MainOverlay");
+		mainOverlay->show();
+
 		createPostproc();
 
@@ -316,5 +320,5 @@
 		//mCamera->setPosition(0,100,0);
 		//mCamera->lookAt(0,-1,0);
-		mCamera->setFOVy(Radian(Degree(100)));
+		mCamera->setFOVy(Radian(Degree(80)));
 		mCamera->setNearClipDistance(0.001);
 		mCamera->setFarClipDistance(150);
@@ -329,5 +333,5 @@
 		inputStream = ResourceGroupManager::getSingleton().openResource("moria.level");	//towers2.level	
 		World* NXWorld = new World("FrameListener: no, log: html");
-		NXWorld->getPhysXDriver()->createFrameListener(25);
+		NXWorld->getPhysXDriver()->createFrameListener(90);
 		NXScene = NXWorld->createScene("Main", mSceneMgr, "gravity: yes, floor: no"); 
 		s.setScene(NXScene);
@@ -336,15 +340,10 @@
 		s.parseEntryPoints("prmEntryPoints.text");
 
-		NXScene->createActor("FakeFloor", new CubeShape(100,2,100), Vector3(0,-1,0), "static: yes"); 
-		
-/*
-		Body* b = NXScene->createBody("ize",
-							"sphere.mesh",
-							new SphereShape(0.5f),
-							Vector3(5,0,5),
-							"mass: 10");
-		b->getNode()->setScale(0.005,0.005,0.005);
-		b->setGlobalPosition(Vector3(5,10,5));*/
-
+		NXScene->createActor("FakeFloor", new CubeShape(140,2,60), Vector3(0,-1,0), "static: yes"); 
+		NXScene->createActor("FakeCeiling", new CubeShape(140,2,60), Vector3(0,17,0), "static: yes"); 
+		NXScene->createActor("Wall1", new CubeShape(140,16,2), Vector3(0,8,30), "static: yes"); 
+		NXScene->createActor("Wall2", new CubeShape(140,16,2), Vector3(0,8,-30), "static: yes"); 
+		NXScene->createActor("Wall3", new CubeShape(2,16,60), Vector3(70,8,0), "static: yes"); 
+		NXScene->createActor("Wall4", new CubeShape(2,16,60), Vector3(-70,8,0), "static: yes"); 
 /*
 	   ParticleSystem* pSys1 = mSceneMgr->createParticleSystem("psys1", "GTP/Moria/Smoke_Large");
@@ -353,16 +352,5 @@
 	   pSysNode->attachObject(pSys1);
 	   pSysNode->setPosition(-40,-1,-15);*/
-		
-	   /*Entity* object = mSceneMgr->createEntity("object", "head.mesh");
-		object->setMaterialName("GTP/Caustic/Glass");
-		SceneNode* objectNode = rootNode->createChildSceneNode();
-		objectNode->attachObject(object);
-		objectNode->scale(0.1,0.1,0.1);
-		objectNode->rotate(Vector3(0,1,0),Radian(0.2));
-		objectNode->setPosition(-30,2.0,-5);
-		objectNode->_updateBounds();*/
-			
-		//createPlane("p","groundmaterial",Vector3(0,-0.3,0),Vector2(150,150));
-
+	
 		mainLight = mSceneMgr->createLight("MainLight");
 		mainLight->setType(Light::LT_POINT);
@@ -378,15 +366,5 @@
 		//mainLight->setSpotlightRange(Degree(0),Degree(120));
 		mainLight->setAttenuation(200.0, 0, 0, 3);
-/*
-		Light* blueLight = mSceneMgr->createLight("blueLight");
-		blueLight->setType(Light::LT_POINT);
-		blueLight->setCastShadows(true);
-		blueLight->setDiffuseColour(ColourValue(0.45,0.75,0.8));
-		blueLight->setPowerScale(30);
-		blueLight->setAttenuation(40.0, 0, 4, 0);
-		SceneNode* blueLightNode = rootNode->createChildSceneNode();
-		blueLightNode->setPosition(15,10,15);
-		blueLightNode->attachObject(blueLight);*/
-		
+	
 		Vector4 v = mainLight->getAs4DVector();
 
@@ -407,12 +385,27 @@
 
 		PlayerCharacter::frameListenerPriority = 20;
+	
 		gFPSPlayer = new FPSPlayer(NXScene, mSceneMgr, Vector3(0.5, 1.8, 0.3), Vector3(5, 10, 15), 1.6, mCamera, false);
-		gFPSPlayer->addPlayerMesh("FPSarm.mesh", 0.02, true);
+		gFPSPlayer->addPlayerMesh("FPSarm.mesh", 0.02, false);
 		gFPSPlayer->addWeaponModel("sword.mesh", "joint28");
-
-		PlayerCharacter* troll = new PlayerCharacter("troll1", NXScene, mSceneMgr, Vector3(1.5, 3.0, 1.2), Vector3(15, 10, 15), false);
+	
+		TrollCharacter* troll = new TrollCharacter("troll1", NXScene, mSceneMgr, Vector3(1.5, 3.0, 1.2), Vector3(15, 10, 15), false);
 		troll->addPlayerMesh("troll.mesh", 0.05, false);
+		troll->addWeaponModel("trollMace.mesh", "RightHand");
+
+		CharacterManager::getSingleton().mScene = NXScene;
+		CharacterManager::getSingleton().mSceneManager = mSceneMgr;
+
 /*
-		for(float i = 0; i< 7; i++)
+		TrollCharacter* troll2 = new TrollCharacter("troll2", NXScene, mSceneMgr, Vector3(1.5, 3.0, 1.2), Vector3(25, 10, 15), false);
+		troll2->addPlayerMesh("troll.mesh", 0.05, false);
+		troll2->addWeaponModel("trollMace.mesh", "RightHand");
+
+		TrollCharacter* troll3 = new TrollCharacter("troll3", NXScene, mSceneMgr, Vector3(1.5, 3.0, 1.2), Vector3(35, 10, 15), false);
+		troll3->addPlayerMesh("troll.mesh", 0.05, false);
+		troll3->addWeaponModel("trollMace.mesh", "RightHand");
+*/
+		
+		/*for(float i = 0; i< 7; i++)
 		{
 			float size = 0.5;
@@ -426,12 +419,17 @@
 								ac);
 			b->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_PUSHABLE);
-		}
-	*/
-	   ParticleSystem* pSys1 = mSceneMgr->createParticleSystem("psys1", "MoriaDust");
+			
+		}*/
+		
+	
+	 /*  ParticleSystem* pSys1 = mSceneMgr->createParticleSystem("psys1", "MoriaDust");
 	   pSys1->setKeepParticlesInLocalSpace(true);
 	   pSysNode = rootNode->createChildSceneNode("psys1");
 	   pSysNode->attachObject(pSys1);
-	   pSysNode->setPosition(0,0,0);
-
+	   pSysNode->setPosition(0,0,0);*/
+
+	//	LightList LL;
+	//	mSceneMgr->_populateLightList(Vector3(0,0,0), 200, LL);
+	//	int numlights = LL.size();
 
 		OgreIlluminationManager::getSingleton().initTechniques();
@@ -467,5 +465,5 @@
 //		gFPSPlayer->setPriority(20);
 //		mRoot->addFrameListener(gFPSPlayer);
-		OgreIlluminationManager::getSingleton().setPriority(40);
+		OgreIlluminationManager::getSingleton().setPriority(100);
 	    mRoot->addFrameListener(&OgreIlluminationManager::getSingleton());
 	  
Index: GTP/trunk/App/Demos/Illum/Ogre/src/Moria/scripts/Moria.7.10.vcproj
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/src/Moria/scripts/Moria.7.10.vcproj	(revision 2391)
+++ GTP/trunk/App/Demos/Illum/Ogre/src/Moria/scripts/Moria.7.10.vcproj	(revision 2459)
@@ -90,4 +90,5 @@
 				StringPooling="TRUE"
 				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="0"
 				RuntimeLibrary="2"
 				BufferSecurityCheck="FALSE"
Index: GTP/trunk/App/Demos/Illum/Ogre/src/Common/include/FPSPlayer.h
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/src/Common/include/FPSPlayer.h	(revision 2418)
+++ GTP/trunk/App/Demos/Illum/Ogre/src/Common/include/FPSPlayer.h	(revision 2459)
@@ -2,4 +2,6 @@
 
 #include "Ogre.h"
+#include "OgreBillboardParticleRenderer.h"
+#include "OgreIlluminationManager.h"
 #include "NXOgre.h"
 
@@ -16,9 +18,50 @@
 	PLAYERANIMSTATE_PAIN,
 	PLAYERANIMSTATE_DEATH,
-	PLAYERANIMSTATE_URN
-};
-
+	PLAYERANIMSTATE_TURN
+};
+
+class PlayerCharacter;
+class FireBall;
 class MyCharMoveController;
 
+class CharacterManager
+{
+public:
+	static CharacterManager& getSingleton()
+	{
+		if(mSingleton == 0)
+			mSingleton = new CharacterManager();
+		return *mSingleton;
+	}
+	PlayerCharacter* getTrigger(NxOgre::Actor* a)
+	{
+		if(triggers.find(a)== triggers.end())
+			return 0;
+		return triggers[a];
+	}
+	PlayerCharacter* getTarget(NxOgre::Actor* a)
+	{
+		if(targets.find(a)== targets.end())
+			return 0;
+		return targets[a]; 
+	}
+
+	void addTrigger(NxOgre::Actor* a, PlayerCharacter* c){triggers[a] = c;}
+	void addTarget(NxOgre::Actor* a, PlayerCharacter* c){targets[a] = c;}
+
+	void levelUP();
+	
+	SceneManager* mSceneManager;
+	Scene* mScene;
+
+protected:
+	CharacterManager(){}
+	static CharacterManager* mSingleton;
+	std::map<NxOgre::Actor*, PlayerCharacter*> triggers;
+	std::map<NxOgre::Actor*, PlayerCharacter*> targets;
+	
+};
+
+
 class PlayerCharacter  : public FrameListener
 {
@@ -28,8 +71,10 @@
 	
 	virtual void addPlayerMesh(String meshname, float meshscale, bool rotateModel);
-	bool frameStarted(const FrameEvent& evt);
+	virtual bool frameStarted(const FrameEvent& evt);
 	virtual void addWeaponModel(String meshname, String attachBoneName);
-	void doAction(float dt);
-
+	virtual void doAction(float dt){}
+	virtual float getHit(){return 0;}
+	virtual void addHit(float hit){mHealth -= hit; if(mHealth < 0) mHealth = 0;}
+	
 	static unsigned int frameListenerPriority;
 	
@@ -58,18 +103,41 @@
 	Vector3 mPlayerDimensions;
 	bool mRunning;
+	bool isAlive;
 	
 	SceneNode* mWeaponNode2;
 	bool mDebug;
 
+	float mHealth;
+		
+	float getAnimSpeed(){return 1.2;}
 	virtual String getAnimStateName(PlayerAnimState as,  int option = 0){return "stand";}
-	virtual void setAnimState(PlayerAnimState as)
-	{
-		if(mCurrentAnimState != PLAYERANIMSTATE_WALK)
-		{
-			mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(as));
-			mCharacterMesh_AnimState->setLoop(true);
-			mCharacterMesh_AnimState->setEnabled(true);
-		}
-	}
+	virtual void setAnimState(PlayerAnimState as){}
+	
+};
+
+class TrollCharacter : public PlayerCharacter
+{
+public:
+	TrollCharacter(String name, Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, bool debug = false);
+	~TrollCharacter(){}
+
+	void doAction(float dt);
+	float getHit(){ if(mCurrentAnimState == PLAYERANIMSTATE_ATTACK) return 20; else return 0;}
+	void addHit(float hit);
+
+	bool frameStarted(const FrameEvent& evt)
+	{
+	/*	OverlayElement* healthUI = OverlayManager::getSingleton().getOverlayElement("MannaColumn");
+		float relHealth = mHealth / MaxHealth;
+		healthUI->setHeight(0.29 * relHealth);
+		healthUI->setTop(0.005 +  (1.0 - relHealth) * 0.29);*/
+		
+		return PlayerCharacter::frameStarted(evt);
+	}
+protected:
+	String getAnimStateName(PlayerAnimState as,  int option = 0);
+	void setAnimState(PlayerAnimState as);
+
+	static float MaxHealth;
 };
 
@@ -87,13 +155,53 @@
 	Vector3 getPosition(){return mPlayerNode->getWorldPosition();
 		return mPlayerCharacter->getGlobalPosition();}
+	Vector3 getDirection()
+	{
+		Vector3 dir = mCamera->getDerivedDirection();
+		dir.normalise();
+		return dir;
+	}
 //	Vector3 getOrienation(){return mPlayerCharacter->getGlobalOrientation();}
+	float getHit()
+	{ 
+		if(mCurrentAnimState == PLAYERANIMSTATE_ATTACK){
+			if(mWeapon) return 20;
+			else return 15;
+		}else return 0;
+	}
+	void addHit(float hit)
+	{
+		if(isAlive)
+		{
+			PlayerCharacter::addHit(hit);
+			if(mHealth <= 0)//death
+			{
+				static deaths = 0;
+				deaths++;
+				isAlive = false;
+				OverlayElement* deathsTextBox = OverlayManager::getSingleton().getOverlayElement("Deaths");
+					deathsTextBox->setCaption("Deaths: "+StringConverter::toString(deaths));
+			}
+		}
+	}
+
+	void levelUp(){mMaxHealth += 30; mHealth = mMaxHealth;}
 
 	static FPSPlayer* thePlayer;
 	static FPSPlayer* getPlayer(){return thePlayer;}
+	void addCharacterInRange(PlayerCharacter* c){mCharactersInRange.insert(c);}
+	void removeCharacterInRange(PlayerCharacter* c){mCharactersInRange.erase(c);}
 
 protected:
 
 	Camera* mCamera;
-	float mCameraHeight;	
+	float mCameraHeight;
+	float mStrength;
+	float mMaxStrength;
+	float mManna;
+	float mMaxManna;
+	float mMaxHealth;
+	FireBall* mFireBall;
+	
+	std::set<PlayerCharacter*> mCharactersInRange;
 
 	String getAnimStateName(PlayerAnimState as,  int option = 0);
Index: GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/FPSPlayer.cpp
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/FPSPlayer.cpp	(revision 2443)
+++ GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/FPSPlayer.cpp	(revision 2459)
@@ -3,4 +3,35 @@
 FPSPlayer* FPSPlayer::thePlayer = NULL;
 unsigned int PlayerCharacter::frameListenerPriority = 1;
+float TrollCharacter::MaxHealth = 350;
+CharacterManager* CharacterManager::mSingleton = 0;
+
+void CharacterManager::levelUP()
+{
+		//player level up
+		FPSPlayer::thePlayer->levelUp();
+		//add 2 new trolls
+		static int trollID = 2;
+		static int kills = 0;
+		kills++;
+		
+		OverlayElement* killsTextBox = OverlayManager::getSingleton().getOverlayElement("Level");
+			killsTextBox->setCaption("Kills: "+StringConverter::toString(kills));
+
+		for(int i = 0; i < 2; i++)
+		{
+			TrollCharacter* troll = new TrollCharacter("troll" + StringConverter::toString(trollID),
+															mScene,
+															mSceneManager,
+															Vector3(1.5, 3.0, 1.2),
+															Vector3(25, 10, 25 - i * 10), false);
+
+			troll->addPlayerMesh("troll.mesh", 0.05, false);
+			troll->addWeaponModel("trollMace.mesh", "RightHand");
+			trollID++;			
+		}
+
+
+		
+}
 
 class MyTrigger : public Trigger
@@ -14,9 +45,165 @@
 	 void onEnter(Actor* a)
 	 {
-		int ize = 0;
+		 PlayerCharacter* trigger = CharacterManager::getSingleton().getTrigger(this);
+		 PlayerCharacter* target = CharacterManager::getSingleton().getTarget(a);
+		
+		 if(target != trigger && target == FPSPlayer::thePlayer)
+			target->addHit(trigger->getHit());
+
 	 }
 };
 
-class MyCharMoveController : public CharacterMovementVectorController
+class FireBall : public Trigger
+{
+public:
+	FireBall(String& name,
+		     SceneManager* sm,
+			 SceneNode* meshNode,
+			 Bone* attachBone,
+			 const NxString& meshIdentifier,
+			 Scene* scene,
+			 ShapeDescription* shape,
+			 const NxOgre::Pose& pose,
+			 ActorParams params = "")
+	: Trigger(meshIdentifier, scene, shape, pose, params)
+	  {
+		  mFire=false;
+		  isActive = false;
+		 mFireBall = sm->createParticleSystem("FPS_PLAYER_FIREBALL", "Moria/FireBall");
+			
+		 mFireBallLight = sm->createLight(mName+"FireBallLight");
+		 mFireBallLight->setType(Light::LT_POINT);
+		 mFireBallLight->setCastShadows(true);
+		 mFireBallLight->setDiffuseColour(ColourValue(0.95,0.98,0.8));
+		 mFireBallLight->setPowerScale(200);
+		 mFireBallLight->setAttenuation(200.0, 0, 0, 6);	
+
+		 attachNode = meshNode->createChildSceneNode(name + "_AttachNode");
+		 fireBallNode = attachNode->createChildSceneNode(name + "_FireBallNode");
+		 fireBallNode->attachObject(mFireBall);
+		 //fireBallNode->attachObject(mFireBallLight);
+		 BillboardSet* bbs = ((BillboardParticleRenderer*)mFireBall->getRenderer())->getBillboardSet();
+		 bbs->setMaterialName(mFireBall->getMaterialName());
+			OgreIlluminationManager::getSingleton().initTechniques(
+				bbs,
+				mFireBall);
+		 fireBallNode->detachObject(mFireBall);
+		 sceneManager = sm;
+		 this->attachBone = attachBone;
+
+		/* explosionNode = sm->getRootSceneNode()->createChildSceneNode(name + "_EXPLOSION_NODE");
+		 mExplosion = sm->createParticleSystem("FPS_PLAYER_EXPLOSION", "Moria/Explosion");
+		 explosionNode->attachObject(mExplosion);
+		 bbs = ((BillboardParticleRenderer*)mExplosion->getRenderer())->getBillboardSet();
+		 bbs->setMaterialName(mExplosion->getMaterialName());
+			OgreIlluminationManager::getSingleton().initTechniques(
+				bbs,
+				mExplosion);*/
+         		
+	 }
+   void update(float dt)
+   {
+	   if(isActive)
+	   {
+		/*if(explodeTimer.getMilliseconds() > 1000)
+			mExplosion->getEmitter(0)->setEmissionRate(0);*/
+		   
+		Vector3 pos = attachBone->getWorldPosition();
+		Quaternion orientation = attachBone->getWorldOrientation();
+
+		attachNode->setPosition(pos);
+		attachNode->setOrientation(orientation);
+
+		if(mFire)
+		{
+			Vector3 testCenter = position - direction;
+			bool collidedWithStatic = getScene()->getNxScene()->checkOverlapSphere( 
+					NxSphere(NxVec3(testCenter.x,testCenter.y,testCenter.z), 0.4),  
+					NX_STATIC_SHAPES);
+			position += direction * dt * 10.0;
+			fireBallNode->setPosition(position);
+			
+			if(collidedWithStatic)
+				explode();		
+ 		}
+		  
+		this->setGlobalPosition(fireBallNode->getWorldPosition());
+		this->setGlobalOrientation(fireBallNode->getWorldOrientation());
+	   }
+   }
+   void fire()
+   {
+	   mFire = true;
+	   position = fireBallNode->getWorldPosition();
+	   direction = FPSPlayer::getPlayer()->getDirection();
+	   //position += direction * 2.0;	
+
+	   attachNode->removeChild(fireBallNode);
+	   sceneManager->getRootSceneNode()->addChild(fireBallNode);
+  }
+   void activate()
+   {
+	   isActive = true;
+	   fireBallNode->attachObject(mFireBall);
+	   fireBallNode->attachObject(mFireBallLight);
+	   //mFireBallLight->setPowerScale(200);
+	   CompositorManager::getSingleton().setCompositorEnabled(
+		   OgreIlluminationManager::getSingleton().getMainViewport(),
+			"FireHeatCompositor", true);
+	   
+   }
+   void deactivate()
+   {
+	   isActive = false;
+	   fireBallNode->detachObject(mFireBall);
+	   fireBallNode->detachObject(mFireBallLight);	   
+	   //mFireBallLight->setPowerScale(0);
+	   CompositorManager::getSingleton().setCompositorEnabled(
+		   OgreIlluminationManager::getSingleton().getMainViewport(),
+			"FireHeatCompositor", false);
+   }
+
+   void onEnter(Actor* a)
+   {
+	 PlayerCharacter* target = CharacterManager::getSingleton().getTarget(a);
+	 if(target != FPSPlayer::thePlayer)
+	 {
+		 if(mFire)
+		 {
+			 if(target)
+		 		target->addHit(30);
+		     explode();
+		 }
+	 }
+ }
+
+protected:
+   Vector3 position;
+   Vector3 direction;
+	bool mFire;
+	bool isActive;
+	SceneNode* fireBallNode;
+	SceneNode* explosionNode;
+	SceneNode* attachNode;
+	ParticleSystem* mFireBall;
+	ParticleSystem* mExplosion;
+	Light* mFireBallLight;
+	Bone* attachBone;
+	SceneManager* sceneManager;	
+	Timer explodeTimer;
+
+	void explode()
+	{
+		/*mExplosion->getEmitter(0)->setEmissionRate(100);
+		explodeTimer.reset();
+		mExplosion->getEmitter(0)->setPosition(position);*/
+		sceneManager->getRootSceneNode()->removeChild(fireBallNode);
+		attachNode->addChild(fireBallNode);
+		fireBallNode->setPosition(2.8, -2.28, 0.47);
+		mFire = false;		
+	}
+};
+
+class MyCharMoveController : public CharacterController
 {
 public:
@@ -28,8 +215,18 @@
 		out = ((dir * movespeed) + g) * t;		
 	}
+	NxControllerAction onShapeHit(const NxControllerShapeHit & hit)
+	{
+		return CharacterController::onShapeHit(hit);
+	}
+	NxControllerAction onControllerHit(const NxControllersHit & hit)
+	{
+		return CharacterController::onControllerHit(hit);
+	}
 };
 
 PlayerCharacter::PlayerCharacter(String name, Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, bool debug)
 {
+	mCurrentAnimState = PLAYERANIMSTATE_STAND;
+	isAlive = true;
 	mName = name;
 	mPlayerDimensions = dimensions;
@@ -42,4 +239,6 @@
 	cp.mType = CharacterParams::CT_Box;
 	mPlayerCharacter = mScene->createCharacter(mName, startPosition, cp); 
+	NxActor* a = mPlayerCharacter->getNxController()->getActor();
+	CharacterManager::getSingleton().addTarget((Actor*) a->userData, this);
 	mPlayerCharacter->createNode();
 	mPlayerNode = mPlayerCharacter->getNode();
@@ -51,7 +250,11 @@
 	if(mDebug)
 	{
+		
 		mPlayerBoundDebugNode = mPlayerNode->createChildSceneNode(mName + "_BoundDebugNode");
-		mPlayerBoundDebugNode->setScale(dimensions);
-		mPlayerBoundDebugNode->attachObject(mSceneManager->createEntity(mName + "_BoundDebug", "cube.mesh"));
+		mPlayerBoundDebugNode->setScale(Vector3(dimensions.x, dimensions.y, dimensions.z));
+	//	mPlayerBoundDebugNode->attachObject(mSceneManager->createEntity(mName + "_BoundDebug", "cube.mesh"));
+		
+		//mPlayerNode->setScale(Vector3(dimensions.x, dimensions.y, dimensions.z));
+		//mPlayerNode->attachObject(mSceneManager->createEntity(mName + "_BoundDebug", "cube.mesh"));
 	}
 
@@ -78,12 +281,28 @@
 }
 
+TrollCharacter::TrollCharacter(String name, Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, bool debug)
+: PlayerCharacter(name, scene, sceneManager, dimensions, startPosition, debug)
+{
+	mHealth = MaxHealth;
+}
+
 FPSPlayer::FPSPlayer(Scene* scene, SceneManager* sceneManager, Vector3 dimensions, Vector3 startPosition, float cameraHeight, Camera* cam, bool debug)
 : PlayerCharacter("FPSPlayerCharacter", scene, sceneManager, dimensions, startPosition, debug)
 {
+	mMaxHealth = 50;
+	mMaxStrength = 100;
+	mMaxManna = 100;
+	mStrength = mMaxStrength;
+	mHealth = mMaxHealth;
+	mManna = mMaxManna;
+	
 	mCameraHeight = cameraHeight - dimensions.y / 2.0;
 	mCamera = cam;
 	mPlayerNode->attachObject(cam); 
+	mCamera->rotate(Vector3(0,1,0), Radian(Degree(180)));
 	
 	thePlayer = this;
+	mFireBall = 0;
+	
 }
 
@@ -95,5 +314,5 @@
 {
 	mCharacterMeshEntity = mSceneManager->createEntity(mName, meshname);
-	mCharacterMeshEntity->setCastShadows(false);
+	mCharacterMeshEntity->setCastShadows(true);
 	mMeshScale = meshscale;
 	mCurrentAnimState = PLAYERANIMSTATE_STAND;
@@ -123,5 +342,16 @@
 	FPSArmNode->setScale(meshscale, meshscale, meshscale);
 	if(rotateModel)
-	FPSArmNode->rotate(Vector3::UNIT_Y, Degree(180.0));
+	FPSArmNode->rotate(Vector3::UNIT_Y, Degree(180.0));	
+
+	mFireBall = new FireBall(mName+"_FIREBALL",
+							 mSceneManager,
+							 FPSArmNode,
+							 mCharacterMeshEntity->getSkeleton()->getBone("joint4"),
+							 mName+"FireBallTrigger",
+							 mScene,
+							 new SphereShape(0.5, "trigger: yes"),
+							 Vector3(0,0,0),
+							 "mass: 0, density: 0");
+	mScene->addTrigger(mFireBall);
 }
 
@@ -133,13 +363,12 @@
 	mWeaponNode = mCharacterMeshEntity->getParentSceneNode()->createChildSceneNode(mName + "_WeaponNode");	
 	mWeaponNode->attachObject(mWeaponEntity);
+	mWeaponEntity->setCastShadows(true);
 
 	AxisAlignedBox bb = mWeaponEntity->getBoundingBox();
 
 	Vector3 max = bb.getMaximum();
-	//max.z *= 2.0;
 	Vector3 min = bb.getMinimum();
 	Vector3 center = (min + max) / 2.0;
-	//center.z = max.z;
-
+	
 	mWeaponBoundNode = mWeaponNode->createChildSceneNode(mName + "_WeaponBoundNode");
 	mWeaponBoundNode->setPosition(center);
@@ -162,5 +391,6 @@
 	mWeaponBound = new MyTrigger(mName + "_WeaponTrigger", mScene, new CubeShape(dimX, dimY, dimZ, "trigger: yes"), Vector3(0,0,0), "mass: 0, density: 0");
 	mScene->addTrigger((Trigger*)mWeaponBound);
-		
+
+	CharacterManager::getSingleton().addTrigger(mWeaponBound, this);	
 	if(mDebug)
 	{
@@ -174,55 +404,35 @@
 
 void FPSPlayer::addWeaponModel(String meshname, String attachBoneName)
-{
+{	
+	mWeaponEntity = mSceneManager->createEntity(mName + "_Weapon", meshname);
+	mWeaponAttachBone = mCharacterMeshEntity->getSkeleton()->getBone(attachBoneName);
+	mWeaponNode = mCharacterMeshEntity->getParentSceneNode()->createChildSceneNode(mName + "_WeaponNode");	
+	mWeaponNode->attachObject(mWeaponEntity);
+	mWeaponEntity->setCastShadows(false);
+
+	AxisAlignedBox bb = mWeaponEntity->getBoundingBox();
+
+	mWeaponBoundNode = mPlayerNode->createChildSceneNode(mName + "_WeaponBoundNode");
+	mWeaponBoundNode->setPosition(0,1.5,0.5);
 	
-	mWeaponEntity = mSceneManager->createEntity(mName + "_Weapon", meshname);
-	mWeaponEntity->setCastShadows(false);
-	mWeaponAttachBone = mCharacterMeshEntity->getSkeleton()->getBone(attachBoneName);
-	mWeaponNode = mCharacterMeshEntity->getParentSceneNode()->createChildSceneNode(mName+"_WeaponNode");	
-	mWeaponNode->attachObject(mWeaponEntity);
-
-	AxisAlignedBox bb = mWeaponEntity->getBoundingBox();
-
-	Vector3 max = bb.getMaximum();
-	//max.z *= 2.0;
-	Vector3 min = bb.getMinimum();
-	Vector3 center = (min + max) / 2.0;
-	//center.z = max.z;
-
-	//mWeaponBoundNode = mWeaponNode->createChildSceneNode();
-	//mWeaponBoundNode->setPosition(center);
-
-	SceneNode* ArmNode2 = mPlayerNode->createChildSceneNode(mName+"_ArmNode2");
-	ArmNode2->setPosition(0,mCameraHeight , -mPlayerDimensions.z);
-	ArmNode2->rotate(Vector3::UNIT_Y, Degree(180.0));
-	mWeaponNode2 = ArmNode2->createChildSceneNode();
-	mWeaponBoundNode = mWeaponNode2->createChildSceneNode(mName+"_WeaponBoundNode");
-	mWeaponBoundNode->setPosition(center * mMeshScale );
-	
-
-	max *= mMeshScale;
-	min *= mMeshScale;
-	float dimX = max.x-min.x;
-	float dimY = max.y-min.y;
-	dimY *=3;
-	float dimZ = max.z-min.z;
-	Vector3 dim(dimX, dimY, dimZ);
-
-//	mWeaponBound = mScene->createActor("FPSPlayerWeapon", new CubeShape(dimX, dimY, dimZ), Vector3(0,0,0), "kinematic: yes, mass: 10");
-	mWeaponBound = new MyTrigger(mName + "_WeaponTrigger", mScene, new CubeShape(dimX, dimY, dimZ, "trigger: yes"), Vector3(0,0,0), "mass: 0, density: 0");
+	mWeaponBound = new MyTrigger(mName + "_WeaponTrigger", mScene, new CubeShape(0.5, 0.5, 0.5, "trigger: yes"), Vector3(0,0,0), "mass: 0, density: 0");
 	mScene->addTrigger((Trigger*)mWeaponBound);
-	
+
+	CharacterManager::getSingleton().addTrigger(mWeaponBound, this);	
 	if(mDebug)
 	{
 		mWeaponBoundDebugNode = mSceneManager->getRootSceneNode()->createChildSceneNode(mName+"_WeaponBoundDebugNode");
-		mWeaponBoundDebugNode->setScale(dim);
-		mWeaponBoundDebugNode->attachObject(mSceneManager->createEntity(mName+"_WeaponBoundDebug", "cube.mesh"));
-	}
-
-	mWeaponBound->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_NON_COLLIDABLE);	
-}
-
-void PlayerCharacter::doAction(float dt)
-{
+		mWeaponBoundDebugNode->setScale(0.5,0.5,0.5);
+	//	mWeaponBoundDebugNode->attachObject(mSceneManager->createEntity(mName+"_WeaponBoundDebug", "cube.mesh"));
+	}
+
+	//mWeaponBound->setCharacterCollisionGroup(NX_CHARACTER_COL_GROUP_NON_COLLIDABLE);	
+}
+
+void TrollCharacter::doAction(float dt)
+{
+	if(mCurrentAnimState == PLAYERANIMSTATE_DEATH)
+		return;
+
 	FPSPlayer* thePlayer = FPSPlayer::getPlayer();
 
@@ -231,227 +441,94 @@
 		Vector3 playerPos = thePlayer->getPosition();
 		Vector3 myPos = mPlayerNode->getWorldPosition();
-		Vector3 dir = playerPos - myPos;
+		static Vector3 dir = Vector3(0,0,1);
+		Vector3 lastDir = dir;
+		dir = playerPos - myPos;
 		dir.y = 0;
-		//if( dir.length() > 1.0)
-		//{
-			dir.normalise();
-			Vector3 right = -dir.crossProduct(Vector3::UNIT_Y);
-			Quaternion q; 			
-			q.FromAxes(right,Vector3::UNIT_Y,dir);
-			//mPlayerCharacter->setDirection(q); 
-			if(mCharacterController )
-			((MyCharMoveController*)mCharacterController)->movespeed = 1.5;
-			//mPlayerCharacter->addMovement(Character::DR_StepRight);
-		//}
-
-	}
-	//if(mCharacterMeshEntity)
-	//setAnimState(PLAYERANIMSTATE_WALK);
-}
-
-bool PlayerCharacter::frameStarted(const FrameEvent& evt)
-{
-//	LogManager::getSingleton().logMessage("CHARACTERPLAYER_FRAMESTARTED");
-	doAction(evt.timeSinceLastFrame);
-
-	float dt = evt.timeSinceLastFrame;
-		
-	if(mCharacterMesh_AnimState)
-	{
-		float animspeed = 1.2;
-		if(mCurrentAnimState == PLAYERANIMSTATE_WALK && !mRunning)
-			animspeed /= 2;
-
-		mCharacterMesh_AnimState->addTime(dt*animspeed);	
-	}
-
-	return true;
-}
-
-void FPSPlayer::processKeyInputs(InputReader* inputDevice)
-{		
-		mMoving = false;
-		if (inputDevice->isKeyDown(KC_W))
-		{ 
-			mPlayerCharacter->addMovement(Character::DR_StepLeft); 
-			mMoving = true;
-		} 	
-		if (inputDevice->isKeyDown(KC_S))
-		{ 
-			mPlayerCharacter->addMovement(Character::DR_StepRight);
-			mMoving = true;
-		} 
-		if (inputDevice->isKeyDown(KC_A))
-		{ 
-			mPlayerCharacter->addMovement(Character::DR_Forward);
-			mMoving = true;
-		} 
-		if (inputDevice->isKeyDown(KC_D))
-		{ 
-			mPlayerCharacter->addMovement(Character::DR_Backward); 
-			mMoving = true;
-		} 
-
-		if (inputDevice->isKeyDown(KC_1))
-		{
-			mWeapon = 0;
-			mForceAnimChange = true;
-		}
-		if (inputDevice->isKeyDown(KC_2))
-		{
-			mWeapon = 1;
-			mForceAnimChange = true;
-		}
-
-		if (inputDevice->isKeyDown(KC_LSHIFT))
-		{
-			if(mCharacterController)
-			((MyCharMoveController*)mCharacterController)->movespeed = 4.0;
-			mRunning = true;
+
+		float dist = dir.length();
+
+		dir.normalise();
+		Vector3 right = -dir.crossProduct(Vector3::UNIT_Y);
+		Quaternion q; 			
+		q.FromAxes(right,Vector3::UNIT_Y, dir);
+		mPlayerCharacter->setDirection(q);
+		
+		if(dist < 1.8)
+		{
+			if(dist < 1.2)
+			{
+				setAnimState(PLAYERANIMSTATE_WALK);
+				if(mCurrentAnimState != PLAYERANIMSTATE_DEATH &&
+					mCurrentAnimState != PLAYERANIMSTATE_ATTACK &&
+					mCurrentAnimState != PLAYERANIMSTATE_PAIN)
+				{
+					if(mCharacterController )
+						((MyCharMoveController*)mCharacterController)->movespeed = 1.5;
+					mPlayerCharacter->addMovement(Character::DR_Backward);
+					
+				}		
+				FPSPlayer::thePlayer->addCharacterInRange(this);
+			}
+			else
+			{
+				if(Math::UnitRandom()>0.6)
+				{
+					if(Math::ACos(dir.dotProduct(lastDir)).valueDegrees() > 2.0)
+						setAnimState(PLAYERANIMSTATE_TURN);
+					else
+						setAnimState(PLAYERANIMSTATE_STAND);
+				}
+				else
+				{
+					setAnimState(PLAYERANIMSTATE_ATTACK);
+				}
+			}
 		}
 		else
 		{
-			if(mCharacterController)
-			((MyCharMoveController*)mCharacterController)->movespeed = 2.0;
-			mRunning = false;
-		}
-}
-
-void FPSPlayer::processMouseInputs(InputReader* inputDevice)
-{
-	if( inputDevice->getMouseButton( 0 ) )//attack
-		setAnimState(PLAYERANIMSTATE_ATTACK);
-		
-	else if( inputDevice->getMouseButton( 1 ) )//block
-		setAnimState(PLAYERANIMSTATE_BLOCK);
-
-	Quaternion q; 
-	q.FromAngleAxis( Radian(Degree(-inputDevice->getMouseRelX() * 0.13)), Vector3::UNIT_Y ); 
-	q = mPlayerCharacter->getGlobalOrientation() * q; 
-	mPlayerCharacter->setDirection(q); 
-
-	mCamera->pitch(Radian(Degree(-inputDevice->getMouseRelY() * 0.13)));		
-}
-
-bool FPSPlayer::frameStarted(const FrameEvent& evt)
-{
-//	LogManager::getSingleton().logMessage("FPSPLAYER_FRAMESTARTED");
-
-	float dt = evt.timeSinceLastFrame;
-		
-	if(mCharacterMesh_AnimState)
-	{
-		float animspeed = 1.2;
-		if(mCurrentAnimState == PLAYERANIMSTATE_WALK && mRunning)
-			animspeed *= 1.5;
-		if(mCurrentAnimState == PLAYERANIMSTATE_ATTACK)
-			animspeed *= 2.0;
-
-		mCharacterMesh_AnimState->addTime(dt*animspeed);	
-	}
-
-	static float moveTime=0;
-	
-	float movecameraup = 0;
-	if(mDebug)movecameraup = 20.0;
-
-	if(mMoving)
-	{
-		setAnimState(PLAYERANIMSTATE_WALK);
-
-		moveTime += dt;
-		mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0) + Vector3(0,0.009 * pow(sin(moveTime*5.0), 2),0));
-	}
-	else
-	{
-		if(Math::UnitRandom() > 0.98)
-			setAnimState(PLAYERANIMSTATE_IDLE);
-		else
-			setAnimState(PLAYERANIMSTATE_STAND);
-
-		moveTime = 0;
-		mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0));
-	}
-
-	if(mCharacterMeshEntity)
-	this->mCharacterMeshEntity->_updateAnimation();
-
-	if(mWeaponEntity)
-	{
-		mWeaponNode->setPosition(mWeaponAttachBone->getWorldPosition());
-		mWeaponNode->setOrientation(mWeaponAttachBone->getWorldOrientation());
-
-		mWeaponNode2->setPosition(mWeaponAttachBone->getWorldPosition() * mMeshScale);
-		mWeaponNode2->setOrientation(mWeaponAttachBone->getWorldOrientation());
-
-		Vector3 translation = mWeaponBoundNode->getWorldPosition();
-		Quaternion orientation = mWeaponBoundNode->getWorldOrientation();
-		
-		mWeaponBound->setGlobalOrientation(orientation);		
-		mWeaponBound->setGlobalPosition(translation);
-
-		//mWeaponBound->setGlobalPosition(translation);		
-		//mWeaponBound->setGlobalOrientation(orientation);
-
-		if(mDebug)
-		{
-			mWeaponBoundDebugNode->setPosition(translation);
-			mWeaponBoundDebugNode->setOrientation(orientation);
-		}
-	}
-
-	return true;
-}
-
-String FPSPlayer::getAnimStateName(PlayerAnimState as, int option)
-{
-	switch (as)
-	{
-		case PLAYERANIMSTATE_IDLE:
-		{
-			if(mWeapon < 1)
-				return "sword_idle";
-			else
-				return "magic_idle";
-		}
-		case PLAYERANIMSTATE_STAND:
-		{
-			if(mWeapon < 1)
-				return "sword_stand";
-			else
-				return "magic_stand";
-		}
-		case PLAYERANIMSTATE_BLOCK:
-		{
-				return "block";			
-		}
-		case PLAYERANIMSTATE_WALK:
-		{
-				return "walk";			
-		}
-		case PLAYERANIMSTATE_ATTACK:
-		{
-			if(option)
-			{
-				if(mWeapon < 1)
-					return "attack1";
-				else
-					return "magic_attack";
-			}
-			else
-			{
-				if(mWeapon < 1)
-					return "attack2";
-				else
-					return "magic_attack";
-			}
-		}
-	}
-	return "";
-}
-
-void FPSPlayer::setAnimState(PlayerAnimState as)
+			FPSPlayer::thePlayer->removeCharacterInRange(this);
+
+			setAnimState(PLAYERANIMSTATE_WALK);
+			if(mCurrentAnimState != PLAYERANIMSTATE_DEATH &&
+				mCurrentAnimState != PLAYERANIMSTATE_ATTACK &&
+				mCurrentAnimState != PLAYERANIMSTATE_PAIN)
+			{
+				if(mCharacterController )
+					((MyCharMoveController*)mCharacterController)->movespeed = 1.5;
+				mPlayerCharacter->addMovement(Character::DR_Forward);
+				
+			}		
+		}	
+	}	
+}
+
+void TrollCharacter::addHit(float hit)
+{
+	if(hit == 0 || !isAlive)
+		return;
+
+	PlayerCharacter::addHit(hit);
+
+	if(mHealth <= 0)//death
+	{
+		isAlive = false;
+		setAnimState(PLAYERANIMSTATE_DEATH);
+
+		//TODO:  free character controller
+		mScene->destroyCharacter(mName);
+		CharacterManager::getSingleton().levelUP();
+	}
+	else//pain
+	{
+		setAnimState(PLAYERANIMSTATE_PAIN);
+	}
+}
+
+void  TrollCharacter::setAnimState(PlayerAnimState as)
 {
 	if(!mCharacterMeshEntity)
+		return;
+
+	if(mCurrentAnimState == PLAYERANIMSTATE_DEATH)
 		return;
 
@@ -497,4 +574,515 @@
 			if(mCurrentAnimState != PLAYERANIMSTATE_WALK)
 			{
+				if(mCurrentAnimState == PLAYERANIMSTATE_IDLE || mCurrentAnimState == PLAYERANIMSTATE_STAND || mCurrentAnimState == PLAYERANIMSTATE_TURN 
+					|| mCharacterMesh_AnimState->getTimePosition() >= mCharacterMesh_AnimState->getLength())
+				{
+					mCurrentAnimState = PLAYERANIMSTATE_WALK;
+					mCharacterMesh_AnimState->setEnabled(false);
+					mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_WALK));
+					mCharacterMesh_AnimState->setLoop(true);
+					mCharacterMesh_AnimState->setEnabled(true);
+				}
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_TURN:
+		{
+			if(mCurrentAnimState != PLAYERANIMSTATE_TURN)
+			{
+				if(mCurrentAnimState == PLAYERANIMSTATE_IDLE || mCurrentAnimState == PLAYERANIMSTATE_STAND)
+				{
+					int turnType = 0;
+					if(Math::UnitRandom() > 0.5)
+					 turnType = 1;
+
+					mCurrentAnimState = PLAYERANIMSTATE_TURN;
+					mCharacterMesh_AnimState->setEnabled(false);
+					mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_TURN, turnType));
+					mCharacterMesh_AnimState->setLoop(true);
+					mCharacterMesh_AnimState->setEnabled(true);
+				}
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_ATTACK:
+		{
+			if(mCharacterMesh_AnimState->getTimePosition() >=
+					mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop() || mCurrentAnimState == PLAYERANIMSTATE_IDLE)
+			{
+			    int attackType = 0;
+				if(Math::UnitRandom() > 0.5)
+					 attackType = 1;
+
+				mCurrentAnimState = PLAYERANIMSTATE_ATTACK;
+				mCharacterMesh_AnimState->setEnabled(false);
+				mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_ATTACK, attackType));
+				mCharacterMesh_AnimState->setTimePosition(0);
+				mCharacterMesh_AnimState->setLoop(false);
+				mCharacterMesh_AnimState->setEnabled(true);
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_PAIN:
+		{
+			if(mCharacterMesh_AnimState->getTimePosition() >=
+					mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop()
+					//mCurrentAnimState != PLAYERANIMSTATE_PAIN
+					)
+			{
+				int painType = 0;
+				if(Math::UnitRandom() > 0.5)
+					 painType = 1;
+
+			    mCurrentAnimState = PLAYERANIMSTATE_PAIN;
+				mCharacterMesh_AnimState->setEnabled(false);
+				mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_PAIN, painType));
+				mCharacterMesh_AnimState->setTimePosition(0);
+				mCharacterMesh_AnimState->setLoop(false);
+				mCharacterMesh_AnimState->setEnabled(true);
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_DEATH:
+		{
+			if(mCurrentAnimState != PLAYERANIMSTATE_DEATH)
+			{
+				int deathType = 0;
+				if(Math::UnitRandom() > 0.5)
+					 deathType = 1;
+
+			    mCurrentAnimState = PLAYERANIMSTATE_DEATH;
+				mCharacterMesh_AnimState->setEnabled(false);
+				mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_DEATH, deathType));
+				mCharacterMesh_AnimState->setTimePosition(0);
+				mCharacterMesh_AnimState->setLoop(false);
+				mCharacterMesh_AnimState->setEnabled(true);
+			}
+			break;
+		}		
+	}
+
+	if(mForceAnimChange)
+		mForceAnimChange = false;
+}
+
+String TrollCharacter::getAnimStateName(PlayerAnimState as,  int option)
+{
+	switch (as)
+	{
+		case PLAYERANIMSTATE_IDLE:
+		{
+			if(option)
+				return "turn_idle1";
+			else
+				return "turn_idle2";
+		}
+		case PLAYERANIMSTATE_TURN:
+		{
+			if(option)
+				return "turn_idle1";
+			else
+				return "turn_idle2";
+		}
+		case PLAYERANIMSTATE_STAND:
+		{
+			return "stand";			
+		}
+		case PLAYERANIMSTATE_WALK:
+		{
+				return "walk";			
+		}
+		case PLAYERANIMSTATE_ATTACK:
+		{
+			if(option)
+			 return "attack1";				
+			else
+			 return "attack2";				
+		}
+		case PLAYERANIMSTATE_PAIN:
+		{
+			if(option)
+			 return "pain1";				
+			else
+			 return "pain2";				
+		}
+		case PLAYERANIMSTATE_DEATH:
+		{
+			if(option)
+			 return "death1";				
+			else
+			 return "death2";				
+		}
+	}
+	return "";
+}
+
+bool PlayerCharacter::frameStarted(const FrameEvent& evt)
+{
+//	LogManager::getSingleton().logMessage("CHARACTERPLAYER_FRAMESTARTED");
+	doAction(evt.timeSinceLastFrame);
+
+	float dt = evt.timeSinceLastFrame;
+		
+	if(mCharacterMesh_AnimState)
+	 mCharacterMesh_AnimState->addTime(dt * getAnimSpeed());	
+	
+	if(mCharacterMeshEntity)
+	this->mCharacterMeshEntity->_updateAnimation();
+
+	if(mWeaponEntity)
+	{
+		mWeaponNode->setPosition(mWeaponAttachBone->getWorldPosition());
+		mWeaponNode->setOrientation(mWeaponAttachBone->getWorldOrientation());
+
+		Vector3 translation = mWeaponBoundNode->getWorldPosition();
+		Quaternion orientation = mWeaponBoundNode->getWorldOrientation();
+		
+		mWeaponBound->setGlobalOrientation(orientation);		
+		mWeaponBound->setGlobalPosition(translation);
+
+		if(mDebug)
+		{
+			mWeaponBoundDebugNode->setPosition(translation);
+			mWeaponBoundDebugNode->setOrientation(orientation);
+		}
+	}
+
+	return true;
+}
+
+void FPSPlayer::processKeyInputs(InputReader* inputDevice)
+{	
+	if(mHealth > 0)
+	{
+		mMoving = false;
+		if (inputDevice->isKeyDown(KC_W))
+		{ 
+			mPlayerCharacter->addMovement(Character::DR_Forward); 
+			mMoving = true;
+		} 	
+		if (inputDevice->isKeyDown(KC_S))
+		{ 
+			mPlayerCharacter->addMovement(Character::DR_Backward);
+			mMoving = true;
+		} 
+		if (inputDevice->isKeyDown(KC_A))
+		{ 
+			mPlayerCharacter->addMovement(Character::DR_StepRight);
+			mMoving = true;
+		} 
+		if (inputDevice->isKeyDown(KC_D))
+		{ 
+			mPlayerCharacter->addMovement(Character::DR_StepLeft); 
+			mMoving = true;
+		} 
+
+		if (inputDevice->isKeyDown(KC_1))
+		{
+			if(mWeapon != 0)
+			{
+				mWeapon = 0;
+				mForceAnimChange = true;
+				if(mFireBall)
+				 mFireBall->deactivate();
+
+				OverlayElement* SwordIcon = OverlayManager::getSingleton().getOverlayElement("Sword");
+				SwordIcon->setHeight(0.1);
+				SwordIcon->setWidth(0.1);
+				SwordIcon->setTop(0.89);
+				SwordIcon->setLeft(0.1);
+
+				OverlayElement* FBIcon = OverlayManager::getSingleton().getOverlayElement("FireBall");
+				FBIcon->setHeight(0.04);
+				FBIcon->setWidth(0.04);
+				FBIcon->setTop(0.92);
+				FBIcon->setLeft(0.22);
+			}
+		}
+		if (inputDevice->isKeyDown(KC_2))
+		{
+			if(mWeapon!= 1)
+			{
+				mWeapon = 1;
+				mForceAnimChange = true;
+				if(mFireBall)
+				 mFireBall->activate();
+
+				OverlayElement* SwordIcon = OverlayManager::getSingleton().getOverlayElement("Sword");
+				SwordIcon->setHeight(0.04);
+				SwordIcon->setWidth(0.04);
+				SwordIcon->setTop(0.92);
+				SwordIcon->setLeft(0.13);
+
+				OverlayElement* FBIcon = OverlayManager::getSingleton().getOverlayElement("FireBall");
+				FBIcon->setHeight(0.1);
+				FBIcon->setWidth(0.1);
+				FBIcon->setTop(0.89);
+				FBIcon->setLeft(0.18);
+			}
+		}
+
+		if (inputDevice->isKeyDown(KC_LSHIFT))
+		{
+			mStrength -= 1.5 * mMaxStrength * 0.018;
+				if(mStrength < 0.0) mStrength = 0.0;
+
+			if(mStrength > 0.1 * mMaxStrength)
+			{
+				if(mCharacterController)
+					((MyCharMoveController*)mCharacterController)->movespeed = 2.0;
+				mRunning = true;				
+			}
+			else
+			{
+				if(mCharacterController)
+					((MyCharMoveController*)mCharacterController)->movespeed = 1.0;
+				mRunning = false;
+			}
+		}
+		else
+		{
+			if(mCharacterController)
+			((MyCharMoveController*)mCharacterController)->movespeed = 1.0;
+			mRunning = false;
+		}
+	}
+}
+
+void FPSPlayer::processMouseInputs(InputReader* inputDevice)
+{
+	if(mHealth > 0)
+	{
+		if( inputDevice->getMouseButton( 0 ) )//attack
+			setAnimState(PLAYERANIMSTATE_ATTACK);
+			
+		//else if( inputDevice->getMouseButton( 1 ) )//block
+		//	setAnimState(PLAYERANIMSTATE_BLOCK);
+	}
+	else if( inputDevice->getMouseButton( 1 ))//respawn
+	{
+		mHealth = mMaxHealth;
+		CompositorManager::getSingleton().setCompositorEnabled(OgreIlluminationManager::getSingleton().getMainViewport(),
+														"GTP/PostProc/MotionBlur", false);
+		this->mWeaponEntity->setVisible(true);
+		this->mCharacterMeshEntity->setVisible(true);
+		mWeapon = 0;
+		isAlive = true;
+	}
+
+	Quaternion q; 
+	q.FromAngleAxis( Radian(Degree(-inputDevice->getMouseRelX() * 0.13)), Vector3::UNIT_Y ); 
+	q = mPlayerCharacter->getGlobalOrientation() * q; 
+	mPlayerCharacter->setDirection(q); 
+
+	mCamera->pitch(Radian(Degree(-inputDevice->getMouseRelY() * 0.13)));		
+}
+
+bool FPSPlayer::frameStarted(const FrameEvent& evt)
+{
+//	LogManager::getSingleton().logMessage("FPSPLAYER_FRAMESTARTED");
+
+	float dt = evt.timeSinceLastFrame;
+		
+	if(mHealth == 0)//we are dead
+	{
+		CompositorManager::getSingleton().setCompositorEnabled(OgreIlluminationManager::getSingleton().getMainViewport(),
+														"GTP/PostProc/MotionBlur", true);
+		if(mFireBall)
+			mFireBall->deactivate();
+		static float dedanimT = 0;
+
+		this->mWeaponEntity->setVisible(false);
+		this->mCharacterMeshEntity->setVisible(false);
+
+		float cameraPos = - dedanimT;
+		if(cameraPos < -mCameraHeight) cameraPos = -mCameraHeight;
+		
+		mCamera->setPosition(Vector3(0,cameraPos,0));
+
+		dedanimT += dt * 0.7;
+
+		OverlayElement* healthUI = OverlayManager::getSingleton().getOverlayElement("HealthColumn");
+		healthUI->setHeight(0);		
+	}
+	else
+	{
+		mStrength += mMaxStrength * 0.018;
+		if(mStrength > mMaxStrength) mStrength = mMaxStrength;
+		
+		OverlayElement* strengthUI = OverlayManager::getSingleton().getOverlayElement("StrengthColumn");
+		float relStrength = mStrength / mMaxStrength;
+		strengthUI->setHeight(0.29 * relStrength);
+		strengthUI->setTop(0.005 +  (1.0 - relStrength) * 0.29);
+
+		mHealth += mMaxHealth * 0.005;
+		if(mHealth > mMaxHealth) mHealth = mMaxHealth;
+		
+		OverlayElement* healthUI = OverlayManager::getSingleton().getOverlayElement("HealthColumn");
+		float relHealth = mHealth / mMaxHealth;
+		healthUI->setHeight(0.29 * relHealth);
+		healthUI->setTop(0.005 +  (1.0 - relHealth) * 0.29);
+
+		mManna += mMaxManna * 0.005;
+		if(mManna > mMaxManna) mManna = mMaxManna;
+
+		OverlayElement* mannaUI = OverlayManager::getSingleton().getOverlayElement("MannaColumn");
+		float relManna = mManna / mMaxManna;
+		mannaUI->setHeight(0.29 * relManna);
+		mannaUI->setTop(0.005 +  (1.0 - relManna) * 0.29);
+
+			
+		if(mCharacterMesh_AnimState)
+		{
+			float animspeed = 1.2;
+			if(mCurrentAnimState == PLAYERANIMSTATE_WALK && mRunning)
+				animspeed *= 1.5;
+			if(mCurrentAnimState == PLAYERANIMSTATE_ATTACK)
+				animspeed *= 2.0;
+
+			mCharacterMesh_AnimState->addTime(dt*animspeed);	
+		}
+
+		static float moveTime=0;
+		
+		float movecameraup = 0;
+		if(mDebug)movecameraup = 2.0;
+
+		if(mMoving)
+		{
+			setAnimState(PLAYERANIMSTATE_WALK);
+
+			moveTime += dt;
+			mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0) + Vector3(0,0.009 * pow(sin(moveTime*5.0), 2),0));
+		}
+		else
+		{
+			if(Math::UnitRandom() > 0.98)
+				setAnimState(PLAYERANIMSTATE_IDLE);
+			else
+				setAnimState(PLAYERANIMSTATE_STAND);
+
+			moveTime = 0;
+			mCamera->setPosition(Vector3(0,mCameraHeight + movecameraup,0));
+		}
+
+		if(mCharacterMeshEntity)
+		this->mCharacterMeshEntity->_updateAnimation();
+
+		if(mWeaponEntity)
+		{
+			mWeaponNode->setPosition(mWeaponAttachBone->getWorldPosition());
+			mWeaponNode->setOrientation(mWeaponAttachBone->getWorldOrientation());
+
+			Vector3 translation = mWeaponBoundNode->getWorldPosition();
+			Quaternion orientation = mWeaponBoundNode->getWorldOrientation();
+			
+			mWeaponBound->setGlobalOrientation(orientation);		
+			mWeaponBound->setGlobalPosition(translation);
+			
+			if(mDebug)
+			{
+				mWeaponBoundDebugNode->setPosition(translation);
+				mWeaponBoundDebugNode->setOrientation(orientation);
+			}
+		}
+		if(mFireBall)
+			mFireBall->update(dt);	
+	}
+	return true;
+}
+
+String FPSPlayer::getAnimStateName(PlayerAnimState as, int option)
+{
+	switch (as)
+	{
+		case PLAYERANIMSTATE_IDLE:
+		{
+			if(mWeapon < 1)
+				return "sword_idle";
+			else
+				return "magic_idle";
+		}
+		case PLAYERANIMSTATE_STAND:
+		{
+			if(mWeapon < 1)
+				return "sword_stand";
+			else
+				return "magic_stand";
+		}
+		case PLAYERANIMSTATE_BLOCK:
+		{
+				return "block";			
+		}
+		case PLAYERANIMSTATE_WALK:
+		{
+				return "walk";			
+		}
+		case PLAYERANIMSTATE_ATTACK:
+		{
+			if(option)
+			{
+				if(mWeapon < 1)
+					return "attack1";
+				else
+					return "magic_attack";
+			}
+			else
+			{
+				if(mWeapon < 1)
+					return "attack2";
+				else
+					return "magic_attack";
+			}
+		}
+	}
+	return "";
+}
+
+void FPSPlayer::setAnimState(PlayerAnimState as)
+{
+	if(!mCharacterMeshEntity)
+		return;
+
+	switch(as)	
+	{
+		case PLAYERANIMSTATE_STAND:
+		{
+			if(mCurrentAnimState != PLAYERANIMSTATE_STAND || mForceAnimChange)
+			{
+				//wait until anim finishes
+				if(mCharacterMesh_AnimState->getTimePosition() >=
+					mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop())
+				{
+					mCurrentAnimState = PLAYERANIMSTATE_STAND;
+					mCharacterMesh_AnimState->setEnabled(false);
+					mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_STAND));
+					mCharacterMesh_AnimState->setLoop(true);
+					mCharacterMesh_AnimState->setEnabled(true);
+				}
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_IDLE:
+		{
+			if(mCurrentAnimState != PLAYERANIMSTATE_IDLE || mForceAnimChange)
+			{
+				//wait until anim finishes
+				if(mCharacterMesh_AnimState->getTimePosition() >=
+					mCharacterMesh_AnimState->getLength() || mCharacterMesh_AnimState->getLoop() || mCurrentAnimState == PLAYERANIMSTATE_IDLE)
+				{
+					mCurrentAnimState = PLAYERANIMSTATE_IDLE;
+					mCharacterMesh_AnimState->setEnabled(false);
+					mCharacterMesh_AnimState = mCharacterMeshEntity->getAnimationState(getAnimStateName(PLAYERANIMSTATE_IDLE));
+					mCharacterMesh_AnimState->setTimePosition(0);
+					mCharacterMesh_AnimState->setLoop(false);
+					mCharacterMesh_AnimState->setEnabled(true);
+				}
+			}
+			break;
+		}
+		case PLAYERANIMSTATE_WALK:
+		{
+			if(mCurrentAnimState != PLAYERANIMSTATE_WALK)
+			{
 				if(mCurrentAnimState == PLAYERANIMSTATE_IDLE || mCurrentAnimState == PLAYERANIMSTATE_STAND)
 				{
@@ -523,4 +1111,21 @@
 				mCharacterMesh_AnimState->setLoop(false);
 				mCharacterMesh_AnimState->setEnabled(true);
+
+				if(mWeapon == 0)
+				{
+					for(std::set<PlayerCharacter*>::iterator it = mCharactersInRange.begin();
+						it != mCharactersInRange.end(); it++)
+						(*it)->addHit(getHit());
+				}
+				else
+				{
+					if(mManna > 20)
+					{
+						mManna -= 20;
+						mStrength = 0;
+						if(mFireBall)
+							mFireBall->fire();
+					}
+				}
 			}
 			break;
Index: GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/SceneSerializer.cpp
===================================================================
--- GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/SceneSerializer.cpp	(revision 2388)
+++ GTP/trunk/App/Demos/Illum/Ogre/src/Common/src/SceneSerializer.cpp	(revision 2459)
@@ -78,4 +78,5 @@
 	context.sceneNode->attachObject(context.entity);	
 #endif	
+	context.entity->setCastShadows(true);
     return false;
 }
