Merge branch 'master' of github.com:EQEmu/Server

This commit is contained in:
KimLS 2014-11-08 15:18:52 -08:00
commit fe7774ab75
6 changed files with 51 additions and 53 deletions

View File

@ -1,5 +1,9 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) EQEMu Changelog (Started on Sept 24, 2003 15:50)
------------------------------------------------------- -------------------------------------------------------
== 11/06/2014 ==
demonstar55: Tracking default sort will now be correct order
Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone.
== 11/03/2014 == == 11/03/2014 ==
Secrets: Fixed an overflow in melee lifetap calculations (int16 vs int32) Secrets: Fixed an overflow in melee lifetap calculations (int16 vs int32)
Secrets: Fixed overflow on AC and ATK values that can go out of range. Secrets: Fixed overflow on AC and ATK values that can go out of range.

View File

@ -63,6 +63,7 @@ extern uint16 adverrornum;
Entity::Entity() Entity::Entity()
{ {
id = 0; id = 0;
spawn_timestamp = time(nullptr);
} }
Entity::~Entity() Entity::~Entity()
@ -2934,8 +2935,14 @@ void EntityList::SignalMobsByNPCID(uint32 snpc, int signal_id)
} }
} }
bool tracking_compare(const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b)
{
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
}
bool EntityList::MakeTrackPacket(Client *client) bool EntityList::MakeTrackPacket(Client *client)
{ {
std::list<std::pair<Mob *, float> > tracking_list;
uint32 distance = 0; uint32 distance = 0;
float MobDistance; float MobDistance;
@ -2950,60 +2957,42 @@ bool EntityList::MakeTrackPacket(Client *client)
if (distance < 300) if (distance < 300)
distance = 300; distance = 300;
uint32 spe= 0;
bool ret = false;
spe = mob_list.size() + 50;
uchar *buffer1 = new uchar[sizeof(Track_Struct)];
Track_Struct *track_ent = (Track_Struct*) buffer1;
uchar *buffer2 = new uchar[sizeof(Track_Struct)*spe];
Tracking_Struct *track_array = (Tracking_Struct*) buffer2;
memset(track_array, 0, sizeof(Track_Struct)*spe);
uint32 array_counter = 0;
Group *g = client->GetGroup(); Group *g = client->GetGroup();
auto it = mob_list.begin(); for (auto it = mob_list.cbegin(); it != mob_list.cend(); ++it) {
while (it != mob_list.end()) { if (!it->second || it->second == client || !it->second->IsTrackable())
if (it->second && ((MobDistance = it->second->DistNoZ(*client)) <= distance)) { continue;
if ((it->second != client) && it->second->IsTrackable()) {
memset(track_ent, 0, sizeof(Track_Struct));
Mob *cur_entity = it->second;
track_ent->entityid = cur_entity->GetID();
track_ent->distance = MobDistance;
track_ent->level = cur_entity->GetLevel();
track_ent->NPC = !cur_entity->IsClient();
if (g && cur_entity->IsClient() && g->IsGroupMember(cur_entity->CastToMob()))
track_ent->GroupMember = 1;
else
track_ent->GroupMember = 0;
strn0cpy(track_ent->name, cur_entity->GetName(), sizeof(track_ent->name));
memcpy(&track_array->Entrys[array_counter], track_ent, sizeof(Track_Struct));
array_counter++;
}
}
++it; MobDistance = it->second->DistNoZ(*client);
if (MobDistance > distance)
continue;
tracking_list.push_back(std::make_pair(it->second, MobDistance));
} }
if (array_counter <= spe) { tracking_list.sort(tracking_compare);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_Track,sizeof(Track_Struct)*(array_counter)); EQApplicationPacket *outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
memcpy(outapp->pBuffer, track_array,sizeof(Track_Struct)*(array_counter)); Tracking_Struct *outtrack = (Tracking_Struct *)outapp->pBuffer;
outapp->priority = 6; outapp->priority = 6;
client->QueuePacket(outapp);
safe_delete(outapp); int index = 0;
ret = true; for (auto it = tracking_list.cbegin(); it != tracking_list.cend(); ++it, ++index) {
} else { Mob *cur_entity = it->first;
LogFile->write(EQEMuLog::Status, "ERROR: Unable to transmit a Tracking_Struct packet. Mobs in zone = %i. Mobs in packet = %i", array_counter, spe); outtrack->Entrys[index].entityid = cur_entity->GetID();
outtrack->Entrys[index].distance = it->second;
outtrack->Entrys[index].level = cur_entity->GetLevel();
outtrack->Entrys[index].NPC = !cur_entity->IsClient();
if (g && cur_entity->IsClient() && g->IsGroupMember(cur_entity->CastToMob()))
outtrack->Entrys[index].GroupMember = 1;
else
outtrack->Entrys[index].GroupMember = 0;
strn0cpy(outtrack->Entrys[index].name, cur_entity->GetName(), sizeof(outtrack->Entrys[index].name));
} }
safe_delete_array(buffer1); client->QueuePacket(outapp);
safe_delete_array(buffer2); safe_delete(outapp);
return ret; return true;
} }
void EntityList::MessageGroup(Mob *sender, bool skipclose, uint32 type, const char *message, ...) void EntityList::MessageGroup(Mob *sender, bool skipclose, uint32 type, const char *message, ...)

View File

@ -97,6 +97,7 @@ public:
const Beacon *CastToBeacon() const; const Beacon *CastToBeacon() const;
inline const uint16& GetID() const { return id; } inline const uint16& GetID() const { return id; }
inline const time_t& GetSpawnTimeStamp() const { return spawn_timestamp; }
virtual const char* GetName() { return ""; } virtual const char* GetName() { return ""; }
bool CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z, float trg_x, float trg_y, float trg_z, float perwalk=1); bool CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z, float trg_x, float trg_y, float trg_z, float perwalk=1);
@ -112,6 +113,7 @@ protected:
uint32 pDBAsyncWorkID; uint32 pDBAsyncWorkID;
private: private:
uint16 id; uint16 id;
time_t spawn_timestamp;
}; };
class EntityList class EntityList

View File

@ -608,7 +608,7 @@ int32 Mob::CalcMaxMana() {
int32 Mob::CalcMaxHP() { int32 Mob::CalcMaxHP() {
max_hp = (base_hp + itembonuses.HP + spellbonuses.HP); max_hp = (base_hp + itembonuses.HP + spellbonuses.HP);
max_hp += max_hp * ((aabonuses.MaxHPChange + spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000); max_hp += max_hp * ((aabonuses.MaxHPChange + spellbonuses.MaxHPChange + itembonuses.MaxHPChange) / 10000.0f);
return max_hp; return max_hp;
} }

View File

@ -299,7 +299,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
//This effect can also do damage by percent. //This effect can also do damage by percent.
if (val < 0) { if (val < 0) {
if (-val > spell.max[i]) if (spell.max[i] && -val > spell.max[i])
val = -spell.max[i]; val = -spell.max[i];
if (caster) if (caster)
@ -309,7 +309,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
else else
{ {
if (val > spell.max[i]) if (spell.max[i] && val > spell.max[i])
val = spell.max[i]; val = spell.max[i];
if(caster) if(caster)
@ -2647,7 +2647,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
case SE_Taunt: case SE_Taunt:
{ {
if (IsNPC()){ if (IsNPC()){
caster->Taunt(this->CastToNPC(), false, spell.base[i]); caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]));
if (spell.base2[i] > 0) if (spell.base2[i] > 0)
CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i])); CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i]));
@ -3558,6 +3558,8 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
case SE_WipeHateList: case SE_WipeHateList:
{ {
if (IsMezSpell(spell_id))
break;
int wipechance = spells[spell_id].base[i]; int wipechance = spells[spell_id].base[i];
int bonus = 0; int bonus = 0;

View File

@ -445,7 +445,7 @@ void Zone::LoadNewMerchantData(uint32 merchantid) {
std::list<MerchantList> merlist; std::list<MerchantList> merlist;
std::string query = StringFormat("SELECT item, slot, faction_required, level_required, alt_currency_cost, " std::string query = StringFormat("SELECT item, slot, faction_required, level_required, alt_currency_cost, "
"classes_required FROM merchantlist WHERE merchantid=%d ORDER BY slot", merchantid); "classes_required, probability FROM merchantlist WHERE merchantid=%d ORDER BY slot", merchantid);
auto results = database.QueryDatabase(query); auto results = database.QueryDatabase(query);
if (!results.Success()) { if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadNewMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); LogFile->write(EQEMuLog::Error, "Error in LoadNewMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
@ -459,8 +459,9 @@ void Zone::LoadNewMerchantData(uint32 merchantid) {
ml.slot = atoul(row[1]); ml.slot = atoul(row[1]);
ml.faction_required = atoul(row[2]); ml.faction_required = atoul(row[2]);
ml.level_required = atoul(row[3]); ml.level_required = atoul(row[3]);
ml.alt_currency_cost = atoul(row[3]); ml.alt_currency_cost = atoul(row[4]);
ml.classes_required = atoul(row[4]); ml.classes_required = atoul(row[5]);
ml.probability = atoul(row[6]);
merlist.push_back(ml); merlist.push_back(ml);
} }