Author Topic: Help understanding a script.  (Read 1854 times)

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Help understanding a script.
« Reply #60 on: December 03, 2011, 03:00:37 pm »


               

//private function
//1.70 by Shadooow: Is my target immune to last spell cast?
int MyResistSpell_GetIsSpellImmune(object oTarget, int bAOE)
{
object oRight = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,oTarget);
object oLeft = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,oTarget);
int bNoChange = GetLocalObject(oTarget,"ITEM_IN_RIGHT") == oRight && GetLocalObject(oTarget,"ITEM_IN_LEFT") == oLeft;
int nSpellId = GetEffectSpellId(EffectDazed());//AOE spells workaround
 if(bAOE && bNoChange && !GetIsPC(oTarget) && GetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId)) == 1)
 {
 return TRUE;//immunity to AOE is granted via itemproperty, no reason to repeat whole process again
 }
 else if((nSpellId == SPELL_MAGIC_MISSILE || nSpellId == SPELL_SHADOW_CONJURATION_MAGIC_MISSILE) && GetHasSpellEffect(SPELL_SHIELD,oTarget))
 {
 return TRUE;//magic missile on target with Shield spell effect
 }
 else if((nSpellId == SPELL_DROWN || nSpellId == SPELLABILITY_PULSE_DROWN || nSpellId == SPELL_FLESH_TO_STONE) && GetHasSpellEffect(nSpellId,oTarget))
 {
 return TRUE;//drown and flesh to stone immunity workaround
 }
int nSpellLevel = 99;
int nclass = GetLastSpellCastclass();
 if(bAOE)
 {
 nSpellLevel = GetLocalInt(OBJECT_SELF,"AOE_INNATE")-1;
  if(nSpellLevel < 0)
  {
  nSpellLevel = 99;
   if(GetLocalInt(OBJECT_SELF,"AOE_class") > 0)
   {
   nclass = GetLocalInt(OBJECT_SELF,"AOE_class")-1;
   }
  }
 }
 if(nSpellLevel == 99)
 {
 string sCollumn = "Innate";
  switch(nclass)
  {
  case class_TYPE_WIZARD:
  case class_TYPE_SORCERER:     sCollumn = "Wiz_Sorc";  break;
  case class_TYPE_CLERIC:       sCollumn = "Cleric";    break;
  case class_TYPE_DRUID:        sCollumn = "Druid";     break;
  case class_TYPE_BARD:         sCollumn = "Bard";      break;
  case class_TYPE_RANGER:       sCollumn = "Ranger";    break;
  case class_TYPE_PALADIN:      sCollumn = "Paladin";   break;
  }
 sCollumn = Get2DAString("spells",sCollumn,nSpellId);
  if(sCollumn != "****" && sCollumn != "")
  {
  nSpellLevel = StringToInt(sCollumn);
   if(bAOE) SetLocalInt(OBJECT_SELF,"AOE_INNATE",nSpellLevel+1);
  }
 }
int nMaxLevel;
 if(GetHasSpellEffect(734,oTarget))
 nMaxLevel = 8;
 else if(GetHasSpellEffect(SPELL_GLOBE_OF_INVULNERABILITY,oTarget))
 nMaxLevel = 4;
 else if(GetHasSpellEffect(SPELL_MINOR_GLOBE_OF_INVULNERABILITY,oTarget) || GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MINOR_GLOBE,oTarget))
 nMaxLevel = 3;
 else if(GetHasSpellEffect(SPELL_ETHEREAL_VISAGE,oTarget))
 nMaxLevel = 2;                                                                                                                          //shadow ghostly visage
 else if(GetHasSpellEffect(SPELL_GHOSTLY_VISAGE,oTarget) || GetHasSpellEffect(SPELLABILITY_AS_GHOSTLY_VISAGE,oTarget) || GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MIRROR_IMAGE,oTarget))
 nMaxLevel = 1;
 if(nSpellLevel <= nMaxLevel)
 {
 return TRUE;//immunity via spell immunity effect like globe of invulnerability
 }
string sSchool = Get2DAString("spells","School",nSpellId);
 if(GetHasSpellEffect(SPELL_SHADOW_SHIELD,oTarget) && sSchool == "N")
 {
 return TRUE;//Necromantic spell cast at target with Shadow Shield
 }
 else if(GetHasSpellEffect(390,oTarget) && sSchool == "E")
 {
 return TRUE;//Enchantment spell cast at target polymorphed into pixie
 }
int nSchool = -1;
 if     (sSchool == "A")     nSchool = 0;
 else if(sSchool == "C")     nSchool = 1;
 else if(sSchool == "D")     nSchool = 2;
 else if(sSchool == "E")     nSchool = 3;
 else if(sSchool == "V")     nSchool = 4;
 else if(sSchool == "I")     nSchool = 5;
 else if(sSchool == "N")     nSchool = 6;
 else if(sSchool == "T")     nSchool = 7;
 if(bAOE && !GetIsPC(oTarget))
 {
  if(bNoChange && GetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId)) == -1)
  {
  return FALSE;//immunity to AOE is not granted via itemproperty, no reason to repeat whole process again
  }
  else
  {
  SetLocalObject(oTarget,"ITEM_IN_RIGHT",oRight);
  SetLocalObject(oTarget,"ITEM_IN_LEFT",oLeft);
  }
 }
//still nothing, lets check target skin as well to handle creatures like demiliches
int nSlot;
object oItem;
itemproperty ip;
 for(;nSlot < NUM_INVENTORY_SLOTS;nSlot++)
 {
 oItem = GetItemInSlot(nSlot,oTarget);
  if(GetIsObjectValid(oItem))
  {
  itemproperty ip = GetFirstItemProperty(oItem);
   while(GetIsItemPropertyValid(ip))
   {
    switch(GetItemPropertyType(ip))
    {
    case ITEM_PROPERTY_IMMUNITY_SPECIFIC_SPELL:
     if(StringToInt(Get2DAString("iprp_spellcost","SpellIndex",GetItemPropertyCostTableValue(ip))) == nSpellId)
     {
      if(bAOE) SetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId),1);
     return TRUE;//immunity specifically on our spell from itemproperty
     }
    break;
    case ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL:
     if(nSpellLevel <= GetItemPropertyCostTableValue(ip))
     {
      if(bAOE) SetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId),1);
     return TRUE;//immunity to spell by level from itemproperty
     }
    break;
    case ITEM_PROPERTY_IMMUNITY_SPELL_SCHOOL:
     if(GetItemPropertySubType(ip) == nSchool)
     {
      if(bAOE) SetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId),1);
     return TRUE;//immunity to spell school from itemproperty
     }
    break;
    }
   ip = GetNextItemProperty(oItem);
   }
  }
 }
 if(bAOE) SetLocalInt(oTarget,"IMMUNE_TO_"+IntToString(nSpellId),-1);
return FALSE;
}

update for the weapon switching issue
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Help understanding a script.
« Reply #61 on: December 03, 2011, 03:57:36 pm »


               

ShaDoOoW wrote...

OK I see, however Im not sure what to do now - the performancy is really problem, the default scripts causes huge cross-server lags in the situation #1, my scripts made it a little better but still not perfect. ...



Sorry I have not been following this thread that much.   Mainly because I have not had the time to test and fulsh out my Idea.   If you have the time however you may want to test it out. 

The Original Idea that I did not fully explaine with Fester pots original script is still valid.   That was to use the  ResistSell function.  Where It would have worked with his script. It will take even more testion with your AoE's to make sure every thing is flushed out right.  

I know you are now going to say that ResistSpell(),GetSpellId(), GetSpellSaveDC(), GetCasterLevel(), and so on; do not work outside of the SpellCastEvent.   So to me the solution is to just place the script back inside of the Spell.     

In Festers case he was trying to cast a fake spell that the player had to have, then reducing the spell usages, and then doing the calculations outside of the spell event.  For him it would have been better to cast Real spell and create a spell hook that would re-run the script he was running inside the spellevent.  Of cource the spell hook would also stop the SpellScript from running.  Yes, you will also need to place a filter in the script/function to make sure that the script only tries to cast the splee to place it back into the Spellevent one time.  

Festers script would have nt been to hard to get to work that way.   After all we had full contorl of the action que for the in his script.   

I do not currently have enought time to test out the Idea with the AOE's  It should work there are just more thing to take into concideration.    Like who is going to cast the spell to place it back into the spell event.   If the PC who cast the spell to bengin with is no longer even log in, he sure can not do it.   even if he was does the bInstant  switch in actionCastSpell bypass the action que. would be nice if it did,  Yea I really don have the time to flush it out right now.   

Hopefully that give you enough information if you wanted to try and work out the kinks.
               
               

               


                     Modifié par Lightfoot8, 03 décembre 2011 - 03:57 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Help understanding a script.
« Reply #62 on: December 03, 2011, 05:54:38 pm »


               

ShaDoOoW wrote...

OK I see, however Im not sure what to do now - the performancy is really problem, the default scripts causes huge cross-server lags in the situation #1, my scripts made it a little better but still not perfect. While the issue is in different place any additional code has relevance in such situations. You can try lure like 30monsters into stacked AOEs -> 3x grease 3x entangle 5x stonehold 7x vengeance and you will see. I know that issue is elsewhere but in this situation any additional piece of code matters I think.


If performance is an issue, and the alternative bugs to serious of an issue to allow compromise, I think you're stuck with the onun/equip variable solution. I understand you want to avoid mod events, and why, but I think that's the only alternative.

Funky
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Help understanding a script.
« Reply #63 on: December 03, 2011, 06:45:45 pm »


               But the latest script should be reliable in 99% cases.

The issue that does these lags is "cross-shouts". If there is a spell with larger are of effect which hits in one cast multiple enemies, then every enemy hit triggers OnSpellCastAt event which triggers two times OnConversation event which causes every creature nerby shouter to attack caster. Even single spell like fireball can cause lag for whole minute if the spell hits 100 enemies. And this is even worse with AOE spells.

I found no other solution than disable the silent shouts in SpellCast event which unfortunately results into non-reaction in situation where caster cast a spellll and hit only single enemy. Other will then not respond to the spell being cast, only to the vision.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Help understanding a script.
« Reply #64 on: December 03, 2011, 11:42:07 pm »


               

ShaDoOoW wrote...

But the latest script should be reliable in 99% cases.

The issue that does these lags is "cross-shouts". If there is a spell with larger are of effect which hits in one cast multiple enemies, then every enemy hit triggers OnSpellCastAt event which triggers two times OnConversation event which causes every creature nerby shouter to attack caster. Even single spell like fireball can cause lag for whole minute if the spell hits 100 enemies. And this is even worse with AOE spells.

I found no other solution than disable the silent shouts in SpellCast event which unfortunately results into non-reaction in situation where caster cast a spellll and hit only single enemy. Other will then not respond to the spell being cast, only to the vision.


As an aside, acaos cut most (like 90%) of our silent shouts out, as they are mostly useless overhead. That's something else you could look at for your patch.

Funky