Merge git://github.com/EQEmu/Server into Development

This commit is contained in:
KayenEQ
2014-10-05 07:49:20 -04:00
23 changed files with 249 additions and 223 deletions
+9 -13
View File
@@ -1751,19 +1751,15 @@ void ZoneDatabase::FillAAEffects(SendAA_Struct* aa_struct){
if(!aa_struct)
return;
std::string query = StringFormat("SELECT effectid, base1, base2, slot from aa_effects where aaid=%i order by slot asc", aa_struct->id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Client::FillAAEffects query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
int index = 0;
for (auto row = results.begin(); row != results.end(); ++row, ++index) {
aa_struct->abilities[index].skill_id=atoi(row[0]);
aa_struct->abilities[index].base1=atoi(row[1]);
aa_struct->abilities[index].base2=atoi(row[2]);
aa_struct->abilities[index].slot=atoi(row[3]);
auto it = aa_effects.find(aa_struct->id);
if (it != aa_effects.end()) {
for (int slot = 0; slot < aa_struct->total_abilities; slot++) {
// aa_effects is a map of a map, so the slot reference does not start at 0
aa_struct->abilities[slot].skill_id = it->second[slot + 1].skill_id;
aa_struct->abilities[slot].base1 = it->second[slot + 1].base1;
aa_struct->abilities[slot].base2 = it->second[slot + 1].base2;
aa_struct->abilities[slot].slot = it->second[slot + 1].slot;
}
}
}
+8 -18
View File
@@ -39,15 +39,10 @@
extern volatile bool RunLoops;
#include "../common/features.h"
#include "masterentity.h"
#include "worldserver.h"
#include "../common/misc.h"
#include "zonedb.h"
#include "../common/spdat.h"
#include "net.h"
#include "../common/packet_dump.h"
#include "../common/packet_functions.h"
#include "petitions.h"
#include "../common/serverinfo.h"
#include "../common/zone_numbers.h"
#include "../common/moremath.h"
@@ -55,6 +50,12 @@ extern volatile bool RunLoops;
#include "../common/breakdowns.h"
#include "../common/rulesys.h"
#include "../common/string_util.h"
#include "../common/data_verification.h"
#include "net.h"
#include "masterentity.h"
#include "worldserver.h"
#include "zonedb.h"
#include "petitions.h"
#include "forage.h"
#include "command.h"
#include "string_ids.h"
@@ -594,19 +595,8 @@ bool Client::Save(uint8 iCommitNow) {
database.SaveCharacterTribute(this->CharacterID(), &m_pp);
SaveTaskState(); /* Save Character Task */
if(m_pp.hunger_level < 0) {
m_pp.hunger_level = 0;
}
else if(m_pp.hunger_level > 6000) {
m_pp.hunger_level = 6000;
}
if(m_pp.thirst_level < 0) {
m_pp.thirst_level = 0;
}
else if(m_pp.thirst_level > 6000) {
m_pp.thirst_level = 6000;
}
m_pp.hunger_level = EQEmu::Clamp(m_pp.hunger_level, 0, 50000);
m_pp.thirst_level = EQEmu::Clamp(m_pp.thirst_level, 0, 50000);
database.SaveCharacterData(this->CharacterID(), this->AccountID(), &m_pp, &m_epp); /* Save Character Data */
return true;
+2 -1
View File
@@ -896,7 +896,8 @@ public:
//This is used to later set the buff duration of the spell, in slot to duration.
//Doesn't appear to work directly after the client recieves an action packet.
void SendBuffDurationPacket(uint16 spell_id, int duration, int inlevel);
void SendBuffDurationPacket(Buffs_Struct &buff);
void SendBuffNumHitPacket(Buffs_Struct &buff, int slot);
void ProcessInspectRequest(Client* requestee, Client* requester);
bool ClientFinishedLoading() { return (conn_state == ClientConnectFinished); }
+31 -39
View File
@@ -3395,7 +3395,7 @@ void Mob::BuffProcess()
{
if(buffs[buffs_i].UpdateClient == true)
{
CastToClient()->SendBuffDurationPacket(buffs[buffs_i].spellid, buffs[buffs_i].ticsremaining, buffs[buffs_i].casterlevel);
CastToClient()->SendBuffDurationPacket(buffs[buffs_i]);
buffs[buffs_i].UpdateClient = false;
}
}
@@ -5559,64 +5559,56 @@ void Mob::CheckNumHitsRemaining(uint8 type, uint32 buff_slot, uint16 spell_id)
uint32 buff_max = GetMaxTotalSlots();
//Spell specific procs [Type 7,10,11]
if (IsValidSpell(spell_id)){
for(uint32 d = 0; d < buff_max; d++) {
if((buffs[d].spellid == spell_id) && (buffs[d].numhits > 0) && (spells[buffs[d].spellid].numhitstype == type)){
if(--buffs[d].numhits == 0) {
if (IsValidSpell(spell_id)) {
for (uint32 d = 0; d < buff_max; d++) {
if (buffs[d].spellid == spell_id && buffs[d].numhits > 0 &&
spells[buffs[d].spellid].numhitstype == type) {
if (--buffs[d].numhits == 0) {
CastOnNumHitFade(buffs[d].spellid);
if(!TryFadeEffect(d))
if (!TryFadeEffect(d))
BuffFadeBySlot(d, true);
} else if (IsClient()) { // still have numhits and client, update
CastToClient()->SendBuffNumHitPacket(buffs[d], d);
}
}
}
}
else if (type == 7){
if (buff_slot > 0){
if(--buffs[buff_slot].numhits == 0) {
} else if (type == 7) {
if (buff_slot > 0) {
if (--buffs[buff_slot].numhits == 0) {
CastOnNumHitFade(buffs[buff_slot].spellid);
if(!TryFadeEffect(buff_slot))
if (!TryFadeEffect(buff_slot))
BuffFadeBySlot(buff_slot , true);
}
} else if (IsClient()) { // still have numhits and client, update
CastToClient()->SendBuffNumHitPacket(buffs[buff_slot], buff_slot);
}
else {
for(int d = 0; d < buff_max; d++) {
if(!m_spellHitsLeft[d])
} else {
for (int d = 0; d < buff_max; d++) {
if (!m_spellHitsLeft[d])
continue;
if ((IsValidSpell(buffs[d].spellid)) && (m_spellHitsLeft[d] == buffs[d].spellid)) {
if(--buffs[d].numhits == 0) {
if (IsValidSpell(buffs[d].spellid) && m_spellHitsLeft[d] == buffs[d].spellid) {
if (--buffs[d].numhits == 0) {
CastOnNumHitFade(buffs[d].spellid);
m_spellHitsLeft[d] = 0;
if(!TryFadeEffect(d))
if (!TryFadeEffect(d))
BuffFadeBySlot(d, true);
} else if (IsClient()) { // still have numhits and client, update
CastToClient()->SendBuffNumHitPacket(buffs[d], d);
}
}
}
}
}
else{
for(uint32 d = 0; d < buff_max; d++) {
if((IsValidSpell(buffs[d].spellid)) && (buffs[d].numhits > 0) && (spells[buffs[d].spellid].numhitstype == type)){
if(--buffs[d].numhits == 0) {
} else {
for (uint32 d = 0; d < buff_max; d++) {
if (IsValidSpell(buffs[d].spellid) && buffs[d].numhits > 0 &&
spells[buffs[d].spellid].numhitstype == type) {
if (--buffs[d].numhits == 0) {
CastOnNumHitFade(buffs[d].spellid);
if(!TryFadeEffect(d)){
if (!TryFadeEffect(d))
BuffFadeBySlot(d, true);
}
} else if (IsClient()) { // still have numhits and client, update
CastToClient()->SendBuffNumHitPacket(buffs[d], d);
}
}
}
}
+36 -21
View File
@@ -484,19 +484,6 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
return false;
}
// This needs a bit more work for saving timer to PP for zoning etc
if (IsClient() && item_slot != INVALID_INDEX && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT))) {
ItemInst *itm = CastToClient()->GetInv().GetItem(item_slot);
if (itm && itm->GetItem()->RecastDelay) {
outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
ird->recast_delay = itm->GetItem()->RecastDelay;
ird->recast_type = itm->GetItem()->RecastType;
CastToClient()->QueuePacket(outapp);
safe_delete(outapp);
}
}
return(true);
}
@@ -2228,6 +2215,12 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot);
if(itm && itm->GetItem()->RecastDelay > 0){
CastToClient()->GetPTimers().Start((pTimerItemStart + itm->GetItem()->RecastType), itm->GetItem()->RecastDelay);
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ItemRecastDelay, sizeof(ItemRecastDelay_Struct));
ItemRecastDelay_Struct *ird = (ItemRecastDelay_Struct *)outapp->pBuffer;
ird->recast_delay = itm->GetItem()->RecastDelay;
ird->recast_type = itm->GetItem()->RecastType;
CastToClient()->QueuePacket(outapp);
safe_delete(outapp);
}
}
@@ -5164,20 +5157,40 @@ void Mob::_StopSong()
//Thus I use this in the buff process to update the correct duration once after casting
//this allows AAs and focus effects that increase buff duration to work correctly, but could probably
//be used for other things as well
void Client::SendBuffDurationPacket(uint16 spell_id, int duration, int inlevel)
void Client::SendBuffDurationPacket(Buffs_Struct &buff)
{
EQApplicationPacket* outapp;
outapp = new EQApplicationPacket(OP_Buff, sizeof(SpellBuffFade_Struct));
SpellBuffFade_Struct* sbf = (SpellBuffFade_Struct*) outapp->pBuffer;
sbf->entityid = GetID();
sbf->slot=2;
sbf->spellid=spell_id;
sbf->slotid=0;
sbf->effect = inlevel > 0 ? inlevel : GetLevel();
sbf->level = inlevel > 0 ? inlevel : GetLevel();
sbf->slot = 2;
sbf->spellid = buff.spellid;
sbf->slotid = 0;
sbf->effect = buff.casterlevel > 0 ? buff.casterlevel : GetLevel();
sbf->level = buff.casterlevel > 0 ? buff.casterlevel : GetLevel();
sbf->bufffade = 0;
sbf->duration = duration;
sbf->duration = buff.ticsremaining;
sbf->num_hits = buff.numhits;
FastQueuePacket(&outapp);
}
void Client::SendBuffNumHitPacket(Buffs_Struct &buff, int slot)
{
// UF+ use this packet
if (GetClientVersion() < EQClientUnderfoot)
return;
EQApplicationPacket *outapp;
outapp = new EQApplicationPacket(OP_BuffCreate, sizeof(BuffIcon_Struct) + sizeof(BuffIconEntry_Struct));
BuffIcon_Struct *bi = (BuffIcon_Struct *)outapp->pBuffer;
bi->entity_id = GetID();
bi->count = 1;
bi->all_buffs = 0;
bi->entries[0].buff_slot = slot;
bi->entries[0].spell_id = buff.spellid;
bi->entries[0].tics_remaining = buff.ticsremaining;
bi->entries[0].num_hits = buff.numhits;
FastQueuePacket(&outapp);
}
@@ -5252,6 +5265,7 @@ EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target)
BuffIcon_Struct *buff = (BuffIcon_Struct*)outapp->pBuffer;
buff->entity_id = GetID();
buff->count = count;
buff->all_buffs = 1;
uint32 index = 0;
for(unsigned int i = 0; i < buff_count; ++i)
@@ -5261,6 +5275,7 @@ EQApplicationPacket *Mob::MakeBuffsPacket(bool for_target)
buff->entries[index].buff_slot = i;
buff->entries[index].spell_id = buffs[i].spellid;
buff->entries[index].tics_remaining = buffs[i].ticsremaining;
buff->entries[index].num_hits = buffs[i].numhits;
++index;
}
}
@@ -5278,7 +5293,7 @@ void Mob::BuffModifyDurationBySpellID(uint16 spell_id, int32 newDuration)
buffs[i].ticsremaining = newDuration;
if(IsClient())
{
CastToClient()->SendBuffDurationPacket(buffs[i].spellid, buffs[i].ticsremaining, buffs[i].casterlevel);
CastToClient()->SendBuffDurationPacket(buffs[i]);
}
}
}
+57 -79
View File
@@ -2895,96 +2895,74 @@ void ZoneDatabase::LoadBuffs(Client *client) {
}
}
void ZoneDatabase::SavePetInfo(Client *client) {
void ZoneDatabase::SavePetInfo(Client *client)
{
PetInfo *petinfo = nullptr;
PetInfo *petinfo = client->GetPetInfo(0);
PetInfo *suspended = client->GetPetInfo(1);
std::string query = StringFormat("DELETE FROM `character_pet_buffs` WHERE `char_id` = %u", client->CharacterID());
auto results = database.QueryDatabase(query);
if(!results.Success())
std::string query = StringFormat("DELETE FROM `character_pet_buffs` WHERE `char_id` = %u", client->CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
return;
query = StringFormat("DELETE FROM `character_pet_buffs` WHERE `char_id` = %u", client->CharacterID());
query = StringFormat("DELETE FROM `character_pet_inventory` WHERE `char_id` = %u", client->CharacterID());
results = database.QueryDatabase(query);
if(!results.Success())
if (!results.Success())
return;
query = StringFormat("INSERT INTO `character_pet_info` "
"(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`) "
"VALUES (%u, 0, '%s', %i, %u, %u, %u, %f) "
"ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, "
"`hp` = %u, `mana` = %u, `size` = %f",
client->CharacterID(), petinfo->Name, petinfo->petpower, petinfo->SpellID,
petinfo->HP, petinfo->Mana, petinfo->size, petinfo->Name, petinfo->petpower,
petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size);
results = database.QueryDatabase(query);
if(!results.Success())
return;
for (int pet = 0; pet < 2; pet++) {
petinfo = client->GetPetInfo(pet);
if (!petinfo)
continue;
for(int index = 0; index < RuleI(Spells, MaxTotalSlotsPET); index++) {
if (petinfo->Buffs[index].spellid == SPELL_UNKNOWN || petinfo->Buffs[index].spellid == 0)
continue;
query = StringFormat("INSERT INTO `character_pet_info` "
"(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`) "
"VALUES (%u, %u, '%s', %i, %u, %u, %u, %f) "
"ON DUPLICATE KEY UPDATE `petname` = '%s', `petpower` = %i, `spell_id` = %u, "
"`hp` = %u, `mana` = %u, `size` = %f",
client->CharacterID(), pet, petinfo->Name, petinfo->petpower, petinfo->SpellID,
petinfo->HP, petinfo->Mana, petinfo->size, // and now the ON DUPLICATE ENTRIES
petinfo->Name, petinfo->petpower, petinfo->SpellID, petinfo->HP, petinfo->Mana, petinfo->size);
results = database.QueryDatabase(query);
if (!results.Success())
return;
query.clear();
query = StringFormat("INSERT INTO `character_pet_buffs` "
"(`char_id`, `pet`, `slot`, `spell_id`, `caster_level`, "
"`ticsremaining`, `counters`) "
"VALUES (%u, 0, %u, %u, %u, %u, %d)",
client->CharacterID(), index, petinfo->Buffs[index].spellid,
petinfo->Buffs[index].level, petinfo->Buffs[index].duration,
petinfo->Buffs[index].counters);
database.QueryDatabase(query);
}
// pet buffs!
for (int index = 0; index < RuleI(Spells, MaxTotalSlotsPET); index++) {
if (petinfo->Buffs[index].spellid == SPELL_UNKNOWN || petinfo->Buffs[index].spellid == 0)
continue;
if (query.length() == 0)
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)",
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)",
client->CharacterID(), pet, index, petinfo->Buffs[index].spellid,
petinfo->Buffs[index].level, petinfo->Buffs[index].duration,
petinfo->Buffs[index].counters);
}
database.QueryDatabase(query);
query.clear();
for(int index = 0; index < RuleI(Spells, MaxTotalSlotsPET); index++) {
if (petinfo->Buffs[index].spellid == SPELL_UNKNOWN || petinfo->Buffs[index].spellid == 0)
continue;
// pet inventory!
for (int index = EmuConstants::EQUIPMENT_BEGIN; index <= EmuConstants::EQUIPMENT_END; index++) {
if (!petinfo->Items[index])
continue;
query = StringFormat("INSERT INTO `character_pet_buffs` "
"(`char_id`, `pet`, `slot`, `spell_id`, `caster_level`, "
"`ticsremaining`, `counters`) "
"VALUES (%u, 1, %u, %u, %u, %u, %d)",
client->CharacterID(), index, suspended->Buffs[index].spellid,
suspended->Buffs[index].level, suspended->Buffs[index].duration,
suspended->Buffs[index].counters);
database.QueryDatabase(query);
if (query.length() == 0)
query = StringFormat("INSERT INTO `character_pet_inventory` "
"(`char_id`, `pet`, `slot`, `item_id`) "
"VALUES (%u, %u, %u, %u)",
client->CharacterID(), pet, index, petinfo->Items[index]);
else
query += StringFormat(", (%u, %u, %u, %u)", client->CharacterID(), pet, index, petinfo->Items[index]);
}
database.QueryDatabase(query);
}
for (int index = EmuConstants::EQUIPMENT_BEGIN; index <= EmuConstants::EQUIPMENT_END; index++) {
if(!petinfo->Items[index])
continue;
query = StringFormat("INSERT INTO `character_pet_inventory` "
"(`char_id`, `pet`, `slot`, `item_id`) "
"VALUES (%u, 0, %u, %u)",
client->CharacterID(), index, petinfo->Items[index]);
database.QueryDatabase(query);
}
query = StringFormat("INSERT INTO `character_pet_info` "
"(`char_id`, `pet`, `petname`, `petpower`, `spell_id`, `hp`, `mana`, `size`) "
"VALUES (%u, 1, '%s', %u, %u, %u, %u, %f) "
"ON DUPLICATE KEY UPDATE "
"`petname`='%s', `petpower`=%i, `spell_id`=%u, `hp`=%u, `mana`=%u, `size`=%f",
client->CharacterID(), suspended->Name, suspended->petpower, suspended->SpellID,
suspended->HP, suspended->Mana, suspended->size, suspended->Name, suspended->petpower,
suspended->SpellID, suspended->HP, suspended->Mana, suspended->size);
results = database.QueryDatabase(query);
if(!results.Success())
return;
for (int index = EmuConstants::EQUIPMENT_BEGIN; index <= EmuConstants::EQUIPMENT_END; index++) {
if(!suspended->Items[index])
continue;
query = StringFormat("INSERT INTO `character_pet_inventory` "
"(`char_id`, `pet`, `slot`, `item_id`) "
"VALUES (%u, 1, %u, %u)",
client->CharacterID(), index, suspended->Items[index]);
database.QueryDatabase(query);
}
}
void ZoneDatabase::RemoveTempFactions(Client *client) {