//:://///////////////////////////////////////////// //:: Name Respawning Ground Traps //:: FileName groundtrap1 //:: Written by Firestarter //::////////////////////////////////////////////// /* Allows ground traps to respawn. Works in association with David Etheridge/Firestarter's illusion/trap detection system but those scripts not essential. Closely follows individual scripts for nw traps ie. nw_t1_* created by Preston Watamaniuk. Instructions: Put this script in the OnEnter of a generic trigger. Place a trapped placeable with tag: "Trapme" over the trigger. The placeable must be within 3m of the trigger. Modify the Appearance of the placeable to a throw rug, stones, grass stalk etc to match its environment. Uncheck the Has Inventory box of the placeable. Alter the placeable description as required. Check the plot box of the placeable - this is used not only to preserve the trap but as a switch to ensure that multiple trap objects do not spawn. The faction of the placeable & trigger should be Hostile. Put a trap on the placeable of your choice. Make a custom copy of the placeable and use that custom copy to place the placeable - otherwise the ResRef will not match and the placeable will not respawn. It is a good idea to make a few custom placeables with those changes made for quicker placement later. The trigger area must not extend out from the trapped placeable so that the PC can reach the placeable without setting off the trap. This script closely reproduces the effects of all the standard game traps. It will work in Persistant Worlds. To alter the respawn time see the line 74. The respawn time is from when the script is triggered so if noone steps on the trigger the trap won't respawn. The minimum respawn time is 5.0 seconds. If fDelay is set to 0.0 the trap won't respawn at all then any respawning must be controlled by another script. */ //::////////////////////////////////////////////// //:: Created By: Firestarter //:: Created On: 10 Dec 2002 //:: Modified & debugged: 19th Feb 2003 //::////////////////////////////////////////////// #include "prc_inc_spells" //needed for MySavingThrow function #include "NW_I0_SPELLS" //function to respawn trap void CreateTrap(string sTrap,location lTrap) { CreateObject(OBJECT_TYPE_PLACEABLE,sTrap,lTrap); } void main() { object oEnter=GetEnteringObject(); object oTrap=GetNearestObjectByTag("Trapme"); effect eKillTrap=EffectDamage(200); string sTrap=GetResRef(oTrap); location lTrap=GetLocation(oTrap); float fDelay=60.0; //delay before trap respawns //if 0.0 trap will not respawn //check if oEnter is a someone trying to remove trap int iAction=GetCurrentAction(oEnter); if (iAction==ACTION_DISABLETRAP || iAction==ACTION_RECOVERTRAP || iAction==ACTION_EXAMINETRAP) return; if ((GetIsEnemy(oEnter,oTrap)) &&GetIsTrapped(oTrap) &&GetDistanceToObject(oTrap)<3.0) { //object oTrapper=GetTrapCreator(oTrap); //SendMessageToPC(oTrapper,"trap away"); object oTarget; //area targets int iTrap=GetTrapBaseType(oTrap); int iTrapDC=GetTrapDisarmDC(oTrap); //**? location lTarget=GetLocation(oEnter); //centre of area (sphere) effects int eTrap; //visual effect number int iAreaEffect=0; //set to 1 if vis effect is an area effect effect eEffect; effect eLightning; //beam effect in lightning trap //Used e for effect int numbers int eBeam; //any beam effect to add effect eBad; //bad effect of trap int NoSaveBad=0; //set to 1 if there is no save vs eBad int eToLink; //effect number to link to eBad effect eLink; //linked eBad+eToLink effect int iDamageFactor; //minor(1),average(2),strong(3),deadly(4) int iDamageType; effect eDam; //damage effect int iSaveType; int iDamage; //actual damage done int NoSaveDam=0; //Set to 1 if there is no save vs damage //int iTrapSpell; //any associated spells //int iTrapSpell2; int iFakeSpell; int iRepeat; //**? if TRUE spell iDamageFactor times int iCount; //for spell repeating int iNuDice; //number of damage dice location lTrapvis; //used if vis effect to apply to location int iRacialType; //type of monster the trap attacks float fRadius=0.0; //radius for area effect traps int iMaxHits=99; //maximum creatures that can be hit //for elecric traps is less int iDuration; //any effect duration int iDC; //any difficulty check int iSaveThrow=SAVING_THROW_REFLEX; //normal saving throw //set trap effect type and damage if (iTrap<4) { //spike trap eTrap=253; //spikes lTrapvis=GetLocation(oEnter); iDamageFactor=1+iTrap; iDamageType=DAMAGE_TYPE_PIERCING; iNuDice=iDamageFactor+1; if (iDamageFactor==3) iNuDice=5; if (iDamageFactor==4) iNuDice=25; NoSaveDam=1; } else if (iTrap<8) { //holy trap (do 1/3 damage if not undead) eTrap=VFX_IMP_SUNSTRIKE; iDamageFactor=iTrap-3; iDamageType=DAMAGE_TYPE_DIVINE; iNuDice=(iDamageFactor*5)-1; //approx as d10s not used iRacialType=RACIAL_TYPE_UNDEAD; NoSaveDam=1; } else if (iTrap<12) { //tangle trap eTrap=VFX_IMP_SLOW; iDamageFactor=iTrap-7; //iTrapSpell=SPELL_SLOW; //iRepeat=TRUE; eBad=EffectSlow(); iSaveType=SAVING_THROW_TYPE_NONE; iDC=(iDamageFactor+3)*5; fRadius=RADIUS_SIZE_SMALL; if (iDamageFactor>2) fRadius=RADIUS_SIZE_MEDIUM; } else if (iTrap<16) { //acid trap eTrap=VFX_IMP_ACID_S; eBad=EffectParalyze(); eToLink=VFX_DUR_PARALYZED; iDamageFactor=iTrap-11; iDuration=iDamageFactor+1; iDamageType=DAMAGE_TYPE_ACID; iSaveType=SAVING_THROW_TYPE_ACID; iNuDice=(iDamageFactor*iDamageFactor)+2; iDC=(iDamageFactor+2)*5; if (iDamageFactor==4) iDC=25; NoSaveDam=1; } else if (iTrap<20) { //fire trap eTrap=VFX_IMP_FLAME_M; iDamageFactor=iTrap-15; iDamageType=DAMAGE_TYPE_FIRE; iSaveType=SAVING_THROW_TYPE_FIRE; fRadius=RADIUS_SIZE_SMALL; if (iDamageFactor>2) fRadius=RADIUS_SIZE_MEDIUM; iNuDice=(iDamageFactor*iDamageFactor)+4; if (iDamageFactor==3) iNuDice=11; if (iDamageFactor==4) iNuDice=14; iDC=(iDamageFactor*3)+14; //1 low for minor trap } else if (iTrap<24) { //electrical trap eTrap=VFX_IMP_LIGHTNING_S; eBeam=VFX_BEAM_LIGHTNING; iDamageFactor=iTrap-19; iDamageType=DAMAGE_TYPE_ELECTRICAL; iSaveType=SAVING_THROW_TYPE_ELECTRICITY; iNuDice=iDamageFactor*8; fRadius=RADIUS_SIZE_LARGE; iMaxHits=iDamageFactor+2; iDC=(iDamageFactor*3)+16; //1 low for strong trap } else if (iTrap<28) { //gas trap iDamageFactor=iTrap-23; iFakeSpell=SPELL_STINKING_CLOUD;//?? eTrap=AOE_PER_FOGACID; if (iDamageFactor==1) eBad=EffectPoison(POISON_GIANT_WASP_POISON); if (iDamageFactor==2) eBad=EffectPoison(POISON_DEATHBLADE); if (iDamageFactor==3) eBad=EffectPoison(POISON_DARK_REAVER_POWDER); if (iDamageFactor==4) eBad=EffectPoison(POISON_BLACK_LOTUS_EXTRACT); fRadius=RADIUS_SIZE_LARGE; iDuration=3; iAreaEffect=1; NoSaveBad=1; } else if (iTrap<32) { //frost trap eTrap=VFX_IMP_FROST_S; iDamageFactor=iTrap-27; iDamageType=DAMAGE_TYPE_COLD; iSaveType=SAVING_THROW_TYPE_COLD; iNuDice=2; if (iDamageFactor==4) iNuDice=6; eBad=EffectParalyze(); eToLink=VFX_DUR_BLUR; iDuration=iDamageFactor; iDC=11+iDamageFactor; int iSaveThrow=SAVING_THROW_FORT; NoSaveDam=1; } else if (iTrap<36) { //negative trap eTrap=VFX_IMP_REDUCE_ABILITY_SCORE; iDamageFactor=iTrap-31; iDamageType=DAMAGE_TYPE_NEGATIVE; iSaveType=SAVING_THROW_TYPE_NEGATIVE; iNuDice=(iDamageFactor+1); if (iDamageFactor==4) iNuDice=10; int StrLoss=iDamageFactor-1; if (StrLoss==0) StrLoss=1; eBad=EffectAbilityDecrease(ABILITY_STRENGTH, StrLoss); eBad = SupernaturalEffect(eBad); iDC=(iDamageFactor*3)+9; int iSaveThrow=SAVING_THROW_FORT; NoSaveDam=1; } else if (iTrap<40) { //sonic trap eTrap=VFX_FNF_SOUND_BURST; iDamageFactor=iTrap-35; iDamageType=DAMAGE_TYPE_SONIC; iSaveType=SAVING_THROW_TYPE_SONIC; iNuDice=iDamageFactor; //approx as d4s not used if (iDamageFactor==4) iNuDice=6; eBad = EffectStunned(); eToLink = VFX_DUR_MIND_AFFECTING_DISABLED; fRadius=RADIUS_SIZE_MEDIUM; int iSaveThrow=SAVING_THROW_WILL; iDuration=iDamageFactor+1; iDC=(iDamageFactor*3)+8; //1 low for minor trap iAreaEffect=1; NoSaveDam=1; } else { //acid splash trap eTrap=VFX_IMP_ACID_S; iDamageFactor=iTrap-39; iDamageType=DAMAGE_TYPE_ACID; iSaveType=SAVING_THROW_TYPE_ACID; iNuDice=(iDamageFactor*2);//approx as d8s not used if (iDamageFactor==4) iNuDice=10; iDC=(iDamageFactor*3)+9; } //set universal variables if (eTrap==AOE_PER_FOGACID) eEffect=EffectAreaOfEffect(eTrap, "****", "****", "****"); else eEffect=EffectVisualEffect(eTrap); iDamage=d6(iNuDice); eDam = EffectDamage(iDamage, iDamageType); //Apply trap effects if (fRadius>0.0) //for traps with area effect { //Place visible effect if (eTrap==AOE_PER_FOGACID) { ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eEffect, lTarget, RoundsToSeconds(iDuration)); } if (eToLink>0) //sonic { //Place visible effect ApplyEffectAtLocation(DURATION_TYPE_INSTANT,eEffect,lTarget); effect eMind=EffectVisualEffect(eToLink); eLink=EffectLinkEffects(eBad, eMind); } oTarget = GetFirstObjectInShape(SHAPE_SPHERE, fRadius,lTarget); int nCount; for(nCount=1;GetIsObjectValid(oTarget)&&nCount<=iMaxHits;nCount++) { if(!GetIsReactionTypeFriendly(oTarget)) { //Adjust the trap damage based on the feats of the target if(!PRCMySavingThrow(iSaveThrow, oTarget, iDC, iSaveType)) { if (GetHasFeat(FEAT_IMPROVED_EVASION, oTarget)) iDamage /= 2; } else if (GetHasFeat(FEAT_EVASION, oTarget) || GetHasFeat(FEAT_IMPROVED_EVASION, oTarget)) iDamage = 0; else iDamage /= 2; if(NoSaveDam==1) iDamage=d6(iNuDice); if (iDamage > 0) { //Apply effects to the target. eDam = EffectDamage(iDamage, iDamageType); if (iAreaEffect==0) ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget); if (eBeam>0) { //Connect the beam from initial target to all others. eLightning = EffectBeam(eBeam, oEnter, BODY_NODE_CHEST); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLightning, oTarget, 0.75); } ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget); } if (GetIsEffectValid(eBad)) //Tangle or Gas or Sonic trap { if (NoSaveBad=1)ApplyEffectToObject(DURATION_TYPE_INSTANT, eBad, oTarget); else if(!PRCMySavingThrow(iSaveThrow,oTarget,iDC,iSaveType)) { //Apply bad effect and visible effect if (eToLink>0) ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, RoundsToSeconds(iDuration)); else { ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oTarget); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBad, oTarget, RoundsToSeconds(iDuration)); } } } } //if (GetCurrentHitPoints(oTarget)<=0) //GiveXPToCreature(oTrapper,FloatToInt //(IntToFloat(GetHitDice(oTarget))*20/(FloatToInt(IntToFloat(GetHitDice(oTrapper))/2)))); oTarget = GetNextInPersistentObject(); } } else //Acid, Frost, Negative, Holy, Spike or Acid Splash { if(!PRCMySavingThrow(iSaveThrow, oTarget, iDC, iSaveType)) { if (eToLink>0) //Acid, Frost { effect eBadLink=EffectVisualEffect(eToLink); eLink=EffectLinkEffects(eBad, eBadLink); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eBadLink, oTarget, RoundsToSeconds(iDuration)); } else ApplyEffectToObject(DURATION_TYPE_PERMANENT, eBad, oTarget); } if ((!MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD) && eTrap==VFX_IMP_SUNSTRIKE) //holy trap not vs undead iDamage=FloatToInt(IntToFloat(iDamage)/3); if (eTrap==VFX_IMP_ACID_S)//acid splash iDamage=PRCGetReflexAdjustedDamage(iDamage, oTarget, iDC, iSaveType); //renew eDam for above tests eDam = EffectDamage(iDamage, iDamageType); //apply visible and damage ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oEnter); if (eTrap==253)//spike effect at location ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eEffect, lTarget); else ApplyEffectToObject(DURATION_TYPE_INSTANT, eEffect, oEnter); } //destroy trap and respawn it in one minute SetTrapDisabled(oTrap); SetPlotFlag(oTrap,FALSE); DelayCommand(5.0,ApplyEffectToObject(DURATION_TYPE_INSTANT, eKillTrap,oTrap)); //Trap has gone off, respawn it after fDelay seconds. if (fDelay>0.0) { if (fDelay<5.0) fDelay=5.0; DelayCommand(fDelay,CreateTrap(sTrap,lTrap)); } } //if trap has been disarmed then respawn it in fDelay seconds if(!GetIsTrapped(oTrap) &&GetDistanceToObject(oTrap)<3.0 &&GetPlotFlag(oTrap)==TRUE &&fDelay>0.0) { //SendMessageToPC(GetFirstPC(),"no trap .."); SetPlotFlag(oTrap,FALSE); //change the 55.0 and 60.0 (keep ~5 secs between) to alter //the respawn time. if (fDelay<5.0) fDelay=5.0; DelayCommand(fDelay-5.0,ApplyEffectToObject(DURATION_TYPE_INSTANT, eKillTrap,oTrap)); DelayCommand(fDelay,CreateTrap(sTrap,lTrap)); } } //Notes: //Could not use TrapDoElectricalDamage nw function //-it seemed indiscriminate. //Only used gas trap visible AOE. //Negative deadly does not use EffectNegativeLevel(1) //instead applies extra damage and more Strength loss.