#define BP_DEBUG

#ifdef BP_DEBUG
    #define DebugLog(x)			Sys.Print("" + x)
    #define DebugError(x)		Sys.Warning("" + x + "\n")
	#define DebugLogThis(x)		DebugLog(#x + " = " + x)
	#define DebugLogIsNull(x)	DebugLog(#x + " is null = " + (x is null))
    #define DebugLogAssert(x)	DebugError("[ASSERT] " + x)

	namespace BP
	{
		namespace Debug
		{
			void Assert(bool condition, const kStr& in message, const bool crash)
			{
				if (!condition)
				{
					if (BP::String::IsEmpty(message))
					{
						DebugLogAssert("Assertion failed");
					}
					else
					{
						DebugLogAssert(message);
					}
					if (crash)
					{
						//Crash game and exit with decent runtime error message
						array<int> doCrash = { doCrash[0] };
					}
				}
			}
		}
	}
	#define DebugAssert(condition, message)	BP::Debug::Assert(condition, message, true)
	
#else
    #define DebugLog(x)
    #define DebugError(x)
	#define DebugLogThis(x)
	#define DebugLogIsNull(x)
	#define DebugLogAssert(x)
	#define DebugAssert(x, y)
#endif

#define QUAT_IDENTITY kQuat(0.0f, 0.0f, 0.0f)

#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))

bool DeserializeBool(kDict& in dict, const kStr& in key)
{
    kStr szOut;
    
    if(dict.GetString(key, szOut))
    {
        return szOut == "true";
    }
    
    return false;
}

#ifdef KEX_DEBUG
    #define DEBUG_PRINT(x) Sys.Print(x)
#else
    #define DEBUG_PRINT(x)
#endif

#define SERIALIZE(x)			dict.Add(#x, ""+x)
#define SERIALIZE_INT(x)		dict.Add(#x, ""+x)
#define SERIALIZE_FLOAT(x)		dict.Add(#x, ""+x)
#define SERIALIZE_BOOL(x)		dict.Add(#x, ""+x)
#define SERIALIZE_STRING(x)		dict.Add(#x, x)
#define SERIALIZE_VECTOR(x)		dict.Add(#x, x.ToString())
#define SERIALIZE_SACTOR(x)		x.Serialize(dict, #x)
#define DESERIALIZE_FLOAT(x)	dict.GetFloat(#x, x)
#define DESERIALIZE_INT(x)		dict.GetInt(#x, x)
#define DESERIALIZE_BOOL(x)		x = DeserializeBool(dict, #x)
#define DESERIALIZE_STRING(x)	dict.GetString(#x, x)
#define DESERIALIZE_VECTOR(x)	dict.GetVector(#x, x)
#define DESERIALIZE_SACTOR(x)	x.Deserialize(dict, #x)

#define SERIALIZEKEY_INT(key, x)		dict.Add(key + #x, ""+x)
#define SERIALIZEKEY_FLOAT(key, x)		dict.Add(key + #x, ""+x)
#define SERIALIZEKEY_BOOL(key, x)		dict.Add(key + #x, ""+x)
#define SERIALIZEKEY_STRING(key, x)		dict.Add(key + #x, x)
#define SERIALIZEKEY_VECTOR(key, x)		dict.Add(key + #x, x.ToString())
#define SERIALIZEKEY_SACTOR(key, x)		x.Serialize(dict, key + #x)
#define DESERIALIZEKEY_FLOAT(key, x)	dict.GetFloat(key + #x, x)
#define DESERIALIZEKEY_INT(key, x)		dict.GetInt(key + #x, x)
#define DESERIALIZEKEY_BOOL(key, x)		x = DeserializeBool(dict, key + #x)
#define DESERIALIZEKEY_STRING(key, x)	dict.GetString(key + #x, x)
#define DESERIALIZEKEY_VECTOR(key, x)	dict.GetVector(key + #x, x)
#define DESERIALIZEKEY_SACTOR(key, x)	x.Deserialize(dict, key + #x)

#include "defs/common.txt"
#include "defs/BP/Common.txt"

#include "scripts/animations.txt"
#include "scripts/actions.txt"
#include "scripts/destructibles.txt"
#include "scripts/door.txt"
#include "scripts/actionObject.txt"
#include "scripts/interactiveAnim.txt"
#include "scripts/turret.txt"
#include "scripts/totem.txt"
#include "scripts/blindBoss.txt"
#include "scripts/queenBoss.txt"
#include "scripts/motherBoss.txt"
#include "scripts/primagenBoss.txt"
#include "scripts/netcallbacks.txt"

#include "scripts/BP/Trigger.txt"
#include "scripts/BP/SActor.txt"
#include "scripts/BP/ScriptActor.txt"
#include "scripts/BP/Game.txt"
#include "scripts/BP/Math.txt"
#include "scripts/BP/String.txt"
#include "scripts/BP/Array.txt"
#include "scripts/BP/LocalPlayer.txt"
#include "scripts/BP/Actor.txt"
#include "scripts/BP/Inventory.txt"
#include "scripts/BP/Input.txt"
#include "scripts/BP/Dictionary.txt"
#include "scripts/BP/DictionaryString.txt"
#include "scripts/BP/DictionaryInt.txt"
#include "scripts/BP/DictionaryActors.txt"
#include "scripts/BP/Player.txt"
#include "scripts/BP/Spawn.txt"
#include "scripts/BP/EventListener.txt"
#include "scripts/BP/DifficultyCheck.txt"
#include "scripts/BP/WorldText.txt"
#include "scripts/BP/Tasks.txt"
#include "scripts/BP/Team.txt"
#include "scripts/BP/HostileInfo.txt"
#include "scripts/BP/BotInfo.txt"
#include "scripts/BP/Debug.txt"
#include "scripts/BP/Dash.txt"
#include "scripts/BP/Rect.txt"

#include "scripts/BP/UI/UI.txt"
#include "scripts/BP/UI/Window.txt"
#include "scripts/BP/UI/Element.txt"
#include "scripts/BP/UI/ScriptElement.txt"

#include "scripts/BP/AI/AI.txt"
#include "scripts/BP/AI/AraissiSoldier.txt"
#include "scripts/BP/AI/BioBot.txt"
#include "scripts/BP/AI/BlindGuardian.txt"
#include "scripts/BP/AI/BlindSentinel.txt"
#include "scripts/BP/AI/CaveSpider.txt"
#include "scripts/BP/AI/CaveWorm.txt"
#include "scripts/BP/AI/Compsognathus.txt"
#include "scripts/BP/AI/Deadman.txt"
#include "scripts/BP/AI/DeadmanHalf.txt"
#include "scripts/BP/AI/DeathGuard.txt"
#include "scripts/BP/AI/Endtrail.txt"
#include "scripts/BP/AI/Fireborn.txt"
#include "scripts/BP/AI/FleshSentinel.txt"
#include "scripts/BP/AI/FleshWorm.txt"
#include "scripts/BP/AI/Grub.txt"
#include "scripts/BP/AI/HiveDrone.txt"
#include "scripts/BP/AI/HiveSoldier.txt"
#include "scripts/BP/AI/HiveWorker.txt"
#include "scripts/BP/AI/Leaper.txt"
#include "scripts/BP/AI/LordoftheDead.txt"
#include "scripts/BP/AI/LordoftheFlesh.txt"
#include "scripts/BP/AI/Mite.txt"
#include "scripts/BP/AI/MotherGrub.txt"
#include "scripts/BP/AI/Nala.txt"
#include "scripts/BP/AI/PrimagenDrone.txt"
#include "scripts/BP/AI/PrimagenGuard.txt"
#include "scripts/BP/AI/PrimagenTrooper.txt"
#include "scripts/BP/AI/PurlinGunner.txt"
#include "scripts/BP/AI/PurlinJuggernaut.txt"
#include "scripts/BP/AI/PurlinWarClub.txt"
#include "scripts/BP/AI/Raptoid.txt"
#include "scripts/BP/AI/Raptor.txt"
#include "scripts/BP/AI/SisterofDespair.txt"
#include "scripts/BP/AI/SpiderHatchling.txt"
#include "scripts/BP/AI/SwampWasp.txt"
#include "scripts/BP/AI/MonkeyRobber.txt"

#include "scripts/BP/Weapons/ScriptWeapon.txt"
#include "scripts/BP/Weapons/Bow.txt"
#include "scripts/BP/Weapons/CerebralBore.txt"
#include "scripts/BP/Weapons/ChargeDart.txt"
#include "scripts/BP/Weapons/FireStormCannon.txt"
#include "scripts/BP/Weapons/FlameThrower.txt"
#include "scripts/BP/Weapons/Flare.txt"
#include "scripts/BP/Weapons/FlyingGun.txt"
#include "scripts/BP/Weapons/GrenadeLauncher.txt"
#include "scripts/BP/Weapons/Harpoon.txt"
#include "scripts/BP/Weapons/Mag60.txt"
#include "scripts/BP/Weapons/Nuke.txt"
#include "scripts/BP/Weapons/PFMLayer.txt"
#include "scripts/BP/Weapons/Pistol.txt"
#include "scripts/BP/Weapons/PlasmaRifle.txt"
#include "scripts/BP/Weapons/QuadMissileLauncher.txt"
#include "scripts/BP/Weapons/RaptorClaws.txt"
#include "scripts/BP/Weapons/RazorWind.txt"
#include "scripts/BP/Weapons/RidingGun.txt"
#include "scripts/BP/Weapons/Shotgun.txt"
#include "scripts/BP/Weapons/Shredder.txt"
#include "scripts/BP/Weapons/SunfirePod.txt"
#include "scripts/BP/Weapons/Talons.txt"
#include "scripts/BP/Weapons/TekBow.txt"
#include "scripts/BP/Weapons/TorpedoLauncher.txt"
#include "scripts/BP/Weapons/Tranquilizer.txt"
#include "scripts/BP/Weapons/WarBlade.txt"
#include "scripts/BP/Weapons/AssaultRifleMP.txt"
#include "scripts/BP/Weapons/CerebralBoreMP.txt"
#include "scripts/BP/Weapons/ChargeDartMP.txt"
#include "scripts/BP/Weapons/CrossbowMP.txt"
#include "scripts/BP/Weapons/FireStormCannonMP.txt"
#include "scripts/BP/Weapons/GrenadeLauncherMP.txt"
#include "scripts/BP/Weapons/PlasmaRifleMP.txt"
#include "scripts/BP/Weapons/QuadMissileLauncherMP.txt"

#include "scripts/BP/Actors/Area.txt"
#include "scripts/BP/Actors/Barrel.txt"
#include "scripts/BP/Actors/Bullseye.txt"
#include "scripts/BP/Actors/Pickup.txt"
#include "scripts/BP/Actors/WayPoint.txt"
#include "scripts/BP/Actors/PathPoint.txt"
#include "scripts/BP/Actors/PickupHealth2.txt"
#include "scripts/BP/Actors/PickupHealth10.txt"
#include "scripts/BP/Actors/PickupHealthFull.txt"
#include "scripts/BP/Actors/PickupHealthUltra.txt"
#include "scripts/BP/Actors/PickupLifeForce.txt"

#include "scripts/BP/Ailments/Ailment.txt"
#include "scripts/BP/Ailments/Regen.txt"
#include "scripts/BP/Ailments/Quad.txt"
#include "scripts/BP/Ailments/Haste.txt"
#include "scripts/BP/Ailments/Stun.txt"
#include "scripts/BP/Ailments/AilmentMan.txt"

#include "scripts/BP/Controllers/Flare.txt"
#include "scripts/BP/Controllers/RazorWind.txt"
#include "scripts/BP/Controllers/QuadMissileLauncher.txt"
#include "scripts/BP/Controllers/CerebralBore.txt"
#include "scripts/BP/Controllers/WorldChar.txt"

#include "scripts/BP/Maps/Hub.txt"
#include "scripts/BP/Maps/Arena.txt"
#include "scripts/BP/Maps/VShooter.txt"

#include "scripts/BP/Events/DamageInfo.txt"

void OpenMenu()
{
	BP::UI::OpenMainMenu();
}

void main(void)
{
    InitDestructibleModeTable();
    InitActionObjectModeTable();
    InitInteractiveAnimModeTable();
    InitTurretModeTable();
    InitDoorModeTable();
    InitBlindBossModeTable();
    InitQueenBossModeTable();
    InitMotherBossModeTable();
    InitPrimagenBossModeTable();
}
