namespace BP
{
	namespace Game
	{
		int difficulty = DIFFICULTY_NORMAL; //current difficulty
		float time = 0.0f;
		bool enableDamageDisplay = false;
		bool initialWarpFix = false;
		
		float playerSpeedBase = BP::PLAYER_INITIAL_SPEED; //Serialize
		float playerDamageBase = BP::PLAYER_INITIAL_DAMAGE; //Serialize
		float playerPowerTimeBase = BP::PLAYER_INITIAL_POWERTIME; //Serialize
		float playerMaxHealth = BP::PLAYER_INITIAL_MAX_HEALTH; //Serialize
		int playerMaxAirJumps = BP::PLAYER_INITIAL_MAX_AIR_JUMPS; //Serialize
		bool playerMag60Upgrade = false; //Serialize
		bool gotBullsEyeBonus = false;

		//SActor monkeyRobber;
		//------------------------------------------------------------------------------------------------------------------------
		void Initialize()
		{
			time = 0.0f;
			enableDamageDisplay = false;
			initialWarpFix = false;
		
			playerSpeedBase = BP::PLAYER_INITIAL_SPEED; //Serialize
			playerDamageBase = BP::PLAYER_INITIAL_DAMAGE; //Serialize
			playerPowerTimeBase = BP::PLAYER_INITIAL_POWERTIME; //Serialize
			playerMaxHealth = BP::PLAYER_INITIAL_MAX_HEALTH; //Serialize
			playerMaxAirJumps = BP::PLAYER_INITIAL_MAX_AIR_JUMPS; //Serialize
			playerMag60Upgrade = false; //Serialize
			gotBullsEyeBonus = false;
		
			//Give all single player weapons
			// for (int i = 0; i < 24; i++)
			// {
				// LocalPlayer.GiveWeapon(i, 999);
			// }
			
			// LocalPlayer.GiveWeapon(kWpn_Plasma_MP, 999);
			// LocalPlayer.GiveWeapon(kWpn_Rocket_MP, 999);
			// LocalPlayer.GiveWeapon(kWpn_AssaultRifle_MP, 999);
			
			//Give all needed inventory for the single player campaign
			BP::Inventory::Give(kActor_Inventory_CaveDoorKey, 6);
			BP::Inventory::Give(kActor_Inventory_GraveyardKey, 2);
			BP::Inventory::Give(kActor_Inventory_KeyGate, 2);
			BP::Inventory::Give(kActor_Inventory_Satchel, 3);
			BP::Inventory::Give(kActor_Inventory_ThermalSatchel, 3);
			BP::Inventory::Give(kActor_Inventory_PowerCell, 3);
			BP::Inventory::Give(kActor_Inventory_RedLaserCell, 2);
			BP::Inventory::Give(kActor_Inventory_BlueLaserCell, 2);
			BP::Inventory::Give(kActor_Inventory_IonCapacitor, 16);
			BP::Inventory::Give(kActor_Inventory_Level1Key, 3);
			BP::Inventory::Give(kActor_Inventory_Level2Key, 3);
			BP::Inventory::Give(kActor_Inventory_Level3Key, 3);
			BP::Inventory::Give(kActor_Inventory_Level4Key, 3);
			BP::Inventory::Give(kActor_Inventory_Level5Key, 3);
			BP::Inventory::Give(kActor_Inventory_Level6Key, 6);
			BP::Inventory::Give(kActor_Inventory_PrimKey1, 1);
			BP::Inventory::Give(kActor_Inventory_PrimKey2, 1);
			BP::Inventory::Give(kActor_Inventory_PrimKey3, 1);
			BP::Inventory::Give(kActor_Inventory_PrimKey4, 1);
			BP::Inventory::Give(kActor_Inventory_PrimKey5, 1);
			BP::Inventory::Give(kActor_Inventory_PrimKey6, 1);
			BP::Inventory::Give(kActor_Inventory_Level2Talisman, 1);
			BP::Inventory::Give(kActor_Inventory_Level3Talisman, 1);
			BP::Inventory::Give(kActor_Inventory_Level4Talisman, 1);
			BP::Inventory::Give(kActor_Inventory_Level5Talisman, 1);
			BP::Inventory::Give(kActor_Inventory_Level6Talisman, 1);
			BP::Inventory::Give(kActor_Inventory_Level2Feather, 1);
			BP::Inventory::Give(kActor_Inventory_Level3Feather, 1);
			BP::Inventory::Give(kActor_Inventory_Level4Feather, 1);
			BP::Inventory::Give(kActor_Inventory_Level5Feather, 1);
			BP::Inventory::Give(kActor_Inventory_Level6Feather, 1);
			BP::Inventory::Give(kActor_Inventory_NukePart, 6);
			// BP::Inventory::Give(kActor_Misc_TotemInventory, 6);
			
			
			// DoPlayerWarp(0, 17401, kLevel_BlindOneBoss, false);
			// DoPlayerWarp(0, 17501, kLevel_QueenBoss, false);
			// DoPlayerWarp(0, 17601, kLevel_MotherBoss, false);
			
			CinemaPlayer.StopCinema();
			
			//DoPlayerWarp(0, 1, kLevel_PortOfAdia_1, false);
			//DoPlayerWarp(0, 1, kLevel_Test, false);
			CinemaPlayer.StartCinema("cinemas/bp/start2.txt");			
		}
		//------------------------------------------------------------------------------------------------------------------------
		void OnSerialize(kDict dict)
		{
			SERIALIZE_BOOL(BP::Game::enableDamageDisplay);
			SERIALIZE_BOOL(BP::Game::gotBullsEyeBonus);
			SERIALIZE_FLOAT(BP::Game::time);
			SERIALIZE_INT(BP::lastInstanceID);
			SERIALIZE_INT(BP::LocalPlayer::controlLockFlags);
			SERIALIZE_INT(BP::LocalPlayer::moveLockFlags);
			SERIALIZE_INT(BP::LocalPlayer::noWeaponFlags);
			SERIALIZE_INT(BP::Game::difficulty);
			
			SERIALIZE_INT(playerMaxAirJumps);
			SERIALIZE_FLOAT(playerMaxHealth);
			SERIALIZE_FLOAT(playerDamageBase);
			SERIALIZE_FLOAT(playerSpeedBase);
			SERIALIZE_FLOAT(playerPowerTimeBase);
			SERIALIZE_BOOL(playerMag60Upgrade);
			SERIALIZE_BOOL(initialWarpFix);
			
			// SERIALIZE_SACTOR(BP::Game::monkeyRobber);
			if (difficulty == DIFFICULTY_HARDCORE && Game.ActiveMapID() != kLevel_Hub)
			{
				BP::LocalPlayer::Actor.PlaySound("sounds/shaders/BP/Adon/ADSAV018_SHORT.ksnd");
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
		void OnDeserialize(kDict& in dict)
		{
			DESERIALIZE_BOOL(BP::Game::enableDamageDisplay);
			DESERIALIZE_BOOL(BP::Game::gotBullsEyeBonus);
			DESERIALIZE_FLOAT(BP::Game::time);
			DESERIALIZE_INT(BP::lastInstanceID);
			DESERIALIZE_INT(BP::LocalPlayer::controlLockFlags);
			DESERIALIZE_INT(BP::LocalPlayer::moveLockFlags);
			DESERIALIZE_INT(BP::LocalPlayer::noWeaponFlags);
			DESERIALIZE_INT(BP::Game::difficulty);
			
			DESERIALIZE_INT(playerMaxAirJumps);
			DESERIALIZE_FLOAT(playerMaxHealth);
			DESERIALIZE_FLOAT(playerDamageBase);
			DESERIALIZE_FLOAT(playerSpeedBase);
			DESERIALIZE_FLOAT(playerPowerTimeBase);
			DESERIALIZE_BOOL(playerMag60Upgrade);
			DESERIALIZE_BOOL(initialWarpFix);

			// DESERIALIZE_SACTOR(BP::Game::monkeyRobber);
		}
		//------------------------------------------------------------------------------------------------------------------------
		void OnDeserializeStart()
		{
			BP::UI::OnDeserializeStart();
			
			
			// monkeyRobber.SetDeserializedActor();
				
			if (Game.ActiveMapID() != kLevel_Hub)
			{
				//if loaded a game on hardest difficulty then go to the title
				if (difficulty == DIFFICULTY_HARDCORE)
				{
					CinemaPlayer.StartCinema("cinemas/bp/totitle.txt");
					return;
				}
				else
				{
					BP::LocalPlayer::Actor.PlaySound("sounds/shaders/BP/Adon/AdonA048.ksnd");
					Hud.AddMessage("Monkey stole your ammo!", 260);
					
					LocalPlayer.ConsumeAltAmmo(999);
					LocalPlayer.ConsumeAmmo(999);
					
					BP::LocalPlayer::Actor.Health() /= 2.0f;
					BP::LocalPlayer::Script.AddAilment(BP::Ailments::TYPE_STUN);
					
					bool isMonkeyRobber = false;
					kActorIterator iter;
					kActor@ iActor;
					while ((@iActor = iter.GetNext()) !is null)
					{
						if (iActor.Type() == kActor_Monkey_Robber)
						{
							isMonkeyRobber = true;
							break;
						}
					}
					
					//in battle then spawn monkey(using SActor) if theres no monkey
					//if (!monkeyRobber.Exists() || (monkeyRobber.actor.Flags() & AF_NODAMAGE) != 0)
					if (!isMonkeyRobber)
					{
						kVec3 pos = Math::vecZero; //closest point near player
						kActor @monkeyActor = BP::Spawn::Enemy(kActor_Monkey_Robber, BP::LocalPlayer::Actor.Origin(), 50.0f);

						monkeyActor.WorldComponent().SetNearestPosition(BP::LocalPlayer::Actor.Origin());
						//monkeyRobber.SetActor(@monkeyActor);
						monkeyActor.PlaySound(kSfx_Monkey_Scream);
						monkeyActor.RunFxEvent("Monkey_Select");
					}
				}
			}
		}
		//------------------------------------------------------------------------------------------------------------------------
		void OnStart()
		{
			BP::Tasks::Clear();
			// monkeyRobber.Clear();
			BP::UI::OnStart();
		}
		//------------------------------------------------------------------------------------------------------------------------
		void OnTick()
		{
			if (!initialWarpFix && !CinemaPlayer.Playing() && Game.ActiveMapID() == kLevel_PortOfAdia_1)
			{
				initialWarpFix = true;
				DoPlayerWarp(0, 11111, kLevel_PortOfAdia_1, false);
			}
			
			time += GAME_DELTA_TIME;
			BP::Input::OnTick();
			BP::Tasks::Tick();
			BP::UI::OnTick();
			BP::LocalPlayer::tauntTime = MAX(BP::LocalPlayer::tauntTime - GAME_DELTA_TIME, 0.0f);
		}
		//------------------------------------------------------------------------------------------------------------------------
		// Returns the current FOV value in Graphics options
		//------------------------------------------------------------------------------------------------------------------------
		float GetFOV()
		{
			kStr fovString;
			bool foundVar = Sys.GetCvarValue("r_fov", fovString);
			return fovString.Atof();
		}
		//------------------------------------------------------------------------------------------------------------------------
	}
}
