//This function is called from the onenter event of an underwater area // //Set a local int on the underwater creatures that will be spawned in the underwater //area. If you do not the creatures will also drown. // Name: Aquatic // Type: int // Value: 1 // ----------------------------------------------------------------------------- // CONSTANTS // ----------------------------------------------------------------------------- const float BREATH_CHECK = 6.0; // << Breath check delay in seconds const string WATER_BREATHING_ITEM = "vg_wb_item"; // << Tag of water breathing items const string WATER_SWIMMING_ITEM = "vg_ws_item"; // << Tag of water swimming items // ----------------------------------------------------------------------------- // PROTOTYPES // ----------------------------------------------------------------------------- // Check player is wearing an underwater breathing item int WearingWaterItemCheck(object oPC); //Do the underwater check void UnderWaterCheck(object oPC); #include "prc_inc_racial" //:: void main (){} // ----------------------------------------------------------------------------- // FUNCTIONS // ----------------------------------------------------------------------------- int WearingWaterBreathingItem(object oPC) { if(GetTag(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_BELT, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_NECK, oPC)) == WATER_BREATHING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC)) == WATER_BREATHING_ITEM || GetLocalInt(oPC, "WBPOTION")) return TRUE; return FALSE; } int WearingWaterSwimmingItem(object oPC) { if(GetTag(GetItemInSlot(INVENTORY_SLOT_ARMS, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_BELT, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_BOOTS, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CHEST, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_CLOAK, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_HEAD, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_LEFTRING, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_NECK, oPC)) == WATER_SWIMMING_ITEM || GetTag(GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oPC)) == WATER_SWIMMING_ITEM || GetLocalInt(oPC, "WSPOTION")) return TRUE; return FALSE; } void UnderWaterCheck(object oPC) { int iCON = GetAbilityModifier(ABILITY_CONSTITUTION,oPC); // << Constitution Modifier of oPC int iCONSave = d20(1) + iCON; // << CON Save if failed to hold breath int iHOLD = 2 + (iCON*2); // << Let them hold their breath in seconds if(GetLocalInt(oPC, "UNDERWATER") == 0) return; if(WearingWaterBreathingItem(oPC) == FALSE) { if(WearingWaterSwimmingItem(oPC) == FALSE) { // Reduce the entering objects movement speed and mark them as being under water ApplyEffectToObject(2, EffectMovementSpeedDecrease(50), oPC, 0.0); } int iROUND = GetLocalInt(oPC,"ROUND"); // << Determines number of rounds if (iROUND <= iHOLD) { iROUND=iROUND+1; SetLocalInt(oPC,"ROUND",iROUND); SendMessageToPC(oPC,"** You are holding your breath **"); // DEBUG if (GetLocalInt(GetModule(),"Debug")==1) { string sROUND = IntToString(iROUND); SendMessageToPC(oPC,"DEBUG: This is round number "+sROUND); } } if (iROUND > iHOLD) { int iDC = GetLocalInt(oPC,"DC"); // << DC to keep holding breath if (iCONSave>=iDC) { iDC=iDC+1; SetLocalInt(oPC,"DC",iDC); SendMessageToPC(oPC,"** You are barely holding your breath **"); FloatingTextStringOnCreature("** blub blub **", oPC); ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_DUR_BUBBLES), oPC); // DEBUG if (GetLocalInt(GetModule(),"Debug")==1) { string sDC = IntToString(iDC); SendMessageToPC(oPC,"DEBUG: The DC is now "+sDC); } } if (iCONSave < iDC) { int iHPs=GetCurrentHitPoints(oPC); int iDROWN=GetLocalInt(oPC,"DROWN"); FloatingTextStringOnCreature("** Drowning: blub blub **", oPC, FALSE); ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_DUR_BUBBLES), oPC); if(iDROWN == 2) { effect eDamage=EffectDamage(iHPs,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); //effect eDamage=EffectDamage(10,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oPC,0.0); SetLocalInt(oPC,"DROWN",0); } if(iDROWN == 1) { effect eDamage=EffectDamage(iHPs/2,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); //effect eDamage=EffectDamage(1,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oPC,0.0); SetLocalInt(oPC,"DROWN",2); } if(iDROWN == 0) { effect eDamage=EffectDamage(iHPs/4,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); //effect eDamage=EffectDamage(iHPs,DAMAGE_TYPE_DIVINE,DAMAGE_POWER_PLUS_TWENTY); ApplyEffectToObject(DURATION_TYPE_INSTANT,eDamage,oPC,0.0); SetLocalInt(oPC,"DROWN",1); } } iROUND=iROUND+1; SetLocalInt(oPC,"ROUND",iROUND); } } DelayCommand(BREATH_CHECK, UnderWaterCheck(oPC)); } void Water_Enter(object oPC) { // Skip creatures set to breathe underwater if(GetLocalInt(oPC, "Aquatic") == TRUE) return; // Skip DM's if(GetIsDM(oPC) || GetIsDMPossessed(oPC)) return; // Skip Undead, Constructs & Elementals if(MyPRCGetRacialType(oPC) == RACIAL_TYPE_UNDEAD || MyPRCGetRacialType(oPC) == RACIAL_TYPE_CONSTRUCT || MyPRCGetRacialType(oPC) == RACIAL_TYPE_ELEMENTAL) return; // Torch goes out underwater object oItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC); if(GetBaseItemType(oItem) == BASE_ITEM_TORCH) { DelayCommand(1.0, FloatingTextStringOnCreature("Your torch fizzles out.", oPC)); DelayCommand(1.0, AssignCommand(oPC, ActionUnequipItem(oItem))); } if(WearingWaterSwimmingItem(oPC) == FALSE) { // Reduce the entering objects movement speed and mark them as being under water ApplyEffectToObject(2, EffectMovementSpeedDecrease(75), oPC, 0.0); } // Set up drowning control Ints SetLocalInt(oPC, "UNDERWATER", 1); SetLocalInt(oPC,"ROUND",0); SetLocalInt(oPC,"DC",10); SetLocalInt(oPC,"DROWN",0); DelayCommand(0.1, FloatingTextStringOnCreature("** This water is deep! **", oPC)); // Start checking for holding of breath and damage DelayCommand(0.5, UnderWaterCheck(oPC)); }