#include "utl_i_sqluuid"

void SetToken(object oPC,object oSender, int iToken, string sToken);
string GetToken(int iToken, object oNPC=OBJECT_SELF);
int ZoneLevel(object oArea,int iLevel);
int GetPCCount(object oTargetPC);
string GetZone(object oPC);
string GetZoneDungeonCamp(object oNPC);
string GetRandomZone();
void SetPartyString(object oPC,string sVariable, string sValue);
void SetPartyInt(object oPC,string sVariable, int iValue);
int PCDeathsLeft(object oPC);
object GetRandomPC();
int GetPCAreaCount(object oTargetPC);
int GetQuestGiver();
void SitInChairs(string sPrefix);
int GetXSpot(string sZone);
void Randomize();
int CheckHardcore();

int ZoneLevel(object oArea,int iLevel)
{
int iMinLevel;
int iMaxLevel;

//Check for oArea being a PC in case wrong object is passed
if (GetIsPC(oArea))
    oArea = GetArea(oArea);

iMinLevel = GetLocalInt(oArea,"MinimumLevel");
iMaxLevel = GetLocalInt(oArea,"MaximumLevel");

if (iLevel < iMinLevel)
    iLevel = iMinLevel;
if (iLevel > iMaxLevel && iMaxLevel > 0)
    iLevel = iMaxLevel;

return iLevel;
}

//oTargetPC not used for PC Count but is in the function for compatabity
int GetPCCount(object oTargetPC)
{
string sZone;
string sTargetZone;
object oPC;
object oLastPC;
int iCount;
int iFlag;

oPC=GetFirstPC();
iCount = 0;
iFlag = 0;

sTargetZone = GetZone(oTargetPC);

//start with iCount of 0 because we will run into target pc in pc list

while (iFlag == 0)
    {
    iCount++;
    oLastPC = oPC;
    oPC = GetNextPC();

    if (GetName(oLastPC) == GetName(oPC))
        {
        iFlag = 1;
        }
    }
iCount--;

return iCount;
}


int GetPCAreaCount(object oTargetPC)
{
string sZone;
string sTargetZone;
object oPC;
object oLastPC;
int iCount;
int iFlag;

oPC=GetFirstPC();
iCount = 0;
iFlag = 0;

sTargetZone = GetZone(oTargetPC);

//start with iCount of 0 because we will run into target pc in pc list

while (iFlag == 0)
    {
    oLastPC = oPC;

    sZone=GetZone(oPC);
    if (sZone == sTargetZone)
        {
        iCount++;
        }

    oPC = GetNextPC();

    if (GetName(oLastPC) == GetName(oPC))
        {
        iFlag = 1;
        }
    }

return iCount;
}

string GetZone(object oPC)
{
object oZone;
int iLevel;
string sZone;

oZone = GetArea(oPC);
sZone = GetLocalString(oZone,"Prefix");

if (sZone == "")
    {
    iLevel = GetHitDice(oPC);
    if (iLevel < 4)
        sZone = "RP1";
    else if (iLevel < 8)
        sZone = "WG1";
    else if (iLevel < 12)
        sZone = "SS1";
    else if (iLevel < 17)
        sZone = "RW1";
    else if (iLevel < 22)
        sZone = "DW1";
    else if (iLevel < 27)
        sZone = "SP1";
    else if (iLevel < 33)
        sZone = "IP1";
    else
        sZone = "DP1";
    }

return sZone;
}

string GetZoneDungeonCamp(object oNPC)
{
object oZone;
int iLevel;
string sZone;

oZone = GetArea(oNPC);
sZone = GetLocalString(oZone,"Dungeon");

if (sZone == "")
    {
    iLevel = GetHitDice(oNPC);
    if (iLevel < 4)
        sZone = "SC1";
    else if (iLevel < 8)
        sZone = "WGT1";
    else if (iLevel < 12)
        sZone = "CA1";
    else if (iLevel < 17)
        sZone = "AM1";
    else if (iLevel < 22)
        sZone = "ED1";
    else if (iLevel < 27)
        sZone = "AT1";
    else if (iLevel < 33)
        sZone = "UD1";
    else
        sZone = "AL1";
    }

return sZone;

}

string GetRandomZone()
{
string sZone;
int iRandom;

sZone = "NH1";
iRandom = Random(2) + 1;
switch (iRandom)
    {
    case 1: sZone = "NH1"; break;
    case 2: sZone = "SF1"; break;
    }

return sZone;
}

void SetPartyString(object oPC,string sVariable, string sValue)
{

object oPartyMember = GetFirstFactionMember(oPC, TRUE);
while (GetIsObjectValid(oPartyMember) == TRUE)
    {
    SetLocalString(oPartyMember,sVariable,sValue);
    oPartyMember = GetNextFactionMember(oPC, TRUE);
    }

}

void SetPartyInt(object oPC,string sVariable, int iValue)
{

object oPartyMember = GetFirstFactionMember(oPC, TRUE);
while (GetIsObjectValid(oPartyMember) == TRUE)
    {
    SetLocalInt(oPartyMember,sVariable,iValue);
    oPartyMember = GetNextFactionMember(oPC, TRUE);
    }

}

int PCDeathsLeft(object oPC)
{
int iLevel;
int iDeaths;
int iDeathAllowed;
int iDeathsLeft;

iLevel = GetHitDice(oPC);

iDeaths = SQLocalsUUID_GetInt(oPC,"PCDeaths");
iDeathAllowed = 3 + iLevel - SQLocalsUUID_GetInt(oPC,"PCEnterLevel");

iDeathsLeft = iDeathAllowed - iDeaths;

if (SQLocalsUUID_GetInt(oPC,"PCHardcore") == 1 || SQLocalsUUID_GetInt(oPC,"PCHardCorePNP") == 1)
    iDeathsLeft = 1;

return iDeathsLeft;
}

object GetRandomPC()
{
int iCount;
int iFlag;
int iIndex;
object oPC;
object oLastPC;

oPC=GetFirstPC();
iCount = 0;
iFlag = 0;

while (iFlag == 0)
    {
    iCount++;
    oLastPC = oPC;
    oPC = GetNextPC();

    if (GetName(oLastPC) == GetName(oPC))
        {
        iFlag = 1;
        }
    if (iCount>65)
        {
        iFlag = 1;
        }
    }
iCount--;
for (iIndex=1; iIndex <= iCount; iIndex++)
    {
    if (iIndex == 1)
        {
        oPC = GetFirstPC();
        } else {
        oPC = GetNextPC();
        }
    }

return oPC;
}

void SetToken(object oPC,object oSender, int iToken, string sToken)
{
SetCustomToken(iToken,sToken);
SetPartyString(oPC,"Token" + IntToString(iToken),sToken);
SetLocalString(oSender,"Token" + IntToString(iToken),sToken);
}

string GetToken(int iToken, object oNPC=OBJECT_SELF)
{
string sToken;

sToken = GetLocalString(oNPC,"Token" + IntToString(iToken));

return sToken;
}

int GetQuestGiver()
{
int iQuestGivers;
int iNPC;
int iStart;
int iIndex;

iQuestGivers=4;
iNPC = Random(iQuestGivers)+1;
iStart = iNPC;

iIndex=0;
while (GetLocalInt(GetModule(),"QuestGiver" + IntToString(iNPC)) == 1 && iIndex<200)
    {
    iIndex++;
    iNPC++;
    if (iNPC > iQuestGivers)
        iNPC = 1;

    //Set original NPC as open if we've looped
    if (iNPC == iStart)
        SetLocalInt(GetModule(),"QuestGiver" + IntToString(iNPC),0);
    }

SetLocalInt(GetModule(),"QuestGiver" + IntToString(iNPC),1);

return iNPC;
}

void SitInChairs(string sPrefix)
{
int iCount;
string sTag;
object oNPC;
object oChair;

iCount=1;
sTag = sPrefix + "_sit" + IntToString(iCount);
oNPC = GetObjectByTag(sTag);
//SendMessageToPC(GetFirstPC(),"NPC sitting - first = " + sTag);
while (GetIsObjectValid(oNPC))
    {
    sTag = sPrefix + "_chair" + IntToString(iCount);
    //SendMessageToPC(GetFirstPC(),"Try to Sit in Chair " + sTag);
    oChair = GetObjectByTag(sTag);
    if (GetIsObjectValid(oChair))
        {
        DelayCommand(0.5f,AssignCommand(oNPC,ActionSit(oChair)));
        //SendMessageToPC(GetFirstPC(),"Sit in Chair " + sTag);
        }
    iCount++;
    sTag = sPrefix + "_sit" + IntToString(iCount);
    oNPC = GetObjectByTag(sTag);
    }
}

int GetXSpot(string sZone)
{
int iIndex;
int iFlag;
string sTag;
object oSpawn;

iIndex = 0;
iFlag = 0;

while (iFlag==0)
    {
    iIndex++;
    sTag = sZone + "_X_" + IntToString(iIndex);
    oSpawn=GetObjectByTag(sTag);
    if (!(GetIsObjectValid(oSpawn)))
        iFlag = 1;
    }
iIndex--;

return iIndex;
}

void Randomize()
{
int iIndex;
int iRandomize;
int iRnd;

iRandomize = GetCampaignInt("Endless Nights IV","Randomize");
iRandomize++;
iIndex=1;
while (iIndex<=iRandomize)
    {
    iIndex++;
    iRnd=Random(100);
    }
if (iRandomize>1000)
    iRandomize = 1;
SetCampaignInt("Endless Nights IV","Randomize",iRandomize);
}

int CheckHardcore()
{
int iResult;
object oPC;

iResult = TRUE;

oPC = GetFirstPC();
while (GetIsObjectValid(oPC))
    {
    if (GetLocalInt(oPC,"PCHardCorePNP") == 0)
        iResult = FALSE;
    oPC = GetNextPC();
    }

return iResult;
}

void ClearZoneMobs(object oArea)
{
object oMob;

oMob = GetFirstObjectInArea(oArea);
while (GetIsObjectValid(oMob) && GetIsPC(oMob) != TRUE)
    {
    if (GetObjectType(oMob) == OBJECT_TYPE_CREATURE)
        {
        AssignCommand(oMob,SetIsDestroyable(TRUE,FALSE));
        DestroyObject(oMob,0.5f);
        }
    oMob = GetNextObjectInArea(oArea);
    }
}