//::////////////////////////////////////////////////////////////////////////////
//::
//		underwater_hb.nss
/*
	Handles being underwater. 

*/
//
//::
//::////////////////////////////////////////////////////////////////////////////

#include "prc_inc_spells"
#include "x0_i0_match" 


//:: Checks if a creature is Aquatic for underwater related scripting
int GetIsAquatic(object oCreature)
{
//:: Check if the provided object is valid
    if (!GetIsObjectValid(oCreature))
    {
		return FALSE;
	}

//:: Get the subrace field of the creature or player, set to lowercase
	string sSubrace = GetStringLowerCase(GetSubRace(oCreature));

    if (FindSubString(sSubrace, "aquatic") != -1)
    {
        return TRUE;
    }

//:: Check for aquatic or amphibious appearance
	int nAppearance = GetAppearanceType(oCreature);
    switch(nAppearance)
    {
        case APPEARANCE_TYPE_SHARK_GOBLIN:
		case APPEARANCE_TYPE_SHARK_HAMMERHEAD:
        case APPEARANCE_TYPE_SHARK_MAKO:
		case APPEARANCE_TYPE_MEPHIT_OOZE:
        case APPEARANCE_TYPE_MEPHIT_WATER:
        case APPEARANCE_TYPE_SEA_HAG:
		
	//:: CEP appearances follow
        case 872:	//:: Leviathan
        case 990:	//:: Troll, Scrag		
		case 1427:	//:: Crab: Blue: Giant* (Eligio Sacateca)
		case 1428:	//:: Crab: Blue: Small* (Eligio Sacateca)
		case 1429:	//:: Crab: Red: Giant 1* (Eligio Sacateca)
		case 1430:	//:: Crab: Red: Small 1* (Eligio Sacateca)		
		case 3053:	//:: Bullywug: Brown-Green* (baba yaga)
		case 3054:	//:: Bullywug: Green* (baba yaga)
		case 3055:	//:: Bullywug: Brown* (baba yaga)
		case 3538:  //:: Fish: Pike* (JFK)
		case 3539:	//:: Fish: Pike, Giant* (JFK)	
		case 3889:	//:: Hag: Sea 2* (Hardpoints)

        return TRUE;
	}

//:: If you made it this far, return false.
    return FALSE;
}


//:: Can't breathe in water
void ApplySuffocationEffect(object oCreature)
{
    int iConstitution 	= GetAbilityScore(oCreature, ABILITY_CONSTITUTION);
    int iBreathRounds 	= iConstitution * 2;
    int iSuffocationDC 	= 10;  // Starting suffocation DC

    int iCurrentRound = GetLocalInt(oCreature, "SuffocationRound");

    if (iCurrentRound <= iBreathRounds)
    {
        if (GetResRef(OBJECT_SELF) != "mepooze001" &&
            GetResRef(OBJECT_SELF) != "tarmephit001" &&
			!GetHasFeat(FEAT_WATER_BREATHING, oCreature) &&
            !GetHasFeat(FEAT_BREATHLESS, oCreature) &&
            !GetHasSpellEffect(SPELL_WATER_BREATHING, oCreature) &&
            (MyPRCGetRacialType(oCreature) != RACIAL_TYPE_UNDEAD) &&
			(MyPRCGetRacialType(oCreature) != RACIAL_TYPE_ELEMENTAL) &&
            (MyPRCGetRacialType(oCreature) != RACIAL_TYPE_CONSTRUCT))
        {
            SendMessageToPC(oCreature, "You are struggling to breathe in the water!");

            if (d20() + GetFortitudeSavingThrow(oCreature) >= iSuffocationDC)
            {
                SendMessageToPC(oCreature, "You manage to hold your breath and avoid suffocation for now.");
            }
            else
            {
                SendMessageToPC(oCreature, "You are drowning!");

                if (iCurrentRound == 1)
                {
                    AssignCommand(oCreature, ActionPlayAnimation(ANIMATION_LOOPING_SPASM, 0.5f, 6.0f));
                    SetCurrentHitPoints(oCreature, 1);
                }
                else if (iCurrentRound == 2)
                {
                    SetCurrentHitPoints(oCreature, 0);
                }
                else if (iCurrentRound == 3)
                {
                    ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_DEATH), oCreature);
                    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDeath(), oCreature);
                }

                iCurrentRound++;
            }
        }

        // Store the updated round counter back in the creature's local variables
        SetLocalInt(oCreature, "SuffocationRound", iCurrentRound);
    }
}


//:: Water slows non-aquatic to 1/2 speed 
//:: unless they are under the effect of Freedom of Movement
void ApplySlowEffect(object oCreature)
{
	if (GetIsAquatic(oCreature)	== FALSE			&&
		GetResRef(OBJECT_SELF) 	!= "mepooze001"		&& 
		GetResRef(OBJECT_SELF) 	!= "tarmephit001"	&&
		!GetHasSpellEffect(SPELL_FREEDOM_OF_MOVEMENT, oCreature) ||
        GetHasEffect(IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE, oCreature))
    {
        // Object has either Freedom of Movement spell effect or IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE effect
        SendMessageToPC(GetFirstPC(), "This object has Freedom of Movement or immunity to movement speed decrease!");
    }
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectMovementSpeedDecrease(50), oCreature, 6.0f);
}

void main()
{
    object oArea 		= GetArea(OBJECT_SELF);
    object oCreature 	= GetFirstObjectInArea(oArea, OBJECT_TYPE_CREATURE);
	
	string sResref 		= GetResRef(oCreature);

    while (GetIsObjectValid(oCreature))
    {
        //:: Calculate the armor penalty
        int iArmorPenalty = 0;
        object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oCreature);
        if (GetIsObjectValid(oArmor))
        {
            iArmorPenalty = GetItemACValue(oArmor);
        }

        //:: Calculate the DC for the Strength check
        int iStrengthDC = 15 + iArmorPenalty;

        //:: Be an Ooze Mephit or roll a Strength check against the DC
        if (GetIsAquatic(oCreature)	== FALSE			&&
			GetResRef(OBJECT_SELF) != "mepooze001"		&& 
			GetResRef(OBJECT_SELF) != "tarmephit001"	||
			GetAppearanceType(oCreature) != APPEARANCE_TYPE_MEPHIT_OOZE ||
			d20() + GetAbilityModifier(ABILITY_STRENGTH, oCreature) < iStrengthDC)
        {
            //:: Apply the other effects since the Strength check failed
			SendMessageToPC(oCreature, "You are floundering in the water!");
            ApplySuffocationEffect(oCreature);
        }
		
		//:: Tar is always hot & slowing
		ApplySlowEffect(oCreature);
		
        oCreature = GetNextObjectInArea(oArea, OBJECT_TYPE_CREATURE);
    }
}