/*
trigger_player_class
Author: kmkz (e-mail: al_basualdo@hotmail.com )

This trigger when touched assigns a class to a player modifying its atributes depending of the class selected.

--------------------------------------
important vars:
Player_class(player_class): class that will affect the player. 

---------------------------------------
flags:
1: "Start off"
self explanatory.
*/

#include "data_classlevels_data"
#include "data_classlevels"
#include "game_spritetext"

	const string MODEL_NEUTRAL		= "models/player/helmet/helmet.mdl";
	const string MODEL_SCOUT 		= "models/player/tfc_scout/tfc_scout.mdl";
	const string MODEL_SECURITY		= "models/player/barney/barney.mdl";
	const string MODEL_MEDIEVAL		= "models/player/androgyknight/androgyknight.mdl";
	const string MODEL_SOLDIER 		= "models/player/veteran/veteran.mdl";
	const string MODEL_MEDIC 		= "models/player/q3tf_medic/q3tf_medic.mdl";
	const string MODEL_SCIENTIST	= "models/player/scientist/scientist.mdl";

	enum TriggerPlayerClassSpawnFlags
	{
		SF_START_OFF 		= 1 << 0,
	}

	class trigger_player_class : ScriptBaseAnimating
	{
		CBaseEntity@ pEntity = null;
		string PlayerClass;
		int class_level;
		string class_model;
		string m_iszMaster;
				
		float custom_health;
		float custom_armor;
		float custom_damage;
		float custom_speed;
		float custom_jump;
		
		void Precache() 
		{
			if (PlayerClass == string(PLAYERCLASS_NONE))		{g_Game.PrecacheModel( MODEL_NEUTRAL);}
			if (PlayerClass == string(PLAYERCLASS_NEUTRAL))		{g_Game.PrecacheModel( MODEL_NEUTRAL);}
			if (PlayerClass == string(PLAYERCLASS_SCOUT))		{g_Game.PrecacheModel( MODEL_SCOUT); }
			if (PlayerClass == string(PLAYERCLASS_SECURITY))	{g_Game.PrecacheModel( MODEL_SECURITY); }
			if (PlayerClass == string(PLAYERCLASS_MEDIEVAL)) 	{g_Game.PrecacheModel( MODEL_MEDIEVAL); }
			if (PlayerClass == string(PLAYERCLASS_SOLDIER)) 	{g_Game.PrecacheModel( MODEL_SOLDIER); }
			if (PlayerClass == string(PLAYERCLASS_MEDIC)) 		{g_Game.PrecacheModel( MODEL_MEDIC); }
			if (PlayerClass == string(PLAYERCLASS_SCIENTIST)) 	{g_Game.PrecacheModel( MODEL_SCIENTIST); }
			
			if (PlayerClass == string(PLAYERCLASS_CUSTOM))
			{
				if( string( self.pev.model ).IsEmpty() )
					g_Game.PrecacheModel( "models/player/helmet/helmet.mdl" );
				else
					g_Game.PrecacheModel( self.pev.model );
			}
				
			BaseClass.Precache();
		}
		
		void Spawn() 
		{
			self.pev.movetype 		= MOVETYPE_NONE;
			self.pev.solid 			= SOLID_TRIGGER;
			self.pev.framerate 		= 1.0f;
			self.pev.rendermode		= 4;
			self.pev.renderamt		= 180;
			
			Precache();
			g_EntityFuncs.SetOrigin( self, self.pev.origin + Vector (0, 0, 36 ));
			g_EntityFuncs.SetSize( self.pev, Vector (0, 0, 0), Vector (16, 16, 72));
			SetUse(UseFunction(this.TriggerUse));
			if (self.pev.SpawnFlagBitSet (SF_START_OFF))
				{
				SetThink(ThinkFunction(this.ThinkDisabled));
				SetTouch(TouchFunction(this.TriggerTouchOff));
				}
			else
				{
				SetThink(ThinkFunction(this.ThinkOff));
				SetTouch(TouchFunction(this.TriggerTouchOn));
				}
			
			if (PlayerClass == string(PLAYERCLASS_CUSTOM))
			{
				if( string( self.pev.model ).IsEmpty() )
					class_model = MODEL_NEUTRAL;
				else
					class_model = self.pev.model;
			}
						
			int INPlayerClass = atoi(PlayerClass);
			SetClassData(INPlayerClass, @self);
			
			self.InitBoneControllers();
		}
		
		bool KeyValue( const string& in szKey, const string& in szValue )
			{
				if(szKey == "player_class")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "custom_health")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "custom_armor")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "custom_damage")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "custom_speed")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "custom_jump")
				{
					PlayerClass = szValue;
					return true;
				}
				else if(szKey == "master")
				{
					m_iszMaster = szValue;
					return true;
				}
				else 
				{
					return BaseClass.KeyValue( szKey, szValue );
				}
			}
		
		void TriggerUse(CBaseEntity@ pActivator, CBaseEntity@ pCaller, USE_TYPE useType, float flValue)
		{
			if (useType == USE_SET) // set new atributes if level up
			{
				SetLevelUp();
				return;
			}
			
			/*if( !m_iszMaster.IsEmpty() && !g_EntityFuncs.IsMasterTriggered( m_iszMaster, self ) )
			{	
				return;
			}*/
		
			SetTouch(TouchFunction(this.TriggerTouchOn));
			SetThink(ThinkFunction(this.ThinkOn));
		}
		
		void TriggerTouchOn(CBaseEntity@ pOther )
		{
			int IPlayerClass;
			IPlayerClass = StringToInt(PlayerClass);
			SetClassData(IPlayerClass,@self);
			SetPlayerClass (pOther,IPlayerClass);
			
			CBasePlayer@ pPlayer = cast<CBasePlayer@>(pOther);
			
			HUDTextParams textParams;
			textParams.channel = CHAN_AUTO;
			textParams.x = -1;
			textParams.y = -1;
			textParams.effect = 0;
			textParams.r1 = 255;
			textParams.g1 = 255;
			textParams.b1 = 255;
			textParams.a1 = 255;
			textParams.r2 = 255;
			textParams.g2 = 255;
			textParams.b2 = 255;
			textParams.a2 = 255;
			textParams.fadeinTime = 0.5;
			textParams.fadeoutTime = 1.5;
			textParams.holdTime = 2;
			textParams.fxTime = 0.5;
				
			ClasslevelSet(classlevels_file_array[0]); // check max exp data is updated
			if (iLanguage == LANGUAGE_SPANISH) {g_PlayerFuncs.HudMessage( pPlayer, textParams, class_description + string(classlevels_file_array[1]) + "\nExp:" + string(classlevels_file_array[0]) + "\nProximo nivel:" + cl_maxexp );} else
			if (iLanguage == LANGUAGE_ENGLISH) {g_PlayerFuncs.HudMessage( pPlayer, textParams, class_description + string(classlevels_file_array[1]) + "\nExp:" + string(classlevels_file_array[0]) + "\nNext level:" + cl_maxexp );}
		}
		
		void SetClassData(int SCPlayerClass, CBaseAnimating@ pEntity)
		{
			if (SCPlayerClass == PLAYERCLASS_NEUTRAL) 	{classvector[CLASSVECTOR_HEALTH] = neutral_health; 	classvector[CLASSVECTOR_DAMAGE] = neutral_damage;	classvector[CLASSVECTOR_SPEED] = neutral_speed; 	classvector[CLASSVECTOR_JUMP] = neutral_jump; 		g_EntityFuncs.SetModel( @pEntity, MODEL_NEUTRAL );	if (iLanguage == 0) {class_description = neutral_description1;} 	else {class_description = neutral_description2;}}
			if (SCPlayerClass == PLAYERCLASS_SCOUT) 	{classvector[CLASSVECTOR_HEALTH] = scout_health; 	classvector[CLASSVECTOR_DAMAGE] = scout_damage;		classvector[CLASSVECTOR_SPEED] = scout_speed; 		classvector[CLASSVECTOR_JUMP] = scout_jump; 		g_EntityFuncs.SetModel( @pEntity, MODEL_SCOUT );	if (iLanguage == 0) {class_description = scout_description1;} 		else {class_description = scout_description2;}}
			if (SCPlayerClass == PLAYERCLASS_SECURITY) 	{classvector[CLASSVECTOR_HEALTH] = security_health;	classvector[CLASSVECTOR_DAMAGE] = security_damage;	classvector[CLASSVECTOR_SPEED] = security_speed;	classvector[CLASSVECTOR_JUMP] = security_jump;		g_EntityFuncs.SetModel( @pEntity, MODEL_SECURITY);	if (iLanguage == 0) {class_description = security_description1;} 	else {class_description = security_description2;}}
			if (SCPlayerClass == PLAYERCLASS_MEDIEVAL) 	{classvector[CLASSVECTOR_HEALTH] = medieval_health;	classvector[CLASSVECTOR_DAMAGE] = medieval_damage; 	classvector[CLASSVECTOR_SPEED] = medieval_speed;	classvector[CLASSVECTOR_JUMP] = medieval_jump;		g_EntityFuncs.SetModel( @pEntity, MODEL_MEDIEVAL);	if (iLanguage == 0) {class_description = medieval_description1;} 	else {class_description = medieval_description2;}}
			if (SCPlayerClass == PLAYERCLASS_SOLDIER) 	{classvector[CLASSVECTOR_HEALTH] = soldier_health; 	classvector[CLASSVECTOR_DAMAGE] = soldier_damage; 	classvector[CLASSVECTOR_SPEED] = soldier_speed;		classvector[CLASSVECTOR_JUMP] = soldier_jump; 		g_EntityFuncs.SetModel( @pEntity, MODEL_SOLDIER);	if (iLanguage == 0) {class_description = soldier_description1;}		else {class_description = soldier_description2;}}
			if (SCPlayerClass == PLAYERCLASS_MEDIC) 	{classvector[CLASSVECTOR_HEALTH] = medic_health; 	classvector[CLASSVECTOR_DAMAGE] = medic_damage; 	classvector[CLASSVECTOR_SPEED] = medic_speed; 		classvector[CLASSVECTOR_JUMP] = medic_jump; 		g_EntityFuncs.SetModel( @pEntity, MODEL_MEDIC);		if (iLanguage == 0) {class_description = medic_description1;} 		else {class_description = medic_description2;}}
			if (SCPlayerClass == PLAYERCLASS_SCIENTIST) {classvector[CLASSVECTOR_HEALTH] = scientist_health;classvector[CLASSVECTOR_DAMAGE] = scientist_damage;	classvector[CLASSVECTOR_SPEED] = scientist_speed;	classvector[CLASSVECTOR_JUMP] = scientist_jump;		g_EntityFuncs.SetModel( @pEntity, MODEL_SCIENTIST);	if (iLanguage == 0) {class_description = scientist_description1;}	else {class_description = scientist_description2;}}
			if (SCPlayerClass == PLAYERCLASS_CUSTOM) 	{classvector[CLASSVECTOR_HEALTH] = custom_health;	classvector[CLASSVECTOR_DAMAGE] = custom_damage;	classvector[CLASSVECTOR_SPEED] = custom_speed;		classvector[CLASSVECTOR_JUMP] = custom_jump;		g_EntityFuncs.SetModel( @pEntity, self.pev.model);	if (iLanguage == 0) {class_description = "";} 						else {class_description = "";}}
		}	
		
		void TriggerTouchOff(CBaseEntity@ pOther )
		{
		
		}
		
		void ThinkOn()
		{
			SetTouch(TouchFunction(this.TriggerTouchOn));
			SetThink(ThinkFunction(this.ThinkOff));
		}
		
		void ThinkOff()
		{
			SetTouch(TouchFunction(this.TriggerTouchOff));
			SetThink(ThinkFunction(this.ThinkOn));
		}
		
		void ThinkDisabled()
		{
		
		}
		
		void SetPlayerClass (CBaseEntity@ BasePlayer, int SPlayerClass)
		{
			int tobow_adjust = 0;
			if (BasePlayer.pev.noise == "true")
			{
				tobow_adjust = 90;
			} 
			else
			{
				tobow_adjust = 0;
			}
			
			SetClassData(SPlayerClass,@self);
			
			class_level = classlevels_file_array[1];
			BasePlayer.pev.team = SPlayerClass;
			BasePlayer.pev.max_health = BasePlayer.pev.health = 100 + (classvector[CLASSVECTOR_HEALTH] *10) + (class_level * (classvector[CLASSVECTOR_HEALTH] + 5));
					
			CBasePlayer@ pPlayer = cast<CBasePlayer@>(BasePlayer);
			pPlayer.SetMaxSpeed(270 - (tobow_adjust) + (int(classvector[CLASSVECTOR_SPEED]) * 5) + (class_level  * (int(classvector[CLASSVECTOR_SPEED]) + 5 ))); 
			
			BasePlayer.pev.gravity = (1 - (classvector[CLASSVECTOR_JUMP] * 0.10)) - (class_level * (10 - classvector[CLASSVECTOR_JUMP] ) * 0.001);
			//g_EntityFuncs.SetModel( BasePlayer, class_model);
			
		}
		
		void SetLevelUp()
		{
			for( int iPlayer = 1; iPlayer <= g_PlayerFuncs.GetNumPlayers() + 1; ++iPlayer )
			{
				CBasePlayer@ pPlayer = g_PlayerFuncs.FindPlayerByIndex( iPlayer );
								
				if( pPlayer !is null )
				{
					SetPlayerClass (pPlayer,int (pPlayer.pev.team));
					HUDTextParams textParams;
					textParams.channel = CHAN_AUTO;
					textParams.x = -1;
					textParams.y = 0.1;
					textParams.effect = 0;
					textParams.r1 = 255;
					textParams.g1 = 255;
					textParams.b1 = 255;
					textParams.a1 = 255;
					textParams.r2 = 255;
					textParams.g2 = 255;
					textParams.b2 = 255;
					textParams.a2 = 255;
					textParams.fadeinTime = 0.5;
					textParams.fadeoutTime = 1.5;
					textParams.holdTime = 4;
					textParams.fxTime = 0.5;
				
					if (iLanguage == LANGUAGE_SPANISH) {g_PlayerFuncs.HudMessage( pPlayer, textParams, "Classlevels: Bienvenido al nivel " + string(classlevels_file_array[1]) );} else
					if (iLanguage == LANGUAGE_ENGLISH) {g_PlayerFuncs.HudMessage( pPlayer, textParams, "Classlevels: Welcome to level " + string(classlevels_file_array[1]) );}
				}
			}
		}
	}
	
	HookReturnCode PlayerSpawn( CBasePlayer@ pPlayer )
	{
		pPlayer.SetMaxSpeed(270);
		return HOOK_CONTINUE;
	}

	void RegisterTriggerPlayerClass()
	{
		g_CustomEntityFuncs.RegisterCustomEntity( "trigger_player_class", "trigger_player_class" );
	}

