//
// Copyright(C) 2014-2015 Samuel Villarreal
//
// 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
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// DESCRIPTION:
//      Common defines and constants
//

#include "scripts/animations.txt"
// Smoke39
// moved this here from main.txt so Options.txt could see it, when included from map scripts
const kStr TurokPlusVersion = "1.9";
#include "scripts/Smoke39/MoreMath.txt"
#include "scripts/Smoke39/Util.txt"
#include "scripts/Smoke39/MissingConstants.txt"
// Outpost - removed
//include "scripts/Smoke39/GameSpeedometer.txt"
//include "scripts/Smoke39/EnemySpeed.txt"
//include "scripts/Smoke39/Options.txt"
//include "scripts/Smoke39/debug.txt"

enum turokVariants
{
    TV_NONE = 0,
    TV_BOW,
    TV_KNIFE,
    TV_KEY,
    TV_KEY_FINAL_OUTER,
    TV_KEY_FINAL_CENTER,

    NUMTUROKVARIANTS
}

enum turokWeapons
{
    TW_WEAPON_KNIFE = 0,
    TW_WEAPON_BOW,
    TW_WEAPON_PISTOL,
    TW_WEAPON_SHOTGUN,
    TW_WEAPON_ASHOTGUN,
    TW_WEAPON_RIFLE,
    TW_WEAPON_PULSERIFLE,
    TW_WEAPON_MINIGUN,
    TW_WEAPON_GRENADE,
    TW_WEAPON_ALIENGUN,
    TW_WEAPON_MISSILE,
    TW_WEAPON_ACCELERATOR,
    TW_WEAPON_CANNON,
    TW_WEAPON_CHRONO,

    NUMTUROKWEAPONS
}

enum turokGruntVariants
{
    GV_GENERIC  = 0,
    GV_GENERIC_AXE,
    GV_GENERIC_CLUB,
    GV_COMMANDER_SPEAR,
    GV_COMMANDER_RIFLE1,
    GV_COMMANDER_RIFLE2,
    GV_COMMANDER_RIFLE3,
    GV_GENERIC_RIFLE,
    GV_COMMANDER_RIFLE4,
    GV_POACHER_KNIFE,
    GV_POACHER_PISTOL1,
    GV_POACHER_PISTOL2,
    GV_POACHER_RIFLE,
    GV_POACHER_SHOTGUN,
    GV_WARRIOR_BONE,
    GV_WARRIOR_DART,
    GV_WARRIOR_SPEAR,
    GV_SHAMAN,
    GV_CYBORG_PULSE_RIFLE,
    GV_CYBORG_KNIFE,
    GV_CYBORG_SPEAR,
    GV_DEMON_AXE,
    GV_DEMON_SPEAR,
    GV_DEMON_HANDS,
    GV_DEMON_LORD,
    GV_GENERIC_HANGING,

    NUMGRUNTVARIANTS
}

enum turokMoverFlags
{
    TFF_ACTIVATED   = 0x40000,
    TFF_WAITING     = 0x80000,
    TFF_MOVING      = 0x100000
}

enum turokActorTypes
{
    AT_PLAYER = 0,

    AT_RAPTOR = 1,
    AT_GRUNT = 2,
    AT_DINOSAUR1 = 4,
    AT_RIDER = 5,
    AT_SANDWORM = 8,
    AT_STALKER = 9,
    AT_ALIEN = 10,
    AT_PURLIN = 11,
    AT_MECH = 12,
    AT_FISH = 14,
    AT_SEWERCRAB = 15,
    AT_KILLERPLANT = 16,
    AT_UNKNOWN1 = 19,
    AT_ANIMAL = 20,
    AT_INSECT = 21,
    AT_BOAR = 23,
    AT_DRAGONFLY = 25,
    AT_TURRET = 2001,

    AT_AIBOSS_MANTIS = 1000,
    AT_AIBOSS_TREX = 1001,
    AT_AIBOSS_CAMPAINGER = 1002,
    AT_AIBOSS_HUNTER = 1003,
    AT_AIBOSS_HUMMER = 1004,

    AT_DYNAMIC_DOOR = 300,
    AT_DYNAMIC_LIFT = 303,
    AT_DYNAMIC_FLOOR_5X = 310,
    AT_DYNAMIC_FLOOR_PERPETUAL = 311,
    AT_DYNAMIC_LIFT_LOWER_WAIT_RAISE = 316,
    AT_DYNAMIC_FLOOR_LOWER_AND_ROTATE = 324,
    AT_DYNAMIC_SPIRIT_BRIDGE = 328,
    AT_DYNAMIC_FLOOR_1X = 329,

    AT_DYNAMIC_MANTISSTATUE = 302,
    AT_DYNAMIC_MANTISWALL = 305,
    AT_DYNAMIC_PORTAL = 317,
    AT_DYNAMIC_GATEKEYPANEL = 318,
    AT_DYNAMIC_WATER1 = 319,
    AT_DYNAMIC_WATER2 = 320,
    AT_DYNAMIC_PORTALGATE = 321,
    AT_DYNAMIC_KEYPLAQUE = 325,

    AT_UNKNOWN = 200,

    AT_GIB_ALIEN3 = 701,
    AT_GIB_STALKER4 = 702,
    AT_GIB_ALIEN2 = 703,
    AT_GIB_ALIEN1 = 704,
    AT_GIB_STALKER3 = 705,
    AT_GIB_STALKER5 = 706,
    AT_GIB_STALKER2 = 707,
    AT_GIB_STALKER1 = 708,

    AT_WEAPON_KNIFE = 100,
    AT_WEAPON_BOW = 102,
    AT_WEAPON_PISTOL = 103,
    AT_WEAPON_RIFLE = 104,
    AT_WEAPON_PULSERIFLE = 105,
    AT_WEAPON_SHOTGUN = 106,
    AT_WEAPON_ASHOTGUN = 107,
    AT_WEAPON_MINIGUN = 108,
    AT_WEAPON_GRENADE = 109,
    AT_WEAPON_ALIENGUN = 110,
    AT_WEAPON_CANNON = 111,
    AT_WEAPON_MISSILE = 112,
    AT_WEAPON_ACCELERATOR = 113,
    AT_WEAPON_CHRONO = 114,

    AT_PICKUP_SMALLHEALTH = 400,
    AT_PICKUP_HEALTH = 402,
    AT_PICKUP_FULLHEALTH = 403,
    AT_PICKUP_ULTRAHEALTH = 404,
    AT_PICKUP_MASK = 405,
    AT_PICKUP_BACKPACK = 406,
    AT_PICKUP_SPIRIT = 407,
    AT_PICKUP_PISTOL = 409,          // Smoke39 - now smart pickup
    AT_PICKUP_ASSAULTRIFLE = 410,    // Smoke39 - now smart pickup
    AT_PICKUP_SHOTGUN = 411,
    AT_PICKUP_ASHOTGUN = 412,        // Smoke39 - now smart pickup
    AT_PICKUP_MINIGUN = 413,         // Smoke39 - now smart pickup
    AT_PICKUP_GRENADELAUNCHER = 414, // Smoke39 - now smart pickup
    AT_PICKUP_PULSERIFLE = 415,      // Smoke39 - now smart pickup
    AT_PICKUP_ALIENWEAPON = 416,
    AT_PICKUP_ROCKETLAUNCHER = 417,
    AT_PICKUP_ACCELERATOR = 418,
    AT_PICKUP_CANNON = 419,
    AT_PICKUP_QUIVER2 = 420, // normal arrows
    AT_PICKUP_ARROWS = 421,  // loose tek arrows
    AT_PICKUP_QUIVER1 = 422, // tek quiver
    AT_PICKUP_CLIP = 423,
    AT_PICKUP_CLIPBOX = 424,
    AT_PICKUP_SHELLS = 425,
    AT_PICKUP_SHELLBOX = 426,
    AT_PICKUP_EXPSHELLS = 427,
    AT_PICKUP_EXPSHELLBOX = 428,
    AT_PICKUP_MINIGUNAMMO = 429,
    AT_PICKUP_GRENADE = 430,
    AT_PICKUP_GRENADEBOX = 431,
    AT_PICKUP_SMALLCELL = 432,  // energy cell
    AT_PICKUP_CELL = 433,       // large energy cell
    AT_PICKUP_ROCKET = 434,
    AT_PICKUP_FUSIONCELL = 436,
    AT_PICKUP_ARMOR = 437,
    AT_PICKUP_COIN1 = 438,
    AT_PICKUP_COIN10 = 439,
    AT_PICKUP_KEY1 = 440,
    AT_PICKUP_KEY2 = 441,
    AT_PICKUP_KEY3 = 442,
    AT_PICKUP_KEY4 = 443,
    AT_PICKUP_KEY5 = 444,
    AT_PICKUP_KEY6 = 445,
    AT_PICKUP_FINALKEY1 = 446,   // main level 8 key
    AT_PICKUP_CHRONOPIECE1 = 447,
    AT_PICKUP_FINALKEY3 = 448,   // center level 8 key (Smoke39 - added missing enum entry)
    AT_PICKUP_FINALKEY2 = 449,   // mantis level 8 key
    AT_PICKUP_CHRONOPIECE2 = 450,
    AT_PICKUP_CHRONOPIECE3 = 451,
    AT_PICKUP_CHRONOPIECE4 = 452,
    AT_PICKUP_CHRONOPIECE5 = 453,
    AT_PICKUP_CHRONOPIECE6 = 454,
    AT_PICKUP_CHRONOPIECE7 = 455,
    AT_PICKUP_CHRONOPIECE8 = 456,

    AT_MINIPORTAL = 600,
    AT_WATER = 800,

    AT_WARPPOINT = 4000,

	// Smoke39
	AT_DUMMY_PISTOL = 500,
	AT_REAL_AR_PICKUP,
	AT_REAL_ASHOTGUN_PICKUP,
	AT_REAL_SHREDDER_PICKUP,
	AT_PICKUP_DOUBLE_SHOTGUN,
	AT_DUMMY_MINIGUN,
	AT_DUMMY_FIRESTORM,
	AT_DUMMY_PULSERIFLE,
	AT_PROTO_PULSE,
	AT_DUMMY_PROTO_PULSE,
	AT_DUMMY_PLASMARIFLE,
	AT_REAL_SHOCKWAVE,
	AT_PICKUP_CHARGEDART,
	AT_DUMMY_ALIENWEP,
	AT_REAL_GL_PICKUP,
	AT_REAL_TEKARROWS = 520,
	AT_REAL_TEKARROWQUIVER,
	AT_DUMMY_TEKARROWS,
	AT_DUMMY_TEKARROWQUIVER,
	AT_LOADER_TEKARROWS,
	AT_LOADER_ARROWS,
	AT_REAL_EXPSHELLS,
	AT_REAL_EXPSHELLBOX,
	AT_DUMMY_EXPSHELLS,
	AT_DUMMY_EXPSHELLBOX,
	AT_LOADER_EXPSHELLS,
	AT_LOADER_SHELLS,
	AT_REAL_MINIGUNAMMO,
	AT_REAL_FIRESTORMAMMO,
	AT_REAL_GRENADE,
	AT_REAL_GRENADE_BOX,
	AT_DUMMY_GRENADE,
	AT_DUMMY_GRENADE_BOX,
	AT_PICKUP_ARROW,
	AT_PICKUP_MICROCELL = 650,  // new small energy cell
	AT_PICKUP_MINIGUNAMMO_SMALL,
	AT_REAL_MINIGUNAMMO_SMALL,
	AT_REAL_FIRESTORMAMMO_SMALL,
	AT_STUCKFLARE = 801,
	AT_PROJ_ARROW,
	AT_PROJ_TEKARROW,
	AT_PICKUP_WARBLADE = 2500,
	AT_PICKUP_PISTOL_BURST,
	AT_DUMMY_MAG60,
//	AT_PICKUP_KNIFE_BOOMERANG,
	AT_TUROK_PLUS_MENU = 3000,
	AT_TUROK_PLUS_SETUP,
	AT_TUROK_PLUS_TERMINAL,

	AT_TUROK_PLUS_SETUP_OLDSAVE = 10000, // menu for setting options when loading pre-1.65 save

    NUMACTORTYPES
}

enum hummerGlobalState
{
    HGS_NEW             = 0,
    HGS_ENTERED_ARENA,
    HGS_DEAD
}

enum longHunterGlobalState
{
    LHGS_NEW             = 0,
    LHGS_OBSERVING,
    LHGS_INCOMBAT,
    LHGS_DEAD
}

enum mantisState
{
    MS_GROUNDCHASE  = 0,
    MS_BASHWALL,
    MS_DEAD,

    NUM_MANTIS_STATES
}

///////////////////////////////////////////////////////////////////////////////

// Smoke39 - ammo maxes (keep these in sync with defs/ammoInfo)
// NOTE: if these are changed, update TurokPlayer::UsingBackpack() to avoid false positives
const int MaxArrows              = 30;
const int MaxArrowsBackpack      = MaxArrows;
const int MaxTekArrows           = 15;
const int MaxTekArrowsBackpack   = MaxTekArrows;
const int MaxBullets             = 100;
const int MaxBulletsBackpack     = 200;
const int MaxMinigunAmmo         = 250;
const int MaxMinigunAmmoBackpack = MaxMinigunAmmo;
const int MaxShells              = 20;
const int MaxShellsBackpack      = 40;
const int MaxExpShells           = 10;
const int MaxExpShellsBackpack   = 20;
const int MaxEnergyAmmo          = 100;
const int MaxEnergyAmmoBackpack  = MaxEnergyAmmo;
const int MaxGrenades            = 20;
const int MaxGrenadesBackpack    = 30;
const int MaxRockets             = 6;
const int MaxRocketsBackpack     = 12;
const int MaxFusionAmmo          = 2;
const int MaxFusionAmmoBackpack  = 3;
const int MaxChronoAmmo          = 3;
const int MaxChronoAmmoBackpack  = MaxChronoAmmo;

int MaxAmmo( int slot )
{
	switch ( slot )
	{
		case TW_WEAPON_BOW:       return PlayerHasBackpack() ? MaxArrowsBackpack : MaxArrows;
		case TW_WEAPON_PISTOL:
		case TW_WEAPON_RIFLE:     return PlayerHasBackpack() ? MaxBulletsBackpack : MaxBullets;
		case TW_WEAPON_MINIGUN:   return PlayerHasBackpack() ? MaxMinigunAmmoBackpack : MaxMinigunAmmo;
		case TW_WEAPON_SHOTGUN:
		case TW_WEAPON_ASHOTGUN:  return PlayerHasBackpack() ? MaxShellsBackpack : MaxShells;
		case TW_WEAPON_PULSERIFLE:
		case TW_WEAPON_ACCELERATOR:
		case TW_WEAPON_ALIENGUN:  return PlayerHasBackpack() ? MaxEnergyAmmoBackpack : MaxEnergyAmmo;
		case TW_WEAPON_GRENADE:   return PlayerHasBackpack() ? MaxGrenadesBackpack : MaxGrenades;
		case TW_WEAPON_MISSILE:   return PlayerHasBackpack() ? MaxRocketsBackpack : MaxRockets;
		case TW_WEAPON_CANNON:    return PlayerHasBackpack() ? MaxFusionAmmoBackpack : MaxFusionAmmo;
		case TW_WEAPON_CHRONO:    return PlayerHasBackpack() ? MaxChronoAmmoBackpack : MaxChronoAmmo;
	}
	return 0;
}

bool HasMaxAmmo( int slot )
{
	if ( slot == TW_WEAPON_GRENADE )
		return GrenadeCount() >= MaxAmmo(slot);
	return Player.GetAmmo(slot) >= MaxAmmo(slot);
}

// get primary/alt ammo, whichever is loaded
int GetLoadedAmmo( int slot )
{
	return Player.HasAltAmmo(slot)? Player.GetAltAmmo(slot) : Player.GetAmmo(slot);
}
int GetLoadedAmmo()
{
	return GetLoadedAmmo( Player.CurrentWeapon() );
}

// Smoke39 - alt ammo toggle info
// all this stuff should be const, but the engine wasn't built with very robust const use,
// so concatenation doesn't work with const strings
kStr NoAmmoStr = "Out of ";

class AmmoType
{
	kStr GVK;      // GameVariables key for stored ammo
	kStr Name;     // presentational
	kStr BaseName; // name of corresponding standard ammo
	kStr LoadStr;  // presentational: "Name + LoadStr" will be printed
	int RealPickupSmall, RealPickupBig;
	int DummyPickupSmall, DummyPickupBig;
	int Loader, Unloader;
	int Slot;  // slot of any of the weapons that uses this as its alt ammo type
	int Max, BackpackMax;

	AmmoType(){}
	AmmoType( kStr k, kStr n, kStr b, kStr ls,
		int rs, int rb, int ds, int db, int lr, int ulr,
		int s, int m, int bm )
	{
		GVK=k;  Name=n;  BaseName=b;  LoadStr=ls;
		RealPickupSmall=rs;  RealPickupBig=rb;
		DummyPickupSmall=ds;  DummyPickupBig=db;
		Loader=lr;  Unloader=ulr;
		Slot=s;  Max=m;  BackpackMax=bm;
	}
};

AmmoType TekArrows(
	"TekArrowStorage",
	"Tek Arrows",
	"Arrows",
	" Equipped",
	AT_REAL_TEKARROWS,
	AT_REAL_TEKARROWQUIVER,
	AT_DUMMY_TEKARROWS,
	AT_DUMMY_TEKARROWQUIVER,
	AT_LOADER_TEKARROWS,
	AT_LOADER_ARROWS,
	TW_WEAPON_BOW,
	MaxTekArrows,
	MaxTekArrowsBackpack
);
AmmoType ExpShells(
	"ExpShellStorage",
	"Explosive Shells",
	"Shells",
	" Loaded",
	AT_REAL_EXPSHELLS,
	AT_REAL_EXPSHELLBOX,
	AT_DUMMY_EXPSHELLS,
	AT_DUMMY_EXPSHELLBOX,
	AT_LOADER_EXPSHELLS,
	AT_LOADER_SHELLS,
	TW_WEAPON_SHOTGUN,
	MaxExpShells,
	MaxExpShellsBackpack
);

// Smoke39 - helper for checking new backpack game variable
bool PlayerHasBackpack()
{
	return GetGameVarB( "bHasBackpack" );
}

// Smoke39 - helpers for grenade "debt"
int GrenadeCount()
{
	return Player.GetAmmo(TW_WEAPON_GRENADE) - GetGameVarI("GrenadeDebt");
}
/* Outpost - removed
void BorrowGrenades( int amt )
{
	int grenades = Player.GetAmmo( TW_WEAPON_GRENADE );
	int grenDebt = GetGameVarI( "GrenadeDebt" );
	bool bInfAmmo = false;
	int i = GetLoadedAmmo();
	// try using ammo to see if infinite ammo is on
	// (add ammo with negative value to prevent putting weapon away if only 1 ammo is left)
	// skip this if weapon is out of ammo, because returning to 0 in the next step would put it away
	// (also skips weapons without ammo [namely the knife], which this test doesn't work with)
	if ( i > 0 )
	{
		Player.ConsumeAmmo( -1 );
		bInfAmmo = GetLoadedAmmo() == i;
	}
	// borrow grenade and undo ammo test, if infinite ammo is off
	if ( !bInfAmmo )
	{
		grenDebt = Math::Min( grenDebt+amt, grenades );
		SetGameVarI( "GrenadeDebt", grenDebt );
		if ( i > 0 )
			Player.ConsumeAmmo( 1 );
	}
	Game.PrintLine( ""+ (grenades-grenDebt) +" grenades remaining", 0 );
}

bool PlayerHasHandGrenades()
{
	return Player.HasWeapon(TW_WEAPON_GRENADE) && Opt::bHandGrenades && !CheckSmoke39Flag(SMOKE39_HAS_GL);
}
bool PlayerHasGL()
{
	return Player.HasWeapon(TW_WEAPON_GRENADE) && (!Opt::bHandGrenades || CheckSmoke39Flag(SMOKE39_HAS_GL));
}
*/
void ForcePickup( int actorID )
{
	kPuppet@ P = Player.Actor();
	kActor@ a = Spawn( actorID, P.Origin() );
	// nudge the player a tiny bit to trigger the touch
	if ( a !is null )
		P.MoveToPosition( P.Origin().x + 0.1f * (1 - 2*Math::RandMax(2)), P.Origin().y );
}

////////////////////////////////////////////////////////////////////////////////

// helper for getting area flags at an actor's location
uint GetAreaFlags( kActor@ A )
{
	return World.GetAreaFlags( A.AreaID() );
}
uint GetAreaFlags( kPuppet@ A )
{
	return GetAreaFlags(A.CastToActor());
}

// Smoke39 - actor spawning functions that properly determine sector automatically
kActor@ Spawn( const kStr&in actorName, const kVec3&in loc, float yaw=0, int sector=-2 )
{
	if ( sector == -2 )
		sector = Player.Actor().GetSectorIndexAtLocation(loc);
	return ActorFactory.Spawn( actorName, loc.x, loc.y, loc.z, yaw, sector );
}
kActor@ Spawn( const kStr&in actorName, float x, float y, float z, float yaw=0, int sector=-2 )
{
	return Spawn( actorName, kVec3(x,y,z), yaw );
}

kActor@ Spawn( int actorID, const kVec3&in loc, float yaw=0, int sector=-2 )
{
	if ( sector == -2 )
		sector = Player.Actor().GetSectorIndexAtLocation(loc);
	return ActorFactory.Spawn( actorID, loc.x, loc.y, loc.z, yaw, sector );
}
kActor@ Spawn( int actorID, float x, float y, float z, float yaw=0, int sector=-2 )
{
	return Spawn( actorID, kVec3(x,y,z), yaw );
}

ref@ ActorScript( kActor@ A )
{
	if ( A is null || A.ScriptObject() is null )
		return null;
	return A.ScriptObject().obj;
}

///////////////////////////////////////////////////////////////////////////////

kStr GetGameVarS( const kStr&in key, const kStr&in def="" )
{
	kStr val;
	if ( !GameVariables.GetString( key, val ) )
		return def;
	return val;
}
float GetGameVarF( const kStr&in key, float def=0 )
{
	float val;
	GameVariables.GetFloat( key, val, def );
	return val;
}
int GetGameVarI( const kStr&in key, int def=0 )
{
	int val;
	GameVariables.GetInt( key, val, def );
	return val;
}
bool GetGameVarB( const kStr&in key, bool def=false )
{
	bool val;
	GameVariables.GetBool( key, val, def );
	return val;
}

void SetGameVarS( const kStr&in key, const kStr&in val )
{
	if ( GameVariables.HasKey(key) )
		GameVariables.SetValue( key, val );
	else
		GameVariables.Add( key, val );
}
void SetGameVarI( const kStr&in key, int val )
{
	SetGameVarS( key, ""+ val );
}
void SetGameVarF( const kStr&in key, float val )
{
	SetGameVarS( key, ""+ val );
}
void SetGameVarB( const kStr&in key, bool val )
{
	SetGameVarS( key, val? "1" : "0" );
}

// Smoke39 - bits for new Smoke39Flags game variable
enum ESmoke39FlagBits
{
	SMOKE39_PISTOL_BURST    = 1 << 0,
	SMOKE39_KNIFE_BOOMERANG = 1 << 1,
	SMOKE39_HAS_GL          = 1 << 2,
	SMOKE39_PROTO_PULSE     = 1 << 3,
	SMOKE39_DOUBLE_SHOTGUN  = 1 << 4,
	SMOKE39_WARBLADE        = 1 << 5,
	SMOKE39_FLAREGUN        = 1 << 6, // alien weapon slot is being used as T2 flare gun

	// shortcut unlock bits
	SMOKE39_SHORTCUT_NULL = 1 << 15,
	SMOKE39_SHORTCUT_1_1  = 1 << 16,
	SMOKE39_SHORTCUT_1_2  = 1 << 17,
	SMOKE39_SHORTCUT_2_1  = 1 << 18,
	SMOKE39_SHORTCUT_2_2  = 1 << 19,
	SMOKE39_SHORTCUT_3_1  = 1 << 20,
	SMOKE39_SHORTCUT_3_2  = 1 << 21,
	SMOKE39_SHORTCUT_4_1  = 1 << 22,
	SMOKE39_SHORTCUT_4_2  = 1 << 23,
	SMOKE39_SHORTCUT_5_1  = 1 << 24,
	SMOKE39_SHORTCUT_5_2  = 1 << 25,
	SMOKE39_SHORTCUT_6_1  = 1 << 26,
	SMOKE39_SHORTCUT_6_2  = 1 << 27,
	SMOKE39_SHORTCUT_7_1  = 1 << 28,
	SMOKE39_SHORTCUT_7_2  = 1 << 29,
	SMOKE39_SHORTCUT_8_1  = 1 << 30,
	SMOKE39_SHORTCUT_8_2  = 1 << 31
}
int DefaultSmoke39Flags = SMOKE39_HAS_GL;

// Smoke39 - helpers for working with new Smoke39Flags game variable
bool CheckSmoke39Flag( int mask )
{
	int smokeBits = GetGameVarI( "Smoke39Flags", DefaultSmoke39Flags );
	return smokeBits & mask == mask;
}
void SetSmoke39Flag( int mask, bool bVal )
{
	int smokeBits = GetGameVarI( "Smoke39Flags", DefaultSmoke39Flags );
	if ( bVal )
		smokeBits |= mask;
	else
		smokeBits &= ~mask;
	SetGameVarI( "Smoke39Flags", smokeBits );
}
