//::///////////////////////////////////////////////
//:: Food Functions
//:: inc_food
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*

*/
//:://////////////////////////////////////////////
//:: Created By: Kilana Evra
//:: Created On:
//:://////////////////////////////////////////////
#include "colors_inc"
#include "inc_system_const"

//TAG of placeable/area that will create food effects
//  This is to prevent food effect stacking
const string FOOD_CASTER = "KI_HOUSE001";

//TAG of placeable/area that will create drink effects
//  This is to prevent drink effect stacking
const string DRINK_CASTER = "KI_HOUSE002";

//Represents how many points of hunger each type will restore
//  Each hunger point will last 3 minutes
//  Food effects will last (HUNGERPOINTS/2 + 1) * 3 minutes
const int FOOD_SNACK = 8;            //Default  4(12 minutes) Effect:  9 mins
const int FOOD_SIDEDISH = 12;        //Default  6(18 minutes) Effect: 12 mins
const int FOOD_MEAL = 16;            //Default  8(24 minutes) Effect: 15 mins
const int FOOD_HARDYMEAL = 24;       //Default 12(36 minutes) Effect: 21 mins
const int FOOD_FEAST = 32;           //Default 16(48 minutes) Effect: 27 mins
const int FOOD_BANQUET = 40;         //Default 20(60 minutes) Effect: 33 mins

//Hunger must be under this number while eating to gain food effects.
//A character's CONSTITUTION will increase their cap by 1 for each point above 10
//  Example: (14 CONSTITUTION) Character will gain food effects if they eat while under 89% Hunger
const int HUNGER_EFFECTCAP = 85;

//Maximum number of drinks a canteen can hold. Should be 1-9.
const int CANTEEN_MAX = 5;

//:://////////////////////////////////////////////
//::
//:://////////////////////////////////////////////

//Removes food effects from oPC
void DispelFoodEffect(object oPC);

//returns duration effect for foods
//resref: ki_mfood### = preparable foods
//        ki_food### = raw foods
effect GetFoodDurationEffect(object oFood);

//returns the class of oFood
//FOOD_SNACK, FOOD_SIDEDISH...
int GetFoodType(object oFood);

//When player oPC eats oFood
void ApplyFoodEffect(object oFood, object oPC);

//Returns # of drinks remaining in oCanteen
int GetCanteenCharges(object oCanteen);

//Renames oCanteen: Canteen: sDrink (nCharges/CANTEEN_MAX)
//Sets localstring DRINKTYPE to sDrink
void FillCanteen(object oCanteen, string sDrink = "Fresh Water", int nCharges = CANTEEN_MAX);

//When player oPC drinks from oCanteen
void ApplyDrinkEffect(object oCanteen, object oPC);

//:://////////////////////////////////////////////
//::
//:://////////////////////////////////////////////

void DispelFoodEffect(object oPC)
{ effect eTest;
  object oTest;
  object oCaster = GetObjectByTag(FOOD_CASTER);
  if(!GetIsObjectValid(oCaster)) return;

  eTest = GetFirstEffect(oPC);
  while(GetIsEffectValid(eTest))
  { oTest = GetEffectCreator(eTest);
    if(oTest==oCaster)
    { RemoveEffect(oPC, eTest);
      break;
    }
    eTest = GetNextEffect(oPC);
  }
}

effect GetFoodDurationEffect(object oFood)
{ effect eReturn, e1, e2, e3, eVis1, eVis2;
  string sResref = GetResRef(oFood);
  int nType, nOuter, nInner;

  //Preparable foods Resref: "ki_mfood###"
  if(GetStringLeft(sResref, 8)=="ki_mfood")
  { nType = StringToInt(GetStringRight(sResref, 3));
    nOuter = nType/10;
    nInner = nType%10;

    switch(nOuter)
    { case 0: switch(nInner) //01-09
              { case 1: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectAbilityIncrease(ABILITY_STRENGTH, 1);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
                case 2: e1 = EffectAbilityIncrease(ABILITY_STRENGTH, 1);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1 = EffectAbilityIncrease(ABILITY_STRENGTH, 2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1 = EffectAbilityIncrease(ABILITY_STRENGTH, 3);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectAbilityIncrease(ABILITY_DEXTERITY, 1);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
                case 6: e1 = EffectAbilityIncrease(ABILITY_DEXTERITY, 1);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1 = EffectAbilityIncrease(ABILITY_DEXTERITY, 2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1 = EffectAbilityIncrease(ABILITY_DEXTERITY, 3);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectAbilityIncrease(ABILITY_CONSTITUTION, 1);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
              } break;
      case 1: switch(nInner) //10-19
              { case 0: e1 = EffectAbilityIncrease(ABILITY_CONSTITUTION, 1);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1 = EffectAbilityIncrease(ABILITY_CONSTITUTION, 2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 2: e1 = EffectAbilityIncrease(ABILITY_CONSTITUTION, 3);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_DISEASE);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
                case 4: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_DISEASE);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 2, SAVING_THROW_TYPE_DISEASE);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 3, SAVING_THROW_TYPE_DISEASE);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_POISON);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
                case 8: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_POISON);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 2, SAVING_THROW_TYPE_POISON);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
      case 2: switch(nInner) //20-29
              { case 0: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 3, SAVING_THROW_TYPE_POISON);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1 = EffectAbilityDecrease(ABILITY_INTELLIGENCE, 2);
                        e2 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_TRAP);
                        eReturn = EffectLinkEffects(e1, e2);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(eReturn, eVis1); break;
                case 2: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_TRAP);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 2, SAVING_THROW_TYPE_TRAP);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 3, SAVING_THROW_TYPE_TRAP);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 1, SAVING_THROW_TYPE_MIND_SPELLS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 2, SAVING_THROW_TYPE_MIND_SPELLS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1 = EffectSavingThrowIncrease(SAVING_THROW_ALL, 3, SAVING_THROW_TYPE_MIND_SPELLS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1 = EffectACIncrease(1, AC_NATURAL_BONUS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1 = EffectACIncrease(1, AC_NATURAL_BONUS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
      case 3: switch(nInner) //30-39
              { case 0: e1 = EffectACIncrease(1, AC_NATURAL_BONUS);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1 = EffectRegenerate(1, 60.0f);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 2: e1 = EffectRegenerate(2, 60.0f);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1 = EffectRegenerate(3, 60.0f);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1 = EffectTemporaryHitpoints(3);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_NEUTRAL);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1 = EffectTemporaryHitpoints(5);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_NEUTRAL);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1 = EffectTemporaryHitpoints(8);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_NEUTRAL);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1 = EffectDamageResistance(DAMAGE_TYPE_FIRE, 1, 10);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1 = EffectDamageResistance(DAMAGE_TYPE_FIRE, 2, 20);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1 = EffectDamageResistance(DAMAGE_TYPE_FIRE, 3, 30);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
      case 4: switch(nInner) //40-49
              { case 0: e1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 1, 10);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 2, 20);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 2: e1 = EffectDamageResistance(DAMAGE_TYPE_COLD, 3, 30);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1 = EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 1, 10);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1 = EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 2, 20);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1 = EffectDamageResistance(DAMAGE_TYPE_ELECTRICAL, 3, 30);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1 = EffectDamageResistance(DAMAGE_TYPE_ACID, 1, 10);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1 = EffectDamageResistance(DAMAGE_TYPE_ACID, 2, 20);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1 = EffectDamageResistance(DAMAGE_TYPE_ACID, 3, 30);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1 = EffectDamageResistance(DAMAGE_TYPE_NEGATIVE, 1, 10);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
      case 5: switch(nInner) //50-59
              { case 0: e1 = EffectDamageResistance(DAMAGE_TYPE_NEGATIVE, 2, 20);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1 = EffectDamageResistance(DAMAGE_TYPE_NEGATIVE, 3, 30);
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 2: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
      case 6: switch(nInner) //60-69
              { case 0: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 1: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 2: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 3: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 4: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 5: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 6: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 7: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 8: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
                case 9: e1;
                        eVis1 = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
                        eReturn = EffectLinkEffects(e1, eVis1); break;
              } break;
    } //Close switch
  } //Close Preparable Foods Condition

  return eReturn;
}

int GetFoodType(object oFood)
{ string sResref = GetResRef(oFood);
  int nType, nOuter, nInner;
  int nResult = FOOD_SNACK;

  //Preparable Foods (Magic)
  if(GetStringLeft(sResref, 8)=="ki_mfood")
  { nType = StringToInt(GetStringRight(sResref, 3));
    nOuter = nType/10;
    nInner = nType%10;

    switch(nOuter)
    { case 0: switch(nInner) //01-09
              { case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_MEAL; break;
                case 4: nResult = FOOD_HARDYMEAL; break;
                case 5: nResult = FOOD_MEAL; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_HARDYMEAL; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
      case 1: switch(nInner) //10-19
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_HARDYMEAL; break;
                case 3: nResult = FOOD_MEAL; break;
                case 4: nResult = FOOD_MEAL; break;
                case 5: nResult = FOOD_MEAL; break;
                case 6: nResult = FOOD_HARDYMEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_MEAL; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
      case 2: switch(nInner) //20-29
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_MEAL; break;
                case 4: nResult = FOOD_HARDYMEAL; break;
                case 5: nResult = FOOD_MEAL; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_SNACK; break;
                case 9: nResult = FOOD_SIDEDISH; break;
              } break;
      case 3: switch(nInner) //30-39
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_HARDYMEAL; break;
                case 4: nResult = FOOD_SNACK; break;
                case 5: nResult = FOOD_SIDEDISH; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_SIDEDISH; break;
                case 8: nResult = FOOD_SIDEDISH; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
      case 4: switch(nInner) //40-49
              { case 0: nResult = FOOD_SIDEDISH; break;
                case 1: nResult = FOOD_SIDEDISH; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_SNACK; break;
                case 4: nResult = FOOD_MEAL; break;
                case 5: nResult = FOOD_SIDEDISH; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_HARDYMEAL; break;
                case 9: nResult = FOOD_SIDEDISH; break;
              } break;
      case 5: switch(nInner) //50-59
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;   //Holy Pancakes(ki_mfood051)
                case 2: nResult = FOOD_SNACK; break;
                case 3: nResult = FOOD_SNACK; break;
                case 4: nResult = FOOD_SNACK; break;
                case 5: nResult = FOOD_SNACK; break;
                case 6: nResult = FOOD_SNACK; break;
                case 7: nResult = FOOD_SNACK; break;
                case 8: nResult = FOOD_SNACK; break;
                case 9: nResult = FOOD_SNACK; break;
              } break;
      case 6: switch(nInner) //60-69
              { case 0: nResult = FOOD_SNACK; break;
                case 1: nResult = FOOD_SNACK; break;
                case 2: nResult = FOOD_SNACK; break;
                case 3: nResult = FOOD_SNACK; break;
                case 4: nResult = FOOD_SNACK; break;
                case 5: nResult = FOOD_SNACK; break;
                case 6: nResult = FOOD_SNACK; break;
                case 7: nResult = FOOD_SNACK; break;
                case 8: nResult = FOOD_SNACK; break;
                case 9: nResult = FOOD_SNACK; break;
              } break;
    } //Close Switch
  } //Close Preparable Foods Condition

  //Plain Foods
  else if(GetStringLeft(sResref, 7)=="ki_food")
  { nType = StringToInt(GetStringRight(sResref, 3));
    nOuter = nType/10;
    nInner = nType%10;

    switch(nOuter)
    { case 0: switch(nInner) //01-09
              { case 1: nResult = FOOD_SNACK; break;
                case 2: nResult = FOOD_SNACK; break;
                case 3: nResult = FOOD_SNACK; break;
                case 4: nResult = FOOD_SNACK; break;
                case 5: nResult = FOOD_SNACK; break;
                case 6: nResult = FOOD_SNACK; break;
                case 7: nResult = FOOD_SNACK; break;
                case 8: nResult = FOOD_SNACK; break;
                case 9: nResult = FOOD_SNACK; break;
              } break;
      case 1: switch(nInner) //10-19
              { case 0: nResult = FOOD_SNACK; break;
                case 1: nResult = FOOD_SNACK; break;
                case 2: nResult = FOOD_SNACK; break;
                case 3: nResult = FOOD_SNACK; break;
                case 4: nResult = FOOD_SNACK; break;
                case 5: nResult = FOOD_SNACK; break;
                case 6: nResult = FOOD_SNACK; break;
                case 7: nResult = FOOD_SNACK; break;
                case 8: nResult = FOOD_SNACK; break;
                case 9: nResult = FOOD_SNACK; break;
              } break;
      case 2: switch(nInner) //20-29
              { case 0: nResult = FOOD_SNACK; break;
                case 1: nResult = FOOD_SNACK; break;
                case 2: nResult = FOOD_SNACK; break;
                case 3: nResult = FOOD_SNACK; break; //Onion: ki_food023
                case 4: nResult = FOOD_SIDEDISH; break;
                case 5: nResult = FOOD_SIDEDISH; break;
                case 6: nResult = FOOD_MEAL; break;  //Cooked Meat
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_MEAL; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
      case 3: switch(nInner) //30-39
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_MEAL; break;
                case 4: nResult = FOOD_MEAL; break;
                case 5: nResult = FOOD_MEAL; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_MEAL; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
      case 4: switch(nInner) //40-49
              { case 0: nResult = FOOD_MEAL; break;
                case 1: nResult = FOOD_MEAL; break;
                case 2: nResult = FOOD_MEAL; break;
                case 3: nResult = FOOD_MEAL; break;
                case 4: nResult = FOOD_MEAL; break;
                case 5: nResult = FOOD_MEAL; break;
                case 6: nResult = FOOD_MEAL; break;
                case 7: nResult = FOOD_MEAL; break;
                case 8: nResult = FOOD_MEAL; break;
                case 9: nResult = FOOD_MEAL; break;
              } break;
    } //Close Switch
  } //Close Plain Foods Condition

  return nResult;
}

void ApplyFoodEffect(object oFood, object oPC)
{ effect eFood = GetFoodDurationEffect(oFood);
  int iType = GetFoodType(oFood);

  object oDatabase = GetItemPossessedBy(oPC, "database");
  int iHunger = GetLocalInt(oDatabase, FOOD_CURRENT_HUNGER);
  int iHungerMax = GetLocalInt(oDatabase, FOOD_MAX_HUNGER);

  string sMessage = GetNamePCColor(oPC)
                   +ColorTokenGameEngine()+" eats something."+ColorTokenEnd();
  object oBroadcast = GetFirstObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(oPC), TRUE, OBJECT_TYPE_CREATURE);
  while(GetIsObjectValid(oBroadcast))
  { if(GetIsPC(oBroadcast)) SendMessageToPC(oBroadcast, sMessage);
    oBroadcast = GetNextObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(oPC), TRUE, OBJECT_TYPE_CREATURE);
  }

  int iRestore = iHunger + iType;
  if(iRestore>iHungerMax)iRestore = iHungerMax;
  SendMessageToPC(oPC, ColorTokenGreen() + "Current Hunger: " + ColorTokenWhite() + IntToString(iRestore)+"% / " + ColorTokenRed() + IntToString(iHungerMax) + "%");
  SetLocalInt(oDatabase, FOOD_CURRENT_HUNGER, iRestore);

  //Player will only gain food effects if hunger is under:
  //  HUNGER_EFFECTCAP + Constitution Score - 10
  int iEffectMax = HUNGER_EFFECTCAP + GetAbilityScore(oPC, ABILITY_CONSTITUTION, TRUE) - 10;
  if(iEffectMax>iHungerMax) iEffectMax = iHungerMax;

  if(GetStringLeft(GetResRef(oFood), 8)=="ki_mfood")
  { if(iHunger<=iEffectMax)
    { effect eImp = EffectVisualEffect(VFX_IMP_PDK_INSPIRE_COURAGE);
      ApplyEffectToObject(DURATION_TYPE_INSTANT, eImp, oPC);
      DispelFoodEffect(oPC);
      DelayCommand(0.5, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFood, oPC, IntToFloat((iType/2)+1)*180));
    }
    else
      FloatingTextStringOnCreature("You are too full to enjoy the food. It gives no bonus effect.", oPC, FALSE);
  }

}

int GetCanteenCharges(object oCanteen)
{ string sName = GetName(oCanteen);

  // Canteen: Water (2/5)
  string sResult = GetStringRight(sName, 4);
  sResult = GetStringLeft(sResult, 1);
  return StringToInt(sResult);
}

void FillCanteen(object oCanteen, string sDrink = "Fresh Water", int nCharges = CANTEEN_MAX)
{ SetName(oCanteen, "Canteen: "
                   +ColorTokenPurple()+sDrink+ColorTokenEnd()
                   +" ("+IntToString(nCharges)+"/"+IntToString(CANTEEN_MAX)+")");
  SetLocalString(oCanteen, "DRINKTYPE", sDrink);
}

void ApplyDrinkEffect(object oCanteen, object oPC)
{ int iCharges = GetCanteenCharges(oCanteen);

  if(iCharges<=0) //Canteen is empty!
  { SendMessageToPC(oPC, ColorTokenRed()+"Your canteen is empty!"+ColorTokenEnd());
    return;
  }

  object oDatabase = GetItemPossessedBy(oPC, "database");
  int iThurst = GetLocalInt(oDatabase, FOOD_CURRENT_THIRST);

  string sMessage = GetNamePCColor(oPC)
                   +ColorTokenGameEngine()+" takes a drink."+ColorTokenEnd();
  object oBroadcast = GetFirstObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(oPC), TRUE, OBJECT_TYPE_CREATURE);
  while(GetIsObjectValid(oBroadcast))
  { if(GetIsPC(oBroadcast)) SendMessageToPC(oBroadcast, sMessage);
    oBroadcast = GetNextObjectInShape(SHAPE_SPHERE, 15.0, GetLocation(oPC), TRUE, OBJECT_TYPE_CREATURE);
  }

}

void FOOD_RunHungerCycle(object oPC)
{
    // Hunger doesn't degrade in the OOC entry area or the death realms
    string sTag = GetTag(GetArea(oPC));
    if(sTag == "ooc_area" || sTag == "WelcometoHeaven" || sTag == "WelcometoHell" || sTag == "WelcometoLimbo" || sTag == "LostSoulsRoom") return;

    object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE);
    int iHungerCountDown = GetLocalInt(oDatabase, FOOD_HUNGER_COUNTDOWN) - 1;
    int iCurrentHunger = GetLocalInt(oDatabase, FOOD_CURRENT_HUNGER);

    if (iHungerCountDown <= 0)
    {
        iCurrentHunger = iCurrentHunger - 1;
        SetLocalInt(oDatabase, FOOD_CURRENT_HUNGER, iCurrentHunger);
        iHungerCountDown = 50;

        if (iCurrentHunger == 70 || iCurrentHunger == 60 || iCurrentHunger == 50 || iCurrentHunger == 40)
            FloatingTextStringOnCreature("You are hungry.", oPC, FALSE);

        else if (iCurrentHunger == 30 || iCurrentHunger == 20 || iCurrentHunger <= 10)
            FloatingTextStringOnCreature("You are starving!", oPC, FALSE);

        if(iCurrentHunger <= 0)
        {
            ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPC);
        }
    }
    SetLocalInt(oDatabase, FOOD_HUNGER_COUNTDOWN, iHungerCountDown);
}
// Error checking
//void main(){}