private static void HandleTrapDetected(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint detector)
        {
            trap.Detected = true;
           
            NWEffect vfx = s.SupernaturalEffect(s.EffectNWN2SpecialEffectFile(trap.TrapTriggerVFX, OBJECT_INVALID, s.Vector(0.0f, 0.0f, 0.0f)));
            s.ApplyEffectToObject(DURATION_TYPE_PERMANENT, vfx, s.GetObjectByTag(trap.Tag, 0), 0.0f);

            uint detectWidget = s.CreateObject(OBJECT_TYPE_PLACEABLE, "acr_trap_disarm", s.GetLocation(detector), TRUE, trap.Tag + "_");
            if (!String.IsNullOrEmpty(trap.Description))
            {
                s.SetDescription(detectWidget, trap.Description);
            }
            s.SetFirstName(detectWidget, String.Format("Disarm the {0} trap", trap.SpellTrap ? "Spell" : "Mechanical"));
            
            // If they clicked to walk, let's stop them from walking into the hazard they just found.
            if (s.GetCurrentAction(detector) == ACTION_MOVETOPOINT)
            {
                s.AssignCommand(detector, delegate { s.ClearAllActions(0); });
            }
            s.PlaySound("alert", FALSE);
            s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.SupernaturalEffect(s.EffectNWN2SpecialEffectFile("fx_bang", detector, s.Vector(0.0f,0.0f,0.0f))), detector, 6.0f);
            s.SendMessageToPC(detector, "You spot a trap!");
        }
        public static void Fire(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint specialTarget)
        {
            List<uint> targets = new List<uint>();
            if (s.GetIsObjectValid(specialTarget) == TRUE)
            {
                targets.Add(specialTarget);
            }
            foreach (uint contents in s.GetObjectsInPersistentObject(s.GetObjectByTag(trap.Tag, 0), OBJECT_TYPE_CREATURE, 0))
            {
                if (FitsTrapTargetRestriction(s, trap, contents))
                {
                    targets.Add(contents);
                }
            }

            if (targets.Count == 0)
            {
                // Might be that they all left. In any case
                // we have nothing to shoot
                trap.IsFiring = false;
                return;
            }
            uint target;
            if (targets.Count == 1)
            {
                target = targets[0];
            }
            else
            {
                target = targets[s.Random(targets.Count)];
            }

            uint caster;
            if (s.GetIsObjectValid(trap.TrapOrigin) == FALSE)
            {
                caster = s.GetObjectByTag(trap.Tag, 0);
            }
            else
            {
                caster = trap.TrapOrigin;
            }

            if (trap.SpellTrap)
            {
                // It's a spell-- guess this is simple.
                s.AssignCommand(caster, delegate { s.ActionCastSpellAtObject(trap.SpellId, target, METAMAGIC_NONE, TRUE, 0, 0, 1); });
            }
            else
            {
                foreach (uint victim in s.GetObjectsInShape(trap.EffectArea, trap.EffectSize, s.GetLocation(target), false, OBJECT_TYPE_CREATURE, s.GetPosition(caster)))
                {
                    s.ApplyEffectToObject(DURATION_TYPE_INSTANT, GetTrapEffect(s, trap, victim), victim, 0.0f);
                    _doSoloVFX(s, trap, victim);
                }
                _doGroupVFX(s, trap, s.GetLocation(target));
            }

            if (trap.NumberOfShots > -1)
            {
                if (trap.NumberOfShots < 2)
                {
                    TrapDisable.RemoveTrap(s, trap);
                    return;
                }
                else
                {
                    trap.NumberOfShots--;
                }
            }

            trap.IsFiring = true;
            s.DelayCommand(6.0f, delegate { Fire(s, trap); });
        }
 private static void _doSoloVFX(CLRScriptBase s, ALFA.Shared.ActiveTrap trap, uint target)
 {
     if (trap.EffectSize < 2.0f)
     {
         if (s.GetArea(trap.TrapOrigin) == s.GetArea(s.GetObjectByTag(trap.Tag, 0)))
         {
             if ((trap.DamageType & DAMAGE_TYPE_ACID) == DAMAGE_TYPE_ACID)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_ACID, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_BLUDGEONING) == DAMAGE_TYPE_BLUDGEONING)
             {
                 s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_SLING, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0);
                 float fShotDelay = 0.1f;
                 int c = 1;
                 while (c < trap.DiceNumber)
                 {
                     s.DelayCommand(fShotDelay, delegate { s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_SLING, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0); });
                     fShotDelay += 0.1f;
                     c++;
                 }
             }
             if ((trap.DamageType & DAMAGE_TYPE_COLD) == DAMAGE_TYPE_COLD)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_ICE, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_DIVINE) == DAMAGE_TYPE_DIVINE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_HOLY, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_ELECTRICAL) == DAMAGE_TYPE_ELECTRICAL)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_LIGHTNING, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_FIRE) == DAMAGE_TYPE_FIRE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_FIRE, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_MAGICAL) == DAMAGE_TYPE_MAGICAL)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_MAGIC, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_NEGATIVE) == DAMAGE_TYPE_NEGATIVE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_EVIL, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_PIERCING) == DAMAGE_TYPE_PIERCING)
             {
                 s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_DART, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0);
                 float fShotDelay = 0.1f;
                 int c = 1;
                 while (c < trap.DiceNumber)
                 {
                     s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_DART, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0);
                     fShotDelay += 0.1f;
                     c++;
                 }
             }
             if ((trap.DamageType & DAMAGE_TYPE_POSITIVE) == DAMAGE_TYPE_POSITIVE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_HOLY, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_SLASHING) == DAMAGE_TYPE_SLASHING)
             {
                 s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_THROWINGAXE, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0);
                 float fShotDelay = 0.1f;
                 int c = 1;
                 while (c < trap.DiceNumber)
                 {
                     s.SpawnItemProjectile(trap.TrapOrigin, target, s.GetLocation(trap.TrapOrigin), s.GetLocation(target), BASE_ITEM_THROWINGAXE, PROJECTILE_PATH_TYPE_HOMING, OVERRIDE_ATTACK_RESULT_HIT_SUCCESSFUL, 0);
                     fShotDelay += 0.1f;
                     c++;
                 }
             }
             if ((trap.DamageType & DAMAGE_TYPE_SONIC) == DAMAGE_TYPE_SONIC)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_TEMPORARY, s.EffectBeam(VFX_BEAM_SONIC, trap.TrapOrigin, BODY_NODE_CHEST, FALSE), target, 1.0f);
             }
         }
         else
         {
             // These are pretty much single-target effects.
             if ((trap.DamageType & DAMAGE_TYPE_ACID) == DAMAGE_TYPE_ACID)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_ACID_S, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_BLUDGEONING) == DAMAGE_TYPE_BLUDGEONING)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_COLD) == DAMAGE_TYPE_COLD)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_FROST_L, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_DIVINE) == DAMAGE_TYPE_DIVINE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_HIT_DIVINE, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_ELECTRICAL) == DAMAGE_TYPE_ELECTRICAL)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_LIGHTNING_S, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_FIRE) == DAMAGE_TYPE_FIRE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_FLAME_S, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_MAGICAL) == DAMAGE_TYPE_MAGICAL)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_MAGBLUE, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_NEGATIVE) == DAMAGE_TYPE_NEGATIVE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_NEGATIVE_ENERGY, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_PIERCING) == DAMAGE_TYPE_PIERCING)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SPIKE_TRAP, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_POSITIVE) == DAMAGE_TYPE_POSITIVE)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SUNSTRIKE, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_SLASHING) == DAMAGE_TYPE_SLASHING)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_COM_BLOOD_CRT_RED, FALSE), target, 0.0f);
             }
             if ((trap.DamageType & DAMAGE_TYPE_SONIC) == DAMAGE_TYPE_SONIC)
             {
                 s.ApplyEffectToObject(DURATION_TYPE_INSTANT, s.EffectVisualEffect(VFX_IMP_SONIC, FALSE), target, 0.0f);
             }
         }
     }
     else { return; }
 }
 private static void SwimHeartbeat(CLRScriptBase script, uint Creature)
 {
     uint Trigger = AppearanceTypes.currentSwimTrigger[Creature];
     foreach(uint contents in script.GetObjectsInPersistentObject(Trigger, CLRScriptBase.OBJECT_TYPE_CREATURE, CLRScriptBase.PERSISTENT_ZONE_ACTIVE))
     {
         if(contents == Creature)
         {
             if (script.GetSubRace(Creature) != CLRScriptBase.RACIAL_SUBTYPE_WATER_GENASI &&
                 script.GetLocalInt(Creature, ACR_CREATURE_AQUATIC) == 0)
             {
                 int SwimDC = script.GetLocalInt(Trigger, ACR_SWIM_DC);
                 int SinkDC = SwimDC - 5;
                 int NoAir = script.GetLocalInt(Trigger, ACR_NO_AIR);
                 int Roll = script.d20(1);
                 int Bonus = script.GetSkillRank(CLRScriptBase.SKILL_SWIM, Creature, CLRScriptBase.FALSE);
                 ProcessWaterEffects(script, Creature, Trigger);
                 if (10 + Bonus >= SwimDC)
                 {
                     // Can take 10 here.
                     Roll = 10;
                 }
                 if (Roll + Bonus >= SwimDC)
                 {
                     script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(50)), Creature, 6.0f);
                     script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Success!*", Roll, Bonus, Roll+Bonus, SwimDC));
                     if(NoAir == CLRScriptBase.FALSE)
                     {
                         CurrentDrownStatus.Remove(Creature);
                         CurrentDrownDC.Remove(Creature);
                     }
                     else
                     {
                         ProcessNoAir(script, Creature);
                     }
                 }
                 else if (Roll + Bonus >= SinkDC)
                 {
                     script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(75)), Creature, 6.0f);
                     script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Failure!*", Roll, Bonus, Roll + Bonus, SwimDC));
                     script.SendMessageToPC(Creature, String.Format("You struggle to move through the water."));
                     if (NoAir == CLRScriptBase.FALSE)
                     {
                         CurrentDrownStatus.Remove(Creature);
                         CurrentDrownDC.Remove(Creature);
                     }
                     else
                     {
                         ProcessNoAir(script, Creature);
                     }
                 }
                 else
                 {
                     script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectMovementSpeedDecrease(75)), Creature, 6.0f);
                     // TODO: Find a way to apply this penalty without completely screwing the PC's AC.
                     //script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectACDecrease(2, CLRScriptBase.AC_DODGE_BONUS, CLRScriptBase.DAMAGE_TYPE_ALL)), Creature, 6.0f);
                     script.SendMessageToPC(Creature, String.Format("*Swim: {0} + {1} = {2} v. DC {3} :: Failure!*", Roll, Bonus, Roll + Bonus, SwimDC));
                     script.SendMessageToPC(Creature, String.Format("You're completely overwhelmed by the pull of the water!"));
                     ProcessNoAir(script, Creature);
                 }
             }
             else
             {
                 script.SendMessageToPC(Creature, "Your swim speed and capacity to breathe water allows you to move easily through the water.");
                 return;
             }
             script.DelayCommand(6.0f, delegate { SwimHeartbeat(script, Creature); });
             return;
         }
     }
     AppearanceTypes.currentSwimTrigger[Creature] = CLRScriptBase.OBJECT_INVALID;
     AppearanceTypes.characterMovement[Creature] = AppearanceTypes.MovementType.Walking;
     if (Swimming.CurrentDrownStatus.ContainsKey(Creature)) Swimming.CurrentDrownStatus.Remove(Creature);
     AppearanceTypes.RecalculateMovement(script, Creature);
 }
 private static void ProcessWaterEffects(CLRScriptBase script, uint Creature, uint Trigger)
 {
     if(script.GetIsImmune(Creature, CLRScriptBase.IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE, Trigger) != CLRScriptBase.FALSE)
     {
         return;
     }
     uint weapon = script.GetItemInSlot(CLRScriptBase.INVENTORY_SLOT_RIGHTHAND, Creature);
     if (script.GetIsObjectValid(weapon) == CLRScriptBase.TRUE)
     {
         int weaponType = script.GetBaseItemType(weapon);
         if (ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].WeaponType != 1 &&
             ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].WeaponType != 0) // unfortunately, this is magic numbered in the 2da as well
         {
             script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectAttackDecrease(2, CLRScriptBase.ATTACK_BONUS_ONHAND)), Creature, 6.0f);
             int damagePenalty = ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].DieToRoll / 4;
             damagePenalty += script.GetAbilityModifier(CLRScriptBase.ABILITY_STRENGTH, Creature) / 2;
             int damageType = CLRScriptBase.DAMAGE_TYPE_SLASHING;
             switch (ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].WeaponType)
             {
                 case 2: damageType = CLRScriptBase.DAMAGE_TYPE_BLUDGEONING; break;
                 case 3: damageType = CLRScriptBase.DAMAGE_TYPE_SLASHING; break;
                 case 4: damageType = CLRScriptBase.DAMAGE_TYPE_SLASHING; break;
                 case 5: damageType = CLRScriptBase.DAMAGE_TYPE_BLUDGEONING; break;
             }
             script.EffectDamageDecrease(damagePenalty, damageType);
         }
         weapon = script.GetItemInSlot(CLRScriptBase.INVENTORY_SLOT_LEFTHAND, Creature);
         if (script.GetIsObjectValid(weapon) == CLRScriptBase.TRUE)
         {
             weaponType = script.GetBaseItemType(weapon);
             if (ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].WeaponType != 1 &&
                 ALFA.Shared.Modules.InfoStore.BaseItems[weaponType].WeaponType != 0) // unfortunately, this is magic numbered in the 2da as well
             {
                 script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectAttackDecrease(2, CLRScriptBase.ATTACK_BONUS_OFFHAND)), Creature, 6.0f);
             }
         }
     }
     else
     {
         script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectAttackDecrease(2, CLRScriptBase.ATTACK_BONUS_ONHAND)), Creature, 6.0f);
         int damagePenalty = 1 + script.GetAbilityModifier(CLRScriptBase.ABILITY_STRENGTH, Creature) / 2;
         if(damagePenalty > 0)
         {
             script.EffectDamageDecrease(damagePenalty, CLRScriptBase.DAMAGE_TYPE_BLUDGEONING);
         }
     }
 }
        private static void ProcessNoAir(CLRScriptBase script, uint Creature)
        {
            if (!GetNeedsToBreathe(script, Creature))
            {
                return;
            }
            script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_TEMPORARY, script.ExtraordinaryEffect(script.EffectSilence()), Creature, 6.0f);
            if (!CurrentDrownStatus.ContainsKey(Creature))
            {
                CurrentDrownStatus.Add(Creature, 1);
            }
            else
            {
                CurrentDrownStatus[Creature]++;
            }

            if(CurrentDrownStatus[Creature] > script.GetAbilityScore(Creature, CLRScriptBase.ABILITY_CONSTITUTION, CLRScriptBase.FALSE) * 2)
            {
                if(!CurrentDrownDC.ContainsKey(Creature))
                {
                    CurrentDrownDC.Add(Creature, 10);
                }
                else
                {
                    CurrentDrownDC[Creature]++;
                }

                int conCheck = script.d20(1);
                int conMod = script.GetAbilityModifier(CLRScriptBase.ABILITY_CONSTITUTION, Creature);
                if(conCheck + conMod < CurrentDrownDC[Creature])
                {
                    script.SendMessageToPC(Creature, String.Format("*Constitution: {0} + {1} = {2} v. DC {3} :: Failure!*", conCheck, conMod, conCheck + conMod, CurrentDrownDC[Creature]));
                    int Damage = 0;
                    string Message;
                    int HP = script.GetCurrentHitPoints(Creature);
                    if(HP > 1)
                    {
                        Damage = script.GetCurrentHitPoints(Creature) - 1;
                        Message = "You're suffocating! If you don't find air NOW, you will DIE!";
                    }
                    else if(HP > 0)
                    {
                        Damage = 2;
                        Message = "You have lost consciousness. Unless someone comes to rescue you, you will die.";
                    }
                    else
                    {
                        Damage = 10;
                        Message = "You have suffocated";
                    }
                    script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_INSTANT, script.EffectDamage(Damage, CLRScriptBase.DAMAGE_TYPE_MAGICAL, CLRScriptBase.DAMAGE_POWER_ENERGY, CLRScriptBase.TRUE), Creature, 0.0f);
                    script.SendMessageToPC(Creature, Message);
                    return;
                }
                else
                {
                    script.SendMessageToPC(Creature, "You are barely clutching to consciousness! Get air NOW!");
                    return;
                }
            }
            else
            {
                int SecondsLeft = ((script.GetAbilityScore(Creature, CLRScriptBase.ABILITY_CONSTITUTION, CLRScriptBase.FALSE) * 2) - CurrentDrownStatus[Creature]) * 6;
                if(SecondsLeft > 60)
                {
                    script.SendMessageToPC(Creature, String.Format("You can hold your breath for {0} more seconds.", SecondsLeft));
                }
                else if(SecondsLeft > 30)
                {
                    script.SendMessageToPC(Creature, String.Format("Careful! You can only hold your breath for {0} more seconds!", SecondsLeft));
                }
                else
                {
                    script.SendMessageToPC(Creature, String.Format("** WARNING ** If you don't find air within {0} seconds, you will DIE!", SecondsLeft));
                }
            }
        }
        public static void Dismount(CLRScriptBase script, uint Character, uint Cloak, NWLocation Location)
        {
            string resRef = "";
            if (script.GetLocalInt(Cloak, ACR_IS_WARHORSE) == 1)
            {
                resRef = "abr_cr_an_horse_pal_";
                int nPalLevel = script.GetLevelByClass(CLRScriptBase.CLASS_TYPE_PALADIN, Character);
                if (nPalLevel >= 15) resRef += "15";
                else if (nPalLevel >= 11) resRef += "11";
                else if (nPalLevel >= 8) resRef += "8";
                else if (nPalLevel >= 5) resRef += "5";
                else resRef = "abr_cr_an_horse03";
            }
            else
            {
                switch (script.GetTag(Cloak))
                {
                    case "acr_ooc_horse01":
                        resRef = "abr_cr_an_horse01";
                        break;
                    case "acr_ooc_horse02":
                        resRef = "abr_cr_an_horse02";
                        break;
                    case "acr_ooc_horse03":
                        resRef = "abr_cr_an_horse03";
                        break;
                    default:
                        // Looks like we're not actually dismounting a horse.
                        return;
                }
            }
            
            uint Horse = script.CreateObject(CLRScriptBase.OBJECT_TYPE_CREATURE, resRef, Location, CLRScriptBase.FALSE, "");
            script.SetLocalInt(Horse, ACR_HORSE_OWNER, script.GetLocalInt(Character, ACR_CID));
            script.SetLocalInt(Horse, ACR_HORSE_ID, script.GetLocalInt(Cloak, ACR_HORSE_ID));
            int damage = script.GetCurrentHitPoints(Horse) - script.GetLocalInt(Cloak, ACR_HORSE_HP);
            if(damage > 0)
            {
                script.ApplyEffectToObject(CLRScriptBase.DURATION_TYPE_INSTANT, script.EffectDamage(damage, CLRScriptBase.DAMAGE_TYPE_MAGICAL, CLRScriptBase.DAMAGE_POWER_PLUS_TWENTY, CLRScriptBase.TRUE), Horse, 0.0f);
            }
            if (script.GetLocalInt(Cloak, ACR_IS_WARHORSE) == 1)
            {
                script.AddHenchman(Character, Horse);
                script.SetLocalInt(Horse, ACR_IS_WARHORSE, 1);
                script.SetLocalObject(Character, ACR_PAL_WARHORSE, Horse);
            }

            uint Item = GetOwnershipItemById(script, Character, script.GetLocalInt(Cloak, ACR_HORSE_ID));
            script.SetLocalObject(Item , ACR_HORSE_OBJECT, Horse);
            script.SetLocalObject(Horse, ACR_HORSE_OBJECT, Character);

            script.SetLocalString(Item, ACR_HORSE_PERS_LOC_AREA, script.GetTag(script.GetArea(Horse)));
            script.SetLocalFloat(Item, ACR_HORSE_PERS_LOC_X, script.GetPosition(Horse).x);
            script.SetLocalFloat(Item, ACR_HORSE_PERS_LOC_Y, script.GetPosition(Horse).y);
            script.SetLocalFloat(Item, ACR_HORSE_PERS_LOC_Z, script.GetPosition(Horse).z);

            script.SetPlotFlag(Cloak, CLRScriptBase.FALSE);
            script.DestroyObject(Cloak, 0.0f, CLRScriptBase.FALSE);
            isWarhorse.Remove(Character);
        }