Author Topic: Types of scripts to avoid  (Read 681 times)

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Types of scripts to avoid
« Reply #15 on: January 04, 2014, 02:00:01 am »


               Sigh @ new bioboards. Yeah, it's a long script:

                if (bPetrify)
                    ApplyPetrifyEffect(nDurType, eLink, oTarget, fDur);
                else
                    ApplyEffectToObject(nDurType, eLink, oTarget, fDur);
            }
        }
    }

    if (nBreach != 0) {
        if (nBreach < 0) {
            int nLevel = GetHitDiceIncludingLLs(oCaster);

            if (nLevel > 60)
                nLevel = 60;

            DoBreachAndDispel(oTarget, nLevel, 100, 0, 0, SPELL_DISPEL_MAGIC);
        } else if (nBreach > 100) {
            DoBreachAndDispel(oTarget, nBreach - 100, 100, 6, 10, SPELL_MORDENKAINENS_DISJUNCTION);
        } else {
            DoBreachAndDispel(oTarget, 0, 0, nBreach, nBreach + 1);
        }
    }
}



Funky
               
               

               
            

Legacy_MagicalMaster

  • Hero Member
  • *****
  • Posts: 2712
  • Karma: +0/-0
Types of scripts to avoid
« Reply #16 on: January 04, 2014, 03:11:07 am »


               Funky,  how expensive is creating a location (throwback to memory link discussion)?

In other words, let's say I wanted to damage anything within 5 meters of a location every second until some outside criteria is met.  In the past, I've used something like this...


void DoStuff (location lTarget)
{
   if (condition) return;

   object oTarget = GetFirstObjectInShape(lTarget);
   while (GetIsObjectValid(oTarget))
    {
        DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, oTarget, EffectDamage(10))
        oTarget = GetNextObjectInShape(lTarget)
    }

    DelayCommand(1.0, DoStuff(lTarget));
}

Obviously that's not fully fleshed out and has some stuff incorrect, but you get the gist.  The DelayCommand on the damage is to avoid an AI bug I found here:  http://social.biowar...1237/2#17510033

From what you've said, that looks like it has two memory leaks: passing the location recursively and delaying the damage call (which has an effect).  I'm not sure how to avoid the latter (would have to edit the AI itself, I think), but for the former I could do something like the following...



void DoStuff (object oArea, vector vVector, float fOrientation)
{
   if (condition) return;

    location lTarget = Location(oArea, vVector, fOrientation);
   object oTarget = GetFirstObjectInShape(lTarget);
   while (GetIsObjectValid(oTarget))
    {
        DelayCommand(0.1, ApplyEffectToObject(DURATION_TYPE_INSTANT, oTarget, EffectDamage(10))
        oTarget = GetNextObjectInShape(lTarget)
    }

    DelayCommand(1.0, DoStuff(oArea, vVector, fOrientation));
}

How expensive is creating that location each time?  Presumably the same amount of memory or less is taken up since the entire structure isn't being passed but it then has to reassemble the location each call.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Types of scripts to avoid
« Reply #17 on: January 04, 2014, 03:57:24 am »


               Short answer is: I don't know, try profiling it. '<img'>

Slightly longer answer is that the effect DC doesn't matter, as I'm almost certain that that DC will not actually cause a memory leak, since it doesn't directly recurse (it's only when you have structs in custom recursing functions, as with the location, as I understand it, that you get leaks). You could test for a memory leak wiith with the NWNX functions I mentioned, but I can tell you know that it's extremely unlikely, as we use ZILLIONS of Delayed Effect Applications. Here's a Find of just those that specify fDelay, rather than a specific number or another variable, in our mod. I'm going to assume that the post length limit here is going to screw me again, and just tell you up front that it occurs in 567 different places in our mod.

Funky

Quote

aa_con (42):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
abo_eldest_ebt (55):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
abo_endcombat (168):         DelayCommand(fDelay, ApplyDirectDamage(oTarget, nDamage, DAMAGE_TYPE_PSIONIC, DAMAGE_POWER_ENERGY));
abo_endcombat (1189):                         DelayCommand(fDelay, ApplyDirectDamage(oTarget, d20(12), DAMAGE_TYPE_ECTOPLASMIC,
abo_endcombat (1414):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eEff, oTarget));
abo_final_enter (72):         DelayCommand(fDelay, ApplyVisualAtLocation(nVis, lLoc));
aby_boss_heart (352):                     DelayCommand(fDelay, ApplyVisualToObject(CEPVFX_FNF_GAS_EXPLOSION_DISPEL, oTarget));
aby_boss_heart (413):                     DelayCommand(fDelay, ApplyVisualToObject(VFX_FNF_GAS_EXPLOSION_FIRE, oTarget));
aby_boss_heart (515):                     DelayCommand(fDelay, ApplyVisualToObject(VFX_FNF_GAS_EXPLOSION_ACID, oTarget));
aby_boss_heart (646):                     DelayCommand(fDelay, ApplyVisualToObject(CEPVFX_FNF_GAS_EXPLOSION_COLD, oTarget));
aby_endcombat (508):             DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eBeam, Location(oArea, vBeam, 0.0)));
aby_endcombat (570):         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (595):             DelayCommand(fDelay, ApplyDaze(oTarget, d3(1), "The dustman flings a bag of dust at you, sending you into a choking, coughing fit!"));
aby_endcombat (702):         DelayCommand(fDelay, ApplyDirectDamage(oTarget, nDamage, DAMAGE_TYPE_PSIONIC, DAMAGE_POWER_ENERGY));
aby_endcombat (879):                                 DelayCommand(fDelay, ApplyDeafness(oTarget, 10, "The vrock's screech deafens you!"));
aby_endcombat (882):                                     DelayCommand(fDelay, ApplyStun(oTarget, 3, "The vrock's screech stuns you!", TRUE, TRUE, SPELL_SOUND_BURST));
aby_endcombat (908):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (942):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (943):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (991):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1045):                                     DelayCommand(fDelay, ApplyDaze(oTarget, 3, "A burst of light from the nalfeshnee dazes you!", TRUE, TRUE, SPELL_DAZE));
aby_endcombat (1067):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1134):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1316):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVis, oTarget));
aby_endcombat (1541):                         DelayCommand(fDelay, ApplyVisualToObject(CEPVFX_IMP_HEALING_S_BLUE, oTarget));
aby_endcombat (1542):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(d100(3 + nParagon)), oTarget, 9.0));
aby_endcombat (1543):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 9.0));
aby_endcombat (1554):                         DelayCommand(fDelay, ApplyVisualToObject(GAOVFX_IMP_NEGATIVE_ENERGY_BLUE, oTarget));
aby_endcombat (1555):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (1593):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1598):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oTarget));
aby_endcombat (1639):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1640):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (1680):                             DelayCommand(fDelay, ApplySleep(oTarget, 10, "The droning buzz from the chasme makes you fall asleep!"));
aby_endcombat (1682):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1683):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (1745):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (1872):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,   eVis, oTarget));
aby_endcombat (1873):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (1931):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 9.0));
aby_endcombat (1975):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2007):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2097):                         DelayCommand(fDelay, ApplyVisualToObject(GAOVFX_IMP_NEGATIVE_ENERGY_GREEN, oTarget));
aby_endcombat (2098):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (2173):                         DelayCommand(fDelay, ApplyVisualToObject(VFX_FNF_GAS_EXPLOSION_GREASE, oTarget));
aby_endcombat (2174):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (2183):                         DelayCommand(fDelay, ApplyVisualToObject(VFX_FNF_GAS_EXPLOSION_GREASE, oTarget));
aby_endcombat (2184):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eCon, oTarget, 60.0));
aby_endcombat (2212):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2242):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,   eVis, oTarget));
aby_endcombat (2243):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (2277):                         DelayCommand(fDelay, ApplyStun(oTarget, 3, "The uzollru's gaze stuns you!", TRUE, TRUE, SPELLABILITY_GAZE_STUNNED));
aby_endcombat (2335):                         DelayCommand(fDelay, ApplySleep(oTarget, 10, "The soporific aura around the guecubu causes you to fall asleep!"));
aby_endcombat (2337):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (2338):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,   eVis, oTarget));
aby_endcombat (2570):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 9.0));
aby_endcombat (2619):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (2620):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2773):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2809):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2845):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2881):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (2915):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3018):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oTarget));
aby_endcombat (3145):                     DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_DOOM, oTarget));
aby_endcombat (3146):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (3222):                     DelayCommand(fDelay, ApplyFumeEffect(oTarget, eEff, eVis));
aby_endcombat (3263):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3264):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oTarget));
aby_endcombat (3376):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3377):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 9.0));
aby_endcombat (3473):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3599):                             DelayCommand(fDelay, ApplyBlindness(oTarget, 10, "You are blinded by a burst of spores from the sporebat!"));
aby_endcombat (3630):                             DelayCommand(fDelay, ApplyConfuse(oTarget, 5, "You are confused by the spores emanating from the violet fungus!"));
aby_endcombat (3631):                             DelayCommand(fDelay, ApplyVisualToObject(GAOVFX_IMP_NEGATIVE_ENERGY_PURPLE, oTarget));
aby_endcombat (3654):                             DelayCommand(fDelay, ApplyDaze(oTarget, 2, "You are dazed by a spray of spores from the violet fungus!"));
aby_endcombat (3743):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3744):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (3774):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3854):                                     DelayCommand(fDelay, ApplyDirectDamage(oTarget, d20(5 + nParagon), DAMAGE_TYPE_VILE,
aby_endcombat (3878):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (3879):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (3922):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4014):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (4016):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4017):                         DelayCommand(fDelay, ApplyBlindness(oTarget, 10, "You are blinded by the bloody spray from the sanguineous drinker!"));
aby_endcombat (4186):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4337):                         DelayCommand(fDelay, ApplyFear(oTarget, 10, "The sight of the manitou fills you with terror!"));
aby_endcombat (4384):                             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4442):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (4482):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4491):                                     DelayCommand(fDelay, ApplyDaze(oTarget, 3, "The bile spit from the sibriex causes you to gag and retch!"));
aby_endcombat (4603):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4643):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4644):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (4794):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4795):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (4831):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (4836):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eEff, oTarget));
aby_endcombat (4901):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT,   eVis, oTarget));
aby_endcombat (4902):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAwe, oTarget, 6.0));
aby_endcombat (5007):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5141):                                     DelayCommand(fDelay, ApplyDirectDamage(oTarget, d20(8 + nParagon), DAMAGE_TYPE_VILE,
aby_endcombat (5165):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5166):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 30.0));
aby_endcombat (5211):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5288):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5320):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5352):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5384):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5443):                                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5549):                         DelayCommand(fDelay, ApplySleep(oTarget, 10, "The soporific aura around Zhelamiss you to fall asleep!"));
aby_endcombat (5808):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (5809):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (6010):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (6050):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (6062):                                     DelayCommand(fDelay, ApplyDaze(oTarget, 3, "The bile spit from Fo-oon-fol causes you to gag and retch!"));
aby_endcombat (6217):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
aby_endcombat (6218):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
aby_endcombat (6305):                                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 24.0));
aby_onhit (248):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ac_mstorm_inc (136):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpact, oTarget));
ac_mstorm_inc (150):                             DelayCommand(fDelay, ApplyDirectDamage(oTarget, nSecondaryDamage, nSecondaryDamType,
ac_mstorm_inc (159):                         DelayCommand(fDelay, ApplyDirectDamage(oTarget, nDamage, nDamType, DAMAGE_POWER_ENERGY,
ac_mstorm_inc (163):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oTarget));
ac_spell_inc (1744):         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ac_spell_inc (1782):         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(nVis), oTarget));
ac_vtouch_inc (28):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpact, si.target));
ac_vtouch_inc (29):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, si.target));
ca_rdd_buffet (40):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
ca_rdd_buffet (43):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eKnock, oTarget, 6.0f));
ca_rdd_buffet (44):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis3, oTarget, 4.0f));
ca_sd_decoy (32):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, oTarget));
ca_sd_decoy (33):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVisHeal, oTarget));
ca_sd_decoy (36):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
ca_sd_decoy (37):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
drow_jud_cm_end (45):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oPC));
drow_jud_cm_end (46):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oPC));
dul_endcombat (96):     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d100(1), DAMAGE_TYPE_PIERCING), oTarget));
dul_endcombat (243):                         DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_FROST_S, oTarget));
dul_endcombat (410):                         DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_FROST_S, oTarget));
dul_endcombat (461):                             DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_DEATH, oTarget));
dul_endcombat (467):                         DelayCommand(fDelay, ApplyFear(oTarget, d6(), "The marzanna's gaze fills you with dread!", TRUE, FALSE, SPELL_FEAR));
dul_endcombat (508):                     DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_SONIC, oTarget));
dul_endcombat (509):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, 60.0));
dul_endcombat (585):                 DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_NEGATIVE_ENERGY, oTarget));
ele_endcombat (137):                                 DelayCommand(fDelay, ApplyKnockdown(oTarget, 1, "The air elemental's vortex knocks you down!",
ele_endcombat (177):                                 DelayCommand(fDelay, ApplyDaze(oTarget, 1 + d3(1), "The earth elemental slams the ground beneath you, leaving you dazed!"));
ele_endcombat (222):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eEff, oTarget, RoundsToSeconds(nResult) + 3.0));
ele_endcombat (258):                                 DelayCommand(fDelay, ApplyKnockdown(oTarget, 1, "The water elemental's vortex knocks you down!",
ele_endcombat (454):                             DelayCommand(fDelay, ApplyFear(oTarget, d2(), "The wolf's howl fills you with terror!"));
ele_endcombat (525):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eEff, oTarget));
ele_endcombat (526):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ele_endcombat (720):                         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ele_endcombat (747):                         DelayCommand(fDelay, ApplyDaze(oTarget, d4(1), "The sirine's song dazes you!", TRUE, TRUE, SPELL_DAZE));
ele_endcombat (998):                     DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_HEALING_S, oHeal));
ele_endcombat (1074):                             DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_FLAME_S, oTarget));
ele_onhit (34):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ele_onhit (65):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ele_onhit (96):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ele_onhit (127):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ely_death_trigg (44):                         AssignCommand(oArea, DelayCommand(fDelay, ApplyEffectToObject(0, eDam, oTarget)));
ely_death_trigg (45):                         AssignCommand(oArea, DelayCommand(fDelay, ApplyEffectToObject(0, eImp, oTarget)));
ely_endcombat (33):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
ely_endcombat (34):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImp, oTarget));
ely_endcombat (50):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eDam, oTarget));
ely_endcombat (51):                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eImp, oTarget));
ely_endcombat (1015):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
ely_endcombat (1016):                                 DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eLink, oTarget));
es_annihilation (54):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
es_dust_to_dust (40):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
es_dust_to_dust (41):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDur));
es_primal_catacl (125):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
es_winteriscomin (27):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
es_winteriscomin (28):             DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eLink, oTarget, fDur));
ev_lifetransrod (104):     AssignCommand(oArea, DelayCommand(fDelay, ApplyResurrection(oTarget, oPC)));
fa_greatersmite (145):         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
fa_greatersmite (146):         DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eSnd, oTarget));
fey_endcombat (106):                         DelayCommand(fDelay, ApplyDaze(oTarget, d3(1), "The corollax's color spray dazes you!"));
fey_endcombat (172):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget));
fey_endcombat (232):                         DelayCommand(fDelay, ApplyDaze(oTarget, d3(1), "The faerie dragon's breath dazes you!"));
fey_endcombat (273):                     DelayCommand(fDelay, ApplyEffectToObject(DURATION_TYPE_INSTANT, eEff, oTarget));
fey_endcombat (363):                 DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_HEAD_FIRE, oPC));
fey_endcombat (402):                 DelayCommand(fDelay, ApplyConfuse(oPC, d3(1), "The rascal's arrow confuses you!", TRUE, TRUE, SPELL_CONFUSION));
fey_endcombat (424):                 DelayCommand(fDelay, ApplyVisualToObject(VFX_IMP_HEAD_ODD, oPC));
fey_endcombat (503):
               
               

               


                     Modifié par FunkySwerve, 04 janvier 2014 - 03:59 .
                     
                  


            

Legacy_MagicalMaster

  • Hero Member
  • *****
  • Posts: 2712
  • Karma: +0/-0
Types of scripts to avoid
« Reply #18 on: January 04, 2014, 04:08:18 am »


               

FunkySwerve wrote...

Short answer is: I don't know, try profiling it. '<img'>


This?  http://www.nwnx.org/...id=doc_profiler

Never used it -- anything specific I should know about using it that wouldn't be obvious?

FunkySwerve wrote...

it's only when you have structs in custom recursing functions, as with the location, as I understand it, that you get leaks


Phew!  Thanks.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Types of scripts to avoid
« Reply #19 on: January 04, 2014, 03:11:37 pm »


               Yup, that. Main thing to remember about the profiler is to just shut it off when you're done, if you're running it on your live mod, as it slows down everything's performance when you're running it.

Funky
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Types of scripts to avoid
« Reply #20 on: January 04, 2014, 04:08:35 pm »


               

FunkySwerve wrote...

There are a lot of ways to reduce lag, the main thing is to be extra careful about using any kind of combat scripting, especially items that use OnHit effects (that can seriously spike your server with 10 - 60+ people firing 2 - 6 scripts a round)...  (10 monks dual welding kamas with on hit cast spell can get insane fast!)

This is an old piece of misinformation which became more prevalent around the time when sonic onhit effects were added. We use onhits like crazy, and they don't cause problems.

This. I might repeat myself, but.. if you would know how many code is executed by single creature during usual fight, you wouldn't be wasting your time to debates whether to use GOBT, GNOBT or GWBT '-_-'
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
Types of scripts to avoid
« Reply #21 on: January 04, 2014, 09:24:22 pm »


               Technically every delay command you have running requires server resources...
So if you were build a treasure system with say a 5 minute DC on it...
With 20 players accessing treasure chest 1 to 4 times a minute, the memory would build up...
So, yes it is technically something to avoid in general.
Of course like I said before, short ones aren't so bad, but long ones are an issue, but mainly only if it's something accessed a lot.  I use to use delay commands, now I use 1 heartbeat to track time passed in the module, and check the heart beat vs a local variable to see how much time has passed instead.  (Yes I know there is a better way using nwnx)

Looping scripts should also be avoided or very minimal as well... (1-8 in a module shouldn't be an issue.)
(Personally I avoid heartbeats like the plague!)
               
               

               


                     Modifié par _Guile, 04 janvier 2014 - 09:27 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Types of scripts to avoid
« Reply #22 on: January 05, 2014, 12:00:23 am »


               

_Guile wrote...

Technically every delay command you have running requires server resources...
So if you were build a treasure system with say a 5 minute DC on it...
With 20 players accessing treasure chest 1 to 4 times a minute, the memory would build up...
So, yes it is technically something to avoid in general.
Of course like I said before, short ones aren't so bad, but long ones are an issue, but mainly only if it's something accessed a lot.  I use to use delay commands, now I use 1 heartbeat to track time passed in the module, and check the heart beat vs a local variable to see how much time has passed instead.  (Yes I know there is a better way using nwnx)

I suggest reading the delagging tutorial linked above. I was only taking issue with calling them a 'big one' - eliminating unnecessary delaycommands is listed at #6 in the tutorial. They way you were talking about them was reminiscent of the way a lot of clueless scripters talk about heartbeats, as well, which results in them coding all sorts of oddities instead of a nice, clean heartbeat. Speaking of which...

Looping scripts should also be avoided or very minimal as well... (1-8 in a module shouldn't be an issue.)
(Personally I avoid heartbeats like the plague!)


 We use TONS of
recursive scripts (I'm assuming you don't mean 'looping' as in actual
looping, as with while and for loops, as that would be even sillier).
They're often the most efficient, if not the only, way to do something,
and there's absolutely no reason to avoid them. I can't easily run a search for them, since they don't have a uniform aspect other than calling their own function name at various points, but I'm confident we have hundreds, plural, at a minimum. They're incredibly useful, and should absolutely NOT be avoided.

Likewise, heartbeats should also not be avoided, simply used when its appropriate. There's a small section in the tutorial talking about replacing heartbeats with pseudos, but sometimes the heartbeat is the appropriate way to go. Avoiding them 'like the plague' is just wrong. By way of example, here's our module heartbeat, which is often the most appropriate place for heartbeat-style code (unless we're talking monster/NPC heartbeats, which are sometimes useful and warranted) (assuming forum-length limits again, it's 357 lines of fairly dense and heavily-included code)

Funky


#include "hg_inc"

#include "fky_chat_inc"
#include "hg_client_inc"

#include "ac_effect_inc"
#include "ac_itemprop_inc"


void SendResetBroadcast (string sMessage, int bTell, object oMessenger) {
    sMessage = "<cþ þ>" + sMessage + "</c>";

    object oPC = GetFirstPC();

    while (GetIsObjectValid(oPC)) {
        SendChatLogMessage(oPC, sMessage, oMessenger, (bTell ? 4 : 5));
        oPC = GetNextPC();
    }
}


void main() {
    object oMod = GetModule();
    object oMes = GetMessenger();
    int nUptime = GetLocalInt(oMod, "uptime");
    int nMemory = GetProcessMemoryUsage();
    int nMessages = 0, nPlayers = 0;
    string sServer = GetLocalString(oMod, "ServerNumber");
    string sBootTime = IntToString(GetLocalInt(oMod, "boottime"));

    {
        object oPC;

        for (oPC = GetFirstPC(); GetIsObjectValid(oPC); oPC = GetNextPC()) {
            nPlayers++;
            RecalculateMovementRate(oPC);
            RecalculateDexModifier(oPC);

            int nAlarm = GetLocalInt(oPC, "AlarmUptime");
            if (nAlarm > 0 && nAlarm <= nUptime) {
                DeleteLocalInt(oPC, "AlarmUptime");
                SendChatLogMessage(oPC, C_PINK + "[Alarm] " + GetLocalString(oPC, "AlarmMessage") + C_END, oMes, 4);
            }
        }

        SetLocalInt(oMod, "ServerPlayers", nPlayers);
    }

    SQLExecDirect("SELECT UNIX_TIMESTAMP() - " + sBootTime + ", UTC_TIMESTAMP(), UNIX_TIMESTAMP(), " +
        "COUNT(*) FROM user_messages WHERE um_recipient = '*" + sServer + "'");

    if (SQLFetch() == SQL_SUCCESS) {
        nUptime = StringToInt(SQLGetData(1));
        nMessages = StringToInt(SQLGetData(4));

        SetLocalInt(oMod, "uptime", nUptime);
        SetLocalInt(oMod, "realtime", StringToInt(SQLGetData(3)));
        SetLocalString(oMod, "utctime", SQLGetData(2));

        SQLExecDirect("UPDATE server_list SET srv_utime = " + IntToString(nUptime) + ", srv_memory = " +
            IntToString(nMemory) + ", srv_players = " + IntToString(nPlayers) + " WHERE srv_id = '" + sServer + "'");

        SQLExecDirect("SELECT COUNT(*) FROM user_list WHERE u_active > 0");
        if (SQLFetch() == SQL_SUCCESS)
            SetLocalInt(oMod, "GlobalPlayers", StringToInt(SQLGetData(1)));

        SQLExecDirect("SELECT COUNT(*) FROM user_list WHERE u_active > 0 AND u_server_name REGEXP '" + GetStringLeft(sServer, 1) + ".[1-8]'");
        if (SQLFetch() == SQL_SUCCESS) {
            int nHubPlayers = StringToInt(SQLGetData(1));

            SetLocalInt(oMod, "HubPlayers", nHubPlayers);

            if (GetStringLeft(sServer, 1) != "1" && GetStringRight(sServer, 1) == "1")
                SetNumberOfPlayers(nHubPlayers);
        }
    }


    /* check for server messages if available */
    if (nMessages > 0) {
        int nGuild;
        string sMessage;
        string sSQL = "SELECT um_id, um_guild, um_text FROM user_messages WHERE um_recipient = '*" + sServer + "'";

        SQLExecDirect(sSQL);

        sSQL = "";

        while (SQLFetch() != SQL_ERROR) {
            if (sSQL == "")
                sSQL = "um_id = " + SQLGetData(1);
            else
                sSQL += " OR um_id = " + SQLGetData(1);

            nGuild   = StringToInt(SQLGetData(2));
            sMessage = SQLDecodeSpecialChars(SQLGetData(3));

            if (nGuild == -2) {
                object oPC = GetFirstPC();

                while (GetIsObjectValid(oPC)) {
                    if (!(GetPCFilter(oPC, PCFILTER_CHANNELS) & 1))
                        SendChatLogMessage(oPC, sMessage, oMes);

                    oPC = GetNextPC();
                }
            } else if (nGuild == -3) {
                object oPC = GetFirstPC();

                while (GetIsObjectValid(oPC)) {
                    if (!(GetPCFilter(oPC, PCFILTER_CHANNELS) & 2))
                        SendChatLogMessage(oPC, sMessage, oMes);

                    oPC = GetNextPC();
                }
            } else if (nGuild == -4) {
                object oPC = GetFirstPC();

                while (GetIsObjectValid(oPC)) {
                    if (!(GetPCFilter(oPC, PCFILTER_CHANNELS) & 4))
                        SendChatLogMessage(oPC, sMessage, oMes);

                    oPC = GetNextPC();
                }
            } else if (nGuild < 0) {
                SendMessageToDMDMs(sMessage);
                SendMessageToPCDMs(sMessage);
                SendMessageToDMAdmins(sMessage);
                SendMessageToPCAdmins(sMessage);
            } else if (nGuild > 0) {
                object oPC = GetFirstPC();

                while (GetIsObjectValid(oPC)) {
                    if (GetLocalInt(oPC, "Guild") == nGuild && !(GetPCFilter(oPC, PCFILTER_GUILD) & 1))
                        SendChatLogMessage(oPC, sMessage, oMes);

                    oPC = GetNextPC();
                }
            } else
                AssignCommand(oMod, SpeakString(sMessage, TALKVOLUME_SHOUT));
        }

        if (sSQL != "")
            SQLExecDirect("DELETE FROM user_messages WHERE " + sSQL);
    }


    /* scan players for inter-server messages every minute; also check for auto-reset */
    if (nUptime >= GetLocalInt(oMod, "LastMessageCheck") + 60) {
        SetLocalInt(oMod, "LastMessageCheck", nUptime);

        if (nMemory > GetLocalInt(oMod, "resetmemory") && !GetLocalInt(oMod, "resetforce")) {
            SetLocalInt(oMod, "resetforce", 1);

            if (GetLocalInt(oMod, "resetuptime") > nUptime)
                SetLocalInt(oMod, "resetuptime", nUptime - 1);
        }


        /* update PCs in the user list */
        UpdateAllClients(sServer, sBootTime, oMes);


        /* check for automatic reset */
        int nResetUptime = GetLocalInt(oMod, "resetuptime");
        if (nResetUptime > 0 && nUptime > nResetUptime) {

            if (!GetIsObjectValid(GetFirstPC())) {
                ResetServer();
                return;
            }
            if (nUptime > nResetUptime + 900) {
                SendResetBroadcast("SERVER RESET IN 10 SECONDS - SERVER REBOOT IS NOW COMMITTED - CANCELLATION " +
                    "IS NO LONGER POSSIBLE - PLEASE STAY OUT OF BANK CHESTS - HAVE A NICE DAY!", 1, oMes);
                DelayCommand(9.0, ResetServer());//ResetServer has built-in 1 second delay
            } else {
                int bTell = 0;
                int nSeconds = (nResetUptime + 900) - nUptime;
                string sMinutes = IntToString((nSeconds / 60) + 1);

                if (sMinutes == "1" || sMinutes == "5" || sMinutes == "10" || sMinutes == "15")
                    bTell = 1;

                if (GetLocalInt(oMod, "resetforce"))
                    SendResetBroadcast("AUTOMATIC SERVER RESET IN " + sMinutes + " MINUTE" +
                        (sMinutes != "1" ? "S" : "") + " - THIS CANNOT BE ABORTED DUE TO A LOW MEMORY CONDITION", bTell, oMes);
                else
                    SendResetBroadcast("AUTOMATIC SERVER RESET IN " + sMinutes + " MINUTE" +
                        (sMinutes != "1" ? "S" : "") + " - USE !delayreset TO DELAY THE RESET", bTell, oMes);
            }
        }
    }


    /* scan players for epic buffs every minute */
    if (nUptime >= GetLocalInt(oMod, "LastImmunityBuffCheck") + 60) {
        int i;
        object oCreator, oArea, oItem, oPC = GetFirstPC();

        while (GetIsObjectValid(oPC)) {
            oArea = GetArea(oPC);

            if (GetIsDead(oPC)           ||
                !GetIsObjectValid(oArea) ||
                GetHasEffectOfType(EFFECT_TYPE_CONFUSED, oPC)) {
                oPC = GetNextPC();
                continue;
            }


            if (GetHasSpellEffect(HGSPELL_EPIC_AEGIS, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Aegis");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Aegis") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_AEGIS, oPC);
                        FloatingTextStringOnCreature(
                            "* The Aegis spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Aegis", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Aegis");
            }


            if (GetHasSpellEffect(HGSPELL_EPIC_CHANT_OF_WARDING, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Chant");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Chant") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_CHANT_OF_WARDING, oPC);
                        FloatingTextStringOnCreature(
                            "* The Chant of Warding spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Chant", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Chant");
            }


            if (GetHasSpellEffect(HGSPELL_EPIC_ELEMENTAL_SHUNT, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Shunt");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Shunt") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_ELEMENTAL_SHUNT, oPC);
                        FloatingTextStringOnCreature(
                            "* The Elemental Shunt spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Shunt", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Shunt");
            }


            if (GetHasSpellEffect(HGSPELL_EPIC_SHROUD_OF_NATURE, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Shroud");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Shroud") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_SHROUD_OF_NATURE, oPC);
                        FloatingTextStringOnCreature(
                            "* The Shroud of Nature spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Shroud", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Shroud");
            }


            oPC = GetNextPC();
        }

        SetLocalInt(oMod, "LastImmunityBuffCheck", (nUptime - 5) + Random(11));
    }


    if (nUptime >= GetLocalInt(oMod, "LastEquipmentBuffCheck") + 60) {
        int i;
        object oCreator, oArea, oItem, oPC = GetFirstPC();

        while (GetIsObjectValid(oPC)) {
            oArea = GetArea(oPC);

            if (GetIsDead(oPC)                                 ||
                !GetIsObjectValid(oArea)                       ||
                GetHasEffectOfType(EFFECT_TYPE_POLYMORPH, oPC) ||
                GetHasEffectOfType(EFFECT_TYPE_CONFUSED, oPC)) {
                oPC = GetNextPC();
                continue;
            }

            if ((GetLevelByClass(CLASS_TYPE_BLACKGUARD, oPC) + GetLevelByClass(CLASS_TYPE_PALADIN, oPC) + GetLevelByClass(CLASS_TYPE_DIVINE_CHAMPION, oPC)) >= 40) {
                if (GetKnowsFeat(FEAT_SMITE_EVIL, oPC))
                    IncrementRemainingFeatUses(oPC, FEAT_SMITE_EVIL);
                if (GetKnowsFeat(FEAT_SMITE_GOOD, oPC))
                    IncrementRemainingFeatUses(oPC, FEAT_SMITE_GOOD);
                // Greater Smite failing to recharge fix.
                int nIndex = GetLocalInt(oPC, "GreaterSmiteAbility") - 1;
                struct SpecialAbilitySlot sa = GetSpecialAbility(oPC, nIndex);

                if ((sa.id == SPELLABILITY_GAZE_DESTROY_EVIL ||
                    sa.id == SPELLABILITY_GAZE_DESTROY_GOOD ||
                    sa.id == SPELLABILITY_PULSE_HOLY) && sa.ready == 0 && !GetLocalInt(oPC, "NeedsRest")) {
                    sa.ready = 1;
                    SetSpecialAbility(oPC, nIndex, sa);
                }
            }

            if (GetHasSpellEffect(HGSPELL_EPIC_GIRDING_OF_THE_FAITHFUL, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Gird");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Gird") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_GIRDING_OF_THE_FAITHFUL, oPC);
                        DelayCommand(0.1, VoidRemoveAllItemPropertiesFromSpell(HGSPELL_EPIC_GIRDING_OF_THE_FAITHFUL, oPC));

                        FloatingTextStringOnCreature(
                            "* The Girding of the Faithful spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Gird", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Gird");
            }


            if (GetHasSpellEffect(HGSPELL_EPIC_INSTRUMENTS_OF_FAITH, oPC)) {
                oCreator = GetLocalObject(oPC, "EpicCreator_Instr");

                if (!GetIsObjectValid(oCreator) || GetArea(oCreator) != oArea || !GetFactionEqual(oCreator, oPC)) {
                    if (GetLocalInt(oPC, "EpicCollapse_Instr") > 1) {
                        RemoveEffectsFromSpell(HGSPELL_EPIC_INSTRUMENTS_OF_FAITH, oPC);
                        DelayCommand(0.1, VoidRemoveAllItemPropertiesFromSpell(HGSPELL_EPIC_INSTRUMENTS_OF_FAITH, oPC));

                        FloatingTextStringOnCreature(
                            "* The Instruments of Faith spell on you collapses without the support of its caster! *",
                            oPC, FALSE);
                    } else
                        AddLocalInt(oPC, "EpicCollapse_Instr", 1);
                } else
                    DeleteLocalInt(oPC, "EpicCollapse_Instr");
            }


            oPC = GetNextPC();
        }

        SetLocalInt(oMod, "LastEquipmentBuffCheck", (nUptime - 5) + Random(11));
    }
}

               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
Types of scripts to avoid
« Reply #23 on: January 06, 2014, 04:45:28 am »


               Another one I'd like to point out is, don't use intensive OnClientEnter / OnEquipItem / OnUnEquipItem event scripting...  Like looping through a player's inventory or properties on items, rather use a trigger or something to do that, after they have entered the module..  The reason I tell you this is because, when a client enters the module these events fire, the more intensive the scripting is, the more likely it will cause issues on a server, like 10 people logging in at once can severely slow down everyone logging back on to the server if a bunch of scripts are firing on each item they have equipped...  (Just A Tip)
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Types of scripts to avoid
« Reply #24 on: January 06, 2014, 05:54:37 am »


               

_Guile wrote...

Another one I'd like to point out is, don't use intensive OnClientEnter / OnEquipItem / OnUnEquipItem event scripting...  Like looping through a player's inventory or properties on items, rather use a trigger or something to do that, after they have entered the module..  The reason I tell you this is because, when a client enters the module these events fire, the more intensive the scripting is, the more likely it will cause issues on a server, like 10 people logging in at once can severely slow down everyone logging back on to the server if a bunch of scripts are firing on each item they have equipped...  (Just A Tip)


Trying to avoid using those events is like trying to type while avoiding use of your fingers. A far better solution to that is to disable most parts of some events oncliententer.  See, for example, the beginning of our onequip script:

void main() {
    object oPC = GetPCItemLastEquippedBy();

    if (GetLocalInt(oPC, "MidPolymorph") || (ScanForPolymorphEffect(oPC) > -2))
        return;
    if (!GetIsPC(oPC) || GetIsDM(oPC))
        return;

    object oItem = GetPCItemLastEquipped();
    object oArea = GetArea(oPC);
    string sItemName = GetName(oItem);

    if (GetLocalInt(oPC, "DebugItemEvents")) {
        SendMessageToPC(oPC, COLOR_WHITE + "Item Event: Equip" +
            ", Owner: " + GetName(oPC) + " (" + GetObjectString(oPC) +
            "), Area: " + GetName(oArea) + " (" + GetObjectString(oArea) +
            "), Item: " + sItemName + " (" + GetObjectString(oItem) +
            ") [x" + IntToString(GetItemStackSize(oItem)) + "]" + COLOR_END);
    }

    /* ensures it doesn't run oncliententer - */
    if (!GetIsObjectValid(GetArea(oPC)))
        return;
*snip*



That check cuts off the next 260 lines of incredibly dense, highly-included code from executing oncliententer. Simple, non?

Likewise, for onacquire:

void main() {
    /* uncommenting below line would activate tag-based scripting for onacquire,
     * but we currently only use it for onactivate and onequip */
    /* ExecuteScript( "x2_mod_def_aqu", OBJECT_SELF); */

    object oAcquire = GetModuleItemAcquiredBy();
    if (!GetIsPC(oAcquire) || GetIsDM(oAcquire))
        return;

    int i;
    object oLoser = GetModuleItemAcquiredFrom();
    object oScan, oItem = GetModuleItemAcquired();

    if (GetLocalInt(oAcquire, "DebugItemEvents")) {
        SendMessageToPC(oAcquire, COLOR_WHITE + "Item Event: Acquire" +
            ", Acquirer: " + GetName(oAcquire) + " (" + GetObjectString(oAcquire) +
            "), Loser: " + GetName(oLoser) + " (" + GetObjectString(oLoser) +
            "), Item: " + GetName(oItem) + " (" + GetObjectString(oItem) +
            ") [x" + IntToString(GetItemStackSize(oItem)) + "]" + COLOR_END);
    }

    /* below lines stops weapon /armor buffs from carrying over */
    RemoveItemPropertiesOfDuration(DURATION_TYPE_TEMPORARY, oItem, -(ITEM_PROPERTY_LIGHT + 1));

    if (GetHasInventory(oItem)) {
        oScan = GetFirstItemInInventory(oItem);

        while (GetIsObjectValid(oScan)) {
            RemoveItemPropertiesOfDuration(DURATION_TYPE_TEMPORARY, oScan, -(ITEM_PROPERTY_LIGHT + 1));
            oScan = GetNextItemInInventory(oItem);
        }
    }

    /* don't run oncliententer */
    if (!GetIsObjectValid(GetArea(oAcquire)))
        return;
*snip*



You don't actually need that shunt anywhere else, despite what you said about OnUnequip conflicting with OCE- just onequip and onacquire. You do, however, want a polymorph shunt on OnUnequip, to match the one in OnEquip (posted above):

void main() {
    object oPC = GetPCItemLastUnequippedBy();
    object oItem = GetPCItemLastUnequipped();

    if (GetLocalInt(oPC, "DebugItemEvents")) {
        object oArea = GetArea(oPC);

        SendMessageToPC(oPC, COLOR_WHITE + "Item Event: Unequip" +
            ", Owner: " + GetName(oPC) + " (" + GetObjectString(oPC) +
            "), Area: " + GetName(oArea) + " (" + GetObjectString(oArea) +
            "), Item: " + GetName(oItem) + " (" + GetObjectString(oItem) +
            ") [x" + IntToString(GetItemStackSize(oItem)) + "]" +
            ", Force: " + IntToString(GetLocalInt(oPC, "ForceUnequipped")) +
            ", Poly: " + IntToString(GetLocalInt(oPC, "MidPolymorph")) +
            COLOR_END);
    }

    /* scripts in onequip, onunequip, onunacquire - script here MUST be before
     * the "ForceUnequipped" int is deleted below */
    if (GetLocalInt(oPC, "MidPolymorph") || (ScanForPolymorphEffect(oPC) > -2))
        return;
*snip*


That prevents a lot of potential issues with shifters and such, though you do have to code in the "MidPolymorph" var to your polymorph scripts. See, e.g.:

void ApplyPolymorphEffect (int nDurType, effect ePoly, object oTarget, float fDur=0.0) {
    if (GetLocalInt(oTarget, "NoPoly"))
        return;

    SetLocalInt(oTarget, "MidPolymorph", TRUE);
    ApplyEffectToObject(nDurType, ePoly, oTarget, fDur);
    DeleteLocalInt(oTarget, "MidPolymorph");
}


and:

act_funfou0021 (67):         ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, eEffect, oTarget, 60.0f);
ele_endcombat (637):                     ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eEff, oPC);
fky_deathprocess (51):         ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, EffectPolymorph(POLYMORPH_TYPE_NULL_HUMAN), oPC, 0.1);
hg_inc (372): void ApplyPolymorphEffect (int nDurType, effect ePoly, object oTarget, float fDur=0.0);
hg_inc (2341): void ApplyPolymorphEffect (int nDurType, effect ePoly, object oTarget, float fDur=0.0) {
loc_endcombat (379):                 ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eEff, oPC);
nw_c2_lycat_d (29):         DelayCommand(1.0, ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eShape, OBJECT_SELF));
nw_c2_lyrat_d (29):         DelayCommand(1.0, ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eShape, OBJECT_SELF));
nw_c2_lywolf_d (29):         DelayCommand(1.0, ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eShape, OBJECT_SELF));
nw_s0_polyself (99):     ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, eLink, si.target, fDur);
nw_s0_shapechg (132):         DelayCommand(0.5, ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, si.target, fDur));
nw_s2_elemshape (205):     ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, OBJECT_SELF, HoursToSeconds(nDuration));
nw_s2_wildshape (226):     ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, OBJECT_SELF, HoursToSeconds(nDuration));
uro_endcmbtrnd (97):                         ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, eEff, oPC);
x0_i0_deckmany (684):     ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, ePoly, oCaster);
x0_s3_rodwonder (87):         ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, oTarget, RoundsToSeconds(d4()));
x0_s3_rodwonder (183):         ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, oCaster, RoundsToSeconds(d4()));
x0_s3_rodwonder (254):         ApplyPolymorphEffect(DURATION_TYPE_TEMPORARY, ePoly, oTarget, RoundsToSeconds(d4()));
x2_s2_gwildshp (513):     ApplyPolymorphEffect(DURATION_TYPE_PERMANENT, ePoly, OBJECT_SELF);


That's getting into more advanced coding, however, and all of this is sort of tangential to the original topic.


Funky