Page 1 of 1

me again: area with limited air

Posted: Thu Apr 27, 2006 12:25 pm
by girlysprite
And its me again, and Im trying to pull quite a thing off.

Once a player enters a certain area, he gets a message that the air is stale and old. There is only a limited supply of air. While the player is in the area, an invisible clock starts ticking.
At some points the player will get a hint that the air supply becomes less. When time is running out, the player will become dazed, and later hp starts to get drained.
This doesnt just affect the player, but also all the creatures in that level.
When the player equips the helm, the countdown will stop counting and he wont receive any bad effects anymore.

There are a few thing Id like to add.
Every time a firespell is cast, the counter goes down with 10. fire consumes air after all.

When the counter is low (<30) or zero, all firespells and sound spells will fail. Might have to pick the spells myself and throw in the effects with each of them.
But how do I detect when certain spells are cast, either by enemy or PC.

and I have to find a way to make several creatures immune to this. Without a helmet. Im still thinking of how to handle that.

this is the code I have so far, it is in the onEnterArea handle, and it works.

Code: Select all

edit- code that wasnt working. got helped, removed to decrease post length

Posted: Thu Apr 27, 2006 2:01 pm
by girlysprite
okay...

with help from Krator I figured out I need spellhooking.
I turned the spellhooking on for my module and made a file myspellsystem, as per example from mistcaller.

Can spells be detected by the element they have? (like firespells). does anyone have suggestions for the code I should use?

Posted: Thu Apr 27, 2006 3:10 pm
by Krator
girlysprite wrote:Can spells be detected by the element they have? (like firespells).
Not without making a switch with case statements for every spell constant you deem is a fire spell.
does anyone have suggestions for the code I should use?
The Avlis spellhooking code, where the above is done in some way. (Elemental damage function to allow for the metamagic substitution rods)

Posted: Thu Apr 27, 2006 3:55 pm
by illawren1
This is not helpful but wow that sounds like some cool almost like PnP stuff.

Posted: Mon May 01, 2006 9:15 pm
by girlysprite
okay, I got a bit futher, but still have some real trouble.

I have 2 pieces of code. In code one, every second an integer gets substracted by 1. A countdown.

The code 2, a spellhooking code, I am tracking firespells, and want to substract an extra 10 from that integer. when integer is 0 or less, no firespells can be cast.

But code 2 is having trouble reading and altering the integer from code 1. How can I make sure they can? I have already tried to store the integer in the area the player is in, and retrieve it from the area again. no luck so far. And also, this way would give me trouble editing the integer fromwithin the spellhook code...

this is code 1

Code: Select all


void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID);

void main()
{
    
    object oPC = GetEnteringObject();
   
    Countdown( 750, oPC);
  FloatingTextStringOnCreature("The air is stale, and old.", oPC);
}

// ** FUNCTION DEFINITIONS ** //
void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID)
{
        int TimeLimit;
        object oPC = GetEnteringObject();
       SetLocalInt(GetArea(oPC), "TimeLimit", nTimeLimit);
       FloatingTextStringOnCreature( IntToString(TimeLimit), oObject);

   
    if( nTimeLimit <= 0 ) {
       

FloatingTextStringOnCreature("You find yourself completely out of air, and collapse. ", oObject);

//die. sense if a player had death immunity. If he doesnt, kill, if he has, drain all his hp.
}



     else {


              if( GetIsObjectValid( oObject) && nTimeLimit == 210) {

      FloatingTextStringOnCreature("The air grows thin. It might run out soon. ", oObject);
            }

    if( GetIsObjectValid( oObject) && nTimeLimit == 150) {

    if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      FloatingTextStringOnCreature("There is little air left, but the helmet keeps you safe.", oObject);
      }

    else{

   FloatingTextStringOnCreature("There is very little air left. You start to feel very light in your head.", oObject);

     object oTarget;
    oTarget = oObject;
    effect eEffect;
    eEffect = EffectDazed();

    eEffect = ExtraordinaryEffect(eEffect);

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
    }
        }

  if( GetIsObjectValid( oObject) && nTimeLimit == 90) {

   if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      FloatingTextStringOnCreature("The air grows thinner and thinner", oObject);
      }
       else{
   FloatingTextStringOnCreature("There is barely any air left, and you feel how you grow weaker. ", oObject);
   }
   }

   if( GetIsObjectValid( oObject) && nTimeLimit <= 90 && nTimeLimit >=30) {

    if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      }
 else{

 effect eEffect;
eEffect = EffectDamage(1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oObject);
}



 }

 if( GetIsObjectValid( oObject) && nTimeLimit == 30) {

   if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
  FloatingTextStringOnCreature("Air ran out, any creature that needs air migth die soon.*", oObject);
      }
      else{

 FloatingTextStringOnCreature("Air ran out, and you try to hold your breath, though the weakness contiues to increase*", oObject);
 }
 }


    if( GetIsObjectValid( oObject) && nTimeLimit <= 29 && nTimeLimit >=0) {
   if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      }
 else{


 effect eEffect;
eEffect = EffectDamage(2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oObject);

  }

 }




            FloatingTextStringOnCreature( IntToString(nTimeLimit), oObject);

        // ...and continue with the countdown, only if the player does not have that helmet on.
            if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) != "Respiratorhelmet"){
        DelayCommand( 3.0, Countdown( --nTimeLimit, oObject));

        }
    }
}

this is code 2

Code: Select all

#include "x2_inc_switches"

void main()
{
     int nSpell=GetSpellId();
     int nSpellDC=GetSpellSaveDC();
     int nCastLevel=GetCasterLevel(OBJECT_SELF);
     int nTimer;
     object oObject = OBJECT_INVALID;
     object oTarget;
     object oArea;
     effect eEffect;


     switch (nSpell)
     {
          case SPELL_FIREBALL:
          case SPELL_FIRE_STORM:
          case SPELL_FIREBRAND:
          case SPELL_FLAME_WEAPON:
          case SPELL_FLAME_LASH:
          case SPELL_FLAME_STRIKE:
          case SPELL_DARKFIRE:
          case SPELL_WALL_OF_FIRE:
          case SPELL_SHADES_FIREBALL:
          case SPELL_METEOR_SWARM:
          case SPELL_FLARE:
          case SPELL_ELEMENTAL_SHIELD:
          case SPELL_DELAYED_BLAST_FIREBALL:



oArea = GetArea(OBJECT_SELF);
nTimer = GetLocalInt( oArea, "TimeLimit" );
if (nTimer>=0 && GetTag(oArea) == "Lichlairdeepbelow"){


nTimer==nTimer-10;


if (nTimer <= 209 && nTimer >=200) {
 FloatingTextStringOnCreature("The air grows thin. It might run out soon. ", oObject);
 }

else if (nTimer <= 149 && nTimer >=140) {

  if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      FloatingTextStringOnCreature("There is little air left, but the helmet keeps you safe.", oObject);
      }

    else{

   FloatingTextStringOnCreature("There is very little air left. You start to feel very light in your head.", oObject);
       oTarget = oObject;

    eEffect = EffectDazed();

    eEffect = ExtraordinaryEffect(eEffect);

    ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);


}   }
else if (nTimer <= 89 && nTimer >=80) {
  if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
      FloatingTextStringOnCreature("The air grows thinner and thinner", oObject);
      }
       else{
   FloatingTextStringOnCreature("There is barely any air left, and you feel how you grow weaker. ", oObject);
   }

}

else if (nTimer <= 29 && nTimer >=20) {

   if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
  FloatingTextStringOnCreature("Air ran out, any creature that needs air migth die soon.*", oObject);
      }
      else{

 FloatingTextStringOnCreature("Air ran out, and you try to hold your breath, though the weakness contiues to increase*", oObject);
 }
 }
break;
}

else if (nTimer<=1 && GetTag(oArea) == "Lichlair"){

SetModuleOverrideSpellScriptFinished();

SendMessageToPC(OBJECT_SELF, "Due to the lack of air, the fire fizzles right away");

break;

}
}
}

Posted: Mon May 01, 2006 9:16 pm
by girlysprite
-double post-

Posted: Mon May 01, 2006 10:10 pm
by Mistcaller
For a start, I would change the function "Countdown", so that the object oPC is not defined again.

In other words, instead of:

Code: Select all

int TimeLimit; 
        object oPC = GetEnteringObject(); 
       SetLocalInt(GetArea(oPC), "TimeLimit", nTimeLimit); 
       FloatingTextStringOnCreature( IntToString(TimeLimit), oObject); 
 
you should have:

Code: Select all

int TimeLimit; 
        SetLocalInt(GetArea(oObject), "TimeLimit", nTimeLimit); 
        FloatingTextStringOnCreature( IntToString(TimeLimit), oObject); 
 
Edit: also try to keep the names of the Tags under 16 letters for good measure. :wink:

Posted: Mon May 01, 2006 11:22 pm
by spool32
One suggestion in concept.. when there's no air, only Silent spells should be castable... you can't talk with no air to breath!

-spool32

Posted: Tue May 02, 2006 1:41 am
by itsabughunt
spool32 wrote:One suggestion in concept.. when there's no air, only Silent spells should be castable... you can't talk with no air to breath!

-spool32
That is a good observation. I guess it wouldn't apply in this particular case since Girlysprite said "...the air is stale and old." But the idea of vacuum or lack of air could make for interesting magically trapped rooms or maybe for areas in Ithilla.

I dont know the first thing about coding, but this whole concept of taking into account the atmospheric qualities is really an interesting idea. Is this something that could/would be imported to Avlis ever?

Posted: Tue May 02, 2006 6:04 am
by Jo' d
*notes to self*

1. Stay away from Girly's dungeons.....way too devious that Lass
2. See note #1

Note to Girly....
Lack of oxygen, does not mandate lack of atmosphere, one can speak with other gases present (ex. helium, nitrous, etc)...probably not for long though

Posted: Tue May 02, 2006 6:32 am
by girlysprite
when you are out of air, you're dying. There is no spellcasting then anyways.
When you wear the special helmet, it provides you with air, and thus you can cast spell. It doesnt provide air to the environment though, so no fireballs.

Let me test the new code snippets :)

by the way, I have applied as builder for avlis. Also, avlis can have all my codes ;) Id be happy to implement such a thing if the rest of the team likes it ;)

Posted: Tue May 02, 2006 6:58 am
by girlysprite
I changed the code, but the value still isnt placed in the Timelimet integer.

Posted: Tue May 02, 2006 7:18 am
by Mistcaller
Just noticed one more little mistake. You shouldnt define again the integer TimeLimit (which is actually nTimeLimit) in the countdown function since you define it in the arguments. It should be corrected also in the FloatingText command.

So it should read:

Code: Select all

void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID) 
{ 
       SetLocalInt(GetArea(oObject), "TimeLimit", nTimeLimit); 
       FloatingTextStringOnCreature( IntToString(nTimeLimit), oObject); 

Posted: Tue May 02, 2006 8:44 am
by girlysprite
I managed to get a working code. Well, partially.

When the counter reaches zero and below, no more firespells can be cast, yeiy :D

The next problem I try to solve is to get the value of the integer from the spellhook to the counter, because the spellhook also should be able to influence the counter.

I try to do that by setting the integer on the area, and reading it out in the counter script, then update it, then put the new value in the area integer again.

The following code I have adjusted: the spellhooking script can alter the area intneger, but something goes wrong in the count down. It isnt counting down. BTW 20 is the starting number, when I use 19 as starting number, the number appearing is 0, because TimeLimit is still empty in the beginning. The counting down isnt working then either. I guess all the swapping of integers make something go wrong.


countdown. I have tried changing oPC to oObject, didnt change anything.

Code: Select all

void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID);

void main()
{

    object oPC = GetEnteringObject();
   
    Countdown( 20, oPC);
   

FloatingTextStringOnCreature("The air is stale, and old.", oPC);
}

// ** FUNCTION DEFINITIONS ** //
void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID)
{


        object oPC = GetEnteringObject();
        object oArea;
        oArea=GetArea( oObject );

        if(nTimeLimit == 20){
        SetLocalInt( GetArea( oPC ), "TimeLimit", nTimeLimit );
        }

   nTimeLimit = GetLocalInt( oArea, "TimeLimit" );
       DelayCommand( 1.0, Countdown( --nTimeLimit, oObject));
   SetLocalInt( GetArea( oPC ), "TimeLimit", nTimeLimit );


    FloatingTextStringOnCreature( IntToString( nTimeLimit), oObject);

}

  
one without object oPC, just to be sure

Code: Select all

void Countdown( int nTimeLimit, object oObject = OBJECT_INVALID)
{


     
        object oArea;
        oArea=GetArea( oObject );
         //if you start, make sure something is in Timelimit
        if(nTimeLimit == 20){
        SetLocalInt( GetArea( oObject ), "TimeLimit", nTimeLimit );
        }
    //get the int from TimeLimit, put it in nTimeLimit
   nTimeLimit = GetLocalInt( oArea, "TimeLimit" );
   //change nTimeLimit
   DelayCommand( 1.0, Countdown( --nTimeLimit, oObject));
   //put the new nTimeLimit back in TimeLimit
   SetLocalInt( GetArea( oObject ), "TimeLimit", nTimeLimit );

       FloatingTextStringOnCreature( IntToString( nTimeLimit), oObject);
also, the counter continues below zero...gotta stop that.

the spellhook:

Code: Select all

#include "x2_inc_switches"
void main()
{
     int nSpell=GetSpellId();
     int nSpellDC=GetSpellSaveDC();
     int nCastLevel=GetCasterLevel(OBJECT_SELF);
     int nTimer;
     object oObject = OBJECT_INVALID;
     object oTarget;
     object oArea;
     effect eEffect;
     switch (nSpell)
     {
          case SPELL_FIREBALL:
          case SPELL_FIRE_STORM:
          case SPELL_FIREBRAND:
          case SPELL_FLAME_WEAPON:
          case SPELL_FLAME_LASH:
          case SPELL_FLAME_STRIKE:
          case SPELL_DARKFIRE:
          case SPELL_WALL_OF_FIRE:
          case SPELL_SHADES_FIREBALL:
          case SPELL_METEOR_SWARM:
          case SPELL_FLARE:
          case SPELL_ELEMENTAL_SHIELD:
          case SPELL_DELAYED_BLAST_FIREBALL:

            oArea = GetArea(OBJECT_SELF);
            nTimer = GetLocalInt( oArea, "TimeLimit" );
            SendMessageToPC( OBJECT_SELF, "TimeLimit is " + IntToString( nTimer) +
               " from object " + ObjectToString( oArea ) );
            if (nTimer>=0 && GetTag(oArea) == "Lichlairdeepbelow")
            {
                nTimer = nTimer-10;
                FloatingTextStringOnCreature( IntToString( nTimer), oObject);
                SetLocalInt( GetArea( OBJECT_SELF ), "TimeLimit", nTimer );
}


            
            if (nTimer<=0)

            {
                SetModuleOverrideSpellScriptFinished();
                SendMessageToPC(OBJECT_SELF, "Due to the lack of air, the fire fizzles right away");
             //break;
            }
}}

Posted: Tue May 02, 2006 12:26 pm
by Jo' d
Girly sez:
...by the way, I have applied as builder for avlis

Uh-Oh!

Posted: Tue May 02, 2006 2:38 pm
by girlysprite
Be afriad Jo'd...I got the code working, and its becoming a beauty :twisted:

Ill post it when I got it wrapped up.

Posted: Tue May 02, 2006 9:10 pm
by girlysprite
the new code.
It works, except for one thing I liked about my old code. It damaged every creature in the area as well when the counter ran low. It was because the counter ran apart for each creature I think, as it was stores on themselves.
Now the counter is stored on the area. The PC gets the damage as the counter runs low, but i have to find a way to define all the creatures in the lair and do the same to them. Maybe give em all the same tag and use GetObjectByTag. Ill figure out tomorrow.

Countdown:

Code: Select all

edit-code that was almost working! complete code is at bottom of page. edited to decrease post length. 
spellhook:

Code: Select all

#include "x2_inc_switches"
void main()
{
     int nSpell=GetSpellId();
     int nSpellDC=GetSpellSaveDC();
     int nCastLevel=GetCasterLevel(OBJECT_SELF);
     int nTimer;
     object oObject = OBJECT_INVALID;
     object oTarget;
     object oArea;
     effect eEffect;
     switch (nSpell)
     {
          case SPELL_FIREBALL:
          case SPELL_FIRE_STORM:
          case SPELL_FIREBRAND:
          case SPELL_FLAME_WEAPON:
          case SPELL_FLAME_LASH:
          case SPELL_FLAME_STRIKE:
          case SPELL_DARKFIRE:
          case SPELL_WALL_OF_FIRE:
          case SPELL_SHADES_FIREBALL:
          case SPELL_METEOR_SWARM:
          case SPELL_FLARE:
          case SPELL_ELEMENTAL_SHIELD:
          case SPELL_DELAYED_BLAST_FIREBALL:

            oArea = GetArea(OBJECT_SELF);
            nTimer = GetLocalInt( oArea, "TimeLimit" );
            SendMessageToPC( OBJECT_SELF, "TimeLimit is " + IntToString( nTimer) + " from object " + ObjectToString( oArea ) );
            if (nTimer>=0 && GetTag(oArea) == "Lichlairdeepbelow")
            {
                int nTimer = GetLocalInt( oArea, "TimeLimit" );
                SetLocalInt( oArea, "TimeLimit", nTimer-10 );

            }


            if (nTimer <= 210 && nTimer >=200)
            {
                 FloatingTextStringOnCreature("The air grows thin. It might run out soon. ", oObject);
            }
            else if (nTimer <= 150 && nTimer >=140)
            {
                 if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet")
                    {
                        FloatingTextStringOnCreature("There is little air left, but the helmet keeps you safe.", oObject);
                    }
                    else
                    {
                        FloatingTextStringOnCreature(
                        "There is very little air left. You start to feel very light in your head.", oObject);
                        oTarget = oObject;
                        eEffect = EffectDazed();
                        eEffect = ExtraordinaryEffect(eEffect);
                        ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);
                    }
                }
           else if (nTimer <= 90 && nTimer >=80)
           {
                 if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet")
                    {
                        FloatingTextStringOnCreature("The air grows thinner and thinner", oObject);
                    }
                    else
                    {
                        FloatingTextStringOnCreature(
                        "There is barely any air left, and you feel how you grow weaker. ", oObject);
                    }
                }
           else if (nTimer <= 30 && nTimer >=20)
           {
                  if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet")
                    {
                        FloatingTextStringOnCreature(
                            "Air ran out, any creature that needs air migth die soon.*", oObject);
                    }
                    else
                    {
                        FloatingTextStringOnCreature(
                        "Air ran out, and you try to hold your breath, though the weakness contiues to increase*", oObject);
                    }
                }


            if (nTimer<=0)

            {
                SetModuleOverrideSpellScriptFinished();
                SendMessageToPC(OBJECT_SELF, "Due to the lack of air, the fire fizzles right away");

            }
            }
}

Posted: Wed May 03, 2006 7:43 am
by girlysprite
Okay, I cant target all creatures in one area by giving them the same tag. GetObjectByTag only targets the first one.

Is there a way to target all creatures in one area? I tried to getenteringobjects, but that doesnt seem to work. Or maybe I did it wrong.

Posted: Wed May 03, 2006 8:51 am
by Mistcaller
To loop around any type of elements you can use those functions that contain the word FIRST and NEXT along with a "while" statement. Check this example from nwnlexicon:

Code: Select all

// Any objects in the area tagged "DESTROY" are destroyed.
// Uses OBJECT_SELF as the area, but this can be subsituted for
// many things.

void main()
{
    // Loop all objects in us, an area
    object oArea = OBJECT_SELF;
    object oObject = GetFirstObjectInArea(oArea);
    while(GetIsObjectValid(oObject))
    {
         // Destroy any objects tagged "DESTROY"
         if(GetTag(oObject) == "DESTROY")
         {
             DestroyObject(oObject);
         }
         oObject = GetNextObjectInArea(oArea);
    }
}
Also, read about the function "GetNearestCreature", which can be of similar use.

Posted: Wed May 03, 2006 9:33 am
by girlysprite
p0m told me it ate too much CPU. someone in bioware forums called it rubbish ;) doesnt matter...I have another system, for a reason.

I dont want to appy damage to all creatures, only those with a certain tag. Yes, your code can do that. Problem is, if i want to adress one of the creatures for a script, how do I adress them? with their tag. Problem occurs of a dozen have the same tag.

So I made this- essentially does the same, but allows every creature to have a unique tag, just in case

Code: Select all

 int i;
         for ( i = 0; i < 4; i++)  {

              ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, GetObjectByTag("creature"+IntToString(i)));
                        eEffect = EffectDamage(2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

                    }

Posted: Wed May 03, 2006 10:39 am
by Heed
I'm kinda confused on what you want to do now, but here's how I would go about creating a suffocating effect in an area:

Code: Select all

void DoAirLimit(object oCreature)
{
   //don't apply to dm's
   if (GetIsDM(oCreature))
      {
      return;
      }
   //create the damage effect
   effect eDmg = SupernaturalEffect(EffectDamage(2, DAMAGE_TYPE_MAGICAL,
                                   DAMAGE_POWER_ENERGY));
   //is the creature in the area?
   if (GetTag(GetArea(oCreature)) == "AREA_TAG_GOES_HERE")
      {
      if (!GetIsDead(oCreature))
         {
         //apply the damage effect
         ApplyEffectToObject(DURATION_TYPE_INSTANT, eDmg, oCreature);

         //if it's a PC, give some feedback
         if (GetIsPC(oCreature))
            {
            SendMessageToPC(oCreature, "You are suffocating!");
            }
         }
      //call the routine every round until the creature is out of the area
      DelayCommand(6.0, DoAirLimit(oCreature));
      }

}


void main()
{
   object oCreature = GetEnteringObject();

   DoAirLimit(oCreature);
}
This would go in the area's onenter event. Just make sure you set the area tag to be unique and input it in the part that reads "AREA_TAG_GOES_HERE".

Posted: Wed May 03, 2006 10:52 am
by girlysprite
I already have a countdown, so I prefer to have it on that beat, not create another counter.

Here is...yes, again!! the complete code of my counter, completely working and applying effects like I want it.

Code: Select all

void Countdown( object oArea, object oObject ) ;

void main()
{


    object oPC = GetEnteringObject();
    if (!GetIsPC(oPC)) return;
    object oObject = OBJECT_INVALID;
   object oArea = GetArea( oPC );
   SetLocalInt( oArea, "TimeLimit", 160 );
   Countdown( oArea, oPC );
   FloatingTextStringOnCreature("The air is stale, and old.", oPC);

}

// ** FUNCTION DEFINITIONS ** //
void Countdown( object oArea, object oObject )
{

   if(GetLocalInt( oArea, "TimeLimit" )>=0 && GetTag(oArea) == "Lichlairdeepbelow"){
   object oPC = GetEnteringObject();
   int nTimeLimit = GetLocalInt( oArea, "TimeLimit" );
   SendMessageToPC( oPC, "nTimeLimit is " + IntToString( nTimeLimit) + " from object " + ObjectToString( oArea ) );
   SetLocalInt( oArea, "TimeLimit", --nTimeLimit );

   DelayCommand( 1.0, Countdown( oArea, oObject ) );





    if( nTimeLimit <= 0 ) {



FloatingTextStringOnCreature("You find yourself completely out of air, and collapse. ", oObject);

//die. sense if a player had death immunity. If he doesnt, kill, if he has, drain all his hp.
}



  else {


        if(nTimeLimit == 210) {

                FloatingTextStringOnCreature("The air grows thin. It might run out soon. ", oObject);
            }

        if(nTimeLimit == 150) {

                if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
                FloatingTextStringOnCreature("There is little air left, but the helmet keeps you safe.", oObject);
            }

                else{

                FloatingTextStringOnCreature("There is very little air left. You start to feel very light in your head.", oObject);

                object oTarget;
                oTarget = oObject;
                effect eEffect;
                eEffect = EffectDazed();

                eEffect = ExtraordinaryEffect(eEffect);

                ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEffect, oTarget);

                  int i;
                    for ( i = 0; i < 4; i++)  {

                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, GetObjectByTag("creature"+IntToString(i)));

                    }
    }
        }

        if(nTimeLimit == 90) {

                if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
                FloatingTextStringOnCreature("The air grows thinner and thinner", oObject);
      }

                else{

                FloatingTextStringOnCreature("There is barely any air left, and you feel how you grow weaker. ", oObject);
                }
     }

        if( GetIsObjectValid( OBJECT_SELF) && nTimeLimit <= 90 && nTimeLimit >=30) {

                if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
                }
                else{

                effect eEffect;
                eEffect = EffectDamage(1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oObject);

                      int i;
                        for ( i = 0; i < 4; i++)  {

                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, GetObjectByTag("creature"+IntToString(i)));
                        eEffect = EffectDamage(1, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

                    }
                }



 }

      if(nTimeLimit == 30) {

                if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
                FloatingTextStringOnCreature("Air ran out, any creature that needs air migth die soon.*", oObject);
                }
                else{

                FloatingTextStringOnCreature("Air ran out, and you try to hold your breath, though the weakness contiues to increase*", oObject);
                }
 }


    if(nTimeLimit <= 29 && nTimeLimit >=0) {
                if (GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oObject)) == "Respiratorhelmet"){
                }
                else{


                effect eEffect;
                eEffect = EffectDamage(2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

                ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oObject);

                    int i;
                    for ( i = 0; i < 4; i++)  {

                        ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, GetObjectByTag("creature"+IntToString(i)));
                        eEffect = EffectDamage(2, DAMAGE_TYPE_MAGICAL, DAMAGE_POWER_ENERGY);

                    }

                }

 }


} }


}