Added Mine & Caverns raise & lower functionality
Added Mine & Caverns raise & lower functionality. Revamped Level 1 events to match PnP. Updated Level 1: Core. Added new Footcatcher trap type. Added Underwater heartbeat to Glop Lake Underwater. Full compile.
This commit is contained in:
		
							
								
								
									
										13
									
								
								_module/nss/at_give_coins.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								_module/nss/at_give_coins.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| void main() | ||||
| { | ||||
|     // Get the PC who is in this conversation. | ||||
|     object oPC      = GetPCSpeaker(); | ||||
|     object oSelf    = OBJECT_SELF; | ||||
|  | ||||
|     string sTag 	= GetTag(oSelf); | ||||
|  | ||||
|  | ||||
|     // Give 2-8 gold to the PC. | ||||
|     GiveGoldToCreature(oPC, d6(1)+2); | ||||
|     SetLocalInt(oPC, "FoundCoins"+sTag, 1); | ||||
| } | ||||
							
								
								
									
										24
									
								
								_module/nss/at_spn_grn_slime.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								_module/nss/at_spn_grn_slime.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| //:: at_spn_grn_slime | ||||
| //:: | ||||
| //:: Spawns a small green slime | ||||
|  | ||||
| #include "nw_i0_generic" | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     object oSpawn; | ||||
|     effect eVFX; | ||||
|     object oSelf = OBJECT_SELF; | ||||
|  | ||||
|     // Get the PC who is in this conversation. | ||||
|     object oPC      = GetPCSpeaker(); | ||||
|     string sName    = GetName(oPC); | ||||
|     string sTag 	= GetTag(oSelf); | ||||
|  | ||||
|     // Spawn Small Green Slime. | ||||
|     eVFX = EffectVisualEffect(VFX_COM_BLOOD_CRT_GREEN); | ||||
|     oSpawn = CreateObject(OBJECT_TYPE_CREATURE, "zep_greenslimes", GetLocation(oSelf)); | ||||
|     AssignCommand(oSpawn, DetermineCombatRound(oPC)); | ||||
|     DelayCommand(0.3f, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVFX, oSpawn)); | ||||
|     SetLocalInt(oPC, "FoundSlime"+sTag, 1); | ||||
| } | ||||
							
								
								
									
										51
									
								
								_module/nss/cavein_retex.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								_module/nss/cavein_retex.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| void main() | ||||
| { | ||||
| //:: Get the placeable object that triggers the script. | ||||
|     object oPlaceable = OBJECT_SELF; | ||||
| 	 | ||||
| 	string sTexture; | ||||
|  | ||||
| //:: Check if a custom local variable has been set to indicate that the script has run. | ||||
|     int bHasRun = GetLocalInt(oPlaceable, "HasRun"); | ||||
|  | ||||
|     if (!bHasRun) | ||||
|     { | ||||
| 		switch (d4(1)) | ||||
| 		{ | ||||
| 			case 1: | ||||
| 			{  | ||||
| 				sTexture = "tdm01_rock01"; | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			case 2: | ||||
| 			{  | ||||
| 				sTexture = "tdm01_rock02";  | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			case 3: | ||||
| 			{  | ||||
| 				sTexture = "tdm01_rock03"; | ||||
| 				break; | ||||
| 			}	 | ||||
|  | ||||
| 			case 4: | ||||
| 			{  | ||||
| 				sTexture = "tdm01_rock04"; | ||||
| 				break; | ||||
| 			}				 | ||||
| 		 | ||||
| 		}		 | ||||
| 			 | ||||
| 		ReplaceObjectTexture(oPlaceable, "tx_rough_006g", sTexture); | ||||
|  | ||||
| 	//:: Set the local variable to indicate that the script has run. | ||||
|         SetLocalInt(oPlaceable, "HasRun", 1); | ||||
| 		 | ||||
| 	//:: Removed HB script from event to save resources | ||||
| 		SetEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_HEARTBEAT, ""); | ||||
| 		 | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										27
									
								
								_module/nss/lvl01_bone_src10.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								_module/nss/lvl01_bone_src10.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| //:: Returns true if PC passes a DC 10 search check | ||||
|  | ||||
| int StartingConditional() | ||||
| { | ||||
| //:: Declare major variables | ||||
|     object oPC      = GetPCSpeaker(); | ||||
|     object oSelf    = OBJECT_SELF; | ||||
|  | ||||
|     string sTag         =GetTag(oSelf); | ||||
|  | ||||
|     if (GetLocalInt(oPC, "FoundCoins"+sTag) == TRUE) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
| // Check if the player's search skill check is successful against DC 10 | ||||
|     if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 10)) | ||||
|     { | ||||
|     //:: Player passed the search check | ||||
|         return TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     //:: Player failed the search check | ||||
|         return FALSE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										27
									
								
								_module/nss/lvl01_bone_srch5.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								_module/nss/lvl01_bone_srch5.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| //:: Returns true if PC passes a DC 5 search check | ||||
|  | ||||
| int StartingConditional() | ||||
| { | ||||
| //:: Declare major variables | ||||
|     object oPC      = GetPCSpeaker(); | ||||
|     object oSelf    = OBJECT_SELF; | ||||
|  | ||||
|     string sTag     	=GetTag(oSelf); | ||||
|  | ||||
|     if (GetLocalInt(oPC, "FoundSlime"+sTag) == TRUE) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
| // Check if the player's search skill check is successful against DC 5 | ||||
|     if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 5)) | ||||
|     { | ||||
|     //:: Player passed the search check | ||||
|         return TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     //:: Player failed the search check | ||||
|         return FALSE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										67
									
								
								_module/nss/lw_trap_ondisarm.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								_module/nss/lw_trap_ondisarm.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|     OnDisarm | ||||
|  | ||||
|     Awards XP for disarming traps | ||||
|  | ||||
|     For nonmagical harmless traps set the trap type to "minor entangle trap" | ||||
|     For magical traps, use the local int TRAP_DAMAGE_OVERRIDE | ||||
| */ | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     object oPC      = GetLastDisarmed(); | ||||
|  | ||||
|     if (GetIsPC(oPC) ) | ||||
|     { | ||||
|         int nTrapCR     = 0; | ||||
|         int nDisarmDC   = GetTrapDisarmDC(OBJECT_SELF); | ||||
|         int nDetectDC   = GetTrapDetectDC(OBJECT_SELF); | ||||
|         int nRow, nDam, nDamOvr; | ||||
|  | ||||
|         // Modify the CR based on the Disarm DC | ||||
|         if (nDisarmDC > 30) | ||||
|         { | ||||
|             nTrapCR = nTrapCR + 2; | ||||
|         } | ||||
|         else if (nDisarmDC > 15) | ||||
|         { | ||||
|             nTrapCR = nTrapCR + 1; | ||||
|         } | ||||
|  | ||||
|         // Modify the CR based on the Detect DC | ||||
|         if (nDetectDC > 30) | ||||
|         { | ||||
|             nTrapCR = nTrapCR + 2; | ||||
|         } | ||||
|         else if (nDetectDC > 15) | ||||
|         { | ||||
|             nTrapCR = nTrapCR + 1; | ||||
|         } | ||||
|  | ||||
|         // Determine the average amount of damage to use in the final CR calculation | ||||
|         nDamOvr = GetLocalInt(OBJECT_SELF, "TRAP_DAMAGE_OVERRIDE"); | ||||
|         if (!nDamOvr) | ||||
|         { | ||||
|             nRow = GetTrapBaseType(OBJECT_SELF); | ||||
|             nDam = StringToInt(Get2DAString("traps.2da", "MedianDamage", nRow)); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             nDam = nDamOvr; | ||||
|         } | ||||
|  | ||||
|         // Calculate the total Trap CR | ||||
|         nTrapCR = nTrapCR + (nDam /7); | ||||
|  | ||||
|         // Calculate the final award - PC only | ||||
|         int nLevel   = GetHitDice(oPC); | ||||
|         int nXPScale = GetModuleXPScale(); | ||||
|         float fAward = (300.00 / IntToFloat(nXPScale)) * IntToFloat(nLevel) * pow(2.0, (IntToFloat(nTrapCR)-IntToFloat(nLevel)) * 0.5); | ||||
|  | ||||
|         // Award some XP | ||||
|         if (fAward > 0.0) | ||||
|         { | ||||
|             GiveXPToCreature(oPC, FloatToInt(fAward)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,43 +0,0 @@ | ||||
| /// ---------------------------------------------------------------------------- | ||||
| /// @file   nui_i_library.nss | ||||
| /// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com> | ||||
| /// @brief  Boilerplate code for creating a library dispatcher. Should only be | ||||
| ///     included in library scripts as it implements main(). | ||||
| /// ---------------------------------------------------------------------------- | ||||
|  | ||||
| #include "nui_i_main" | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
| //                              Function Protoypes | ||||
| // ----------------------------------------------------------------------------- | ||||
|  | ||||
| void DefineForm(); | ||||
| void BindForm(); | ||||
| void HandleNUIEvents(); | ||||
| void HandleModuleEvents(); | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
| //                           Function Implementations | ||||
| // ----------------------------------------------------------------------------- | ||||
|  | ||||
| // These are dummy implementations to prevent nwnsc from complaining that they | ||||
| // do not exist. If you want to compile in the toolset rather than using nwnsc, | ||||
| // comment these lines out. | ||||
| //#pragma default_function(DefineForm) | ||||
| //#pragma default_function(BindForm) | ||||
| //#pragma default_function(HandleNUIEvents) | ||||
| //#pragma default_function(HandleModuleEvents) | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
| //                               Library Dispatch | ||||
| // ----------------------------------------------------------------------------- | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     string sOperation = GetScriptParam("NUI_FUNCTION"); | ||||
|  | ||||
|     if      (sOperation == NUI_DEFINE)    DefineForm(); | ||||
|     else if (sOperation == NUI_BIND)      BindForm(); | ||||
|     else if (sOperation == NUI_EVENT_NUI) HandleNUIEvents(); | ||||
|     else                                  HandleModuleEvents(); | ||||
| } | ||||
							
								
								
									
										89
									
								
								_module/nss/ra_lvl01_onenter.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								_module/nss/ra_lvl01_onenter.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
| /*// | ||||
|  | ||||
|     Level 1: The Lair of the Dung Beast | ||||
|         onEnter script | ||||
|             ra_lvl01_onenter.nss | ||||
|  | ||||
|     Wandering Monsters: Check once per 30 minutes on 1d20 | ||||
|  | ||||
|     Detections: Faint evil from the whole place; slightly more to the south east. | ||||
|  | ||||
|     Continuous Effects: The stench of this level requires all characters to make | ||||
|     a Fortitude save (DC 10) upon entering the level and every 30 minutes | ||||
|     thereafter or all rolls are at –2 morale penalty due to the distraction | ||||
|     caused by the overpowering smell. | ||||
|  | ||||
| */// | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| #include "spawn_functions" | ||||
| #include "tgdc_explore_inc" | ||||
|  | ||||
| void StenchMessage(object oPC = OBJECT_SELF) | ||||
| { | ||||
| //:: Only fire for (real) PCs. | ||||
|     if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) ) | ||||
|         return; | ||||
|  | ||||
| //:: Have text appear over the PC's head. | ||||
|     FloatingTextStringOnCreature("As you enter this area, a terrible, overpowering stench assaults your senses.", oPC, FALSE); | ||||
| } | ||||
|  | ||||
| void main() | ||||
| { | ||||
| //:: Get the entering object (usually a PC) | ||||
|     object oPC      = GetEnteringObject(); | ||||
|  | ||||
| //:: Only fire once per PC. | ||||
|     if (!GetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF)) ) | ||||
|     { | ||||
|         StenchMessage(oPC); | ||||
|  | ||||
|         SetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF), TRUE); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     Spawn_OnAreaEnter() can take three arguments - the name of the heartbeat | ||||
|     script to execute, the heartbeat duration, and a delay for the first | ||||
|     heartbeat.  They default to spawn_sample_hb, 6.0, and 0.0 respectively; as | ||||
|     if it were called like: Spawn_OnAreaEnter( "spawn_sample_hb", 6.0, 0.0 ); | ||||
|     */ | ||||
|  | ||||
|     if ( GetIsAreaAboveGround( OBJECT_SELF ) && ! GetIsAreaNatural( OBJECT_SELF ) ) | ||||
|     { | ||||
|     //:: Indoors - no delay on the first HB | ||||
|         Spawn_OnAreaEnter( "spawn_sample_hb", 6.0, 0.0 ); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     //:: Outdoors or underground - do a 3 second delay on the first HB | ||||
|         Spawn_OnAreaEnter( "spawn_sample_hb", 6.0, 3.0 ); | ||||
|     } | ||||
|  | ||||
| //:: Records that the PC has entered Rappan Athuk at least once. | ||||
|     SetLocalInt(oPC, "bEnteredDungeon", 1); | ||||
|     SetLocalInt(oPC, "bEnteredLevelOne", 1); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										51
									
								
								_module/nss/ra_lvl01_onexit.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								_module/nss/ra_lvl01_onexit.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
| /*// | ||||
|  | ||||
|     Level 1: The Lair of the Dung Beast | ||||
|         onExit script | ||||
|             ra_lvl01_onexit.nss | ||||
|  | ||||
|     Wandering Monsters: Check once per 30 minutes on 1d20 | ||||
|  | ||||
|     Detections: Faint evil from the whole place; slightly more to the south east. | ||||
|  | ||||
|     Continuous Effects: The stench of this level requires all characters to make | ||||
|     a Fortitude save (DC 10) upon entering the level and every 30 minutes | ||||
|     thereafter or all rolls are at –2 morale penalty due to the distraction | ||||
|     caused by the overpowering smell. | ||||
|  | ||||
| */// | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| void main() | ||||
| { | ||||
| //:: Get the entering object (usually a PC) | ||||
|     object oPC      = GetExitingObject(); | ||||
|  | ||||
| //:: Clears Level 1 stench message int var, | ||||
| //:: so it will show up again next time they enter | ||||
|     DelayCommand(0.0f,DeleteLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF))); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										107
									
								
								_module/nss/ra_lvl01_onhb.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								_module/nss/ra_lvl01_onhb.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
| /*// | ||||
|  | ||||
|     Level 1: The Lair of the Dung Beast | ||||
|         onHeartbeat script | ||||
|             ra_lvl01_onhb.nss | ||||
|  | ||||
|     Wandering Monsters: Check once per 30 minutes on 1d20. | ||||
|  | ||||
|     Detections: Faint evil from the whole place; slightly more to the south east. | ||||
|  | ||||
|     Continuous Effects: The stench of this level requires all characters to make | ||||
|     a Fortitude save (DC 10) upon entering the level and every 30 minutes | ||||
|     thereafter or all rolls are at –2 morale penalty due to the distraction | ||||
|     caused by the overpowering smell. | ||||
|  | ||||
| */// | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| //:: Function to process the stench penalty | ||||
| void ApplyStench(object oPC) | ||||
| { | ||||
|     int RA_DEBUG = 0; | ||||
| 	 | ||||
| 	//:: Check for exising variable on player | ||||
|     int oldTime = GetLocalInt(oPC, "StenchFortSaveTime"); | ||||
|  | ||||
|     // Get the current system time in seconds | ||||
|     int newTime = (GetTimeHour()*60*60)+(GetTimeMinute()*60)+GetTimeSecond(); | ||||
| 	 | ||||
|     // Calculate the time difference in seconds | ||||
|     int timeDifference = newTime - oldTime; | ||||
|              | ||||
| 	if (RA_DEBUG) | ||||
| 	{	 | ||||
| 		SendMessageToPC(oPC, "oldTime = " + IntToString(oldTime)); | ||||
| 		SendMessageToPC(oPC, "newTime = " + IntToString(newTime)); | ||||
| 		SendMessageToPC(oPC, "timeDifference = " + IntToString(timeDifference)); | ||||
| 	} | ||||
|  | ||||
|     //:: Check if the character hasn't made a Fortitude save in the last 3 minutes | ||||
|     if (oldTime == 0 || timeDifference >= 180) // 180 seconds = 3 real-time minutes | ||||
|     { | ||||
|         //:: Check if the character failed the save | ||||
|         if (!FortitudeSave(oPC, 10)) | ||||
|         { | ||||
|             //:: Apply a -2 morale penalty to all rolls | ||||
|             effect eMoralePenalty   = EffectAttackDecrease(2); | ||||
|             effect eVFX             = EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE); | ||||
|             effect eLink            = EffectLinkEffects(eMoralePenalty, eVFX); | ||||
|  | ||||
|             eLink                   = SupernaturalEffect(eLink); | ||||
|             eLink                   = TagEffect(eLink, "LvlOneStench"); | ||||
|  | ||||
|             ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oPC, 180.0f); // 180 seconds = 3 real-time minutes & .5 hours in-game. | ||||
|  | ||||
|             //:: Store the current time on player | ||||
|             SetLocalInt(oPC, "StenchFortSaveTime", newTime); | ||||
|  | ||||
|             if (RA_DEBUG) | ||||
| 			{ | ||||
| 				SendMessageToPC(oPC, "Failed StenchFortSave"); | ||||
| 				SendMessageToPC(oPC, "Setting StenchFortSaveTime as " + IntToString(newTime)); | ||||
| 			} | ||||
| 			 | ||||
|             // Send a message to the player | ||||
|             SendMessageToPC(oPC, "The overpowering stench is distracting you."); | ||||
|         } | ||||
|  | ||||
| 	//:: Store the current time on player | ||||
| 		SetLocalInt(oPC, "StenchFortSaveTime", newTime); | ||||
| 		 | ||||
| 		if (RA_DEBUG) | ||||
| 		{ | ||||
| 			SendMessageToPC(oPC, "Passed StenchFortSave"); | ||||
| 			SendMessageToPC(oPC, "Setting StenchFortSaveTime as " + IntToString(newTime)); | ||||
| 		} | ||||
|     } | ||||
| } | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     int RA_DEBUG = 0; | ||||
|  | ||||
|     //:: Declare major variables | ||||
|     object oArea = OBJECT_SELF; | ||||
|     object oPC = GetFirstObjectInArea(oArea, OBJECT_TYPE_CREATURE); | ||||
|  | ||||
|     while (GetIsObjectValid(oPC)) | ||||
|     { | ||||
|         if (GetIsPC(oPC) || (GetMaster(oPC) != OBJECT_INVALID && GetIsPC(GetMaster(oPC)))) | ||||
|         { | ||||
|             if (RA_DEBUG) | ||||
|             { | ||||
|                 SendMessageToPC(oPC, "Running Level 1 Area HB"); | ||||
|             } | ||||
|  | ||||
|             //:: Apply the stench | ||||
|             ApplyStench(oPC); | ||||
|         } | ||||
|  | ||||
|         // Get the next object in the area | ||||
|         oPC = GetNextObjectInArea(oArea); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										83
									
								
								_module/nss/sc_search_dc10.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								_module/nss/sc_search_dc10.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| #include "x0_i0_partywide" | ||||
|  | ||||
| //:: Returns true if PC passes a DC 10 search check. | ||||
| //:: Only allows one chance to search | ||||
|  | ||||
| int StartingConditional() | ||||
| { | ||||
|     object oPC          = GetPCSpeaker(); | ||||
|     string sPlacableTag = GetTag(OBJECT_SELF); | ||||
|     int nPartySearched  = GetLocalInt(oPC, "PartySearched_" + sPlacableTag); // Unique flag for each placable | ||||
|  | ||||
|     // Check if the party has already successfully searched at this placable | ||||
|     if (nPartySearched == 1) | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
|  | ||||
|     // Check if the player's search skill check is successful against DC 10 | ||||
|     if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 10)) | ||||
|     { | ||||
|         // Set the flag on every member of the party to ensure it's only run once per party | ||||
|         SetLocalIntOnAll(oPC, "PartySearched_" + sPlacableTag, 1); | ||||
|  | ||||
|         return TRUE; // Condition met, continue with the conversation | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return FALSE; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| //:: Returns true if PC passes a DC 10 search check | ||||
|  | ||||
| /*int StartingConditional() | ||||
| { | ||||
| //:: Declare major variables | ||||
|     object oPC = GetPCSpeaker(); | ||||
|  | ||||
| // Check if the player's search skill check is successful against DC 10 | ||||
|     if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 10)) | ||||
|     { | ||||
|     //:: Player passed the search check | ||||
|         return TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     //:: Player failed the search check | ||||
|         return FALSE; | ||||
|     } | ||||
| } */ | ||||
							
								
								
									
										19
									
								
								_module/nss/sc_search_dc5.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								_module/nss/sc_search_dc5.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| //:: Returns true if PC passes a DC 5 search check | ||||
|  | ||||
| int StartingConditional() | ||||
| { | ||||
| //:: Declare major variables | ||||
|     object oPC = GetPCSpeaker(); | ||||
|  | ||||
| // Check if the player's search skill check is successful against DC 5 | ||||
|     if (GetIsSkillSuccessful(oPC, SKILL_SEARCH, 5)) | ||||
|     { | ||||
|     //:: Player passed the search check | ||||
|         return TRUE; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|     //:: Player failed the search check | ||||
|         return FALSE; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								_module/nss/stench_onenter.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								_module/nss/stench_onenter.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Stench Area OnEnter Script - stench_onenter.nss | ||||
|  | ||||
| // Function to apply the stench penalty | ||||
| void ApplyStenchPenalty(object oPC) | ||||
| { | ||||
|     // Calculate the current time in minutes | ||||
|     int currentTime = GetTimeHour() * 60 + GetTimeMinute(); | ||||
|  | ||||
|     // Check if the character hasn't made a Fortitude save in the last 30 minutes | ||||
|     if (!GetLocalInt(oPC, "FortitudeSaveTime") || currentTime >= GetLocalInt(oPC, "FortitudeSaveTime") + 30) | ||||
|     { | ||||
|         // Roll a Fortitude save (DC 10) | ||||
|         int fortitudeSaveResult = FortitudeSave(oPC, 10, SAVING_THROW_TYPE_NONE, OBJECT_SELF); | ||||
|  | ||||
|         // Check if the character failed the save | ||||
|         if (fortitudeSaveResult < 1) | ||||
|         { | ||||
|             // Apply a -2 morale penalty to all rolls | ||||
|             effect eMoralePenalty = EffectAttackDecrease(2, ATTACK_BONUS_MISC); | ||||
|             ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eMoralePenalty, oPC, 90.0f); // 90 seconds = 3 real time minutes & .5 hours in game. | ||||
|  | ||||
|             // Store the current time as the last Fortitude save time | ||||
|             SetLocalInt(oPC, "FortitudeSaveTime", currentTime); | ||||
|  | ||||
|             // Send a message to the player | ||||
|             SendMessageToPC(oPC, "The overpowering stench distracts you, imposing a -2 morale penalty to your rolls for the next 30 minutes."); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     // Get the entering object (usually a PC) | ||||
|     object oPC = GetEnteringObject(); | ||||
|  | ||||
|     // Check if the entering object is a valid creature and is a player character | ||||
|     if (GetIsObjectValid(oPC) && GetObjectType(oPC) == OBJECT_TYPE_CREATURE && GetIsPC(oPC)) | ||||
|     { | ||||
|         // Start the periodic script to apply the stench penalty | ||||
|         ApplyStenchPenalty(oPC); | ||||
|     } | ||||
| 	 | ||||
| 	DelayCommand(90.0f, ExecuteScript("stench_onenter")); | ||||
| } | ||||
							
								
								
									
										72
									
								
								_module/nss/trap_footcatch.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								_module/nss/trap_footcatch.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| //:://///////////////////////////////////////////// | ||||
| //:: Footcatcher Trap | ||||
| //:: trap_footcatch | ||||
| //:: Copyright (c) 2023 Project RATDOG | ||||
| //::////////////////////////////////////////////// | ||||
| /* | ||||
|  | ||||
| */ | ||||
| //::////////////////////////////////////////////// | ||||
|  | ||||
| #include "prc_inc_spells" | ||||
| #include "NW_I0_SPELLS" | ||||
|  | ||||
| void CreateObject2(int nObjectType, string sTemplate, location lLocation, int bUseAppearAnimation=FALSE); | ||||
|  | ||||
| void main() | ||||
| { | ||||
|     //Declare major variables | ||||
|     int nDuration 		= 4; | ||||
| 	int nDamage			= d3(1); | ||||
| 	 | ||||
|     object oTarget 		= GetEnteringObject(); | ||||
| 	 | ||||
|     location lTarget 	= GetLocation(oTarget); | ||||
| 	 | ||||
|     effect eStopped 	= EffectCutsceneImmobilize(); | ||||
| 	eStopped			= ExtraordinaryEffect(eStopped); | ||||
| 	 | ||||
| 	effect eDamage		= EffectDamage(nDamage); | ||||
|     effect eVis1 		= EffectVisualEffect(VFX_DUR_ENTANGLE); | ||||
| 	effect eVis2 		= EffectVisualEffect(VFX_IMP_POISON_S); | ||||
| 	 | ||||
| 	effect ePoison		= EffectPoison(POISON_LARGE_SCORPION_VENOM); | ||||
| 	ePoison				= ExtraordinaryEffect(ePoison); | ||||
| 	 | ||||
| 	effect eLink1		= EffectLinkEffects(eVis1, eDamage);	 | ||||
| 	eLink1				= ExtraordinaryEffect(eLink1); | ||||
| 	 | ||||
|     //Find first target in the size | ||||
|     oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget); | ||||
|     //Cycle through the objects in the radius | ||||
|     while (GetIsObjectValid(oTarget)) | ||||
|     { | ||||
|         if(!MySavingThrow(SAVING_THROW_REFLEX, oTarget, 20, SAVING_THROW_TYPE_NONE)) | ||||
|         { | ||||
| 	//:: Apply damage & hold effect | ||||
|             ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink1, oTarget); | ||||
|             ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eStopped, oTarget, RoundsToSeconds(nDuration)); | ||||
| 			SendMessageToPC(oTarget, "You've stepped thru a false floor, into a spiked trap."); | ||||
| 			 | ||||
| 			if(!MySavingThrow(SAVING_THROW_FORT, oTarget, 18, SAVING_THROW_TYPE_POISON)) | ||||
| 			{ | ||||
| 		//:: Apply poison  | ||||
|             ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis2, oTarget); | ||||
|             ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoison, oTarget, RoundsToSeconds(nDuration)); | ||||
| 			 | ||||
| 			} | ||||
| 			 | ||||
|         } | ||||
|         //Get next target in the shape. | ||||
|         oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_SMALL, lTarget); | ||||
|     } | ||||
|     //respawn trap | ||||
|     DelayCommand(598.0, CreateObject2(GetObjectType(OBJECT_SELF), GetResRef(OBJECT_SELF), GetLocation(OBJECT_SELF))); | ||||
|     DelayCommand(600.0, DestroyObject(OBJECT_SELF)); | ||||
| } | ||||
|  | ||||
| void CreateObject2(int nObjectType, string sTemplate, location lLocation, int bUseAppearAnimation=FALSE) | ||||
| { | ||||
|     CreateObject(nObjectType, sTemplate, lLocation, bUseAppearAnimation); | ||||
|     return; | ||||
| } | ||||
							
								
								
									
										174
									
								
								_module/nss/underwater_hb.nss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								_module/nss/underwater_hb.nss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| //:://////////////////////////////////////////////////////////////////////////// | ||||
| //:: | ||||
| //		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); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user