PDA

View Full Version : Proc spells don't work after zoning


AndMetal
08-22-2008, 06:00 AM
Discussion: http://eqemulator.net/forums/showthread.php?t=26307

There's a section of code in client_packet.cpp where it finishes connecting. Search for SE_Illusion, it basically reapplies spells that have specific effects that aren't passive stats when you zone in, think illusion, levitate, etc. It sounds like they're not being reapplied correctly and that's where I'd look first.

It looks like this is the snippet you're talking about:
zone/client_packet.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/client_packet.cpp?revision=1.82&view=markup#l_6702)

6702 //reapply some buffs
6703 for (uint32 j1=0; j1 < BUFF_COUNT; j1++) {
6704 if (buffs[j1].spellid > (int32)SPDAT_RECORDS)
6705 continue;
6706
6707 const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid];
6708
6709 for (int x1=0; x1 < EFFECT_COUNT; x1++) {
6710 switch (spell.effectid[x1]) {
6711 case SE_Illusion: {
6712 if (spell.base[x1] == -1) {
6713 if (gender == 1)
6714 gender = 0;
6715 else if (gender == 0)
6716 gender = 1;
6717 SendIllusionPacket(GetRace(), gender, 0xFFFF, 0xFFFF);
6718 }
6719 else if (spell.base[x1] == -2)
6720 {
6721 if (GetRace() == 128 || GetRace() == 130 || GetRace() <= 12)
6722 SendIllusionPacket(GetRace(), GetGender(), spell.max[x1], spell.max[x1]);
6723 }
6724 else if (spell.max[x1] > 0)
6725 {
6726 SendIllusionPacket(spell.base[x1], 0xFF, spell.max[x1], spell.max[x1]);
6727 }
6728 else
6729 {
6730 SendIllusionPacket(spell.base[x1], 0xFF, 0xFFFF, 0xFFFF);
6731 }
6732 switch(spell.base[x1]){
6733 case OGRE:
6734 SendAppearancePacket(AT_Size, 9);
6735 break;
6736 case TROLL:
6737 SendAppearancePacket(AT_Size, 8);
6738 break;
6739 case VAHSHIR:
6740 case FROGLOK:
6741 case BARBARIAN:
6742 SendAppearancePacket(AT_Size, 7);
6743 break;
6744 case HALF_ELF:
6745 case WOOD_ELF:
6746 case DARK_ELF:
6747 SendAppearancePacket(AT_Size, 5);
6748 break;
6749 case DWARF:
6750 SendAppearancePacket(AT_Size, 4);
6751 break;
6752 case HALFLING:
6753 case GNOME:
6754 SendAppearancePacket(AT_Size, 3);
6755 break;
6756 default:
6757 SendAppearancePacket(AT_Size, 6);
6758 break;
6759 }
6760 break;
6761 }
6762 case SE_SummonHorse: {
6763 SummonHorse(buffs[j1].spellid);
6764 //hasmount = true; //this was false, is that the correct thing?
6765 break;
6766 }
6767 case SE_Silence:
6768 {
6769 Silence(true);
6770 break;
6771 }
6772 case SE_DivineAura:
6773 {
6774 invulnerable = true;
6775 break;
6776 }
6777 case SE_Invisibility2:
6778 case SE_Invisibility:
6779 {
6780 invisible = true;
6781 SendAppearancePacket(AT_Invis, 1);
6782 break;
6783 }
6784 case SE_Levitate:
6785 {
6786 if( !zone->CanLevitate() )
6787 {
6788 if(!GetGM())
6789 {
6790 SendAppearancePacket(AT_Levitate, 0);
6791 BuffFadeByEffect(SE_Levitate);
6792 Message(13, "You can't levitate in this zone.");
6793 }
6794 }else{
6795 SendAppearancePacket(AT_Levitate, 2);
6796 }
6797 break;
6798 }
6799 case SE_InvisVsUndead2:
6800 case SE_InvisVsUndead:
6801 {
6802 invisible_undead = true;
6803 break;
6804 }
6805 case SE_InvisVsAnimals:
6806 {
6807 invisible_animals = true;
6808 break;
6809 }
6810 }
6811 }
6812 }


There isn't one currently there for proc types. Then again, I can't really think why we would want to put it there, since zone should be able to read through the buffs, see if there is currently one with a proc effect.

Digging deeper, there is a spell effect SE_WeaponProc defined in zone/spell_effects.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/spell_effects.cpp?revision=1.58&view=markup#l_1297):

52 bool Mob::SpellEffect(Mob* caster, int16 spell_id, float partial)
53 {

1297 case SE_WeaponProc:
1298 {
1299 uint16 procid = GetProcID(spell_id, i);
1300 #ifdef SPELL_EFFECT_SPAM
1301 snprintf(effect_desc, _EDLEN, "Weapon Proc: %s (id %d)", spells[effect_value].name, procid);
1302 #endif
1303
1304 AddProcToWeapon(procid);
1305 break;
1306 }

2406 }


2810 void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
2811 {

2830 case SE_WeaponProc:
2831 {
2832 uint16 procid = GetProcID(buffs[slot].spellid, i);
2833 RemoveProcFromWeapon(procid, false);
2834 break;
2835 }

3031 }


And seeing as how most of client_packet.cpp is the same as spell_effects.cpp, depending on what's being done, I would assume we could do this:
zone/client_packet.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/client_packet.cpp?revision=1.82&view=markup#l_6702)

case SE_InvisVsAnimals:
{
invisible_animals = true;
break;
}
case SE_WeaponProc:
{
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1));
break;
}


Does that sound about right?

AndMetal
09-07-2008, 05:00 AM
I finally had a chance to test this out and verified that this does work as expected. Looks like this is another one for the submission section :D

While I was at it, I was looking over some more of the Spell Effects, and it looks like there might be 1 more change that could help in the long run:
zone/client_packet.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/client_packet.cpp?revision=1.82&view=markup#l_6702)

for (int x1=0; x1 < EFFECT_COUNT; x1++) {
switch (spell.effectid[x1]) {
case SE_IllusionCopy:
case SE_Illusion: {


Nothing major, but could be an issue for some spells.