//
// cs_misc_functions
//
// Any functions that I found useful...
//

int nCS_DEBUG = FALSE;

//
// Prototypes
//
void cs_CreateObjectOnPlayer(string sItemTag, object oPC);
void cs_CopyObjectOntoPlayer(object oItem, object oPC);
void cs_MakeItemNoClean(object oItem);
void cs_MakeAllItemsNoClean(object oPlayer);
void cs_AcquireDebug();
void cs_LimitGoldInBank(object oPlayer, int iMaxGold);
void cs_LimitGoldOnPlayer(object oPlayer, int iMaxGold);
void cs_StripPlayerSpells(object oPlayer);
void cs_StripPlayerFeats(object oPlayer);
int cs_RemoveIllegalItem(object oPlayer, string sItemTag);
void cs_MovePartyToLocation(object oPC, string sLocation);
void cs_MovePartyNearbyToLocation(object oPC, string sLocation, float fMaxDistance);
int cs_CountItemInventory(object oPlayer, string sItemTag);
int cs_GetGoldInBank(object oPlayer);
void cs_SetGoldInBank(object oPlayer, int nGoldInBank);
void cs_DEBUG_ON();
void cs_DEBUG_OFF();
void cs_DEBUG_SPEAK(string sDebugString);
void cs_DEBUG_PSPEAK(object oPlayer, string sDebugString);
void cs_DEBUG_DMSPEAK(string sDebugString);
void cs_DEBUG_ALLSPEAK(string sDebugString);
void cs_RemakeStolenItems(object oPlayer);
int cs_IsDEBUG();
int cs_IsPCInvStolen(object oPlayer);
void cs_CheckIfLegalCharacter(object oPlayer);
void cs_DestroyStolenItems(object oPlayer);
void cs_SendMessageToAllPCs(string szMessage);


// ********************************************************************************
// ********************************************************************************
void cs_CreateObjectOnPlayer(string sItemTag, object oPC)
{
    object oCreated = CreateItemOnObject(sItemTag, oPC, 1);
    if (oCreated != OBJECT_INVALID) { cs_MakeItemNoClean(oCreated); }
}

// ********************************************************************************
// ********************************************************************************
void cs_CopyObjectOntoPlayer(object oItem, object oPC)
{
    object oCreated = CreateItemOnObject(GetTag(oItem), oPC, GetItemStackSize(oItem));
    if (oCreated != OBJECT_INVALID) { cs_MakeItemNoClean(oCreated); }
}

// ********************************************************************************
// ********************************************************************************
void cs_MakeItemNoClean(object oItem)
{
    if (GetIsPC(GetItemPossessor(oItem))) {
        SetLocalInt(oItem, "PCItem", 1);
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_MakeAllItemsNoClean(object oPlayer)
{
    // Get entering object
    object oPC = oPlayer;

    if(!GetIsPC(oPC)) {
        return;
    } else {
      object oItem = GetFirstItemInInventory(oPC);
      while(GetIsObjectValid(oItem))
        {
        SetLocalInt(oItem, "PCItem", 1);
        oItem = GetNextItemInInventory(oPC);
        } // end while
      }  // end else
}

// ********************************************************************************
// ********************************************************************************
void cs_AcquireDebug()
{
    string          sScriptName     =   "onAcquire";

    object          oIA             =   GetModuleItemAcquired();
    object          oIABy           =   GetModuleItemAcquiredBy();
    object          oIAFrom         =   GetModuleItemAcquiredFrom();
    string          sIAName         =   GetName(oIA);
    string          sIAByName       =   GetName(oIABy);
    string          sIAFromName     =   GetName(oIAFrom);
    string          sIAByType;
    string          sIAFromType;
    string          sIAStolen;

    if (oIA == OBJECT_INVALID) { sIAName = "Invalid Object"; }
    if (oIABy == OBJECT_INVALID) { sIAByName = "Invalid Object"; }
    if (oIAFrom == OBJECT_INVALID) { sIAFromName = "Invalid Object"; }

    if (GetIsPC(oIABy)) { sIAByType = " (PC)"; } else
        if (GetIsDM(oIABy)) { sIAByType = " (DM)"; } else { sIAByType = " (Other)"; }

    if (GetIsPC(oIAFrom)) { sIAFromType = " (PC)"; } else
        if (GetIsDM(oIAFrom)) { sIAFromType = " (DM)"; } else { sIAFromType = " (Other)"; }

    if (GetStolenFlag(oIA) == TRUE) { sIAStolen = "(Stolen!)"; } else { sIAStolen = ""; }

    SendMessageToPC(oIABy, "[ -------- ======== " + sScriptName + " ======== -------- ]");
    SendMessageToPC(oIABy, "Item Acquired..........: " + sIAName + sIAStolen);
    SendMessageToPC(oIABy, "Item Acquired By.......: " + sIAByName + sIAByType);
    SendMessageToPC(oIABy, "Item Acquired From.....: " + sIAFromName + sIAFromType);
}

// ********************************************************************************
// ********************************************************************************
void cs_LimitGoldInBank(object oPlayer, int iMaxGold)
{
    int nGoldInBank = cs_GetGoldInBank(oPlayer);
    if (nGoldInBank > iMaxGold) {
        SendMessageToPC(oPlayer, "You have too much gold in your bank account.  I've fixed it for you.");
        cs_SetGoldInBank(oPlayer, iMaxGold);
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_LimitGoldOnPlayer(object oPlayer, int iMaxGold)
{
    int nPlayerGold = GetGold(oPlayer);
    if (nPlayerGold > iMaxGold) {
        SendMessageToPC(oPlayer, "You have too much gold.  I've fixed it for you.");
        int nGoldToTake = (nPlayerGold - iMaxGold);
        AssignCommand(oPlayer, TakeGoldFromCreature(nGoldToTake, oPlayer, TRUE));
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_StripPlayerSpells(object oPlayer)
{
  // Strip all spells
    int nID = 0;
    int i;

    if(!GetIsDM(oPlayer))
    {
        // Remove all spell uses
        for(nID = 0; nID <= 498; nID++)
        {
            i = 0;
            while(GetHasSpell(nID,oPlayer) && i < 20)
            {
                DecrementRemainingSpellUses(oPlayer,nID);
                i++;
            }
        }
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_StripPlayerFeats(object oPlayer)
{
  // Strip all spell and feat uses on enter
    int nID = 0;
    int i;

    if(!GetIsDM(oPlayer))
    {
        // Remove all feat uses
        for(nID = 0; nID <= 444; nID++)
        {
            i = 0;
            while(GetHasFeat(nID,oPlayer) && i < 20)
            {
                DecrementRemainingFeatUses(oPlayer,nID);
                i++;
            }
        }
    }
}

// ********************************************************************************
// ********************************************************************************
int cs_RemoveIllegalItem(object oPlayer, string sItemTag)
{
    int nRetValue = 0;
    object oItem = GetFirstItemInInventory(oPlayer);
    while (GetIsObjectValid(oItem))
    {
       if (GetTag(oItem) == sItemTag) {
           DestroyObject(oItem);
           nRetValue++;
       }
       oItem = GetNextItemInInventory(oPlayer);
    }

    // Now Check Equipped Slots
    int nCurrentSlot;
    for (nCurrentSlot = 0; nCurrentSlot <= NUM_INVENTORY_SLOTS; nCurrentSlot++) {
        oItem = GetItemInSlot(nCurrentSlot, oPlayer);
        if (GetTag(oItem) == sItemTag) {
            AssignCommand(oPlayer,ActionUnequipItem(oItem));
            DestroyObject(oItem, 1.0);
            nRetValue++;
        }
    }

    return nRetValue;
}

// ********************************************************************************
// ********************************************************************************
void cs_MovePartyToLocation(object oPC, string sLocation)
{
    object oPC = GetPCSpeaker();
    object oTarget = GetWaypointByTag(sLocation);
    location lTarget = GetLocation(oTarget);

    if (GetIsPC(oPC)) {
        object oFactionPC = GetFirstFactionMember(oPC);
        while (oFactionPC != OBJECT_INVALID) {
            AssignCommand(oFactionPC, ClearAllActions());
            AssignCommand(oFactionPC, ActionJumpToLocation(lTarget));
            oFactionPC = GetNextFactionMember(oFactionPC);
        }
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_MovePartyNearbyToLocation(object oPC, string sLocation, float fMaxDistance)
{
    object oPC = GetPCSpeaker();
    object oTarget = GetWaypointByTag(sLocation);
    location lTarget = GetLocation(oTarget);

    if (GetIsPC(oPC)) {
        object oFactionPC = GetFirstFactionMember(oPC);
        while (oFactionPC != OBJECT_INVALID) {
            if (GetArea(oPC) == GetArea(oFactionPC)) {
                float fDistance = GetDistanceBetween(oPC, oFactionPC);
                if (fDistance <= fMaxDistance) {
                    AssignCommand(oFactionPC, ClearAllActions());
                    AssignCommand(oFactionPC, ActionJumpToLocation(lTarget));
                }
            }
            oFactionPC = GetNextFactionMember(oFactionPC);
        }
    }
}

// ********************************************************************************
// ********************************************************************************
int cs_CountItemInventory(object oPlayer, string sItemTag)
{
    int     nItemCount = 0;
    object  oInvItem;

    if (GetIsPC(oPlayer)) {
        oInvItem = GetFirstItemInInventory(oPlayer);
        while (GetIsObjectValid(oInvItem) == TRUE)
        {
            if (GetTag(oInvItem) == sItemTag) { nItemCount = nItemCount + GetNumStackedItems(oInvItem); }
            oInvItem = GetNextItemInInventory(oPlayer);
        }
    }
    return nItemCount;
}

// ********************************************************************************
// ********************************************************************************
int cs_GetGoldInBank(object oPlayer)
{
    int nGoldInBank = GetCampaignInt("Bank", "BankGold", oPlayer);
    return nGoldInBank;
}

// ********************************************************************************
// ********************************************************************************
void cs_SetGoldInBank(object oPlayer, int nGoldInBank)
{
    SetCampaignInt("Bank", "BankGold", nGoldInBank, oPlayer);
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_ON()
{
    nCS_DEBUG = TRUE;
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_OFF()
{
    nCS_DEBUG = FALSE;
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_SPEAK(string sDebugString)
{
    if (cs_IsDEBUG() == TRUE) {
        SpeakString(sDebugString);
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_PSPEAK(object oPlayer, string sDebugString)
{
    if (cs_IsDEBUG() == TRUE) {
        SendMessageToPC(oPlayer, sDebugString);
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_DMSPEAK(string sDebugString)
{
    if (cs_IsDEBUG() == TRUE) {
        SendMessageToAllDMs(sDebugString);
    }
}

// ********************************************************************************
// ********************************************************************************
void cs_DEBUG_ALLSPEAK(string sDebugString)
{
    cs_SendMessageToAllPCs(sDebugString);
}

// ********************************************************************************
// ********************************************************************************
void cs_RemakeStolenItems(object oPlayer)
{
    object  oItem;
    int nValidItem;
    string sItemName;
    int nSlot;

    if (GetIsPC(oPlayer)) {
        oItem = GetFirstItemInInventory(oPlayer);
        nValidItem = GetIsObjectValid(oItem);
        while ((nValidItem == TRUE) && (GetStolenFlag(oItem) == FALSE))
        {
            oItem = GetNextItemInInventory(oPlayer);
            nValidItem = GetIsObjectValid(oItem);
        }

        if (nValidItem == TRUE) {
            sItemName = GetTag(oItem);
            cs_RemoveIllegalItem(oPlayer, sItemName);
            cs_CreateObjectOnPlayer(sItemName, oPlayer);
        }
    }
}

// ********************************************************************************
// ********************************************************************************
int cs_IsDEBUG()
{
    return nCS_DEBUG;
}

// ********************************************************************************
// ********************************************************************************
int cs_IsPCInvStolen(object oPlayer)
{
    object  oItem;
    int nRetValue = FALSE;

    if (GetIsPC(oPlayer)) {
        oItem = GetFirstItemInInventory(oPlayer);
        while (GetIsObjectValid(oItem) == TRUE)
        {
            if (GetStolenFlag(oItem) == TRUE) {
                nRetValue = TRUE;
            }
            oItem = GetNextItemInInventory(oPlayer);
        }
    }
    return nRetValue;
}

// ********************************************************************************
// ********************************************************************************
void cs_CheckIfLegalCharacter(object oPlayer)
{
    int     iMaxStat        =   200;
    int     iMaxAC          =   200;
    int     oLegal          =   TRUE;
    string  sCheatString    =   "Hi!  I'm a cheater (Boot Disabled During Testing)";

    if (GetAbilityScore(oPlayer, ABILITY_STRENGTH) > iMaxStat) { oLegal = FALSE; }
    if (GetAbilityScore(oPlayer, ABILITY_INTELLIGENCE) > iMaxStat) { oLegal = FALSE; }
    if (GetAbilityScore(oPlayer, ABILITY_CONSTITUTION) > iMaxStat) { oLegal = FALSE; }
    if (GetAbilityScore(oPlayer, ABILITY_DEXTERITY) > iMaxStat) { oLegal = FALSE; }
    if (GetAbilityScore(oPlayer, ABILITY_WISDOM) > iMaxStat) { oLegal = FALSE; }
    if (GetAbilityScore(oPlayer, ABILITY_CHARISMA) > iMaxStat) { oLegal = FALSE; }
    if (GetAC(oPlayer) > iMaxAC) { oLegal = FALSE; }

    if (GetIsDM(oPlayer) || GetIsDMPossessed(oPlayer)) { oLegal = TRUE; }
    if (GetItemPossessedBy(oPlayer, "KeyofCheating") != OBJECT_INVALID) { oLegal = TRUE; }

    if (oLegal == FALSE) {
        WriteTimestampedLogEntry("[Cheater]"+GetName(oPlayer)+"-"+GetPCPlayerName(oPlayer)+"-"+GetPCPublicCDKey(oPlayer));
        FloatingTextStringOnCreature(sCheatString, oPlayer, TRUE);

    }
}

// ********************************************************************************
// ********************************************************************************
void cs_DestroyStolenItems(object oPlayer)
{
    object  oItem;

     if (GetIsPC(oPlayer)) {
        oItem = GetFirstItemInInventory(oPlayer);
        while (GetIsObjectValid(oItem) == TRUE)
        {
          if (GetStolenFlag(oItem) == TRUE) {
          DestroyObject(oItem);
         }
         oItem = GetNextItemInInventory(oPlayer);
    }


}
}

// ********************************************************************************
// ********************************************************************************
void cs_SendMessageToAllPCs(string szMessage)
{
    object  oPC = GetFirstPC();
    while (GetIsObjectValid(oPC)) {
        SendMessageToPC(oPC, szMessage);
        oPC = GetNextPC();
    }
}