PDA

View Full Version : Group Based Rune


squevis667
06-20-2012, 08:47 PM
I was working on some custom spells. I wanted to make a group ward for shaman like in eq2. It throws up a short duration (30 sec) Rune for a certain amount. Whenever the total damage to all group members exceeds the amount of the rune, it wears off. So if only one person is getting beat on, they get the whole rune. Otherwise it is divvy'd up based on who is getting beat on.

I added this to spdat.cpp to help me identity whether or not a buff was a Group ward or not:
bool IsGroupWard(int16 spell_id)
{
switch(spell_id)
{
case 9827:
case 9830:
case 9831:
case 9833:
case 9834:
return true;
}
return false;
}

I added a function to spells.cpp for Mob::GetBuffSlotFromSpellID. I only added this because I did not see an apparent way to retrieve what slot contains the buff I want. (Note: this will only return the first instance of a buff slot with this spell id)


sint16 Mob::GetBuffSlotFromSpellID(int16 spell_id) {
uint32 buff_count = GetMaxTotalSlots();
for(int i = 0; i < buff_count; i++) {
if (buffs[i].spellid != SPELL_UNKNOWN) {
if (buffs[i].spellid == spell_id)
return i;
}
}
return -1;
}


I then went into attack.cpp, Mob::ReduceDamage and changed the function that handles runes from
slot = GetBuffSlotFromType(SE_Rune);
while(slot >= 0)
{
uint32 melee_rune_left = buffs[slot].melee_rune;
if(melee_rune_left >= damage)
{
melee_rune_left -= damage;
damage = -6;
buffs[slot].melee_rune = melee_rune_left;
Message(0, "Your group ward has %i points remaining.", melee_rune_left);
break;
}
else
{
if(melee_rune_left > 0)
damage -= melee_rune_left;
if(!TryFadeEffect(slot))
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_Rune);
UpdateRuneFlags();
}
}

to this
slot = GetBuffSlotFromType(SE_Rune);
while(slot >= 0)
{
// This code should apply the damage to the ward of everyone in the group whenever one person in the group takes damage
if(this->IsClient() && IsGroupWard(buffs[slot].spellid) && this->CastToClient()->GetGroup())
{
int groupWardSpellID = buffs[slot].spellid;
Mob* member;
for (int i = 0; i < this->CastToClient()->GetGroup()->GroupCount(); i++)
{
member = this->CastToClient()->GetGroup()->members[i];
if(member == this || !member->FindBuff(groupWardSpellID))
continue;
int _slot = member->GetBuffSlotFromSpellID(groupWardSpellID);

uint32 _melee_rune_left = member->buffs[_slot].melee_rune;
if(_melee_rune_left >= damage)
{
_melee_rune_left -= damage;
member->buffs[_slot].melee_rune = _melee_rune_left;
member->Message(0, "Your group ward has %i points remaining.", _melee_rune_left);
}
else
{
if(!member->TryFadeEffect(_slot))
member->BuffFadeBySlot(_slot);
member->UpdateRuneFlags();
}
}
}
uint32 melee_rune_left = buffs[slot].melee_rune;
if(melee_rune_left >= damage)
{
melee_rune_left -= damage;
damage = -6;
buffs[slot].melee_rune = melee_rune_left;
Message(0, "Your group ward has %i points remaining.", melee_rune_left);
break;
}
else
{
if(melee_rune_left > 0)
damage -= melee_rune_left;
if(!TryFadeEffect(slot))
BuffFadeBySlot(slot);
slot = GetBuffSlotFromType(SE_Rune);
UpdateRuneFlags();
}
}

It iterates through every group member, if they have that ward on them, it decreases their wards by the damage amount, and then moves on and adjusts it for the person actually attacked. To prevent any sort of exploitation, I am now working to add code that will strip the buff off anyone that leaves the shamans group.

Just thought I would share. If anyone knows a better way to handle this, please share.

rencro
02-09-2013, 12:50 PM
To get this to work I had to first decalre it in spdat.h and mob.h then I had to modify:

if(_melee_rune_left >= damage)
{
_melee_rune_left -= damage;
member->buffs[_slot].melee_rune = _melee_rune_left;
member->Message(0, "Your group ward has %i points remaining.", _melee_rune_left);
}



to

if(_melee_rune_left >= damage)
{
_melee_rune_left -= damage;
member->buffs[_slot].melee_rune = _melee_rune_left;
member->Message(0, "Your group ward has %i points remaining.", _melee_rune_left);
return -6;
}


as for removing the buff when shaman is not part of group, was thinking instead of doing the check in this code you could do it when DELMEMBER is called in group.cpp so it can effect multiple classes with multiple spells similar to how eq2 removes group buffs when that particular class is no longer in the group.

Drajor
02-10-2013, 09:18 AM
This is pretty cool! Do you have a server up?