Rework buff duration formulas

These are derived from the client

SE_IllusionPresistence will also set the duration to 10k tics like live
This commit is contained in:
Michael Cook (mackal) 2015-05-23 02:20:36 -04:00
parent 351e63ae72
commit 8aadc36320
16 changed files with 116 additions and 120 deletions

View File

@ -553,7 +553,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
/*020*/
@ -566,7 +566,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;
@ -584,14 +584,8 @@ struct BuffRemoveRequest_Struct
struct PetBuff_Struct {
/*000*/ uint32 petid;
/*004*/ uint32 spellid[BUFF_COUNT];
/*104*/ uint32 unknown700;
/*108*/ uint32 unknown701;
/*112*/ uint32 unknown702;
/*116*/ uint32 unknown703;
/*120*/ uint32 unknown704;
/*124*/ uint32 ticsremaining[BUFF_COUNT];
/*224*/ uchar unknown705[20];
/*004*/ uint32 spellid[BUFF_COUNT+5];
/*124*/ int32 ticsremaining[BUFF_COUNT+5];
/*244*/ uint32 buffcount;
};
@ -4036,7 +4030,7 @@ struct MarkNPC_Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ uint32 tics_remaining[BUFF_COUNT];
/*100*/ int32 tics_remaining[BUFF_COUNT];
};
struct RaidGeneral_Struct {
@ -4737,7 +4731,7 @@ struct BuffIconEntry_Struct
{
uint32 buff_slot;
uint32 spell_id;
uint32 tics_remaining;
int32 tics_remaining;
uint32 num_hits;
};

View File

@ -687,7 +687,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ uint32 duration;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@ -703,7 +703,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@ -720,7 +720,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@ -736,7 +736,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@ -2473,7 +2473,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {

View File

@ -676,7 +676,7 @@ struct SpellBuff_Struct
/*005*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*009*/ uint32 unknown016;
/*013*/ uint8 bard_modifier;
/*014*/ uint32 duration;
/*014*/ int32 duration;
/*018*/ uint8 level;
/*019*/ uint32 spellid;
/*023*/ uint32 counters;
@ -692,7 +692,7 @@ struct SpellBuff_Struct_Old
/*003*/ uint8 effect; // not real
/*004*/ float unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@ -709,7 +709,7 @@ struct SpellBuffFade_Struct_Live {
/*007*/ uint8 unknown007;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 playerId; // Global player ID?
/*024*/ uint32 num_hits;
/*028*/ uint8 unknown0028[64];
@ -725,7 +725,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 num_hits;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@ -2501,7 +2501,7 @@ struct GroupFollow_Struct { // Live Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*168*/ uint32 tics_remaining[BUFF_COUNT];
/*168*/ int32 tics_remaining[BUFF_COUNT];
};
struct LFG_Struct {

View File

@ -547,7 +547,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
@ -564,7 +564,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff

View File

@ -526,7 +526,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 unknown004; //Might need to be swapped with player_id
/*020*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
@ -543,7 +543,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 playerId; // Player id who cast the buff

View File

@ -445,7 +445,7 @@ struct SpellBuff_Struct
/*002*/ uint8 bard_modifier;
/*003*/ uint8 effect; //not real
/*004*/ uint32 spellid;
/*008*/ uint32 duration;
/*008*/ int32 duration;
/*012*/ uint32 counters;
/*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages
};
@ -457,7 +457,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; //prolly global player ID
/*024*/ uint32 slotid;

View File

@ -551,7 +551,7 @@ struct SpellBuff_Struct
/*003*/ uint8 effect; // not real
/*004*/ uint32 unknown004; // Seen 1 for no buff
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 player_id; // 'global' ID of the caster, for wearoff messages
/*024*/ uint32 counters;
@ -568,7 +568,7 @@ struct SpellBuffFade_Struct_Underfoot {
/*007*/ uint8 unknown7;
/*008*/ float unknown008;
/*012*/ uint32 spellid;
/*016*/ uint32 duration;
/*016*/ int32 duration;
/*020*/ uint32 num_hits;
/*024*/ uint32 playerId; // Global player ID?
/*028*/ uint32 unknown020;
@ -585,7 +585,7 @@ struct SpellBuffFade_Struct {
/*006*/ uint8 effect;
/*007*/ uint8 unknown7;
/*008*/ uint32 spellid;
/*012*/ uint32 duration;
/*012*/ int32 duration;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020; // Global player ID?
/*024*/ uint32 playerId; // Player id who cast the buff
@ -2188,7 +2188,7 @@ struct GroupFollow_Struct { // Underfoot Follow Struct
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
/*120*/ uint32 tics_remaining[BUFF_COUNT];
/*120*/ int32 tics_remaining[BUFF_COUNT];
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
};

View File

@ -30,7 +30,7 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9078
#define CURRENT_BINARY_DATABASE_VERSION 9079
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
#ifndef WIN32

View File

@ -332,6 +332,7 @@
9076|2015_02_04_average_coin.sql|SHOW COLUMNS FROM `loottable` WHERE Field = 'avgcoin'|contains|smallint
9077|2015_02_12_zone_gravity.sql|SHOW COLUMNS FROM `zone` LIKE 'gravity'|empty|
9078|2015_05_20_BuffInstrumentMod.sql|SHOW COLUMNS FROM `character_buffs` LIKE 'instrument_mod'|empty|
9079|2015_05_23_BuffDurations.sql|SHOW COLUMNS FROM `character_buffs` LIKE 'ticsremaining'|contains|unsigned|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,2 @@
ALTER TABLE `character_buffs` CHANGE COLUMN `ticsremaining` `ticsremaining` INT(11) SIGNED NOT NULL;
ALTER TABLE `merc_buffs` CHANGE COLUMN `TicsRemaining` `TicsRemaining` INT(11) SIGNED NOT NULL DEFAULT 0;

View File

@ -1473,7 +1473,7 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
}
void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *new_bonus, uint16 casterId,
uint8 WornType, uint32 ticsremaining, int buffslot, int instrument_mod,
uint8 WornType, int32 ticsremaining, int buffslot, int instrument_mod,
bool IsAISpellEffect, uint16 effect_id, int32 se_base, int32 se_limit, int32 se_max)
{
int i, effect_value, base2, max, effectid;

View File

@ -89,7 +89,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
if (IsClient() && GetClass() == WIZARD)
ratio += RuleI(Spells, WizCritRatio); //Default is zero
if (Critical){
value = value_BaseEffect*ratio/100;
@ -172,7 +172,7 @@ int32 Mob::GetActDoTDamage(uint16 spell_id, int32 value, Mob* target) {
value += int(value_BaseEffect*GetFocusEffect(focusImprovedDamage, spell_id)/100)*ratio/100;
value += int(value_BaseEffect*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
value += int(value_BaseEffect*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
extra_dmg = target->GetFcDamageAmtIncoming(this, spell_id) +
int(GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100) +
GetFocusEffect(focusFcDamageAmt, spell_id);
@ -219,11 +219,11 @@ int32 Mob::GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_s
total_cast_time = spells[spell_id].recovery_time + spells[spell_id].cast_time;
if (total_cast_time > 0 && total_cast_time <= 2500)
extra_spell_amt = extra_spell_amt*25/100;
else if (total_cast_time > 2500 && total_cast_time < 7000)
extra_spell_amt = extra_spell_amt*(167*((total_cast_time - 1000)/1000)) / 1000;
else
extra_spell_amt = extra_spell_amt * total_cast_time / 7000;
extra_spell_amt = extra_spell_amt*25/100;
else if (total_cast_time > 2500 && total_cast_time < 7000)
extra_spell_amt = extra_spell_amt*(167*((total_cast_time - 1000)/1000)) / 1000;
else
extra_spell_amt = extra_spell_amt * total_cast_time / 7000;
if(extra_spell_amt*2 < base_spell_dmg)
return 0;
@ -281,7 +281,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
if (Critical) {
entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits,
OTHER_CRIT_HEAL, GetName(), itoa(value));
if (IsClient())
Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value));
}
@ -413,6 +413,10 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
{
if ((aabonuses.IllusionPersistence || spellbonuses.IllusionPersistence || itembonuses.IllusionPersistence) &&
IsEffectInSpell(spell_id, SE_Illusion))
return 10000; // ~16h
if (spells[spell_id].not_extendable)
return duration;
@ -771,7 +775,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
}
} else {
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
if (spells[spell_id].aemaxtargets && iCounter < spells[spell_id].aemaxtargets)
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
if (!spells[spell_id].aemaxtargets)
caster->SpellOnTarget(spell_id, curmob, false, true, resist_adjust);
@ -859,7 +863,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
if (!center->CheckLosFN(curmob))
continue;
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// See notes in AESpell() above for more info.
// See notes in AESpell() above for more info.
if (caster->IsAttackAllowed(curmob, true))
continue;
if (caster->CheckAggro(curmob))

View File

@ -200,7 +200,7 @@ public:
bool IsBeneficialAllowed(Mob *target);
virtual int GetCasterLevel(uint16 spell_id);
void ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterID = 0,
uint8 WornType = 0, uint32 ticsremaining = 0, int buffslot = -1, int instrument_mod = 10,
uint8 WornType = 0, int32 ticsremaining = 0, int buffslot = -1, int instrument_mod = 10,
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
void NegateSpellsBonuses(uint16 spell_id);
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);

View File

@ -83,7 +83,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(c_override)
{
int durat = CalcBuffDuration(caster, this, spell_id, caster_level);
if(durat > 0)
if(durat) // negatives are perma buffs
{
buffslot = AddBuff(caster, spell_id, durat, caster_level);
if(buffslot == -1) // stacking failure
@ -3366,7 +3366,7 @@ void Mob::BuffProcess()
if(buffs[buffs_i].spellid == SPELL_UNKNOWN)
continue;
if(spells[buffs[buffs_i].spellid].buffdurationformula != DF_Permanent)
if(buffs[buffs_i].ticsremaining > 0) // perma buffs will either be -1 or -4
{
if(!zone->BuffTimersSuspended() || !IsSuspendableSpell(buffs[buffs_i].spellid))
{

View File

@ -2630,80 +2630,75 @@ int Mob::CalcBuffDuration(Mob *caster, Mob *target, uint16 spell_id, int32 caste
Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Casting level %d, formula %d, base_duration %d: result %d",
spell_id, castlevel, formula, duration, res);
return(res);
return res;
}
// the generic formula calculations
int CalcBuffDuration_formula(int level, int formula, int duration)
{
int i; // temp variable
int temp;
switch(formula)
{
case 0: // not a buff
return 0;
case 1:
i = (int)ceil(level / 2.0f);
return i < duration ? (i < 1 ? 1 : i) : duration;
case 2:
i = (int)ceil(level / 5.0f * 3);
return i < duration ? (i < 1 ? 1 : i) : duration;
case 3:
i = level * 30;
return i < duration ? (i < 1 ? 1 : i) : duration;
case 4: // only used by 'LowerElement'
return ((duration != 0) ? duration : 50);
case 5:
i = duration;
// 0 value results in a 3 tick spell, else its between 1-3 ticks.
return i < 3 ? (i < 1 ? 3 : i) : 3;
case 6:
i = (int)ceil(level / 2.0f);
return i < duration ? (i < 1 ? 1 : i) : duration;
case 7:
i = level;
return (duration == 0) ? (i < 1 ? 1 : i) : duration;
case 8:
i = level + 10;
return i < duration ? (i < 1 ? 1 : i) : duration;
case 9:
i = level * 2 + 10;
return i < duration ? (i < 1 ? 1 : i) : duration;
case 10:
i = level * 3 + 10;
return i < duration ? (i < 1 ? 1 : i) : duration;
case 11:
return std::min((level + 3) * 30, duration);
case 12:
case 13:
case 14:
case 15: // Don't know what the real formula for this should be. Used by Skinspikes potion.
return duration;
case 50: // Permanent. Cancelled by casting/combat for perm invis, non-lev zones for lev, curing poison/curse counters, etc.
return 72000; // 5 days until better method to make permanent
//case 51: // Permanent. Cancelled when out of range of aura. Placeholder until appropriate duration identified.
case 3600:
return duration ? duration : 3600;
default:
Log.Out(Logs::General, Logs::None, "CalcBuffDuration_formula: unknown formula %d", formula);
switch (formula) {
case 1:
temp = level > 3 ? level / 2 : 1;
break;
case 2:
temp = level > 3 ? level / 2 + 5 : 6;
break;
case 3:
temp = 30 * level;
break;
case 4: // only used by 'LowerElement'
temp = 50;
break;
case 5:
temp = 2;
break;
case 6:
temp = level / 2 + 2;
break;
case 7:
temp = level;
break;
case 8:
temp = level + 10;
break;
case 9:
temp = 2 * level + 10;
break;
case 10:
temp = 3 * level + 10;
break;
case 11:
temp = 30 * (level + 3);
break;
case 12:
temp = level > 7 ? level / 4 : 1;
break;
case 13:
temp = 4 * level + 10;
break;
case 14:
temp = 5 * (level + 2);
break;
case 15:
temp = 10 * (level + 10);
break;
case 50: // Permanent. Cancelled by casting/combat for perm invis, non-lev zones for lev, curing poison/curse
// counters, etc.
return -1;
case 51: // Permanent. Cancelled when out of range of aura.
return -4;
default:
// the client function has another bool parameter that if true returns -2 -- unsure
if (formula < 200)
return 0;
temp = formula;
break;
}
if (duration && duration < temp)
temp = duration;
return temp;
}
// helper function for AddBuff to determine stacking
@ -3066,7 +3061,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
if (duration == 0) {
duration = CalcBuffDuration(caster, this, spell_id);
if (caster)
if (caster && duration > 0) // negatives are perma buffs
duration = caster->GetActSpellDuration(spell_id, duration);
}

View File

@ -2504,7 +2504,7 @@ void ZoneDatabase::SaveMercBuffs(Merc *merc) {
"TicsRemaining, PoisonCounters, DiseaseCounters, CurseCounters, "
"CorruptionCounters, HitCount, MeleeRune, MagicRune, dot_rune, "
"caston_x, Persistent, caston_y, caston_z, ExtraDIChance) "
"VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %i, %u, %i, %i, %i);",
"VALUES (%u, %u, %u, %u, %u, %d, %u, %u, %u, %u, %u, %u, %u, %i, %u, %i, %i, %i);",
merc->GetMercID(), buffs[buffCount].spellid, buffs[buffCount].casterlevel,
spells[buffs[buffCount].spellid].buffdurationformula, buffs[buffCount].ticsremaining,
CalculatePoisonCounters(buffs[buffCount].spellid) > 0 ? buffs[buffCount].counters : 0,
@ -2982,7 +2982,7 @@ void ZoneDatabase::SaveBuffs(Client *client) {
"caster_level, caster_name, ticsremaining, counters, numhits, melee_rune, "
"magic_rune, persistent, dot_rune, caston_x, caston_y, caston_z, ExtraDIChance, "
"instrument_mod) "
"VALUES('%u', '%u', '%u', '%u', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', "
"VALUES('%u', '%u', '%u', '%u', '%s', '%d', '%u', '%u', '%u', '%u', '%u', '%u', "
"'%i', '%i', '%i', '%i', '%i')", client->CharacterID(), index, buffs[index].spellid,
buffs[index].casterlevel, buffs[index].caster_name, buffs[index].ticsremaining,
buffs[index].counters, buffs[index].numhits, buffs[index].melee_rune,
@ -3023,7 +3023,7 @@ void ZoneDatabase::LoadBuffs(Client *client)
Client *caster = entity_list.GetClientByName(row[3]);
uint32 caster_level = atoi(row[2]);
uint32 ticsremaining = atoul(row[4]);
int32 ticsremaining = atoi(row[4]);
uint32 counters = atoul(row[5]);
uint32 numhits = atoul(row[6]);
uint32 melee_rune = atoul(row[7]);
@ -3128,12 +3128,12 @@ void ZoneDatabase::SavePetInfo(Client *client)
query = StringFormat("INSERT INTO `character_pet_buffs` "
"(`char_id`, `pet`, `slot`, `spell_id`, `caster_level`, "
"`ticsremaining`, `counters`) "
"VALUES (%u, %u, %u, %u, %u, %u, %d)",
"VALUES (%u, %u, %u, %u, %u, %d, %d)",
client->CharacterID(), pet, index, petinfo->Buffs[index].spellid,
petinfo->Buffs[index].level, petinfo->Buffs[index].duration,
petinfo->Buffs[index].counters);
else
query += StringFormat(", (%u, %u, %u, %u, %u, %u, %d)",
query += StringFormat(", (%u, %u, %u, %u, %u, %d, %d)",
client->CharacterID(), pet, index, petinfo->Buffs[index].spellid,
petinfo->Buffs[index].level, petinfo->Buffs[index].duration,
petinfo->Buffs[index].counters);
@ -3238,7 +3238,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) {
uint32 caster_level = atoi(row[3]);
int caster_id = 0;
// The castername field is currently unused
uint32 ticsremaining = atoul(row[5]);
int32 ticsremaining = atoi(row[5]);
uint32 counters = atoul(row[6]);
pi->Buffs[slot_id].spellid = spell_id;