merge upstream

This commit is contained in:
Arthur Ice
2015-01-08 19:40:00 -08:00
142 changed files with 5443 additions and 3716 deletions
+27 -21
View File
@@ -444,7 +444,7 @@ void Client::HandleAAAction(aaID activate) {
break;
default:
LogFile->write(EQEMuLog::Error, "Unknown AA nonspell action type %d", caa->action);
LogFile->write(EQEmuLog::Error, "Unknown AA nonspell action type %d", caa->action);
return;
}
@@ -500,7 +500,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
PetRecord record;
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
{
LogFile->write(EQEMuLog::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
LogFile->write(EQEmuLog::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id);
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
return;
}
@@ -527,7 +527,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
if(npc_type == nullptr) {
//log write
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
LogFile->write(EQEmuLog::Error, "Unknown npc type for swarm pet spell id: %d", spell_id);
Message(0,"Unable to find pet!");
return;
}
@@ -606,6 +606,9 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
//the target of these swarm pets will take offense to being cast on...
if(targ != nullptr)
targ->AddToHateList(this, 1, 0);
// The other pointers we make are handled elsewhere.
delete made_npc;
}
void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) {
@@ -621,7 +624,7 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
const NPCType *npc_type = database.GetNPCType(typesid);
if(npc_type == nullptr) {
//log write
LogFile->write(EQEMuLog::Error, "Unknown npc type for swarm pet type id: %d", typesid);
LogFile->write(EQEmuLog::Error, "Unknown npc type for swarm pet type id: %d", typesid);
Message(0,"Unable to find pet!");
return;
}
@@ -697,6 +700,9 @@ void Mob::TypesTemporaryPets(uint32 typesid, Mob *targ, const char *name_overrid
entity_list.AddNPC(npca, true, true);
summon_count--;
}
// The other pointers we make are handled elsewhere.
delete made_npc;
}
void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
@@ -843,8 +849,8 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
make_npc->loottable_id = 0;
make_npc->merchanttype = 0;
make_npc->d_meele_texture1 = 0;
make_npc->d_meele_texture2 = 0;
make_npc->d_melee_texture1 = 0;
make_npc->d_melee_texture2 = 0;
NPC* npca = new NPC(make_npc, 0, GetPosition(), FlyMode3);
@@ -1421,10 +1427,10 @@ SendAA_Struct* Zone::FindAA(uint32 id) {
}
void Zone::LoadAAs() {
LogFile->write(EQEMuLog::Status, "Loading AA information...");
LogFile->write(EQEmuLog::Status, "Loading AA information...");
totalAAs = database.CountAAs();
if(totalAAs == 0) {
LogFile->write(EQEMuLog::Error, "Failed to load AAs!");
LogFile->write(EQEmuLog::Error, "Failed to load AAs!");
aas = nullptr;
return;
}
@@ -1439,11 +1445,11 @@ void Zone::LoadAAs() {
}
//load AA Effects into aa_effects
LogFile->write(EQEMuLog::Status, "Loading AA Effects...");
LogFile->write(EQEmuLog::Status, "Loading AA Effects...");
if (database.LoadAAEffects2())
LogFile->write(EQEMuLog::Status, "Loaded %d AA Effects.", aa_effects.size());
LogFile->write(EQEmuLog::Status, "Loaded %d AA Effects.", aa_effects.size());
else
LogFile->write(EQEMuLog::Error, "Failed to load AA Effects!");
LogFile->write(EQEmuLog::Error, "Failed to load AA Effects!");
}
bool ZoneDatabase::LoadAAEffects2() {
@@ -1452,12 +1458,12 @@ bool ZoneDatabase::LoadAAEffects2() {
const std::string query = "SELECT aaid, slot, effectid, base1, base2 FROM aa_effects ORDER BY aaid ASC, slot ASC";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAEffects2 query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAEffects2 query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
if (!results.RowCount()) { //no results
LogFile->write(EQEMuLog::Error, "Error loading AA Effects, none found in the database.");
LogFile->write(EQEmuLog::Error, "Error loading AA Effects, none found in the database.");
return false;
}
@@ -1794,7 +1800,7 @@ bool ZoneDatabase::LoadAAEffects() {
"redux_aa, redux_rate, redux_aa2, redux_rate2 FROM aa_actions";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadAAEffects query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadAAEffects query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -1833,7 +1839,7 @@ uint8 ZoneDatabase::GetTotalAALevels(uint32 skill_id) {
std::string query = StringFormat("SELECT count(slot) FROM aa_effects WHERE aaid = %i", skill_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTotalAALevels '%s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTotalAALevels '%s: %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1887,7 +1893,7 @@ uint32 ZoneDatabase::CountAAs(){
const std::string query = "SELECT count(title_sid) FROM altadv_vars";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::CountAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1904,7 +1910,7 @@ uint32 ZoneDatabase::CountAAEffects() {
const std::string query = "SELECT count(id) FROM aa_effects";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::CountAALevels query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::CountAALevels query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1937,14 +1943,14 @@ void ZoneDatabase::LoadAAs(SendAA_Struct **load){
load[index]->seq = index+1;
}
} else {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
AARequiredLevelAndCost.clear();
query = "SELECT skill_id, level, cost from aa_required_level_cost order by skill_id";
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadAAs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1962,7 +1968,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
std::string query = "SET @row = 0"; //initialize "row" variable in database for next query
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return nullptr;
}
@@ -1982,7 +1988,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
"FROM altadv_vars a WHERE skill_id=%i", skill_id);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetAASkillVars '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return nullptr;
}
+6 -6
View File
@@ -344,7 +344,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
// Aggro
#if EQDEBUG>=6
LogFile->write(EQEMuLog::Debug, "Check aggro for %s target %s.", GetName(), mob->GetName());
LogFile->write(EQEmuLog::Debug, "Check aggro for %s target %s.", GetName(), mob->GetName());
#endif
return( mod_will_aggro(mob, this) );
}
@@ -469,7 +469,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
//Father Nitwit: make sure we can see them.
if(mob->CheckLosFN(sender)) {
#if (EQDEBUG>=5)
LogFile->write(EQEMuLog::Debug, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
LogFile->write(EQEmuLog::Debug, "AIYellForHelp(\"%s\",\"%s\") %s attacking %s Dist %f Z %f",
sender->GetName(), attacker->GetName(), mob->GetName(), attacker->GetName(), mob->DistNoRoot(*sender), fabs(sender->GetZ()+mob->GetZ()));
#endif
mob->AddToHateList(attacker, 1, 0, false);
@@ -696,7 +696,7 @@ type', in which case, the answer is yes.
}
while( reverse++ == 0 );
LogFile->write(EQEMuLog::Debug, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
LogFile->write(EQEmuLog::Debug, "Mob::IsAttackAllowed: don't have a rule for this - %s vs %s\n", this->GetName(), target->GetName());
return false;
}
@@ -836,7 +836,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
}
while( reverse++ == 0 );
LogFile->write(EQEMuLog::Debug, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
LogFile->write(EQEmuLog::Debug, "Mob::IsBeneficialAllowed: don't have a rule for this - %s to %s\n", this->GetName(), target->GetName());
return false;
}
@@ -948,7 +948,7 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
oloc.z = posZ + (mobSize==0.0?LOS_DEFAULT_HEIGHT:mobSize)/2 * SEE_POSITION;
#if LOSDEBUG>=5
LogFile->write(EQEMuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
LogFile->write(EQEmuLog::Debug, "LOS from (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f) sizes: (%.2f, %.2f)", myloc.x, myloc.y, myloc.z, oloc.x, oloc.y, oloc.z, GetSize(), mobSize);
#endif
return zone->zonemap->CheckLoS(myloc, oloc);
}
@@ -1298,7 +1298,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
void Mob::RogueEvade(Mob *other)
{
int amount = other->GetHateAmount(this) - (GetLevel() * 13);
other->SetHate(this, std::max(1, amount));
other->SetHateAmountOnEnt(this, std::max(1, amount));
return;
}
+26 -24
View File
@@ -61,7 +61,7 @@ bool Mob::AttackAnimation(SkillUseTypes &skillinuse, int Hand, const ItemInst* w
if (weapon && weapon->IsType(ItemClassCommon)) {
const Item_Struct* item = weapon->GetItem();
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug, "Weapon skill:%i", item->ItemType);
LogFile->write(EQEmuLog::Debug, "Weapon skill:%i", item->ItemType);
#endif
switch (item->ItemType)
{
@@ -192,7 +192,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
chancetohit += RuleR(Combat, NPCBonusHitChance);
#if ATTACK_DEBUG>=11
LogFile->write(EQEMuLog::Debug, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
LogFile->write(EQEmuLog::Debug, "CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
#endif
mlog(COMBAT__TOHIT,"CheckHitChance(%s) attacked by %s", defender->GetName(), attacker->GetName());
@@ -334,7 +334,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
//agains a garunteed riposte (for example) discipline... for now, garunteed hit wins
#if EQDEBUG>=11
LogFile->write(EQEMuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
LogFile->write(EQEmuLog::Debug, "3 FINAL calculated chance to hit is: %5.2f", chancetohit);
#endif
//
@@ -1135,7 +1135,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
{
if (!other) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Client::Attack() for evaluation!");
return false;
}
@@ -1518,7 +1518,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
}
entity_list.RemoveFromTargets(this);
hate_list.RemoveEnt(this);
hate_list.RemoveEntFromHateList(this);
RemoveAutoXTargets();
//remove ourself from all proximities
@@ -1699,7 +1699,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
if (!other) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to NPC::Attack() for evaluation!");
return false;
}
@@ -2036,7 +2036,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
{
zone->DelAggroMob();
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug,"NPC::Death() Mobs currently Aggro %i", zone->MobsAggroCount());
LogFile->write(EQEmuLog::Debug,"NPC::Death() Mobs currently Aggro %i", zone->MobsAggroCount());
#endif
}
SetHP(0);
@@ -2076,12 +2076,12 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
if (killerMob) {
if(GetClass() != LDON_TREASURE)
hate_list.Add(killerMob, damage);
hate_list.AddEntToHateList(killerMob, damage);
}
safe_delete(app);
Mob *give_exp = hate_list.GetDamageTop(this);
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
if(give_exp == nullptr)
give_exp = killer;
@@ -2400,7 +2400,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
return true;
}
void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic) {
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/)
{
assert(other != nullptr);
@@ -2413,7 +2414,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
bool wasengaged = IsEngaged();
Mob* owner = other->GetOwner();
Mob* mypet = this->GetPet();
Mob* mypet = this->GetPet();
Mob* myowner = this->GetOwner();
Mob* targetmob = this->GetTarget();
@@ -2488,7 +2489,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
&& other && (buffs[spellbonuses.ImprovedTaunt[2]].casterid != other->GetID()))
hate = (hate*spellbonuses.ImprovedTaunt[1])/100;
hate_list.Add(other, hate, damage, bFrenzy, !iBuffTic);
hate_list.AddEntToHateList(other, hate, damage, bFrenzy, !iBuffTic);
if(other->IsClient())
other->CastToClient()->AddAutoXTarget(this);
@@ -2500,8 +2501,8 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
AddFeignMemory(other->CastToBot()->GetBotOwner()->CastToClient());
}
else {
if(!hate_list.IsOnHateList(other->CastToBot()->GetBotOwner()))
hate_list.Add(other->CastToBot()->GetBotOwner(), 0, 0, false, true);
if(!hate_list.IsEntOnHateList(other->CastToBot()->GetBotOwner()))
hate_list.AddEntToHateList(other->CastToBot()->GetBotOwner(), 0, 0, false, true);
}
}
#endif //BOTS
@@ -2512,8 +2513,8 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
AddFeignMemory(other->CastToMerc()->GetMercOwner()->CastToClient());
}
else {
if(!hate_list.IsOnHateList(other->CastToMerc()->GetMercOwner()))
hate_list.Add(other->CastToMerc()->GetMercOwner(), 0, 0, false, true);
if(!hate_list.IsEntOnHateList(other->CastToMerc()->GetMercOwner()))
hate_list.AddEntToHateList(other->CastToMerc()->GetMercOwner(), 0, 0, false, true);
}
} //MERC
@@ -2528,7 +2529,7 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
// owner must get on list, but he's not actually gained any hate yet
if(!owner->GetSpecialAbility(IMMUNE_AGGRO))
{
hate_list.Add(owner, 0, 0, false, !iBuffTic);
hate_list.AddEntToHateList(owner, 0, 0, false, !iBuffTic);
if(owner->IsClient())
owner->CastToClient()->AddAutoXTarget(this);
}
@@ -2537,10 +2538,10 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
if (mypet && (!(GetAA(aaPetDiscipline) && mypet->IsHeld()))) { // I have a pet, add other to it
if(!mypet->IsFamiliar() && !mypet->GetSpecialAbility(IMMUNE_AGGRO))
mypet->hate_list.Add(other, 0, 0, bFrenzy);
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
} else if (myowner) { // I am a pet, add other to owner if it's NPC/LD
if (myowner->IsAIControlled() && !myowner->GetSpecialAbility(IMMUNE_AGGRO))
myowner->hate_list.Add(other, 0, 0, bFrenzy);
myowner->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
}
if (other->GetTempPetCount())
@@ -3890,11 +3891,12 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
return ProcChance;
}
// argument 'weapon' not used
void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
if (!on) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
return;
}
@@ -3925,7 +3927,7 @@ void Mob::TryDefensiveProc(const ItemInst* weapon, Mob *on, uint16 hand) {
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
if(!on) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
return;
}
@@ -4474,7 +4476,7 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, uint16 ReuseTime, bool Success, ui
if (!on) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Mob::TrySkillProc for evaluation!");
return;
}
@@ -4932,7 +4934,7 @@ void Client::SetAttackTimer()
// this is probably wrong
if (quiver_haste > 0)
speed *= quiver_haste;
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
if (i == MainPrimary)
PrimaryWeapon = ItemToUse;
@@ -4980,6 +4982,6 @@ void NPC::SetAttackTimer()
}
}
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
}
}
+446 -446
View File
File diff suppressed because it is too large Load Diff
+64 -142
View File
@@ -234,45 +234,28 @@ void Bot::SetBotSpellID(uint32 newSpellID) {
this->npc_spells_id = newSpellID;
}
uint32 Bot::GetBotArcheryRange() {
uint32 result = 0;
uint32 Bot::GetBotArcheryRange()
{
const ItemInst *range_inst = GetBotItem(MainRange);
const ItemInst *ammo_inst = GetBotItem(MainAmmo);
ItemInst* rangeItem = GetBotItem(MainRange);
if(!rangeItem)
// empty slots
if (!range_inst || !ammo_inst)
return 0;
const Item_Struct* botweapon = rangeItem->GetItem();
const Item_Struct *range_item = range_inst->GetItem();
const Item_Struct *ammo_item = ammo_inst->GetItem();
uint32 archeryMaterial;
uint32 archeryColor;
uint32 archeryBowID;
uint32 archeryAmmoID;
// no item struct for whatever reason
if (!range_item || !ammo_item)
return 0;
if(botweapon && botweapon->ItemType == ItemTypeBow) {
uint32 range = 0;
// bad item types
if (range_item->ItemType != ItemTypeBow || ammo_item->ItemType != ItemTypeArrow)
return 0;
archeryMaterial = atoi(botweapon->IDFile + 2);
archeryBowID = botweapon->ID;
archeryColor = botweapon->Color;
range =+ botweapon->Range;
rangeItem = GetBotItem(MainAmmo);
if(rangeItem)
botweapon = rangeItem->GetItem();
if(!botweapon || (botweapon->ItemType != ItemTypeArrow)) {
return 0;
}
range += botweapon->Range;
archeryAmmoID = botweapon->ID;
result = range;
}
return result;
// everything is good!
return range_item->Range + ammo_item->Range;
}
void Bot::ChangeBotArcherWeapons(bool isArcher) {
@@ -386,8 +369,8 @@ NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::str
BotNPCType.npc_id = 0;
BotNPCType.texture = 0;
BotNPCType.d_meele_texture1 = 0;
BotNPCType.d_meele_texture2 = 0;
BotNPCType.d_melee_texture1 = 0;
BotNPCType.d_melee_texture2 = 0;
BotNPCType.qglobal = false;
BotNPCType.attack_speed = 0;
BotNPCType.runspeed = 1.25;
@@ -431,8 +414,8 @@ NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string b
Result.hp_regen = 1;
Result.mana_regen = 1;
Result.texture = 0;
Result.d_meele_texture1 = 0;
Result.d_meele_texture2 = 0;
Result.d_melee_texture1 = 0;
Result.d_melee_texture2 = 0;
Result.qglobal = false;
Result.npc_spells_id = 0;
Result.attack_speed = 0;
@@ -1242,7 +1225,7 @@ int32 Bot::acmod()
return (65 + ((agility-300) / 21));
}
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
LogFile->write(EQEmuLog::Error, "Error in Bot::acmod(): Agility: %i, Level: %i",agility,level);
#endif
return 0;
}
@@ -1479,7 +1462,7 @@ void Bot::LoadAAs() {
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadAAs()");
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadAAs()");
return;
}
@@ -2791,7 +2774,7 @@ void Bot::LoadStance() {
std::string query = StringFormat("SELECT StanceID FROM botstances WHERE BotID = %u;", GetBotID());
auto results = database.QueryDatabase(query);
if(!results.Success() || results.RowCount() == 0) {
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadStance()");
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadStance()");
SetDefaultBotStance();
return;
}
@@ -2809,7 +2792,7 @@ void Bot::SaveStance() {
"VALUES(%u, %u);", GetBotID(), GetBotStance());
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveStance()");
LogFile->write(EQEmuLog::Error, "Error in Bot::SaveStance()");
}
@@ -2824,7 +2807,7 @@ void Bot::LoadTimers() {
GetBotID(), DisciplineReuseStart-1, DisciplineReuseStart-1, GetClass(), GetLevel());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Bot::LoadTimers()");
LogFile->write(EQEmuLog::Error, "Error in Bot::LoadTimers()");
return;
}
@@ -2864,7 +2847,7 @@ void Bot::SaveTimers() {
}
if(hadError)
LogFile->write(EQEMuLog::Error, "Error in Bot::SaveTimers()");
LogFile->write(EQEmuLog::Error, "Error in Bot::SaveTimers()");
}
@@ -3439,9 +3422,9 @@ void Bot::AI_Process() {
rest_timer.Disable();
if(IsRooted())
SetTarget(hate_list.GetClosest(this));
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
SetTarget(hate_list.GetTop(this));
SetTarget(hate_list.GetEntWithMostHateOnList(this));
if(!GetTarget())
return;
@@ -3808,9 +3791,9 @@ void Bot::PetAIProcess() {
if (IsEngaged()) {
if (botPet->IsRooted())
botPet->SetTarget(hate_list.GetClosest(botPet));
botPet->SetTarget(hate_list.GetClosestEntOnHateList(botPet));
else
botPet->SetTarget(hate_list.GetTop(botPet));
botPet->SetTarget(hate_list.GetEntWithMostHateOnList(botPet));
// Let's check if we have a los with our target.
// If we don't, our hate_list is wiped.
@@ -4228,7 +4211,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
ItemInst* inst = database.CreateItem(item_id, charges, aug[0], aug[1], aug[2], aug[3], aug[4]);
if (!inst) {
LogFile->write(EQEMuLog::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
LogFile->write(EQEmuLog::Error, "Warning: botid %i has an invalid item_id %i in inventory slot %i", this->GetBotID(), item_id, slot_id);
continue;
}
@@ -4252,7 +4235,7 @@ void Bot::GetBotItems(std::string* errorMessage, Inventory &inv) {
// Save ptr to item in inventory
if (put_slot_id == INVALID_INDEX)
LogFile->write(EQEMuLog::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
LogFile->write(EQEmuLog::Error, "Warning: Invalid slot_id for item in inventory: botid=%i, item_id=%i, slot_id=%i",this->GetBotID(), item_id, slot_id);
}
@@ -5871,7 +5854,7 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, SkillUseTypes att
Save();
Mob *give_exp = hate_list.GetDamageTop(this);
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
Client *give_exp_client = nullptr;
if(give_exp && give_exp->IsClient())
@@ -6025,7 +6008,7 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, SkillUseTypes attack_
}
}
void Bot::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic)
void Bot::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/)
{
Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic);
}
@@ -6034,7 +6017,7 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
{
if (!other) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Bot::Attack for evaluation!");
return false;
}
@@ -7045,7 +7028,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
return 0;
break;
default:
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
}
break;
@@ -7353,7 +7336,7 @@ int32 Bot::CalcBotFocusEffect(BotfocusType bottype, uint16 focus_id, uint16 spel
//this spits up a lot of garbage when calculating spell focuses
//since they have all kinds of extra effects on them.
default:
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
#endif
}
}
@@ -8567,7 +8550,7 @@ int32 Bot::CalcMaxMana() {
}
default:
{
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
max_mana = 0;
break;
}
@@ -11716,106 +11699,46 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
const char* equipped[EmuConstants::EQUIPMENT_SIZE] = {"Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back",
"Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand",
"Left Finger", "Right Finger", "Chest", "Legs", "Feet", "Waist", "Ammo" };
const ItemInst* item1 = nullptr;
const Item_Struct* item2 = nullptr;
const ItemInst* inst = nullptr;
const Item_Struct* item = nullptr;
bool is2Hweapon = false;
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i)
{
std::string item_link;
Client::TextLink linker;
linker.SetLinkType(linker.linkItemInst);
for(int i = EmuConstants::EQUIPMENT_BEGIN; i <= EmuConstants::EQUIPMENT_END; ++i) {
if((i == MainSecondary) && is2Hweapon) {
continue;
}
item1 = b->CastToBot()->GetBotItem(i);
if(item1)
item2 = item1->GetItem();
inst = b->CastToBot()->GetBotItem(i);
if (inst)
item = inst->GetItem();
else
item2 = nullptr;
item = nullptr;
if(!TempErrorMessage.empty()) {
c->Message(13, "Database Error: %s", TempErrorMessage.c_str());
return;
}
if(item2 == 0) {
if(item == nullptr) {
c->Message(15, "I need something for my %s (Item %i)", equipped[i], i);
continue;
}
if((i == MainPrimary) && ((item2->ItemType == ItemType2HSlash) || (item2->ItemType == ItemType2HBlunt) || (item2->ItemType == ItemType2HPiercing))) {
if((i == MainPrimary) && ((item->ItemType == ItemType2HSlash) || (item->ItemType == ItemType2HBlunt) || (item->ItemType == ItemType2HPiercing))) {
is2Hweapon = true;
}
char* itemLink = 0;
if((i == MainCharm) || (i == MainRange) || (i == MainPrimary) || (i == MainSecondary) || (i == MainAmmo)) {
if (c->GetClientVersion() >= EQClientSoF)
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0,
0
);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
else
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
}
else {
if (c->GetClientVersion() >= EQClientSoF)
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0,
0
);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
else
{
MakeAnyLenString(&itemLink, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item2->ID,
item1->GetAugmentItemID(0),
item1->GetAugmentItemID(1),
item1->GetAugmentItemID(2),
item1->GetAugmentItemID(3),
item1->GetAugmentItemID(4),
0,
0,
0,
0);
c->Message(15, "Using %c%s%s%c in my %s (Item %i)", 0x12, itemLink, item2->Name, 0x12, equipped[i], i);
}
}
// I could not find a difference between the criteria positive code and the criteria negative code..
// ..so, I deleted the check (old criteria: i = { MainCharm, MainRange, MainPrimary, MainSecondary, MainAmmo })
linker.SetItemInst(inst);
item_link = linker.GenerateLink();
c->Message(15, "Using %s in my %s (Item %i)", item_link.c_str(), equipped[i], i);
}
}
else {
@@ -14364,8 +14287,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
return;
}
std::list<BotGroup>::iterator botGroupItr = botGroup.begin();
for(botGroupItr; botGroupItr != botGroup.end(); ++botGroupItr) {
for(auto botGroupItr = botGroup.begin(); botGroupItr != botGroup.end(); ++botGroupItr) {
// Don't try to re-spawn the botgroup's leader.
if(botGroupItr->BotID == botGroupLeader->GetBotID()) { continue; }
@@ -15474,7 +15396,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
else {
Mob *target = c->GetTarget();
if(target->IsBot() && (c == target->GetOwner()->CastToClient())) {
if(target && target->IsBot() && (c == target->GetOwner()->CastToClient())) {
const InspectMessage_Struct& playermessage = c->GetInspectMessage();
InspectMessage_Struct& botmessage = target->CastToBot()->GetInspectMessage();
@@ -15504,7 +15426,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
Mob *target = c->GetTarget();
if(target->IsBot() && (c == target->GetOwner()->CastToClient())) {
if(target && target->IsBot() && (c == target->GetOwner()->CastToClient())) {
Bot* bardBot = target->CastToBot();
if(bardBot) {
+1 -1
View File
@@ -208,7 +208,7 @@ public:
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, uint16 slot, bool &stopLogic);
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
void Camp(bool databaseSave = true);
virtual void AddToHateList(Mob* other, int32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false);
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false);
virtual void SetTarget(Mob* mob);
virtual void Zone();
std::vector<AISpells_Struct> GetBotSpells() { return AIspells; }
+260 -70
View File
@@ -327,7 +327,7 @@ Client::~Client() {
ToggleBuyerMode(false);
if(conn_state != ClientConnectFinished) {
LogFile->write(EQEMuLog::Debug, "Client '%s' was destroyed before reaching the connected state:", GetName());
LogFile->write(EQEmuLog::Debug, "Client '%s' was destroyed before reaching the connected state:", GetName());
ReportConnectingState();
}
@@ -425,31 +425,31 @@ void Client::SendLogoutPackets() {
void Client::ReportConnectingState() {
switch(conn_state) {
case NoPacketsReceived: //havent gotten anything
LogFile->write(EQEMuLog::Debug, "Client has not sent us an initial zone entry packet.");
LogFile->write(EQEmuLog::Debug, "Client has not sent us an initial zone entry packet.");
break;
case ReceivedZoneEntry: //got the first packet, loading up PP
LogFile->write(EQEMuLog::Debug, "Client sent initial zone packet, but we never got their player info from the database.");
LogFile->write(EQEmuLog::Debug, "Client sent initial zone packet, but we never got their player info from the database.");
break;
case PlayerProfileLoaded: //our DB work is done, sending it
LogFile->write(EQEMuLog::Debug, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
LogFile->write(EQEmuLog::Debug, "We were sending the player profile, tributes, tasks, spawns, time and weather, but never finished.");
break;
case ZoneInfoSent: //includes PP, tributes, tasks, spawns, time and weather
LogFile->write(EQEMuLog::Debug, "We successfully sent player info and spawns, waiting for client to request new zone.");
LogFile->write(EQEmuLog::Debug, "We successfully sent player info and spawns, waiting for client to request new zone.");
break;
case NewZoneRequested: //received and sent new zone request
LogFile->write(EQEMuLog::Debug, "We received client's new zone request, waiting for client spawn request.");
LogFile->write(EQEmuLog::Debug, "We received client's new zone request, waiting for client spawn request.");
break;
case ClientSpawnRequested: //client sent ReqClientSpawn
LogFile->write(EQEMuLog::Debug, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
LogFile->write(EQEmuLog::Debug, "We received the client spawn request, and were sending objects, doors, zone points and some other stuff, but never finished.");
break;
case ZoneContentsSent: //objects, doors, zone points
LogFile->write(EQEMuLog::Debug, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
LogFile->write(EQEmuLog::Debug, "The rest of the zone contents were successfully sent, waiting for client ready notification.");
break;
case ClientReadyReceived: //client told us its ready, send them a bunch of crap like guild MOTD, etc
LogFile->write(EQEMuLog::Debug, "We received client ready notification, but never finished Client::CompleteConnect");
LogFile->write(EQEmuLog::Debug, "We received client ready notification, but never finished Client::CompleteConnect");
break;
case ClientConnectFinished: //client finally moved to finished state, were done here
LogFile->write(EQEMuLog::Debug, "Client is successfully connected.");
LogFile->write(EQEmuLog::Debug, "Client is successfully connected.");
break;
};
}
@@ -640,7 +640,7 @@ bool Client::SendAllPackets() {
eqs->FastQueuePacket((EQApplicationPacket **)&cp->app, cp->ack_req);
iterator.RemoveCurrent();
#if EQDEBUG >= 6
LogFile->write(EQEMuLog::Normal, "Transmitting a packet");
LogFile->write(EQEmuLog::Normal, "Transmitting a packet");
#endif
}
return true;
@@ -691,7 +691,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug,"Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
LogFile->write(EQEmuLog::Debug,"Client::ChannelMessageReceived() Channel:%i message:'%s'", chan_num, message);
#endif
if (targetname == nullptr) {
@@ -1807,45 +1807,8 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
}
ns->spawn.size = 0; // Changing size works, but then movement stops! (wth?)
ns->spawn.runspeed = (gmspeed == 0) ? runspeed : 3.125f;
if (!m_pp.showhelm) ns->spawn.showhelm = 0;
ns->spawn.showhelm = m_pp.showhelm ? 1 : 0;
/*
// Equipment/Weapons already set from Mob::FillSpawnStruct
// Commenting this out for now
const Item_Struct* item = nullptr;
const ItemInst* inst = nullptr;
int16 invslot;
for (uint32 matslot = 0; matslot < _MaterialCount; matslot++)
{
// Only Player Races Wear Armor
if (IsPlayerRace(race) || matslot > 6)
{
invslot = Inventory::CalcSlotFromMaterial(matslot);
if (invslot == INVALID_INDEX)
continue;
if ((inst = m_inv[invslot]) && inst->IsType(ItemClassCommon))
{
item = inst->GetItem();
if (matslot > 6)
{
// Weapon Models
ns->spawn.equipment[matslot].material = GetEquipmentMaterial(matslot);
}
else
{
// Armor Materials/Models
ns->spawn.equipment[matslot].material = item->Material;
ns->spawn.equipment[matslot].elitematerial = item->EliteMaterial;
ns->spawn.equipment[matslot].heroforgemodel = GetHerosForgeModel(matslot);
ns->spawn.colors[matslot].color = m_pp.item_tint[matslot].rgb.use_tint ? m_pp.item_tint[matslot].color : item->Color;
}
}
}
}
*/
}
bool Client::GMHideMe(Client* client) {
@@ -1944,7 +1907,7 @@ void Client::ReadBook(BookRequest_Struct *book) {
if (booktxt2[0] != '\0') {
#if EQDEBUG >= 6
LogFile->write(EQEMuLog::Normal,"Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
LogFile->write(EQEmuLog::Normal,"Client::ReadBook() textfile:%s Text:%s", txtfile, booktxt2.c_str());
#endif
EQApplicationPacket* outapp = new EQApplicationPacket(OP_ReadBook, length + sizeof(BookText_Struct));
@@ -2138,7 +2101,7 @@ void Client::AddMoneyToPP(uint64 copper, bool updateclient){
SaveCurrency();
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i", GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
}
void Client::EVENT_ITEM_ScriptStopReturn(){
@@ -2178,7 +2141,7 @@ void Client::AddMoneyToPP(uint32 copper, uint32 silver, uint32 gold, uint32 plat
SaveCurrency();
#if (EQDEBUG>=5)
LogFile->write(EQEMuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
LogFile->write(EQEmuLog::Debug, "Client::AddMoneyToPP() %s should have: plat:%i gold:%i silver:%i copper:%i",
GetName(), m_pp.platinum, m_pp.gold, m_pp.silver, m_pp.copper);
#endif
}
@@ -2397,7 +2360,7 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16
Save();
LogFile->write(EQEMuLog::Normal, "Reset %s's caster specialization skills to 1. "
LogFile->write(EQEmuLog::Normal, "Reset %s's caster specialization skills to 1. "
"Too many specializations skills were above 50.", GetCleanName());
}
@@ -4577,14 +4540,14 @@ void Client::HandleLDoNOpen(NPC *target)
{
if(target->GetClass() != LDON_TREASURE)
{
LogFile->write(EQEMuLog::Debug, "%s tried to open %s but %s was not a treasure chest.",
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was not a treasure chest.",
GetName(), target->GetName(), target->GetName());
return;
}
if(DistNoRootNoZ(*target) > RuleI(Adventure, LDoNTrapDistanceUse))
{
LogFile->write(EQEMuLog::Debug, "%s tried to open %s but %s was out of range",
LogFile->write(EQEmuLog::Debug, "%s tried to open %s but %s was out of range",
GetName(), target->GetName(), target->GetName());
Message(13, "Treasure chest out of range.");
return;
@@ -5319,7 +5282,7 @@ void Client::SendRewards()
"ORDER BY reward_id", AccountID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -5387,7 +5350,7 @@ bool Client::TryReward(uint32 claim_id) {
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -5414,7 +5377,7 @@ bool Client::TryReward(uint32 claim_id) {
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
}
else {
query = StringFormat("UPDATE account_rewards SET amount = (amount-1) "
@@ -5422,7 +5385,7 @@ bool Client::TryReward(uint32 claim_id) {
AccountID(), claim_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
}
InternalVeteranReward ivr = (*iter);
@@ -6236,7 +6199,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
PetRecord record;
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
{
LogFile->write(EQEMuLog::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
LogFile->write(EQEmuLog::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id);
Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone);
return;
}
@@ -6250,7 +6213,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
const NPCType *npc_type = database.GetNPCType(pet.npc_id);
if(npc_type == nullptr) {
LogFile->write(EQEMuLog::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
LogFile->write(EQEmuLog::Error, "Unknown npc type for doppelganger spell id: %d", spell_id);
Message(0,"Unable to find pet!");
return;
}
@@ -6274,6 +6237,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->DR = GetDR();
made_npc->PR = GetPR();
made_npc->Corrup = GetCorrup();
made_npc->PhR = GetPhR();
// looks
made_npc->texture = GetEquipmentMaterial(MaterialChest);
made_npc->helmtexture = GetEquipmentMaterial(MaterialHead);
@@ -6287,8 +6251,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->drakkin_heritage = GetDrakkinHeritage();
made_npc->drakkin_tattoo = GetDrakkinTattoo();
made_npc->drakkin_details = GetDrakkinDetails();
made_npc->d_meele_texture1 = GetEquipmentMaterial(MaterialPrimary);
made_npc->d_meele_texture2 = GetEquipmentMaterial(MaterialSecondary);
made_npc->d_melee_texture1 = GetEquipmentMaterial(MaterialPrimary);
made_npc->d_melee_texture2 = GetEquipmentMaterial(MaterialSecondary);
for (int i = EmuConstants::MATERIAL_BEGIN; i <= EmuConstants::MATERIAL_END; i++) {
made_npc->armor_tint[i] = GetEquipmentColor(i);
}
@@ -6374,7 +6338,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
// Set Class
std::string class_Name = itoa(GetClass());
std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SK", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" };
std::string class_List[] = { "WAR", "CLR", "PAL", "RNG", "SHD", "DRU", "MNK", "BRD", "ROG", "SHM", "NEC", "WIZ", "MAG", "ENC", "BST", "BER" };
if(GetClass() < 17 && GetClass() > 0) { class_Name = class_List[GetClass()-1]; }
@@ -6462,7 +6426,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
/*===========================*/
std::string regen_row_header = "";
std::string regen_row_color = "";
std::string base_regen_field = "";
std::string base_regen_field = "";
std::string base_regen_spacing = "";
std::string item_regen_field = "";
std::string item_regen_spacing = "";
@@ -6623,8 +6587,11 @@ void Client::SendStatsWindow(Client* client, bool use_window)
}
case 6: {
a_stat_name = " CHA: ";
a_resist_name = "PhR: "; // Not implemented for clients yet
a_stat = itoa(GetCHA());
h_stat = itoa(GetHeroicCHA());
a_resist = itoa(GetPhR());
h_resist_field = itoa(GetHeroicPhR());
break;
}
default: { break; }
@@ -6639,8 +6606,9 @@ void Client::SendStatsWindow(Client* client, bool use_window)
for(int h = a_resist.size(); h < max_stat_value_len; h++) { a_resist_spacing += " . "; }
stat_field += indP + a_stat_name + a_stat_spacing + a_stat + heroic_color + h_stat + "</c>";
stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "</c>";
if(stat_row_counter < 6) {
stat_field += h_stat_spacing + a_resist_name + a_resist_spacing + a_resist + heroic_color + h_resist_field + "</c><br>";
stat_field += "<br>";
}
}
/*##########################################################
@@ -6849,7 +6817,7 @@ void Client::SendStatsWindow(Client* client, bool use_window)
client->Message(0, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i)", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste);
client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA());
client->Message(0, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA());
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup());
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR());
client->Message(0, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup());
client->Message(0, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects());
client->Message(0, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit());
@@ -7487,8 +7455,17 @@ void Client::GarbleMessage(char *message, uint8 variance)
{
// Garble message by variance%
const char alpha_list[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; // only change alpha characters for now
const char delimiter = 0x12;
int delimiter_count = 0;
for (size_t i = 0; i < strlen(message); i++) {
// Client expects hex values inside of a text link body
if (message[i] == delimiter) {
if (!(delimiter_count & 1)) { i += EmuConstants::TEXT_LINK_BODY_LENGTH; }
++delimiter_count;
continue;
}
uint8 chance = (uint8)zone->random.Int(0, 115); // variation just over worst possible scrambling
if (isalpha(message[i]) && (chance <= variance)) {
uint8 rand_char = (uint8)zone->random.Int(0,51); // choose a random character from the alpha list
@@ -8163,7 +8140,7 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name);
#if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "Eating from slot:%i", (int)slot);
LogFile->write(EQEmuLog::Debug, "Eating from slot:%i", (int)slot);
#endif
}
else
@@ -8180,7 +8157,7 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name);
#if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "Drinking from slot:%i", (int)slot);
LogFile->write(EQEmuLog::Debug, "Drinking from slot:%i", (int)slot);
#endif
}
}
@@ -8280,3 +8257,216 @@ void Client::SendColoredText(uint32 color, std::string message)
safe_delete(outapp);
}
//
// class Client::TextLink
//
std::string Client::TextLink::GenerateLink()
{
m_Link.clear();
m_LinkBody.clear();
m_LinkText.clear();
generate_body();
generate_text();
if ((m_LinkBody.length() == EmuConstants::TEXT_LINK_BODY_LENGTH) && (m_LinkText.length() > 0)) {
m_Link.push_back(0x12);
m_Link.append(m_LinkBody);
m_Link.append(m_LinkText);
m_Link.push_back(0x12);
}
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
m_Error = true;
m_Link = "<LINKER ERROR>";
_log(CHANNELS__ERROR, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
#if EQDEBUG >= 5
_log(CHANNELS__ERROR, ">> LinkBody: %s", m_LinkBody.c_str());
_log(CHANNELS__ERROR, ">> LinkText: %s", m_LinkText.c_str());
#endif
}
return m_Link;
}
void Client::TextLink::Reset()
{
m_LinkType = linkBlank;
m_ItemData = nullptr;
m_LootData = nullptr;
m_ItemInst = nullptr;
m_ProxyItemID = NOT_USED;
m_ProxyText = nullptr;
m_TaskUse = false;
m_Link.clear();
m_LinkBody.clear();
m_LinkText.clear();
m_Error = false;
}
void Client::TextLink::generate_body()
{
/*
Current server mask: EQClientRoF2
RoF2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X" (56)
RoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (55)
SoF: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X" (50)
6.2: "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X" (45)
*/
memset(&m_LinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
const Item_Struct* item_data = nullptr;
switch (m_LinkType) {
case linkBlank:
break;
case linkItemData:
if (m_ItemData == nullptr) { break; }
m_LinkBodyStruct.item_id = m_ItemData->ID;
m_LinkBodyStruct.evolve_group = m_ItemData->LoreGroup; // this probably won't work for all items
//m_LinkBodyStruct.evolve_level = m_ItemData->EvolvingLevel;
// TODO: add hash call
break;
case linkLootItem:
if (m_LootData == nullptr) { break; }
item_data = database.GetItem(m_LootData->item_id);
if (item_data == nullptr) { break; }
m_LinkBodyStruct.item_id = item_data->ID;
m_LinkBodyStruct.augment_1 = m_LootData->aug_1;
m_LinkBodyStruct.augment_2 = m_LootData->aug_2;
m_LinkBodyStruct.augment_3 = m_LootData->aug_3;
m_LinkBodyStruct.augment_4 = m_LootData->aug_4;
m_LinkBodyStruct.augment_5 = m_LootData->aug_5;
m_LinkBodyStruct.augment_6 = m_LootData->aug_6;
m_LinkBodyStruct.evolve_group = item_data->LoreGroup; // see note above
//m_LinkBodyStruct.evolve_level = item_data->EvolvingLevel;
// TODO: add hash call
break;
case linkItemInst:
if (m_ItemInst == nullptr) { break; }
if (m_ItemInst->GetItem() == nullptr) { break; }
m_LinkBodyStruct.item_id = m_ItemInst->GetItem()->ID;
m_LinkBodyStruct.augment_1 = m_ItemInst->GetAugmentItemID(0);
m_LinkBodyStruct.augment_2 = m_ItemInst->GetAugmentItemID(1);
m_LinkBodyStruct.augment_3 = m_ItemInst->GetAugmentItemID(2);
m_LinkBodyStruct.augment_4 = m_ItemInst->GetAugmentItemID(3);
m_LinkBodyStruct.augment_5 = m_ItemInst->GetAugmentItemID(4);
m_LinkBodyStruct.augment_6 = m_ItemInst->GetAugmentItemID(5);
m_LinkBodyStruct.is_evolving = (m_ItemInst->IsEvolving() ? 1 : 0);
m_LinkBodyStruct.evolve_group = m_ItemInst->GetItem()->LoreGroup; // see note above
m_LinkBodyStruct.evolve_level = m_ItemInst->GetEvolveLvl();
m_LinkBodyStruct.ornament_icon = m_ItemInst->GetOrnamentationIcon();
// TODO: add hash call
break;
default:
break;
}
if (m_ProxyItemID != NOT_USED) {
m_LinkBodyStruct.item_id = m_ProxyItemID;
}
if (m_TaskUse) {
m_LinkBodyStruct.hash = 0x14505DC2;
}
m_LinkBody = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & m_LinkBodyStruct.unknown_1),
(0x000FFFFF & m_LinkBodyStruct.item_id),
(0x000FFFFF & m_LinkBodyStruct.augment_1),
(0x000FFFFF & m_LinkBodyStruct.augment_2),
(0x000FFFFF & m_LinkBodyStruct.augment_3),
(0x000FFFFF & m_LinkBodyStruct.augment_4),
(0x000FFFFF & m_LinkBodyStruct.augment_5),
(0x000FFFFF & m_LinkBodyStruct.augment_6),
(0x0F & m_LinkBodyStruct.is_evolving),
(0x0000FFFF & m_LinkBodyStruct.evolve_group),
(0xFF & m_LinkBodyStruct.evolve_level),
(0x000FFFFF & m_LinkBodyStruct.ornament_icon),
(0xFFFFFFFF & m_LinkBodyStruct.hash)
);
}
void Client::TextLink::generate_text()
{
if (m_ProxyText != nullptr) {
m_LinkText = m_ProxyText;
return;
}
const Item_Struct* item_data = nullptr;
switch (m_LinkType) {
case linkBlank:
break;
case linkItemData:
if (m_ItemData == nullptr) { break; }
m_LinkText = m_ItemData->Name;
return;
case linkLootItem:
if (m_LootData == nullptr) { break; }
item_data = database.GetItem(m_LootData->item_id);
if (item_data == nullptr) { break; }
m_LinkText = item_data->Name;
return;
case linkItemInst:
if (m_ItemInst == nullptr) { break; }
if (m_ItemInst->GetItem() == nullptr) { break; }
m_LinkText = m_ItemInst->GetItem()->Name;
return;
default:
break;
}
m_LinkText = "null";
}
bool Client::TextLink::DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody)
{
memset(&textLinkBodyStruct, 0, sizeof(TextLinkBody_Struct));
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
textLinkBodyStruct.unknown_1 = (uint8)strtol(textLinkBody.substr(0, 1).c_str(), nullptr, 16);
textLinkBodyStruct.item_id = (uint32)strtol(textLinkBody.substr(1, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_1 = (uint32)strtol(textLinkBody.substr(6, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_2 = (uint32)strtol(textLinkBody.substr(11, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_3 = (uint32)strtol(textLinkBody.substr(16, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_4 = (uint32)strtol(textLinkBody.substr(21, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_5 = (uint32)strtol(textLinkBody.substr(26, 5).c_str(), nullptr, 16);
textLinkBodyStruct.augment_6 = (uint32)strtol(textLinkBody.substr(31, 5).c_str(), nullptr, 16);
textLinkBodyStruct.is_evolving = (uint8)strtol(textLinkBody.substr(36, 1).c_str(), nullptr, 16);
textLinkBodyStruct.evolve_group = (uint32)strtol(textLinkBody.substr(37, 4).c_str(), nullptr, 16);
textLinkBodyStruct.evolve_level = (uint8)strtol(textLinkBody.substr(41, 2).c_str(), nullptr, 16);
textLinkBodyStruct.ornament_icon = (uint32)strtol(textLinkBody.substr(43, 5).c_str(), nullptr, 16);
textLinkBodyStruct.hash = (int)strtol(textLinkBody.substr(48, 8).c_str(), nullptr, 16);
return true;
}
bool Client::TextLink::GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct)
{
textLinkBody = StringFormat(
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
(0x0F & textLinkBodyStruct.unknown_1),
(0x000FFFFF & textLinkBodyStruct.item_id),
(0x000FFFFF & textLinkBodyStruct.augment_1),
(0x000FFFFF & textLinkBodyStruct.augment_2),
(0x000FFFFF & textLinkBodyStruct.augment_3),
(0x000FFFFF & textLinkBodyStruct.augment_4),
(0x000FFFFF & textLinkBodyStruct.augment_5),
(0x000FFFFF & textLinkBodyStruct.augment_6),
(0x0F & textLinkBodyStruct.is_evolving),
(0x0000FFFF & textLinkBodyStruct.evolve_group),
(0xFF & textLinkBodyStruct.evolve_level),
(0x000FFFFF & textLinkBodyStruct.ornament_icon),
(0xFFFFFFFF & textLinkBodyStruct.hash)
);
if (textLinkBody.length() != EmuConstants::TEXT_LINK_BODY_LENGTH) { return false; }
return true;
}
+60 -8
View File
@@ -428,6 +428,7 @@ public:
inline virtual int32 GetPR() const { return PR; }
inline virtual int32 GetCR() const { return CR; }
inline virtual int32 GetCorrup() const { return Corrup; }
inline virtual int32 GetPhR() const { return PhR; }
int32 GetMaxStat() const;
int32 GetMaxResist() const;
@@ -452,6 +453,7 @@ public:
inline uint8 GetBaseAGI() const { return m_pp.AGI; }
inline uint8 GetBaseWIS() const { return m_pp.WIS; }
inline uint8 GetBaseCorrup() const { return 15; } // Same for all
inline uint8 GetBasePhR() const { return 0; } // Guessing at 0 as base
inline virtual int32 GetHeroicSTR() const { return itembonuses.HeroicSTR; }
inline virtual int32 GetHeroicSTA() const { return itembonuses.HeroicSTA; }
@@ -466,6 +468,7 @@ public:
inline virtual int32 GetHeroicPR() const { return itembonuses.HeroicPR; }
inline virtual int32 GetHeroicCR() const { return itembonuses.HeroicCR; }
inline virtual int32 GetHeroicCorrup() const { return itembonuses.HeroicCorrup; }
inline virtual int32 GetHeroicPhR() const { return 0; } // Heroic PhR not implemented yet
// Mod2
inline virtual int32 GetShielding() const { return itembonuses.MeleeMitigation; }
inline virtual int32 GetSpellShield() const { return itembonuses.SpellShield; }
@@ -804,6 +807,7 @@ public:
int32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
bool PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update = false);
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
void SendCursorBuffer();
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
bool SwapItem(MoveItem_Struct* move_in);
void SwapItemResync(MoveItem_Struct* move_slots);
@@ -814,8 +818,56 @@ public:
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);
bool MakeItemLink(char* &ret_link, const ItemInst* inst);
int GetItemLinkHash(const ItemInst* inst);
//
// class Client::TextLink
//
class TextLink {
public:
enum LinkType { linkBlank = 0, linkItemData, linkLootItem, linkItemInst };
TextLink() { Reset(); }
void SetLinkType(LinkType linkType) { m_LinkType = linkType; }
void SetItemData(const Item_Struct* itemData) { m_ItemData = itemData; }
void SetLootData(const ServerLootItem_Struct* lootData) { m_LootData = lootData; }
void SetItemInst(const ItemInst* itemInst) { m_ItemInst = itemInst; }
void SetProxyItemID(uint32 proxyItemID) { m_ProxyItemID = proxyItemID; } // mainly for saylinks..but, not limited to
void SetProxyText(const char* proxyText) { m_ProxyText = proxyText; } // overrides standard text use
void SetTaskUse() { m_TaskUse = true; }
std::string GenerateLink();
bool LinkError() { return m_Error; }
std::string GetLink() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
std::string GetLinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
std::string GetLinkText() { return m_LinkText; } // contains string format: '<LinkText>'
void Reset();
static bool DegenerateLinkBody(TextLinkBody_Struct& textLinkBodyStruct, const std::string& textLinkBody);
static bool GenerateLinkBody(std::string& textLinkBody, const TextLinkBody_Struct& textLinkBodyStruct);
private:
void generate_body();
void generate_text();
int m_LinkType;
const Item_Struct* m_ItemData;
const ServerLootItem_Struct* m_LootData;
const ItemInst* m_ItemInst;
uint32 m_ProxyItemID;
const char* m_ProxyText;
bool m_TaskUse;
TextLinkBody_Struct m_LinkBodyStruct;
std::string m_Link;
std::string m_LinkBody;
std::string m_LinkText;
bool m_Error;
};
int GetItemLinkHash(const ItemInst* inst); // move to Item_Struct..or make use of the pre-calculated database field
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
void SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);
@@ -832,11 +884,11 @@ public:
bool Hungry() const {if (GetGM()) return false; return m_pp.hunger_level <= 3000;}
bool Thirsty() const {if (GetGM()) return false; return m_pp.thirst_level <= 3000;}
int32 GetHunger() const { return m_pp.hunger_level; }
int32 GetThirst() const { return m_pp.thirst_level; }
void SetHunger(int32 in_hunger);
void SetThirst(int32 in_thirst);
void SetConsumption(int32 in_hunger, int32 in_thirst);
int32 GetHunger() const { return m_pp.hunger_level; }
int32 GetThirst() const { return m_pp.thirst_level; }
void SetHunger(int32 in_hunger);
void SetThirst(int32 in_thirst);
void SetConsumption(int32 in_hunger, int32 in_thirst);
bool CheckTradeLoreConflict(Client* other);
void LinkDead();
@@ -937,7 +989,7 @@ void SetConsumption(int32 in_hunger, int32 in_thirst);
inline bool IsTaskActive(int TaskID) { return (taskstate ? taskstate->IsTaskActive(TaskID) : false); }
inline bool IsTaskActivityActive(int TaskID, int ActivityID) { return (taskstate ? taskstate->IsTaskActivityActive(TaskID, ActivityID) : false); }
inline ActivityState GetTaskActivityState(int index, int ActivityID) { return (taskstate ? taskstate->GetTaskActivityState(index, ActivityID) : ActivityHidden); }
inline void UpdateTaskActivity(int TaskID, int ActivityID, int Count) { if(taskstate) taskstate->UpdateTaskActivity(this, TaskID, ActivityID, Count); }
inline void UpdateTaskActivity(int TaskID, int ActivityID, int Count, bool ignore_quest_update = false) { if (taskstate) taskstate->UpdateTaskActivity(this, TaskID, ActivityID, Count, ignore_quest_update); }
inline void ResetTaskActivity(int TaskID, int ActivityID) { if(taskstate) taskstate->ResetTaskActivity(this, TaskID, ActivityID); }
inline void UpdateTasksOnKill(int NPCTypeID) { if(taskstate) taskstate->UpdateTasksOnKill(this, NPCTypeID); }
inline void UpdateTasksForItem(ActivityType Type, int ItemID, int Count=1) { if(taskstate) taskstate->UpdateTasksForItem(this, Type, ItemID, Count); }
+14 -14
View File
@@ -27,8 +27,8 @@ ClientLogs client_logs;
char ClientLogs::_buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
if(id >= EQEMuLog::MaxLogID)
void ClientLogs::subscribe(EQEmuLog::LogIDs id, Client *c) {
if(id >= EQEmuLog::MaxLogID)
return;
if(c == nullptr)
return;
@@ -47,8 +47,8 @@ void ClientLogs::subscribe(EQEMuLog::LogIDs id, Client *c) {
entries[id].push_back(c);
}
void ClientLogs::unsubscribe(EQEMuLog::LogIDs id, Client *c) {
if(id >= EQEMuLog::MaxLogID)
void ClientLogs::unsubscribe(EQEmuLog::LogIDs id, Client *c) {
if(id >= EQEmuLog::MaxLogID)
return;
if(c == nullptr)
return;
@@ -68,8 +68,8 @@ void ClientLogs::subscribeAll(Client *c) {
if(c == nullptr)
return;
int r;
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
subscribe((EQEMuLog::LogIDs)r, c);
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
subscribe((EQEmuLog::LogIDs)r, c);
}
}
@@ -77,20 +77,20 @@ void ClientLogs::unsubscribeAll(Client *c) {
if(c == nullptr)
return;
int r;
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
unsubscribe((EQEMuLog::LogIDs)r, c);
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
unsubscribe((EQEmuLog::LogIDs)r, c);
}
}
void ClientLogs::clear() {
int r;
for(r = EQEMuLog::Status; r < EQEMuLog::MaxLogID; r++) {
for(r = EQEmuLog::Status; r < EQEmuLog::MaxLogID; r++) {
entries[r].clear();
}
}
void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
if(id >= EQEMuLog::MaxLogID)
void ClientLogs::msg(EQEmuLog::LogIDs id, const char *buf) {
if(id >= EQEmuLog::MaxLogID)
return;
std::vector<Client *>::iterator cur,end;
cur = entries[id].begin();
@@ -103,7 +103,7 @@ void ClientLogs::msg(EQEMuLog::LogIDs id, const char *buf) {
}
}
void ClientLogs::EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count) {
void ClientLogs::EQEmuIO_buf(EQEmuLog::LogIDs id, const char *buf, uint8 size, uint32 count) {
if(size != 1)
return; //cannot print multibyte data
if(buf[0] == '\n' || buf[0] == '\r')
@@ -115,7 +115,7 @@ void ClientLogs::EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, u
client_logs.msg(id, _buffer);
}
void ClientLogs::EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap) {
void ClientLogs::EQEmuIO_fmt(EQEmuLog::LogIDs id, const char *fmt, va_list ap) {
if(fmt[0] == '\n' || fmt[0] == '\r')
return; //skip new lines...
vsnprintf(_buffer, MAX_CLIENT_LOG_MESSAGE_LENGTH, fmt, ap);
@@ -123,7 +123,7 @@ void ClientLogs::EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap) {
client_logs.msg(id, _buffer);
}
void ClientLogs::EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap) {
void ClientLogs::EQEmuIO_pva(EQEmuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap) {
if(fmt[0] == '\n' || fmt[0] == '\r')
return; //skip new lines...
char *buf = _buffer;
+7 -7
View File
@@ -35,21 +35,21 @@ class Client;
class ClientLogs {
public:
static void EQEmuIO_buf(EQEMuLog::LogIDs id, const char *buf, uint8 size, uint32 count);
static void EQEmuIO_fmt(EQEMuLog::LogIDs id, const char *fmt, va_list ap);
static void EQEmuIO_pva(EQEMuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap);
static void EQEmuIO_buf(EQEmuLog::LogIDs id, const char *buf, uint8 size, uint32 count);
static void EQEmuIO_fmt(EQEmuLog::LogIDs id, const char *fmt, va_list ap);
static void EQEmuIO_pva(EQEmuLog::LogIDs id, const char *prefix, const char *fmt, va_list ap);
void subscribe(EQEMuLog::LogIDs id, Client *c);
void unsubscribe(EQEMuLog::LogIDs id, Client *c);
void subscribe(EQEmuLog::LogIDs id, Client *c);
void unsubscribe(EQEmuLog::LogIDs id, Client *c);
void subscribeAll(Client *c);
void unsubscribeAll(Client *c);
void clear(); //unsubscribes everybody
void msg(EQEMuLog::LogIDs id, const char *buf);
void msg(EQEmuLog::LogIDs id, const char *buf);
protected:
std::vector<Client *> entries[EQEMuLog::MaxLogID];
std::vector<Client *> entries[EQEmuLog::MaxLogID];
static char _buffer[MAX_CLIENT_LOG_MESSAGE_LENGTH+1];
};
+5 -5
View File
@@ -825,7 +825,7 @@ int32 Client::acmod() {
return (65 + ((agility-300) / 21));
}
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Error, "Error in Client::acmod(): Agility: %i, Level: %i",agility,level);
LogFile->write(EQEmuLog::Error, "Error in Client::acmod(): Agility: %i, Level: %i",agility,level);
#endif
return 0;
};
@@ -934,7 +934,7 @@ int32 Client::CalcMaxMana()
break;
}
default: {
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
max_mana = 0;
break;
}
@@ -955,7 +955,7 @@ int32 Client::CalcMaxMana()
}
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug, "Client::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
LogFile->write(EQEmuLog::Debug, "Client::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
#endif
return max_mana;
}
@@ -1045,14 +1045,14 @@ int32 Client::CalcBaseMana()
break;
}
default: {
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
max_m = 0;
break;
}
}
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug, "Client::CalcBaseMana() called for %s - returning %d", GetName(), max_m);
LogFile->write(EQEmuLog::Debug, "Client::CalcBaseMana() called for %s - returning %d", GetName(), max_m);
#endif
return max_m;
}
+348 -236
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -1023,7 +1023,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
// Account for merchant lists with gaps.
if (ml.slot >= i) {
if (ml.slot > i)
LogFile->write(EQEMuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
LogFile->write(EQEmuLog::Debug, "(WARNING) Merchantlist contains gap at slot %d. Merchant: %d, NPC: %d", i, merchant_id, npcid);
i = ml.slot + 1;
}
}
@@ -1187,7 +1187,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
{
if(app->size != sizeof(MemorizeSpell_Struct))
{
LogFile->write(EQEMuLog::Error,"Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
LogFile->write(EQEmuLog::Error,"Wrong size on OP_MemorizeSpell. Got: %i, Expected: %i", app->size, sizeof(MemorizeSpell_Struct));
DumpPacket(app);
return;
}
+469 -598
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -135,7 +135,8 @@ enum {
NPC_CHASE_DISTANCE = 40,
ALLOW_TO_TANK = 41,
IGNORE_ROOT_AGGRO_RULES = 42,
MAX_SPECIAL_ATTACK = 43
CASTING_RESIST_DIFF = 43,
MAX_SPECIAL_ATTACK = 44
};
typedef enum { //fear states
+19 -21
View File
@@ -781,7 +781,7 @@ bool Corpse::Process() {
spc->zone_id = zone->graveyard_zoneid();
worldserver.SendPacket(pack);
safe_delete(pack);
LogFile->write(EQEMuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
LogFile->write(EQEmuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
corpse_db_id = 0;
}
@@ -811,10 +811,10 @@ bool Corpse::Process() {
Save();
player_corpse_depop = true;
corpse_db_id = 0;
LogFile->write(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName());
LogFile->write(EQEmuLog::Debug, "Tagged %s player corpse has burried.", this->GetName());
}
else {
LogFile->write(EQEMuLog::Error, "Unable to bury %s player corpse.", this->GetName());
LogFile->write(EQEmuLog::Error, "Unable to bury %s player corpse.", this->GetName());
return true;
}
}
@@ -1017,7 +1017,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
for(; cur != end; ++cur) {
ServerLootItem_Struct* item_data = *cur;
item = database.GetItem(item_data->item_id);
LogFile->write(EQEMuLog::Debug, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
LogFile->write(EQEmuLog::Debug, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
client->Message(0, "Inaccessable Corpse Item: %s", item->Name);
}
}
@@ -1142,7 +1142,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
if ((RuleB(Character, EnableDiscoveredItems))) {
if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
client->DiscoverItem(inst->GetItem()->ID);
}
@@ -1189,33 +1189,31 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
}
}
if (GetPlayerKillItem() != -1){
if (GetPlayerKillItem() != -1) {
SetPlayerKillItemID(0);
}
/* Send message with item link to groups and such */
char *link = 0, *link2 = 0; //just like a db query :-)
client->MakeItemLink(link2, inst);
MakeAnyLenString(&link, "%c" "%s" "%s" "%c",
0x12,
link2,
item->Name,
0x12);
safe_delete_array(link2);
/* Send message with item link to groups and such */
Client::TextLink linker;
linker.SetLinkType(linker.linkItemInst);
linker.SetItemInst(inst);
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, link);
if(!IsPlayerCorpse()) {
auto item_link = linker.GenerateLink();
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
if (!IsPlayerCorpse()) {
Group *g = client->GetGroup();
if(g != nullptr) {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link);
} else {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
}
else {
Raid *r = client->GetRaid();
if(r != nullptr) {
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), link);
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
}
}
}
safe_delete_array(link);
}
else {
SendEndLootErrorPacket(client);
+5 -5
View File
@@ -290,7 +290,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1);
#if EQDEBUG>=5
LogFile->write(EQEMuLog::Debug, "Client has lockpicks: skill=%f", modskill);
LogFile->write(EQEmuLog::Debug, "Client has lockpicks: skill=%f", modskill);
#endif
if(GetLockpick() <= modskill)
@@ -547,13 +547,13 @@ void Doors::ToggleState(Mob *sender)
}
void Doors::DumpDoor(){
LogFile->write(EQEMuLog::Debug,
LogFile->write(EQEmuLog::Debug,
"db_id:%i door_id:%i zone_name:%s door_name:%s %s",
db_id, door_id, zone_name, door_name, to_string(m_Position).c_str());
LogFile->write(EQEMuLog::Debug,
LogFile->write(EQEmuLog::Debug,
"opentype:%i guild_id:%i lockpick:%i keyitem:%i nokeyring:%i trigger_door:%i trigger_type:%i door_param:%i open:%s",
opentype, guild_id, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param, (isopen) ? "open":"closed");
LogFile->write(EQEMuLog::Debug,
LogFile->write(EQEmuLog::Debug,
"dest_zone:%s destination:%s ",
dest_zone, to_string(m_Destination).c_str());
}
@@ -632,7 +632,7 @@ int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version)
}
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
LogFile->write(EQEmuLog::Status, "Loading Doors from database...");
// Door tmpDoor;
+1 -1
View File
@@ -460,7 +460,7 @@ bool Client::TrainDiscipline(uint32 itemid) {
const Item_Struct *item = database.GetItem(itemid);
if(item == nullptr) {
Message(13, "Unable to find the tome you turned in!");
LogFile->write(EQEMuLog::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
LogFile->write(EQEmuLog::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
return(false);
}
+11 -1
View File
@@ -140,7 +140,7 @@ void PerlembParser::ReloadQuests() {
perl = nullptr;
}
LogFile->write(EQEMuLog::Status, "Error re-initializing perlembed: %s", e.what());
LogFile->write(EQEmuLog::Status, "Error re-initializing perlembed: %s", e.what());
throw e.what();
}
@@ -232,6 +232,7 @@ int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::stri
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers) {
// needs pointer validation on 'item' argument
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
}
@@ -335,6 +336,9 @@ bool PerlembParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
if(!perl)
return false;
if (itm == nullptr)
return false;
if(evt >= _LargestEventID)
return false;
@@ -449,6 +453,9 @@ void PerlembParser::LoadGlobalPlayerScript(std::string filename) {
}
void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
if (item == nullptr)
return;
std::stringstream package_name;
package_name << "qst_item_" << item->GetID();
@@ -855,6 +862,7 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye
}
}
else if(isItemQuest) {
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
const Item_Struct* item = iteminst->GetItem();
package_name = "qst_item_";
package_name += itoa(item->ID);
@@ -1292,6 +1300,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
case EVENT_SCALE_CALC:
case EVENT_ITEM_ENTER_ZONE: {
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
ExportVar(package_name.c_str(), "itemid", objid);
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
break;
@@ -1299,6 +1308,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
case EVENT_ITEM_CLICK_CAST:
case EVENT_ITEM_CLICK: {
// need a valid ItemInst pointer check here..unsure how to cancel this process -U
ExportVar(package_name.c_str(), "itemid", objid);
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
ExportVar(package_name.c_str(), "slotid", extradata);
+206 -202
View File
@@ -270,7 +270,6 @@ XS(XS__unique_spawn)
if(items == 7)
heading = (float)SvNV(ST(6));
Mob *r = quest_manager.unique_spawn(npc_type, grid, unused, xyz_heading(x, y, z, heading));
RETVAL = (r != nullptr) ? r->GetID() : 0;
@@ -2267,18 +2266,22 @@ XS(XS__updatetaskactivity)
dXSARGS;
unsigned int task, activity;
int count = 1;
bool ignore_quest_update = false;
if(items == 2) {
task = (int)SvIV(ST(0));
activity = (int)SvIV(ST(1));
quest_manager.updatetaskactivity(task, activity, count);
quest_manager.updatetaskactivity(task, activity, count, false);
}
else if(items == 3) {
else if (items == 3 || items == 4) {
task = (int)SvIV(ST(0));
activity = (int)SvIV(ST(1));
count = (int)SvIV(ST(2));
quest_manager.updatetaskactivity(task, activity, count);
if (items == 4){
bool ignore_quest_update = (bool)SvTRUE(ST(3));
}
quest_manager.updatetaskactivity(task, activity, count, ignore_quest_update);
} else {
Perl_croak(aTHX_ "Usage: updatetaskactivity(task, activity [,count])");
Perl_croak(aTHX_ "Usage: updatetaskactivity(task, activity, [count], [ignore_quest_update])");
}
XSRETURN_EMPTY;
@@ -3503,221 +3506,222 @@ EXTERN_C XS(boot_quest)
file[255] = '\0';
if(items != 1)
LogFile->write(EQEMuLog::Error, "boot_quest does not take any arguments.");
LogFile->write(EQEmuLog::Error, "boot_quest does not take any arguments.");
char buf[128]; //shouldent have any function names longer than this.
//add the strcpy stuff to get rid of const warnings....
XS_VERSION_BOOTCHECK ;
newXS(strcpy(buf, "echo"), XS__echo, file);
newXS(strcpy(buf, "say"), XS__say, file);
newXS(strcpy(buf, "me"), XS__me, file);
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
newXS(strcpy(buf, "write"), XS__write, file);
newXS(strcpy(buf, "spawn"), XS__spawn, file);
newXS(strcpy(buf, "spawn2"), XS__spawn2, file);
newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file);
newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file);
newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file);
newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file);
newXS(strcpy(buf, "setstat"), XS__setstat, file);
newXS(strcpy(buf, "incstat"), XS__incstat, file);
newXS(strcpy(buf, "castspell"), XS__castspell, file);
newXS(strcpy(buf, "selfcast"), XS__selfcast, file);
#ifdef BOTS
newXS(strcpy(buf, "botquest"), XS__botquest, file);
newXS(strcpy(buf, "spawnbotcount"), XS__spawnbotcount, file);
newXS(strcpy(buf, "createbotcount"), XS__createbotcount, file);
newXS(strcpy(buf, "createBot"), XS__createBot, file);
#endif //BOTS
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file);
newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file);
newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file);
newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file);
newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file);
newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file);
newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file);
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
newXS(strcpy(buf, "addloot"), XS__addloot, file);
newXS(strcpy(buf, "zone"), XS__zone, file);
newXS(strcpy(buf, "settimer"), XS__settimer, file);
newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file);
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
newXS(strcpy(buf, "emote"), XS__emote, file);
newXS(strcpy(buf, "shout"), XS__shout, file);
newXS(strcpy(buf, "shout2"), XS__shout2, file);
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
newXS(strcpy(buf, "depop"), XS__depop, file);
newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file);
newXS(strcpy(buf, "settarget"), XS__settarget, file);
newXS(strcpy(buf, "follow"), XS__follow, file);
newXS(strcpy(buf, "sfollow"), XS__sfollow, file);
newXS(strcpy(buf, "changedeity"), XS__changedeity, file);
newXS(strcpy(buf, "exp"), XS__exp, file);
newXS(strcpy(buf, "level"), XS__level, file);
newXS(strcpy(buf, "traindisc"), XS__traindisc, file);
newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file);
newXS(strcpy(buf, "safemove"), XS__safemove, file);
newXS(strcpy(buf, "rain"), XS__rain, file);
newXS(strcpy(buf, "snow"), XS__snow, file);
newXS(strcpy(buf, "surname"), XS__surname, file);
newXS(strcpy(buf, "permaclass"), XS__permaclass, file);
newXS(strcpy(buf, "permarace"), XS__permarace, file);
newXS(strcpy(buf, "permagender"), XS__permagender, file);
newXS(strcpy(buf, "scribespells"), XS__scribespells, file);
newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file);
newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file);
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
newXS(strcpy(buf, "givecash"), XS__givecash, file);
newXS(strcpy(buf, "pvp"), XS__pvp, file);
newXS(strcpy(buf, "movepc"), XS__movepc, file);
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
newXS(strcpy(buf, "movegrp"), XS__movegrp, file);
newXS(strcpy(buf, "doanim"), XS__doanim, file);
newXS(strcpy(buf, "addskill"), XS__addskill, file);
newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file);
newXS(strcpy(buf, "setskill"), XS__setskill, file);
newXS(strcpy(buf, "setallskill"), XS__setallskill, file);
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
newXS(strcpy(buf, "attack"), XS__attack, file);
newXS(strcpy(buf, "attacknpc"), XS__attacknpc, file);
newXS(strcpy(buf, "attacknpctype"), XS__attacknpctype, file);
newXS(strcpy(buf, "save"), XS__save, file);
newXS(strcpy(buf, "faction"), XS__faction, file);
newXS(strcpy(buf, "setsky"), XS__setsky, file);
newXS(strcpy(buf, "setguild"), XS__setguild, file);
newXS(strcpy(buf, "createguild"), XS__createguild, file);
newXS(strcpy(buf, "settime"), XS__settime, file);
newXS(strcpy(buf, "itemlink"), XS__itemlink, file);
newXS(strcpy(buf, "signal"), XS__signal, file);
newXS(strcpy(buf, "signalwith"), XS__signalwith, file);
newXS(strcpy(buf, "setglobal"), XS__setglobal, file);
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
newXS(strcpy(buf, "delglobal"), XS__delglobal, file);
newXS(strcpy(buf, "ding"), XS__ding, file);
newXS(strcpy(buf, "rebind"), XS__rebind, file);
newXS(strcpy(buf, "start"), XS__start, file);
newXS(strcpy(buf, "stop"), XS__stop, file);
newXS(strcpy(buf, "pause"), XS__pause, file);
newXS(strcpy(buf, "moveto"), XS__moveto, file);
newXS(strcpy(buf, "resume"), XS__resume, file);
newXS(strcpy(buf, "addldonpoints"), XS__addldonpoints, file);
newXS(strcpy(buf, "addldonwin"), XS__addldonpoints, file);
newXS(strcpy(buf, "addldonloss"), XS__addldonpoints, file);
newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file);
newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file);
newXS(strcpy(buf, "sethp"), XS__sethp, file);
newXS(strcpy(buf, "respawn"), XS__respawn, file);
newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file);
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file);
newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file);
newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file);
newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file);
newXS(strcpy(buf, "setanim"), XS__setanim, file);
newXS(strcpy(buf, "showgrid"), XS__showgrid, file);
newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file);
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file);
newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file);
newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file);
newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file);
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
newXS(strcpy(buf, "buryplayercorpse"), XS__buryplayercorpse, file);
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file);
newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file);
newXS(strcpy(buf, "depopall"), XS__depopall, file);
newXS(strcpy(buf, "depopzone"), XS__depopzone, file);
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
newXS(strcpy(buf, "npcrace"), XS__npcrace, file);
newXS(strcpy(buf, "npcgender"), XS__npcgender, file);
newXS(strcpy(buf, "npcsize"), XS__npcsize, file);
newXS(strcpy(buf, "npctexture"), XS__npctexture, file);
newXS(strcpy(buf, "playerrace"), XS__playerrace, file);
newXS(strcpy(buf, "playergender"), XS__playergender, file);
newXS(strcpy(buf, "playersize"), XS__playersize, file);
newXS(strcpy(buf, "playertexture"), XS__playertexture, file);
newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file);
newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file);
#ifdef BOTS
newXS(strcpy(buf, "botquest"), XS__botquest, file);
newXS(strcpy(buf, "spawnbotcount"), XS__spawnbotcount, file);
newXS(strcpy(buf, "createbotcount"), XS__createbotcount, file);
newXS(strcpy(buf, "createBot"), XS__createBot, file);
#endif //BOTS
newXS(strcpy(buf, "taskselector"), XS__taskselector, file);
newXS(strcpy(buf, "tasksetselector"), XS__tasksetselector, file);
newXS(strcpy(buf, "enabletask"), XS__enabletask, file);
newXS(strcpy(buf, "disabletask"), XS__disabletask, file);
newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file);
newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file);
newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file);
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file);
newXS(strcpy(buf, "assigntask"), XS__assigntask, file);
newXS(strcpy(buf, "failtask"), XS__failtask, file);
newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file);
newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file);
newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file);
newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file);
newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file);
newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file);
newXS(strcpy(buf, "activespeaktask"), XS__activespeaktask, file);
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
newXS(strcpy(buf, "activetasksinset"), XS__activetasksinset, file);
newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file);
newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file);
newXS(strcpy(buf, "popup"), XS__popup, file);
newXS(strcpy(buf, "castspell"), XS__castspell, file);
newXS(strcpy(buf, "changedeity"), XS__changedeity, file);
newXS(strcpy(buf, "checktitle"), XS__checktitle, file);
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
newXS(strcpy(buf, "clear_proximity"), XS__clear_proximity, file);
newXS(strcpy(buf, "clear_zone_flag"), XS__clear_zone_flag, file);
newXS(strcpy(buf, "clearspawntimers"), XS__clearspawntimers, file);
newXS(strcpy(buf, "ze"), XS__ze, file);
newXS(strcpy(buf, "we"), XS__we, file);
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
newXS(strcpy(buf, "completedtasksinset"), XS__completedtasksinset, file);
newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file);
newXS(strcpy(buf, "creategroundobject"), XS__CreateGroundObject, file);
newXS(strcpy(buf, "creategroundobjectfrommodel"), XS__CreateGroundObjectFromModel, file);
newXS(strcpy(buf, "createdoor"), XS__CreateDoor, file);
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
newXS(strcpy(buf, "collectitems"), XS__collectitems, file);
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
newXS(strcpy(buf, "MerchantSetItem"), XS__MerchantSetItem, file);
newXS(strcpy(buf, "MerchantCountItem"), XS__MerchantCountItem, file);
newXS(strcpy(buf, "varlink"), XS__varlink, file);
newXS(strcpy(buf, "saylink"), XS__saylink, file);
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
newXS(strcpy(buf, "IsRunning"), XS__IsRunning, file);
newXS(strcpy(buf, "IsEffectInSpell"), XS__IsEffectInSpell, file);
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file);
newXS(strcpy(buf, "checktitle"), XS__checktitle, file);
newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file);
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
newXS(strcpy(buf, "wearchange"), XS__wearchange, file);
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
newXS(strcpy(buf, "LearnRecipe"), XS__LearnRecipe, file);
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
newXS(strcpy(buf, "createguild"), XS__createguild, file);
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
newXS(strcpy(buf, "crosszonesignalclientbycharid"), XS__crosszonesignalclientbycharid, file);
newXS(strcpy(buf, "crosszonesignalclientbyname"), XS__crosszonesignalclientbyname, file);
newXS(strcpy(buf, "crosszonemessageplayerbyname"), XS__crosszonemessageplayerbyname, file);
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
newXS(strcpy(buf, "crosszonesetentityvariablebynpctypeid"), XS__crosszonesetentityvariablebynpctypeid, file);
newXS(strcpy(buf, "crosszonesignalnpcbynpctypeid"), XS__crosszonesignalnpcbynpctypeid, file);
newXS(strcpy(buf, "delglobal"), XS__delglobal, file);
newXS(strcpy(buf, "depop"), XS__depop, file);
newXS(strcpy(buf, "depop_withtimer"), XS__depop_withtimer, file);
newXS(strcpy(buf, "depopall"), XS__depopall, file);
newXS(strcpy(buf, "depopzone"), XS__depopzone, file);
newXS(strcpy(buf, "ding"), XS__ding, file);
newXS(strcpy(buf, "disable_proximity_say"), XS__disable_proximity_say, file);
newXS(strcpy(buf, "disable_spawn2"), XS__disable_spawn2, file);
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
newXS(strcpy(buf, "disabletask"), XS__disabletask, file);
newXS(strcpy(buf, "doanim"), XS__doanim, file);
newXS(strcpy(buf, "echo"), XS__echo, file);
newXS(strcpy(buf, "emote"), XS__emote, file);
newXS(strcpy(buf, "enable_proximity_say"), XS__enable_proximity_say, file);
newXS(strcpy(buf, "enable_spawn2"), XS__enable_spawn2, file);
newXS(strcpy(buf, "enabledtaskcount"), XS__enabledtaskcount, file);
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
newXS(strcpy(buf, "enabletask"), XS__enabletask, file);
newXS(strcpy(buf, "enabletitle"), XS__enabletitle, file);
newXS(strcpy(buf, "exp"), XS__exp, file);
newXS(strcpy(buf, "faction"), XS__faction, file);
newXS(strcpy(buf, "factionvalue"), XS_FactionValue, file);
newXS(strcpy(buf, "failtask"), XS__failtask, file);
newXS(strcpy(buf, "firsttaskinset"), XS__firsttaskinset, file);
newXS(strcpy(buf, "follow"), XS__follow, file);
newXS(strcpy(buf, "forcedoorclose"), XS__forcedoorclose, file);
newXS(strcpy(buf, "forcedooropen"), XS__forcedooropen, file);
newXS(strcpy(buf, "getItemName"), XS_qc_getItemName, file);
newXS(strcpy(buf, "get_spawn_condition"), XS__get_spawn_condition, file);
newXS(strcpy(buf, "getguildnamebyid"), XS__getguildnamebyid, file);
newXS(strcpy(buf, "getlevel"), XS__getlevel, file);
newXS(strcpy(buf, "getplayerburriedcorpsecount"), XS__getplayerburriedcorpsecount, file);
newXS(strcpy(buf, "gettaskactivitydonecount"), XS__gettaskactivitydonecount, file);
newXS(strcpy(buf, "givecash"), XS__givecash, file);
newXS(strcpy(buf, "gmmove"), XS__gmmove, file);
newXS(strcpy(buf, "gmsay"), XS__gmsay, file);
newXS(strcpy(buf, "has_zone_flag"), XS__has_zone_flag, file);
newXS(strcpy(buf, "incstat"), XS__incstat, file);
newXS(strcpy(buf, "isdisctome"), XS__isdisctome, file);
newXS(strcpy(buf, "isdooropen"), XS__isdooropen, file);
newXS(strcpy(buf, "istaskactive"), XS__istaskactive, file);
newXS(strcpy(buf, "istaskactivityactive"), XS__istaskactivityactive, file);
newXS(strcpy(buf, "istaskappropriate"), XS__istaskappropriate, file);
newXS(strcpy(buf, "istaskcompleted"), XS__istaskcompleted, file);
newXS(strcpy(buf, "istaskenabled"), XS__istaskenabled, file);
newXS(strcpy(buf, "itemlink"), XS__itemlink, file);
newXS(strcpy(buf, "lasttaskinset"), XS__lasttaskinset, file);
newXS(strcpy(buf, "level"), XS__level, file);
newXS(strcpy(buf, "me"), XS__me, file);
newXS(strcpy(buf, "modifynpcstat"), XS__ModifyNPCStat, file);
newXS(strcpy(buf, "movegrp"), XS__movegrp, file);
newXS(strcpy(buf, "movepc"), XS__movepc, file);
newXS(strcpy(buf, "moveto"), XS__moveto, file);
newXS(strcpy(buf, "nexttaskinset"), XS__nexttaskinset, file);
newXS(strcpy(buf, "npcfeature"), XS__npcfeature, file);
newXS(strcpy(buf, "npcgender"), XS__npcgender, file);
newXS(strcpy(buf, "npcrace"), XS__npcrace, file);
newXS(strcpy(buf, "npcsize"), XS__npcsize, file);
newXS(strcpy(buf, "npctexture"), XS__npctexture, file);
newXS(strcpy(buf, "pause"), XS__pause, file);
newXS(strcpy(buf, "permaclass"), XS__permaclass, file);
newXS(strcpy(buf, "permagender"), XS__permagender, file);
newXS(strcpy(buf, "permarace"), XS__permarace, file);
newXS(strcpy(buf, "playerfeature"), XS__playerfeature, file);
newXS(strcpy(buf, "playergender"), XS__playergender, file);
newXS(strcpy(buf, "playerrace"), XS__playerrace, file);
newXS(strcpy(buf, "playersize"), XS__playersize, file);
newXS(strcpy(buf, "playertexture"), XS__playertexture, file);
newXS(strcpy(buf, "popup"), XS__popup, file);
newXS(strcpy(buf, "pvp"), XS__pvp, file);
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
newXS(strcpy(buf, "rain"), XS__rain, file);
newXS(strcpy(buf, "rebind"), XS__rebind, file);
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
newXS(strcpy(buf, "respawn"), XS__respawn, file);
newXS(strcpy(buf, "resume"), XS__resume, file);
newXS(strcpy(buf, "safemove"), XS__safemove, file);
newXS(strcpy(buf, "save"), XS__save, file);
newXS(strcpy(buf, "say"), XS__say, file);
newXS(strcpy(buf, "saylink"), XS__saylink, file);
newXS(strcpy(buf, "scribespells"), XS__scribespells, file);
newXS(strcpy(buf, "selfcast"), XS__selfcast, file);
newXS(strcpy(buf, "set_proximity"), XS__set_proximity, file);
newXS(strcpy(buf, "set_zone_flag"), XS__set_zone_flag, file);
newXS(strcpy(buf, "setallskill"), XS__setallskill, file);
newXS(strcpy(buf, "setanim"), XS__setanim, file);
newXS(strcpy(buf, "setglobal"), XS__setglobal, file);
newXS(strcpy(buf, "setguild"), XS__setguild, file);
newXS(strcpy(buf, "sethp"), XS__sethp, file);
newXS(strcpy(buf, "setlanguage"), XS__setlanguage, file);
newXS(strcpy(buf, "setnexthpevent"), XS__setnexthpevent, file);
newXS(strcpy(buf, "setnextinchpevent"), XS__setnextinchpevent, file);
newXS(strcpy(buf, "setskill"), XS__setskill, file);
newXS(strcpy(buf, "setsky"), XS__setsky, file);
newXS(strcpy(buf, "setstat"), XS__setstat, file);
newXS(strcpy(buf, "settarget"), XS__settarget, file);
newXS(strcpy(buf, "settime"), XS__settime, file);
newXS(strcpy(buf, "settimer"), XS__settimer, file);
newXS(strcpy(buf, "settimerMS"), XS__settimerMS, file);
newXS(strcpy(buf, "sfollow"), XS__sfollow, file);
newXS(strcpy(buf, "shout"), XS__shout, file);
newXS(strcpy(buf, "shout2"), XS__shout2, file);
newXS(strcpy(buf, "showgrid"), XS__showgrid, file);
newXS(strcpy(buf, "signal"), XS__signal, file);
newXS(strcpy(buf, "signalwith"), XS__signalwith, file);
newXS(strcpy(buf, "snow"), XS__snow, file);
newXS(strcpy(buf, "spawn"), XS__spawn, file);
newXS(strcpy(buf, "spawn2"), XS__spawn2, file);
newXS(strcpy(buf, "spawn_condition"), XS__spawn_condition, file);
newXS(strcpy(buf, "spawn_from_spawn2"), XS__spawn_from_spawn2, file);
newXS(strcpy(buf, "start"), XS__start, file);
newXS(strcpy(buf, "stop"), XS__stop, file);
newXS(strcpy(buf, "stopalltimers"), XS__stopalltimers, file);
newXS(strcpy(buf, "stoptimer"), XS__stoptimer, file);
newXS(strcpy(buf, "summonallplayercorpses"), XS__summonallplayercorpses, file);
newXS(strcpy(buf, "summonburriedplayercorpse"), XS__summonburriedplayercorpse, file);
newXS(strcpy(buf, "summonitem"), XS__summonitem, file);
newXS(strcpy(buf, "surname"), XS__surname, file);
newXS(strcpy(buf, "targlobal"), XS__targlobal, file);
newXS(strcpy(buf, "taskexploredarea"), XS__taskexploredarea, file);
newXS(strcpy(buf, "taskselector"), XS__taskselector, file);
newXS(strcpy(buf, "tasksetselector"), XS__tasksetselector, file);
newXS(strcpy(buf, "tasktimeleft"), XS__tasktimeleft, file);
newXS(strcpy(buf, "toggle_spawn_event"), XS__toggle_spawn_event, file);
newXS(strcpy(buf, "toggledoorstate"), XS__toggledoorstate, file);
newXS(strcpy(buf, "traindisc"), XS__traindisc, file);
newXS(strcpy(buf, "traindiscs"), XS__traindiscs, file);
newXS(strcpy(buf, "unique_spawn"), XS__unique_spawn, file);
newXS(strcpy(buf, "unscribespells"), XS__unscribespells, file);
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
newXS(strcpy(buf, "varlink"), XS__varlink, file);
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
newXS(strcpy(buf, "we"), XS__we, file);
newXS(strcpy(buf, "wearchange"), XS__wearchange, file);
newXS(strcpy(buf, "write"), XS__write, file);
newXS(strcpy(buf, "ze"), XS__ze, file);
newXS(strcpy(buf, "zone"), XS__zone, file);
XSRETURN_YES;
}
+7 -5
View File
@@ -139,12 +139,12 @@ void Embperl::DoInit() {
catch(const char *err)
{
//remember... lasterr() is no good if we crap out here, in construction
LogFile->write(EQEMuLog::Quest, "perl error: %s", err);
LogFile->write(EQEmuLog::Quest, "perl error: %s", err);
throw "failed to install eval_file hook";
}
#ifdef EMBPERL_IO_CAPTURE
LogFile->write(EQEMuLog::Quest, "Tying perl output to eqemu logs");
LogFile->write(EQEmuLog::Quest, "Tying perl output to eqemu logs");
//make a tieable class to capture IO and pass it into EQEMuLog
eval_pv(
"package EQEmuIO; "
@@ -169,14 +169,14 @@ void Embperl::DoInit() {
,FALSE
);
LogFile->write(EQEMuLog::Quest, "Loading perlemb plugins.");
LogFile->write(EQEmuLog::Quest, "Loading perlemb plugins.");
try
{
eval_pv("main::eval_file('plugin', 'plugin.pl');", FALSE);
}
catch(const char *err)
{
LogFile->write(EQEMuLog::Quest, "Warning - plugin.pl: %s", err);
LogFile->write(EQEmuLog::Quest, "Warning - plugin.pl: %s", err);
}
try
{
@@ -194,7 +194,7 @@ void Embperl::DoInit() {
}
catch(const char *err)
{
LogFile->write(EQEMuLog::Quest, "Perl warning: %s", err);
LogFile->write(EQEmuLog::Quest, "Perl warning: %s", err);
}
#endif //EMBPERL_PLUGIN
in_use = false;
@@ -210,6 +210,8 @@ Embperl::~Embperl()
" if(tied *STDERR) { untie(*STDERR); }"
,FALSE);
#endif
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
my_perl = NULL;
+3 -3
View File
@@ -63,7 +63,7 @@ EXTERN_C XS(boot_qc)
file[255] = '\0';
if(items != 1)
LogFile->write(EQEMuLog::Error, "boot_qc does not take any arguments.");
LogFile->write(EQEmuLog::Error, "boot_qc does not take any arguments.");
char buf[128]; //shouldent have any function names longer than this.
@@ -96,7 +96,7 @@ XS(XS_EQEmuIO_PRINT)
int len = 0;
for(i = 0; *cur != '\0'; i++, cur++) {
if(*cur == '\n') {
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
LogFile->writebuf(EQEmuLog::Quest, str + pos, 1, len);
len = 0;
pos = i+1;
} else {
@@ -104,7 +104,7 @@ XS(XS_EQEmuIO_PRINT)
}
}
if(len > 0) {
LogFile->writebuf(EQEMuLog::Quest, str + pos, 1, len);
LogFile->writebuf(EQEmuLog::Quest, str + pos, 1, len);
}
}
+32 -31
View File
@@ -371,7 +371,7 @@ void EntityList::CheckGroupList (const char *fname, const int fline)
{
if (*it == nullptr)
{
LogFile->write(EQEMuLog::Error, "nullptr group, %s:%i", fname, fline);
LogFile->write(EQEmuLog::Error, "nullptr group, %s:%i", fname, fline);
}
}
}
@@ -529,12 +529,12 @@ void EntityList::MobProcess()
zone->StartShutdownTimer();
Group *g = GetGroupByMob(mob);
if(g) {
LogFile->write(EQEMuLog::Error, "About to delete a client still in a group.");
LogFile->write(EQEmuLog::Error, "About to delete a client still in a group.");
g->DelMember(mob);
}
Raid *r = entity_list.GetRaidByClient(mob->CastToClient());
if(r) {
LogFile->write(EQEMuLog::Error, "About to delete a client still in a raid.");
LogFile->write(EQEmuLog::Error, "About to delete a client still in a raid.");
r->MemberZoned(mob->CastToClient());
}
entity_list.RemoveClient(id);
@@ -566,7 +566,7 @@ void EntityList::AddGroup(Group *group)
uint32 gid = worldserver.NextGroupID();
if (gid == 0) {
LogFile->write(EQEMuLog::Error,
LogFile->write(EQEmuLog::Error,
"Unable to get new group ID from world server. group is going to be broken.");
return;
}
@@ -595,7 +595,7 @@ void EntityList::AddRaid(Raid *raid)
uint32 gid = worldserver.NextGroupID();
if (gid == 0) {
LogFile->write(EQEMuLog::Error,
LogFile->write(EQEmuLog::Error,
"Unable to get new group ID from world server. group is going to be broken.");
return;
}
@@ -2025,13 +2025,16 @@ void EntityList::RemoveAllNPCs()
void EntityList::RemoveAllMercs()
{
// doesn't clear the data
merc_list.clear();
}
void EntityList::RemoveAllGroups()
{
while (group_list.size())
while (group_list.size()) {
safe_delete(group_list.front());
group_list.pop_front();
}
#if EQDEBUG >= 5
CheckGroupList (__FILE__, __LINE__);
#endif
@@ -2039,8 +2042,10 @@ void EntityList::RemoveAllGroups()
void EntityList::RemoveAllRaids()
{
while (raid_list.size())
while (raid_list.size()) {
safe_delete(raid_list.front());
raid_list.pop_front();
}
}
void EntityList::RemoveAllDoors()
@@ -2250,7 +2255,8 @@ bool EntityList::RemoveGroup(uint32 delete_id)
while(iterator != group_list.end())
{
if((*iterator)->GetID() == delete_id) {
group_list.remove (*iterator);
safe_delete(*iterator);
group_list.remove(*iterator);
#if EQDEBUG >= 5
CheckGroupList (__FILE__, __LINE__);
#endif
@@ -2273,7 +2279,8 @@ bool EntityList::RemoveRaid(uint32 delete_id)
while(iterator != raid_list.end())
{
if((*iterator)->GetID() == delete_id) {
raid_list.remove (*iterator);
safe_delete(*iterator);
raid_list.remove(*iterator);
return true;
}
++iterator;
@@ -2433,7 +2440,7 @@ void EntityList::RemoveFromHateLists(Mob *mob, bool settoone)
if (!settoone)
it->second->RemoveFromHateList(mob);
else
it->second->SetHate(mob, 1);
it->second->SetHateAmountOnEnt(mob, 1);
}
++it;
}
@@ -2522,7 +2529,7 @@ char *EntityList::MakeNameUnique(char *name)
return name;
}
}
LogFile->write(EQEMuLog::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
LogFile->write(EQEmuLog::Error, "Fatal error in EntityList::MakeNameUnique: Unable to find unique name for '%s'", name);
char tmp[64] = "!";
strn0cpy(&tmp[1], name, sizeof(tmp) - 1);
strcpy(name, tmp);
@@ -2817,7 +2824,7 @@ void EntityList::DoubleAggro(Mob *who)
auto it = npc_list.begin();
while (it != npc_list.end()) {
if (it->second->CheckAggro(who))
it->second->SetHate(who, it->second->CastToNPC()->GetHateAmount(who),
it->second->SetHateAmountOnEnt(who, it->second->CastToNPC()->GetHateAmount(who),
it->second->CastToNPC()->GetHateAmount(who) * 2);
++it;
}
@@ -2828,7 +2835,7 @@ void EntityList::HalveAggro(Mob *who)
auto it = npc_list.begin();
while (it != npc_list.end()) {
if (it->second->CastToNPC()->CheckAggro(who))
it->second->CastToNPC()->SetHate(who, it->second->CastToNPC()->GetHateAmount(who) / 2);
it->second->CastToNPC()->SetHateAmountOnEnt(who, it->second->CastToNPC()->GetHateAmount(who) / 2);
++it;
}
}
@@ -2843,9 +2850,9 @@ void EntityList::Evade(Mob *who)
amt = it->second->CastToNPC()->GetHateAmount(who);
amt -= flatval;
if (amt > 0)
it->second->CastToNPC()->SetHate(who, amt);
it->second->CastToNPC()->SetHateAmountOnEnt(who, amt);
else
it->second->CastToNPC()->SetHate(who, 0);
it->second->CastToNPC()->SetHateAmountOnEnt(who, 0);
}
++it;
}
@@ -2913,7 +2920,7 @@ void EntityList::ClearZoneFeignAggro(Client *targ)
}
}
void EntityList::AggroZone(Mob *who, int hate)
void EntityList::AggroZone(Mob *who, uint32 hate)
{
auto it = npc_list.begin();
while (it != npc_list.end()) {
@@ -2934,11 +2941,6 @@ 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)
{
std::list<std::pair<Mob *, float> > tracking_list;
@@ -2956,8 +2958,6 @@ bool EntityList::MakeTrackPacket(Client *client)
if (distance < 300)
distance = 300;
Group *g = client->GetGroup();
for (auto it = mob_list.cbegin(); it != mob_list.cend(); ++it) {
if (!it->second || it->second == client || !it->second->IsTrackable() ||
it->second->IsInvisible(client))
@@ -2970,7 +2970,10 @@ bool EntityList::MakeTrackPacket(Client *client)
tracking_list.push_back(std::make_pair(it->second, MobDistance));
}
tracking_list.sort(tracking_compare);
tracking_list.sort(
[](const std::pair<Mob *, float> &a, const std::pair<Mob *, float> &b) {
return a.first->GetSpawnTimeStamp() > b.first->GetSpawnTimeStamp();
});
EQApplicationPacket *outapp = new EQApplicationPacket(OP_Track, sizeof(Track_Struct) * tracking_list.size());
Tracking_Struct *outtrack = (Tracking_Struct *)outapp->pBuffer;
outapp->priority = 6;
@@ -2978,15 +2981,13 @@ bool EntityList::MakeTrackPacket(Client *client)
int index = 0;
for (auto it = tracking_list.cbegin(); it != tracking_list.cend(); ++it, ++index) {
Mob *cur_entity = it->first;
outtrack->Entrys[index].entityid = cur_entity->GetID();
outtrack->Entrys[index].entityid = (uint32)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;
outtrack->Entrys[index].is_npc = !cur_entity->IsClient();
strn0cpy(outtrack->Entrys[index].name, cur_entity->GetName(), sizeof(outtrack->Entrys[index].name));
outtrack->Entrys[index].is_pet = cur_entity->IsPet();
outtrack->Entrys[index].is_merc = cur_entity->IsMerc();
}
client->QueuePacket(outapp);
@@ -3641,7 +3642,7 @@ void EntityList::AddTempPetsToHateList(Mob *owner, Mob* other, bool bFrenzy)
if (n->GetSwarmInfo()) {
if (n->GetSwarmInfo()->owner_id == owner->GetID()) {
if (!n->GetSpecialAbility(IMMUNE_AGGRO))
n->hate_list.Add(other, 0, 0, bFrenzy);
n->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
}
}
++it;
+1 -1
View File
@@ -356,7 +356,7 @@ public:
void ClearAggro(Mob* targ);
void ClearFeignAggro(Mob* targ);
void ClearZoneFeignAggro(Client* targ);
void AggroZone(Mob* who, int hate = 0);
void AggroZone(Mob* who, uint32 hate = 0);
bool Fighting(Mob* targ);
void RemoveFromHateLists(Mob* mob, bool settoone = false);
+2 -2
View File
@@ -430,7 +430,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
void Client::SetLevel(uint8 set_level, bool command)
{
if (GetEXPForLevel(set_level) == 0xFFFFFFFF) {
LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
LogFile->write(EQEmuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level);
return;
}
@@ -488,7 +488,7 @@ void Client::SetLevel(uint8 set_level, bool command)
safe_delete(outapp);
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
LogFile->write(EQEmuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
CalcBonuses();
+4 -4
View File
@@ -58,7 +58,7 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
"LIMIT %i", ZoneID, skill, FORAGE_ITEM_LIMIT);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Forage query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -69,7 +69,7 @@ uint32 ZoneDatabase::GetZoneForage(uint32 ZoneID, uint8 skill) {
item[index] = atoi(row[0]);
chance[index] = atoi(row[1]) + chancepool;
LogFile->write(EQEMuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
LogFile->write(EQEmuLog::Error, "Possible Forage: %d with a %d chance", item[index], chance[index]);
chancepool = chance[index];
}
@@ -250,7 +250,7 @@ void Client::GoFish()
Bait = m_inv.GetItem(bslot);
//if the bait isnt equipped, need to add its skill bonus
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait->GetItem()->SkillModType == SkillFishing) {
if(bslot >= EmuConstants::GENERAL_BEGIN && Bait != nullptr && Bait->GetItem()->SkillModType == SkillFishing) {
fishing_skill += Bait->GetItem()->SkillModValue;
}
@@ -391,7 +391,7 @@ void Client::ForageItem(bool guarantee) {
const Item_Struct* food_item = database.GetItem(foragedfood);
if(!food_item) {
LogFile->write(EQEMuLog::Error, "nullptr returned from database.GetItem in ClientForageItem");
LogFile->write(EQEmuLog::Error, "nullptr returned from database.GetItem in ClientForageItem");
return;
}
+49 -59
View File
@@ -26,23 +26,16 @@
extern EntityList entity_list;
extern WorldServer worldserver;
//
// Xorlac: This will need proper synchronization to make it work correctly.
// Also, should investigate client ack for packet to ensure proper synch.
//
/*
note about how groups work:
A group contains 2 list, a list of pointers to members and a
list of member names. All members of a group should have their
name in the membername array, wether they are in the zone or not.
name in the membername array, whether they are in the zone or not.
Only members in this zone will have non-null pointers in the
members array.
*/
//create a group which should allready exist in the database
//create a group which should already exist in the database
Group::Group(uint32 gid)
: GroupIDConsumer(gid)
{
@@ -112,8 +105,7 @@ Group::~Group()
}
}
//Cofruben:Split money used in OP_Split.
//Rewritten by Father Nitwit
//Split money used in OP_Split (/split and /autosplit).
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
//avoid unneeded work
if(copper == 0 && silver == 0 && gold == 0 && platinum == 0)
@@ -122,7 +114,8 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
uint32 i;
uint8 membercount = 0;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] != nullptr) {
// Don't split with Mercs or Bots
if (members[i] != nullptr && members[i]->IsClient()) {
membercount++;
}
}
@@ -196,7 +189,7 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
Client *c = members[i]->CastToClient();
Client *c = members[i]->CastToClient();
//I could not get MoneyOnCorpse to work, so we use this
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
c->Message(2, msg.c_str());
@@ -367,7 +360,6 @@ bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 Characte
void Group::AddMember(const char *NewMemberName)
{
// This method should be called when both the new member and the group leader are in a different zone to this one.
//
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
if(!strcasecmp(membername[i], NewMemberName))
{
@@ -394,9 +386,8 @@ void Group::QueuePacket(const EQApplicationPacket *app, bool ack_req)
members[i]->CastToClient()->QueuePacket(app, ack_req);
}
// solar: sends the rest of the group's hps to member. this is useful when
// someone first joins a group, but otherwise there shouldn't be a need to
// call it
// Sends the rest of the group's hps to member. this is useful when someone
// first joins a group, but otherwise there shouldn't be a need to call it
void Group::SendHPPacketsTo(Mob *member)
{
if(member && member->IsClient())
@@ -458,9 +449,11 @@ void Group::SendHPPacketsFrom(Mob *member)
}
//updates a group member's client pointer when they zone in
//if the group was in the zone allready
//if the group was in the zone already
bool Group::UpdatePlayer(Mob* update){
bool updateSuccess = false;
VerifyGroup();
uint32 i=0;
@@ -486,7 +479,8 @@ bool Group::UpdatePlayer(Mob* update){
{
members[i] = update;
members[i]->SetGrouped(true);
return true;
updateSuccess = true;
break;
}
}
@@ -494,7 +488,7 @@ bool Group::UpdatePlayer(Mob* update){
if (update->IsClient() && !mentoree && mentoree_name.length() && !mentoree_name.compare(update->GetName()))
mentoree = update->CastToClient();
return false;
return updateSuccess;
}
@@ -519,6 +513,7 @@ void Group::MemberZoned(Mob* removemob) {
}
#endif //BOTS
}
if(removemob->IsClient() && HasRole(removemob, RoleAssist))
SetGroupAssistTarget(0);
@@ -591,7 +586,7 @@ bool Group::DelMemberOOZ(const char *Name) {
return false;
}
bool Group::DelMember(Mob* oldmember,bool ignoresender)
bool Group::DelMember(Mob* oldmember, bool ignoresender)
{
if (oldmember == nullptr)
{
@@ -688,6 +683,8 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
if(oldmember->IsClient())
oldmember->CastToClient()->QueuePacket(outapp);
}
safe_delete(outapp);
if(oldmember->IsClient())
{
@@ -706,8 +703,6 @@ bool Group::DelMember(Mob* oldmember,bool ignoresender)
oldmember->SetGrouped(false);
disbandcheck = true;
safe_delete(outapp);
if(HasRole(oldmember, RoleTank))
{
SetGroupTankTarget(0);
@@ -997,24 +992,21 @@ void Group::SendLeadershipAAUpdate()
// aware of it until they are next in the same zone as the leader.
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
gu->action = groupActAAUpdate;
uint32 i = 0;
gu->leader_aas = LeaderAbilities;
gu->NPCMarkerID = GetNPCMarkerID();
uint32 i = 0;
for (i = 0;i < MAX_GROUP_MEMBERS; ++i)
{
if(members[i] && members[i]->IsClient())
{
strcpy(gu->yourname, members[i]->GetName());
strcpy(gu->membername, members[i]->GetName());
members[i]->CastToClient()->QueuePacket(outapp);
}
}
safe_delete(outapp);
}
@@ -1036,8 +1028,8 @@ uint8 Group::GroupCount() {
uint32 Group::GetHighestLevel()
{
uint32 level = 1;
uint32 i;
uint32 level = 1;
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
{
if (members[i])
@@ -1048,10 +1040,11 @@ uint32 i;
}
return level;
}
uint32 Group::GetLowestLevel()
{
uint32 level = 255;
uint32 i;
uint32 level = 255;
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++)
{
if (members[i])
@@ -1082,7 +1075,7 @@ bool Group::LearnMembers() {
return false;
if (results.RowCount() == 0) {
LogFile->write(EQEMuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error getting group members for group %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
return false;
}
@@ -1111,18 +1104,16 @@ void Group::VerifyGroup() {
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (membername[i][0] == '\0') {
#if EQDEBUG >= 7
LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
LogFile->write(EQEmuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long)GetID(), i);
#endif
members[i] = nullptr;
continue;
}
//it should be safe to use GetClientByName, but Group is trying
//to be generic, so we'll go for general Mob
Mob *them = entity_list.GetMob(membername[i]);
if(them == nullptr && members[i] != nullptr) { //they arnt here anymore....
if(them == nullptr && members[i] != nullptr) { //they aren't in zone
#if EQDEBUG >= 6
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' has disappeared!!", (unsigned long)GetID(), membername[i]);
#endif
membername[i][0] = '\0';
members[i] = nullptr;
@@ -1131,18 +1122,17 @@ LogFile->write(EQEMuLog::Debug, "Group %lu: Verify %d: Empty.\n", (unsigned long
if(them != nullptr && members[i] != them) { //our pointer is out of date... not so good.
#if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' had an out of date pointer!!", (unsigned long)GetID(), membername[i]);
#endif
members[i] = them;
continue;
}
#if EQDEBUG >= 8
LogFile->write(EQEMuLog::Debug, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
LogFile->write(EQEmuLog::Debug, "Member of group %lu named '%s' is valid.", (unsigned long)GetID(), membername[i]);
#endif
}
}
void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) {
uint32 i;
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
@@ -1151,13 +1141,14 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co
if(members[i] == sender)
continue;
if(!members[i]->IsClient())
continue;
members[i]->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0);
}
}
void Client::LeaveGroup() {
Group *g = GetGroup();
@@ -1177,7 +1168,7 @@ void Client::LeaveGroup() {
else
{
g->DelMember(this);
if (GetMerc() && GetMerc()->HasGroup() && GetMerc()->GetGroup() == g)
if (GetMerc() != nullptr && g == GetMerc()->GetGroup() )
{
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
}
@@ -1362,7 +1353,7 @@ void Group::MarkNPC(Mob* Target, int Number)
// Send a packet to all group members in this zone causing the client to prefix the Target mob's name
// with the specified Number.
//
if(!Target || Target->IsClient())
if(!Target || Target->IsClient() || Target->IsMerc())
return;
if((Number < 1) || (Number > MAX_MARKED_NPCS))
@@ -1472,7 +1463,7 @@ void Group::DelegateMainTank(const char *NewMainTankName, uint8 toggle)
MainTankName.c_str(), GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set group main tank: %s\n", results.ErrorMessage().c_str());
}
}
@@ -1518,7 +1509,7 @@ void Group::DelegateMainAssist(const char *NewMainAssistName, uint8 toggle)
MainAssistName.c_str(), GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set group main assist: %s\n", results.ErrorMessage().c_str());
}
}
@@ -1565,7 +1556,7 @@ void Group::DelegatePuller(const char *NewPullerName, uint8 toggle)
PullerName.c_str(), GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set group main puller: %s\n", results.ErrorMessage().c_str());
}
@@ -1716,7 +1707,7 @@ void Group::UnDelegateMainTank(const char *OldMainTankName, uint8 toggle)
std::string query = StringFormat("UPDATE group_leaders SET maintank = '' WHERE gid = %i LIMIT 1", GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear group main tank: %s\n", results.ErrorMessage().c_str());
if(!toggle) {
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
@@ -1765,7 +1756,7 @@ void Group::UnDelegateMainAssist(const char *OldMainAssistName, uint8 toggle)
std::string query = StringFormat("UPDATE group_leaders SET assist = '' WHERE gid = %i LIMIT 1", GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear group main assist: %s\n", results.ErrorMessage().c_str());
if(!toggle)
{
@@ -1793,7 +1784,7 @@ void Group::UnDelegatePuller(const char *OldPullerName, uint8 toggle)
std::string query = StringFormat("UPDATE group_leaders SET puller = '' WHERE gid = %i LIMIT 1", GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear group main puller: %s\n", results.ErrorMessage().c_str());
if(!toggle) {
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
@@ -1876,7 +1867,7 @@ void Group::SetGroupMentor(int percent, char *name)
mentoree_name.c_str(), mentor_percent, GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set group mentor: %s\n", results.ErrorMessage().c_str());
}
void Group::ClearGroupMentor()
@@ -1887,7 +1878,7 @@ void Group::ClearGroupMentor()
std::string query = StringFormat("UPDATE group_leaders SET mentoree = '', mentor_percent = 0 WHERE gid = %i LIMIT 1", GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear group mentor: %s\n", results.ErrorMessage().c_str());
}
void Group::NotifyAssistTarget(Client *c)
@@ -1957,7 +1948,7 @@ void Group::DelegateMarkNPC(const char *NewNPCMarkerName)
NewNPCMarkerName, GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set group mark npc: %s\n", results.ErrorMessage().c_str());
}
void Group::NotifyMarkNPC(Client *c)
@@ -2038,7 +2029,7 @@ void Group::UnDelegateMarkNPC(const char *OldNPCMarkerName)
std::string query = StringFormat("UPDATE group_leaders SET marknpc = '' WHERE gid = %i LIMIT 1", GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear group marknpc: %s\n", results.ErrorMessage().c_str());
}
@@ -2055,7 +2046,7 @@ void Group::SaveGroupLeaderAA()
safe_delete_array(queryBuffer);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
}
@@ -2165,7 +2156,6 @@ int8 Group::GetNumberNeedingHealedInGroup(int8 hpr, bool includePets) {
}
}
return needHealed;
}
@@ -2227,7 +2217,7 @@ void Group::ChangeLeader(Mob* newleader)
// this changes the current group leader, notifies other members, and updates leadship AA
// if the new leader is invalid, do nothing
if (!newleader)
if (!newleader || !newleader->IsClient())
return;
Mob* oldleader = GetLeader();
+2 -2
View File
@@ -413,7 +413,7 @@ bool ZoneDatabase::CheckGuildDoor(uint8 doorid, uint16 guild_id, const char* zon
doorid-128, zone);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in CheckGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in CheckGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -433,7 +433,7 @@ bool ZoneDatabase::SetGuildDoor(uint8 doorid,uint16 guild_id, const char* zone)
guild_id, doorid, zone);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in SetGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in SetGuildDoor query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
+225 -227
View File
@@ -1,19 +1,19 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "client.h"
@@ -36,7 +36,7 @@ extern Zone *zone;
HateList::HateList()
{
owner = nullptr;
hate_owner = nullptr;
}
HateList::~HateList()
@@ -45,29 +45,29 @@ HateList::~HateList()
// added for frenzy support
// checks if target still is in frenzy mode
void HateList::CheckFrenzyHate()
void HateList::IsEntityInFrenzyMode()
{
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
if ((*iterator)->ent->GetHPRatio() >= 20)
(*iterator)->bFrenzy = false;
if ((*iterator)->entity_on_hatelist->GetHPRatio() >= 20)
(*iterator)->is_entity_frenzy = false;
++iterator;
}
}
void HateList::Wipe()
void HateList::WipeHateList()
{
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
Mob* m = (*iterator)->ent;
if(m)
Mob* m = (*iterator)->entity_on_hatelist;
if (m)
{
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), m, "0", 0);
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), m, "0", 0);
if(m->IsClient())
if (m->IsClient())
m->CastToClient()->DecrementAggroCount();
}
delete (*iterator);
@@ -76,38 +76,38 @@ void HateList::Wipe()
}
}
bool HateList::IsOnHateList(Mob *mob)
bool HateList::IsEntOnHateList(Mob *mob)
{
if(Find(mob))
if (Find(mob))
return true;
return false;
}
tHateEntry *HateList::Find(Mob *ent)
struct_HateList *HateList::Find(Mob *in_entity)
{
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
if((*iterator)->ent == ent)
if ((*iterator)->entity_on_hatelist == in_entity)
return (*iterator);
++iterator;
}
return nullptr;
}
void HateList::Set(Mob* other, uint32 in_hate, uint32 in_dam)
void HateList::SetHateAmountOnEnt(Mob* other, uint32 in_hate, uint32 in_damage)
{
tHateEntry *p = Find(other);
if(p)
struct_HateList *entity = Find(other);
if (entity)
{
if(in_dam > 0)
p->damage = in_dam;
if(in_hate > 0)
p->hate = in_hate;
if (in_damage > 0)
entity->hatelist_damage = in_damage;
if (in_hate > 0)
entity->stored_hate_amount = in_hate;
}
}
Mob* HateList::GetDamageTop(Mob* hater)
Mob* HateList::GetDamageTopOnHateList(Mob* hater)
{
Mob* current = nullptr;
Group* grp = nullptr;
@@ -115,119 +115,117 @@ Mob* HateList::GetDamageTop(Mob* hater)
uint32 dmg_amt = 0;
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
grp = nullptr;
r = nullptr;
if((*iterator)->ent && (*iterator)->ent->IsClient()){
r = entity_list.GetRaidByClient((*iterator)->ent->CastToClient());
if ((*iterator)->entity_on_hatelist && (*iterator)->entity_on_hatelist->IsClient()){
r = entity_list.GetRaidByClient((*iterator)->entity_on_hatelist->CastToClient());
}
grp = entity_list.GetGroupByMob((*iterator)->ent);
grp = entity_list.GetGroupByMob((*iterator)->entity_on_hatelist);
if((*iterator)->ent && r){
if(r->GetTotalRaidDamage(hater) >= dmg_amt)
if ((*iterator)->entity_on_hatelist && r){
if (r->GetTotalRaidDamage(hater) >= dmg_amt)
{
current = (*iterator)->ent;
current = (*iterator)->entity_on_hatelist;
dmg_amt = r->GetTotalRaidDamage(hater);
}
}
else if ((*iterator)->ent != nullptr && grp != nullptr)
else if ((*iterator)->entity_on_hatelist != nullptr && grp != nullptr)
{
if (grp->GetTotalGroupDamage(hater) >= dmg_amt)
{
current = (*iterator)->ent;
current = (*iterator)->entity_on_hatelist;
dmg_amt = grp->GetTotalGroupDamage(hater);
}
}
else if ((*iterator)->ent != nullptr && (uint32)(*iterator)->damage >= dmg_amt)
else if ((*iterator)->entity_on_hatelist != nullptr && (uint32)(*iterator)->hatelist_damage >= dmg_amt)
{
current = (*iterator)->ent;
dmg_amt = (*iterator)->damage;
current = (*iterator)->entity_on_hatelist;
dmg_amt = (*iterator)->hatelist_damage;
}
++iterator;
}
return current;
}
Mob* HateList::GetClosest(Mob *hater) {
Mob* close = nullptr;
float closedist = 99999.9f;
float thisdist;
Mob* HateList::GetClosestEntOnHateList(Mob *hater) {
Mob* close_entity = nullptr;
float close_distance = 99999.9f;
float this_distance;
auto iterator = list.begin();
while(iterator != list.end()) {
thisdist = (*iterator)->ent->DistNoRootNoZ(*hater);
if((*iterator)->ent != nullptr && thisdist <= closedist) {
closedist = thisdist;
close = (*iterator)->ent;
while (iterator != list.end()) {
this_distance = (*iterator)->entity_on_hatelist->DistNoRootNoZ(*hater);
if ((*iterator)->entity_on_hatelist != nullptr && this_distance <= close_distance) {
close_distance = this_distance;
close_entity = (*iterator)->entity_on_hatelist;
}
++iterator;
}
if ((!close && hater->IsNPC()) || (close && close->DivineAura()))
close = hater->CastToNPC()->GetHateTop();
if ((!close_entity && hater->IsNPC()) || (close_entity && close_entity->DivineAura()))
close_entity = hater->CastToNPC()->GetHateTop();
return close;
return close_entity;
}
// a few comments added, rearranged code for readability
void HateList::Add(Mob *ent, int32 in_hate, int32 in_dam, bool bFrenzy, bool iAddIfNotExist)
void HateList::AddEntToHateList(Mob *in_entity, int32 in_hate, int32 in_damage, bool in_is_entity_frenzied, bool iAddIfNotExist)
{
if(!ent)
if (!in_entity)
return;
if(ent->IsCorpse())
if (in_entity->IsCorpse())
return;
if(ent->IsClient() && ent->CastToClient()->IsDead())
if (in_entity->IsClient() && in_entity->CastToClient()->IsDead())
return;
tHateEntry *p = Find(ent);
if (p)
struct_HateList *entity = Find(in_entity);
if (entity)
{
p->damage+=(in_dam>=0)?in_dam:0;
p->hate+=in_hate;
p->bFrenzy = bFrenzy;
entity->hatelist_damage += (in_damage >= 0) ? in_damage : 0;
entity->stored_hate_amount += in_hate;
entity->is_entity_frenzy = in_is_entity_frenzied;
}
else if (iAddIfNotExist) {
p = new tHateEntry;
p->ent = ent;
p->damage = (in_dam>=0)?in_dam:0;
p->hate = in_hate;
p->bFrenzy = bFrenzy;
list.push_back(p);
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "1", 0);
entity = new struct_HateList;
entity->entity_on_hatelist = in_entity;
entity->hatelist_damage = (in_damage >= 0) ? in_damage : 0;
entity->stored_hate_amount = in_hate;
entity->is_entity_frenzy = in_is_entity_frenzied;
list.push_back(entity);
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "1", 0);
if (ent->IsClient()) {
if (owner->CastToNPC()->IsRaidTarget())
ent->CastToClient()->SetEngagedRaidTarget(true);
ent->CastToClient()->IncrementAggroCount();
if (in_entity->IsClient()) {
if (hate_owner->CastToNPC()->IsRaidTarget())
in_entity->CastToClient()->SetEngagedRaidTarget(true);
in_entity->CastToClient()->IncrementAggroCount();
}
}
}
bool HateList::RemoveEnt(Mob *ent)
bool HateList::RemoveEntFromHateList(Mob *in_entity)
{
if (!ent)
if (!in_entity)
return false;
bool found = false;
bool is_found = false;
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
if((*iterator)->ent == ent)
if ((*iterator)->entity_on_hatelist == in_entity)
{
if(ent)
parse->EventNPC(EVENT_HATE_LIST, owner->CastToNPC(), ent, "0", 0);
found = true;
if (in_entity)
parse->EventNPC(EVENT_HATE_LIST, hate_owner->CastToNPC(), in_entity, "0", 0);
is_found = true;
if(ent && ent->IsClient())
ent->CastToClient()->DecrementAggroCount();
if (in_entity && in_entity->IsClient())
in_entity->CastToClient()->DecrementAggroCount();
delete (*iterator);
iterator = list.erase(iterator);
@@ -236,124 +234,128 @@ bool HateList::RemoveEnt(Mob *ent)
else
++iterator;
}
return found;
return is_found;
}
void HateList::DoFactionHits(int32 nfl_id) {
if (nfl_id <= 0)
void HateList::DoFactionHits(int32 npc_faction_level_id) {
if (npc_faction_level_id <= 0)
return;
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
Client *p;
Client *client;
if ((*iterator)->ent && (*iterator)->ent->IsClient())
p = (*iterator)->ent->CastToClient();
if ((*iterator)->entity_on_hatelist && (*iterator)->entity_on_hatelist->IsClient())
client = (*iterator)->entity_on_hatelist->CastToClient();
else
p = nullptr;
client = nullptr;
if (p)
p->SetFactionLevel(p->CharacterID(), nfl_id, p->GetBaseClass(), p->GetBaseRace(), p->GetDeity());
if (client)
client->SetFactionLevel(client->CharacterID(), npc_faction_level_id, client->GetBaseClass(), client->GetBaseRace(), client->GetDeity());
++iterator;
}
}
int HateList::SummonedPetCount(Mob *hater) {
int HateList::GetSummonedPetCountOnHateList(Mob *hater) {
//Function to get number of 'Summoned' pets on a targets hate list to allow calculations for certian spell effects.
//Unclear from description that pets are required to be 'summoned body type'. Will not require at this time.
int petcount = 0;
int pet_count = 0;
auto iterator = list.begin();
while(iterator != list.end()) {
while (iterator != list.end()) {
if((*iterator)->ent != nullptr && (*iterator)->ent->IsNPC() && ((*iterator)->ent->CastToNPC()->IsPet() || ((*iterator)->ent->CastToNPC()->GetSwarmOwner() > 0)))
if ((*iterator)->entity_on_hatelist != nullptr && (*iterator)->entity_on_hatelist->IsNPC() && ((*iterator)->entity_on_hatelist->CastToNPC()->IsPet() || ((*iterator)->entity_on_hatelist->CastToNPC()->GetSwarmOwner() > 0)))
{
++petcount;
++pet_count;
}
++iterator;
}
return petcount;
return pet_count;
}
Mob *HateList::GetTop(Mob *center)
Mob *HateList::GetEntWithMostHateOnList(Mob *center)
{
Mob* top = nullptr;
int32 hate = -1;
if(center == nullptr)
// hack fix for zone shutdown crashes on some servers
if (!zone->IsLoaded())
return nullptr;
if (RuleB(Aggro,SmartAggroList)){
Mob* topClientTypeInRange = nullptr;
int32 hateClientTypeInRange = -1;
Mob* top_hate = nullptr;
int32 hate = -1;
if (center == nullptr)
return nullptr;
if (RuleB(Aggro, SmartAggroList)){
Mob* top_client_type_in_range = nullptr;
int32 hate_client_type_in_range = -1;
int skipped_count = 0;
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
tHateEntry *cur = (*iterator);
int16 aggroMod = 0;
struct_HateList *cur = (*iterator);
int16 aggro_mod = 0;
if(!cur){
if (!cur){
++iterator;
continue;
}
if(!cur->ent){
if (!cur->entity_on_hatelist){
++iterator;
continue;
}
auto hateEntryPosition = xyz_location(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ());
if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if(!zone->watermap->InLiquid(hateEntryPosition)) {
auto hateEntryPosition = xyz_location(cur->entity_on_hatelist->GetX(), cur->entity_on_hatelist->GetY(), cur->entity_on_hatelist->GetZ());
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if (!zone->watermap->InLiquid(hateEntryPosition)) {
skipped_count++;
++iterator;
continue;
}
}
if (cur->ent->Sanctuary()) {
if(hate == -1)
if (cur->entity_on_hatelist->Sanctuary()) {
if (hate == -1)
{
top = cur->ent;
top_hate = cur->entity_on_hatelist;
hate = 1;
}
++iterator;
continue;
}
if(cur->ent->DivineAura() || cur->ent->IsMezzed() || cur->ent->IsFeared()){
if(hate == -1)
if (cur->entity_on_hatelist->DivineAura() || cur->entity_on_hatelist->IsMezzed() || cur->entity_on_hatelist->IsFeared()){
if (hate == -1)
{
top = cur->ent;
top_hate = cur->entity_on_hatelist;
hate = 0;
}
++iterator;
continue;
}
int32 currentHate = cur->hate;
int32 current_hate = cur->stored_hate_amount;
if(cur->ent->IsClient()){
if (cur->entity_on_hatelist->IsClient()){
if(cur->ent->CastToClient()->IsSitting()){
aggroMod += RuleI(Aggro, SittingAggroMod);
if (cur->entity_on_hatelist->CastToClient()->IsSitting()){
aggro_mod += RuleI(Aggro, SittingAggroMod);
}
if(center){
if(center->GetTarget() == cur->ent)
aggroMod += RuleI(Aggro, CurrentTargetAggroMod);
if(RuleI(Aggro, MeleeRangeAggroMod) != 0)
if (center){
if (center->GetTarget() == cur->entity_on_hatelist)
aggro_mod += RuleI(Aggro, CurrentTargetAggroMod);
if (RuleI(Aggro, MeleeRangeAggroMod) != 0)
{
if(center->CombatRange(cur->ent)){
aggroMod += RuleI(Aggro, MeleeRangeAggroMod);
if (center->CombatRange(cur->entity_on_hatelist)){
aggro_mod += RuleI(Aggro, MeleeRangeAggroMod);
if(currentHate > hateClientTypeInRange || cur->bFrenzy){
hateClientTypeInRange = currentHate;
topClientTypeInRange = cur->ent;
if (current_hate > hate_client_type_in_range || cur->is_entity_frenzy){
hate_client_type_in_range = current_hate;
top_client_type_in_range = cur->entity_on_hatelist;
}
}
}
@@ -361,113 +363,112 @@ Mob *HateList::GetTop(Mob *center)
}
else{
if(center){
if(center->GetTarget() == cur->ent)
aggroMod += RuleI(Aggro, CurrentTargetAggroMod);
if(RuleI(Aggro, MeleeRangeAggroMod) != 0)
if (center){
if (center->GetTarget() == cur->entity_on_hatelist)
aggro_mod += RuleI(Aggro, CurrentTargetAggroMod);
if (RuleI(Aggro, MeleeRangeAggroMod) != 0)
{
if(center->CombatRange(cur->ent)){
aggroMod += RuleI(Aggro, MeleeRangeAggroMod);
if (center->CombatRange(cur->entity_on_hatelist)){
aggro_mod += RuleI(Aggro, MeleeRangeAggroMod);
}
}
}
}
if(cur->ent->GetMaxHP() != 0 && ((cur->ent->GetHP()*100/cur->ent->GetMaxHP()) < 20)){
aggroMod += RuleI(Aggro, CriticallyWoundedAggroMod);
if (cur->entity_on_hatelist->GetMaxHP() != 0 && ((cur->entity_on_hatelist->GetHP() * 100 / cur->entity_on_hatelist->GetMaxHP()) < 20)){
aggro_mod += RuleI(Aggro, CriticallyWoundedAggroMod);
}
if(aggroMod){
currentHate += (currentHate * aggroMod / 100);
if (aggro_mod){
current_hate += (current_hate * aggro_mod / 100);
}
if(currentHate > hate || cur->bFrenzy){
hate = currentHate;
top = cur->ent;
if (current_hate > hate || cur->is_entity_frenzy){
hate = current_hate;
top_hate = cur->entity_on_hatelist;
}
++iterator;
}
if(topClientTypeInRange != nullptr && top != nullptr) {
bool isTopClientType = top->IsClient();
if (top_client_type_in_range != nullptr && top_hate != nullptr) {
bool isTopClientType = top_hate->IsClient();
#ifdef BOTS
if(!isTopClientType) {
if(top->IsBot()) {
if (!isTopClientType) {
if (top_hate->IsBot()) {
isTopClientType = true;
topClientTypeInRange = top;
top_client_type_in_range = top_hate;
}
}
#endif //BOTS
if(!isTopClientType) {
if(top->IsMerc()) {
if (!isTopClientType) {
if (top_hate->IsMerc()) {
isTopClientType = true;
topClientTypeInRange = top;
top_client_type_in_range = top_hate;
}
}
if (!isTopClientType) {
if (top->GetSpecialAbility(ALLOW_TO_TANK)){
if (top_hate->GetSpecialAbility(ALLOW_TO_TANK)){
isTopClientType = true;
topClientTypeInRange = top;
top_client_type_in_range = top_hate;
}
}
if(!isTopClientType)
return topClientTypeInRange ? topClientTypeInRange : nullptr;
if (!isTopClientType)
return top_client_type_in_range ? top_client_type_in_range : nullptr;
return top ? top : nullptr;
return top_hate ? top_hate : nullptr;
}
else {
if(top == nullptr && skipped_count > 0) {
if (top_hate == nullptr && skipped_count > 0) {
return center->GetTarget() ? center->GetTarget() : nullptr;
}
return top ? top : nullptr;
return top_hate ? top_hate : nullptr;
}
}
else{
auto iterator = list.begin();
int skipped_count = 0;
while(iterator != list.end())
while (iterator != list.end())
{
tHateEntry *cur = (*iterator);
auto hateEntryPosition = xyz_location(cur->ent->GetX(), cur->ent->GetY(), cur->ent->GetZ());
if(center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if(!zone->watermap->InLiquid(hateEntryPosition)) {
struct_HateList *cur = (*iterator);
if (center->IsNPC() && center->CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
if (!zone->watermap->InLiquid(cur->entity_on_hatelist->GetPosition())) {
skipped_count++;
++iterator;
continue;
}
}
if(cur->ent != nullptr && ((cur->hate > hate) || cur->bFrenzy ))
if (cur->entity_on_hatelist != nullptr && ((cur->stored_hate_amount > hate) || cur->is_entity_frenzy))
{
top = cur->ent;
hate = cur->hate;
top_hate = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
}
++iterator;
}
if(top == nullptr && skipped_count > 0) {
if (top_hate == nullptr && skipped_count > 0) {
return center->GetTarget() ? center->GetTarget() : nullptr;
}
return top ? top : nullptr;
return top_hate ? top_hate : nullptr;
}
return nullptr;
}
Mob *HateList::GetMostHate(){
Mob *HateList::GetEntWithMostHateOnList(){
Mob* top = nullptr;
int32 hate = -1;
auto iterator = list.begin();
while(iterator != list.end())
while (iterator != list.end())
{
tHateEntry *cur = (*iterator);
if(cur->ent != nullptr && (cur->hate > hate))
struct_HateList *cur = (*iterator);
if (cur->entity_on_hatelist != nullptr && (cur->stored_hate_amount > hate))
{
top = cur->ent;
hate = cur->hate;
top = cur->entity_on_hatelist;
hate = cur->stored_hate_amount;
}
++iterator;
}
@@ -475,16 +476,16 @@ Mob *HateList::GetMostHate(){
}
Mob *HateList::GetRandom()
Mob *HateList::GetRandomEntOnHateList()
{
int count = list.size();
if(count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
if (count == 0) //If we don't have any entries it'll crash getting a random 0, -1 position.
return NULL;
if(count == 1) //No need to do all that extra work if we only have one hate entry
if (count == 1) //No need to do all that extra work if we only have one hate entry
{
if(*list.begin()) // Just in case tHateEntry is invalidated somehow...
return (*list.begin())->ent;
if (*list.begin()) // Just in case tHateEntry is invalidated somehow...
return (*list.begin())->entity_on_hatelist;
return NULL;
}
@@ -494,38 +495,36 @@ Mob *HateList::GetRandom()
for (int i = 0; i < random; i++)
++iterator;
return (*iterator)->ent;
return (*iterator)->entity_on_hatelist;
}
int32 HateList::GetEntHate(Mob *ent, bool damage)
int32 HateList::GetEntHateAmount(Mob *in_entity, bool damage)
{
tHateEntry *p;
struct_HateList *entity;
p = Find(ent);
entity = Find(in_entity);
if ( p && damage)
return p->damage;
else if (p)
return p->hate;
if (entity && damage)
return entity->hatelist_damage;
else if (entity)
return entity->stored_hate_amount;
else
return 0;
}
//looking for any mob with hate > -1
bool HateList::IsEmpty() {
bool HateList::IsHateListEmpty() {
return(list.size() == 0);
}
// Prints hate list to a client
void HateList::PrintToClient(Client *c)
void HateList::PrintHateListToClient(Client *c)
{
auto iterator = list.begin();
while (iterator != list.end())
{
tHateEntry *e = (*iterator);
struct_HateList *e = (*iterator);
c->Message(0, "- name: %s, damage: %d, hate: %d",
(e->ent && e->ent->GetName()) ? e->ent->GetName() : "(null)",
e->damage, e->hate);
(e->entity_on_hatelist && e->entity_on_hatelist->GetName()) ? e->entity_on_hatelist->GetName() : "(null)",
e->hatelist_damage, e->stored_hate_amount);
++iterator;
}
@@ -533,7 +532,7 @@ void HateList::PrintToClient(Client *c)
int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts)
{
if(!target || !caster)
if (!target || !caster)
return 0;
int ret = 0;
@@ -541,25 +540,25 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
auto iterator = list.begin();
while (iterator != list.end())
{
tHateEntry *h = (*iterator);
struct_HateList *h = (*iterator);
++iterator;
if(h && h->ent && h->ent != caster)
if (h && h->entity_on_hatelist && h->entity_on_hatelist != caster)
{
if(caster->CombatRange(h->ent))
if (caster->CombatRange(h->entity_on_hatelist))
{
id_list.push_back(h->ent->GetID());
id_list.push_back(h->entity_on_hatelist->GetID());
++ret;
}
}
}
std::list<uint32>::iterator iter = id_list.begin();
while(iter != id_list.end())
while (iter != id_list.end())
{
Mob *cur = entity_list.GetMobID((*iter));
if(cur)
if (cur)
{
for(int i = 0; i < count; ++i) {
for (int i = 0; i < count; ++i) {
caster->Attack(cur, MainPrimary, false, false, false, opts);
}
}
@@ -571,7 +570,7 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_center)
{
if(!caster)
if (!caster)
return;
Mob* center = caster;
@@ -590,33 +589,32 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range, Mob* ae_cent
auto iterator = list.begin();
while (iterator != list.end())
{
tHateEntry *h = (*iterator);
if(range > 0)
struct_HateList *h = (*iterator);
if (range > 0)
{
dist_targ = center->DistNoRoot(*h->ent);
if(dist_targ <= range && dist_targ >= min_range2)
dist_targ = center->DistNoRoot(*h->entity_on_hatelist);
if (dist_targ <= range && dist_targ >= min_range2)
{
id_list.push_back(h->ent->GetID());
h->ent->CalcSpellPowerDistanceMod(spell_id, dist_targ);
id_list.push_back(h->entity_on_hatelist->GetID());
h->entity_on_hatelist->CalcSpellPowerDistanceMod(spell_id, dist_targ);
}
}
else
{
id_list.push_back(h->ent->GetID());
h->ent->CalcSpellPowerDistanceMod(spell_id, 0, caster);
id_list.push_back(h->entity_on_hatelist->GetID());
h->entity_on_hatelist->CalcSpellPowerDistanceMod(spell_id, 0, caster);
}
++iterator;
}
std::list<uint32>::iterator iter = id_list.begin();
while(iter != id_list.end())
while (iter != id_list.end())
{
Mob *cur = entity_list.GetMobID((*iter));
if(cur)
if (cur)
{
caster->SpellOnTarget(spell_id, cur);
}
iter++;
}
}
+41 -55
View File
@@ -1,19 +1,19 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef HATELIST_H
@@ -25,11 +25,12 @@ class Mob;
class Raid;
struct ExtraAttackOptions;
struct tHateEntry
struct struct_HateList
{
Mob *ent;
int32 damage, hate;
bool bFrenzy;
Mob *entity_on_hatelist;
int32 hatelist_damage;
uint32 stored_hate_amount;
bool is_entity_frenzy;
};
class HateList
@@ -38,53 +39,38 @@ public:
HateList();
~HateList();
// adds a mob to the hatelist
void Add(Mob *ent, int32 in_hate=0, int32 in_dam=0, bool bFrenzy = false, bool iAddIfNotExist = true);
// sets existing hate
void Set(Mob *other, uint32 in_hate, uint32 in_dam);
// removes mobs from hatelist
bool RemoveEnt(Mob *ent);
// Remove all
void Wipe();
// ???
void DoFactionHits(int32 nfl_id);
// Gets Hate amount for mob
int32 GetEntHate(Mob *ent, bool damage = false);
// gets top hated mob
Mob *GetTop(Mob *center);
// gets any on the list
Mob *GetRandom();
// get closest mob or nullptr if list empty
Mob *GetClosest(Mob *hater);
// gets top mob or nullptr if hate list empty
Mob *GetDamageTop(Mob *hater);
// used to check if mob is on hatelist
bool IsOnHateList(Mob *);
// used to remove or add frenzy hate
void CheckFrenzyHate();
//Gets the target with the most hate regardless of things like frenzy etc.
Mob* GetMostHate();
// Count 'Summoned' pets on hatelist
int SummonedPetCount(Mob *hater);
Mob *GetClosestEntOnHateList(Mob *hater);
Mob *GetDamageTopOnHateList(Mob *hater);
Mob *GetEntWithMostHateOnList(Mob *center);
Mob *GetRandomEntOnHateList();
Mob* GetEntWithMostHateOnList();
bool IsEntOnHateList(Mob *mob);
bool IsHateListEmpty();
bool RemoveEntFromHateList(Mob *ent);
int AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts);
int GetSummonedPetCountOnHateList(Mob *hater);
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
int32 GetEntHateAmount(Mob *ent, bool in_damage = false);
bool IsEmpty();
void PrintToClient(Client *c);
std::list<struct_HateList*>& GetHateList() { return list; }
//For accessing the hate list via perl; don't use for anything else
std::list<tHateEntry*>& GetHateList() { return list; }
void AddEntToHateList(Mob *ent, int32 in_hate = 0, int32 in_damage = 0, bool in_is_frenzied = false, bool add_to_hate_list_if_not_exist = true);
void DoFactionHits(int32 npc_faction_level_id);
void IsEntityInFrenzyMode();
void PrintHateListToClient(Client *c);
void SetHateAmountOnEnt(Mob *other, uint32 in_hate, uint32 in_damage);
void SetHateOwner(Mob *new_hate_owner) { hate_owner = new_hate_owner; }
void SpellCast(Mob *caster, uint32 spell_id, float range, Mob *ae_center = nullptr);
void WipeHateList();
//setting owner
void SetOwner(Mob *newOwner) { owner = newOwner; }
protected:
tHateEntry* Find(Mob *ent);
struct_HateList* Find(Mob *ent);
private:
std::list<tHateEntry*> list;
Mob *owner;
std::list<struct_HateList*> list;
Mob *hate_owner;
};
#endif
#endif
+3 -3
View File
@@ -72,12 +72,12 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) {
std::string query = StringFormat("SELECT race, gender, texture, mountspeed FROM horses WHERE filename = '%s'", fileName);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Mount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Mount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return nullptr;
}
if (results.RowCount() != 1) {
LogFile->write(EQEMuLog::Error, "No Database entry for mount: %s, check the horses table", fileName);
LogFile->write(EQEmuLog::Error, "No Database entry for mount: %s, check the horses table", fileName);
return nullptr;
}
@@ -120,7 +120,7 @@ void Client::SummonHorse(uint16 spell_id) {
return;
}
if(!Horse::IsHorseSpell(spell_id)) {
LogFile->write(EQEMuLog::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
LogFile->write(EQEmuLog::Error, "%s tried to summon an unknown horse, spell id %d", GetName(), spell_id);
return;
}
+130 -80
View File
@@ -532,7 +532,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
if(inst == nullptr) {
Message(13, "An unknown server error has occurred and your item was not created.");
// this goes to logfile since this is a major error
LogFile->write(EQEMuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
LogFile->write(EQEmuLog::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n",
GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6);
return false;
@@ -617,6 +617,7 @@ void Client::DropItem(int16 slot_id)
// Save client inventory change to database
if (slot_id == MainCursor) {
SendCursorBuffer();
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(CharacterID(), s, e);
} else {
@@ -678,10 +679,27 @@ int32 Client::GetAugmentIDAt(int16 slot_id, uint8 augslot) {
return INVALID_ID;
}
void Client::SendCursorBuffer() {
// Temporary work-around for the RoF+ Client Buffer
// Instead of dealing with client moving items in cursor buffer,
// we can just send the next item in the cursor buffer to the cursor.
if (GetClientVersion() >= EQClientRoF)
{
if (!GetInv().CursorEmpty())
{
const ItemInst* inst = GetInv().GetCursorItem();
if (inst)
{
SendItemPacket(MainCursor, inst, ItemPacketSummonItem);
}
}
}
}
// Remove item from inventory
void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_update, bool update_db) {
#if (EQDEBUG >= 5)
LogFile->write(EQEMuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false");
LogFile->write(EQEmuLog::Debug, "DeleteItemInInventory(%i, %i, %s)", slot_id, quantity, (client_update) ? "true":"false");
#endif
// Added 'IsSlotValid(slot_id)' check to both segments of client packet processing.
@@ -794,10 +812,6 @@ void Client::DeleteItemInInventory(int16 slot_id, int8 quantity, bool client_upd
}
}
// Puts an item into the person's inventory
// Any items already there will be removed from user's inventory
// (Also saves changes back to the database: this may be optimized in the future)
// client_update: Sends packet to client
bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
{
mlog(INVENTORY__SLOTS, "Putting item %s (%d) on the cursor", inst.GetItem()->Name, inst.GetItem()->ID);
@@ -811,6 +825,10 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
return database.SaveCursor(CharacterID(), s, e);
}
// Puts an item into the person's inventory
// Any items already there will be removed from user's inventory
// (Also saves changes back to the database: this may be optimized in the future)
// client_update: Sends packet to client
bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) {
mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id);
@@ -908,7 +926,7 @@ bool Client::TryStacking(ItemInst* item, uint8 type, bool try_worn, bool try_cur
bool Client::AutoPutLootInInventory(ItemInst& inst, bool try_worn, bool try_cursor, ServerLootItem_Struct** bag_item_data)
{
// #1: Try to auto equip
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && !inst.GetItem()->Attuneable && inst.GetItem()->ItemType != ItemTypeAugmentation)
if (try_worn && inst.IsEquipable(GetBaseRace(), GetClass()) && inst.GetItem()->ReqLevel<=level && (!inst.GetItem()->Attuneable || inst.IsAttuned()) && inst.GetItem()->ItemType != ItemTypeAugmentation)
{
// too messy as-is... <watch>
for (int16 i = EmuConstants::EQUIPMENT_BEGIN; i < MainPowerSource; i++) // originally (i < 22)
@@ -1009,105 +1027,113 @@ void Client::MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type)
}
}
bool Client::MakeItemLink(char* &ret_link, const ItemInst *inst) {
// TODO: needs clean-up to save references
bool MakeItemLink(char* &ret_link, const Item_Struct *item, uint32 aug0, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint8 evolving, uint8 evolvedlevel) {
//we're sending back the entire "link", minus the null characters & item name
//that way, we can use it for regular links & Task links
//note: initiator needs to pass us ret_link
/*
/*
--- Usage ---
Chat: "%c" "%s" "%s" "%c", 0x12, ret_link, inst->GetItem()->name, 0x12
Task: "<a WndNotify=\"27," "%s" "\">" "%s" "</a>", ret_link, inst->GetItem()->name
<a WndNotify="27,00960F000000000000000000000000000000000000000">Master's Book of Wood Elven Culture</a>
http://eqitems.13th-floor.org/phpBB2/viewtopic.php?p=510#510
*/
<a WndNotify="27,00960F000000000000000000000000000000000000000">Master's Book of Wood Elven Culture</a>
http://eqitems.13th-floor.org/phpBB2/viewtopic.php?p=510#510
*/
if (!inst) //have to have an item to make the link
if (!item) //have to have an item to make the link
return false;
const Item_Struct* item = inst->GetItem();
//format:
//0 itemid aug1 aug2 aug3 aug4 aug5 evolving? loregroup evolved level hash
//0 00000 00000 00000 00000 00000 00000 0 0000 0 00000000
//length:
//1 5 5 5 5 5 5 1 4 1 8 = 45
//evolving item info: http://eqitems.13th-floor.org/phpBB2/viewtopic.php?t=145#558
uint8 evolving = 0;
uint16 loregroup = 0;
uint8 evolvedlevel = 0;
int hash = 0;
//int hash = GetItemLinkHash(inst); //eventually this will work (currently crashes zone), but for now we'll skip the extra overhead
if (GetClientVersion() >= EQClientRoF2)
{
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%01X" "%1X" "%04X" "%1X" "%05X" "%08X",
int hash = NOT_USED;
// Tested with UF and RoF..there appears to be a problem with using non-augment arguments below...
// Currently, enabling them causes misalignments in what the client expects. I haven't looked
// into it further to determine the cause..but, the function is setup to accept the parameters.
// Note: some links appear with '00000' in front of the name..so, it's likely we need to send
// some additional information when certain parameters are true -U
//switch (GetClientVersion()) {
switch (0) {
case EQClientRoF2:
// This operator contains 14 parameter masks..but, only 13 parameter values.
// Even so, the client link appears ok... Need to figure out the discrepancy -U
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5),
evolving,
loregroup,
evolvedlevel,
aug0,
aug1,
aug2,
aug3,
aug4,
aug5,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else if (GetClientVersion() >= EQClientRoF)
{
return true;
case EQClientRoF:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5),
evolving,
loregroup,
evolvedlevel,
aug0,
aug1,
aug2,
aug3,
aug4,
aug5,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else if (GetClientVersion() >= EQClientSoF)
{
);
return true;
case EQClientUnderfoot:
case EQClientSoD:
case EQClientSoF:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%05X" "%08X",
0,
item->ID,
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
evolving,
loregroup,
evolvedlevel,
aug0,
aug1,
aug2,
aug3,
aug4,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
0,
hash
);
}
else
{
);
return true;
case EQClientTitanium:
MakeAnyLenString(&ret_link, "%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%1X" "%08X",
0,
item->ID,
inst->GetAugmentItemID(0),
inst->GetAugmentItemID(1),
inst->GetAugmentItemID(2),
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
evolving,
loregroup,
evolvedlevel,
aug0,
aug1,
aug2,
aug3,
aug4,
0,//evolving,
0,//item->LoreGroup,
0,//evolvedlevel,
hash
);
);
return true;
case EQClient62:
default:
return false;
}
return true;
}
int Client::GetItemLinkHash(const ItemInst* inst) {
@@ -1198,6 +1224,7 @@ int Client::GetItemLinkHash(const ItemInst* inst) {
return hash;
}
// This appears to still be in use... The core of this should be incorporated into class Client::TextLink
void Client::SendItemLink(const ItemInst* inst, bool send_to_all)
{
/*
@@ -1299,7 +1326,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
// This could be expounded upon at some point to let the server know that
// the client has moved a buffered cursor item onto the active cursor -U
if (move_in->from_slot == move_in->to_slot) { // Item summon, no further proccessing needed
if (move_in->from_slot == move_in->to_slot) { // Item summon, no further processing needed
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
return true;
}
@@ -1315,13 +1342,15 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
DeleteItemInInventory(move_in->from_slot);
SendCursorBuffer();
return true; // Item destroyed by client
}
else {
mlog(INVENTORY__SLOTS, "Deleted item from slot %d as a result of an inventory container tradeskill combine.", move_in->from_slot);
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
DeleteItemInInventory(move_in->from_slot);
return true; // Item deletetion
return true; // Item deletion
}
}
if(auto_attack && (move_in->from_slot == MainPrimary || move_in->from_slot == MainSecondary || move_in->from_slot == MainRange))
@@ -1363,7 +1392,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
//SetTint(dst_slot_id,src_inst->GetColor());
if (src_inst->GetCharges() > 0 && (src_inst->GetCharges() < (int16)move_in->number_in_stack || move_in->number_in_stack > src_inst->GetItem()->StackSize))
{
Message(13,"Error: Insufficent number in stack.");
Message(13,"Error: Insufficient number in stack.");
return false;
}
}
@@ -1413,7 +1442,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
//verify shared bank transactions in the database
if(src_inst && src_slot_id >= EmuConstants::SHARED_BANK_BEGIN && src_slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
if(!database.VerifyInventory(account_id, src_slot_id, src_inst)) {
LogFile->write(EQEMuLog::Error, "Player %s on account %s was found exploiting the shared bank.\n", GetName(), account_name);
LogFile->write(EQEmuLog::Error, "Player %s on account %s was found exploiting the shared bank.\n", GetName(), account_name);
DeleteItemInInventory(dst_slot_id,0,true);
return(false);
}
@@ -1428,7 +1457,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
if(dst_inst && dst_slot_id >= EmuConstants::SHARED_BANK_BEGIN && dst_slot_id <= EmuConstants::SHARED_BANK_BAGS_END) {
if(!database.VerifyInventory(account_id, dst_slot_id, dst_inst)) {
LogFile->write(EQEMuLog::Error, "Player %s on account %s was found exploting the shared bank.\n", GetName(), account_name);
LogFile->write(EQEmuLog::Error, "Player %s on account %s was found exploting the shared bank.\n", GetName(), account_name);
DeleteItemInInventory(src_slot_id,0,true);
return(false);
}
@@ -1520,11 +1549,19 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
safe_delete(world_inst);
if (src_slot_id == MainCursor) {
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
if (src_slot_id == MainCursor)
{
if (dstitemid == 0)
{
SendCursorBuffer();
}
std::list<ItemInst*>::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end();
database.SaveCursor(character_id, s, e);
} else
}
else
{
database.SaveInventory(character_id, m_inv[src_slot_id], src_slot_id);
}
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in, true); } // QS Audit
@@ -1551,6 +1588,10 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
trade->AddEntity(dst_slot_id, move_in->number_in_stack);
if (dstitemid == 0)
{
SendCursorBuffer();
}
return true;
} else {
@@ -1563,6 +1604,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
}
}
bool all_to_stack = false;
// Step 5: Swap (or stack) items
if (move_in->number_in_stack > 0) {
// Determine if charged items can stack
@@ -1593,6 +1635,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
mlog(INVENTORY__SLOTS, "Dest (%d) now has %d charges, source (%d) was entirely consumed. (%d moved)", dst_slot_id, dst_inst->GetCharges(), src_slot_id, usedcharges);
database.SaveInventory(CharacterID(),nullptr,src_slot_id);
m_inv.DeleteItem(src_slot_id);
all_to_stack = true;
} else {
mlog(INVENTORY__SLOTS, "Dest (%d) now has %d charges, source (%d) has %d (%d moved)", dst_slot_id, dst_inst->GetCharges(), src_slot_id, src_inst->GetCharges(), usedcharges);
}
@@ -1666,6 +1709,11 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
// Step 7: Save change to the database
if (src_slot_id == MainCursor){
// If not swapping another item to cursor and stacking items were depleted
if (dstitemid == 0 || all_to_stack == true)
{
SendCursorBuffer();
}
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
database.SaveCursor(character_id, s, e);
} else
@@ -1968,7 +2016,7 @@ void Client::DyeArmor(DyeStruct* dye){
bool Client::DecreaseByID(uint32 type, uint8 amt) {
const Item_Struct* TempItem = 0;
ItemInst* ins;
ItemInst* ins = nullptr;
int x;
int num = 0;
for(x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::GENERAL_BAGS_END; x++)
@@ -2104,6 +2152,7 @@ void Client::RemoveNoRent(bool client_update) {
std::list<ItemInst*>::iterator iter = local.begin();
while (iter != local.end()) {
inst = *iter;
// should probably put a check here for valid pointer..but, that was checked when the item was put into inventory -U
if (!inst->GetItem()->NoRent)
mlog(INVENTORY__SLOTS, "NoRent Timer Lapse: Deleting %s from `Limbo`", inst->GetItem()->Name);
else
@@ -2229,6 +2278,7 @@ void Client::RemoveDuplicateLore(bool client_update) {
std::list<ItemInst*>::iterator iter = local.begin();
while (iter != local.end()) {
inst = *iter;
// probably needs a valid pointer check -U
if (CheckLoreConflict(inst->GetItem())) {
mlog(INVENTORY__ERROR, "Lore Duplication Error: Deleting %s from `Limbo`", inst->GetItem()->Name);
safe_delete(*iter);
@@ -2431,8 +2481,8 @@ void Client::CreateBandolier(const EQApplicationPacket *app) {
_log(INVENTORY__BANDOLIER, "Char: %s Creating Bandolier Set %i, Set Name: %s", GetName(), bs->number, bs->name);
strcpy(m_pp.bandoliers[bs->number].name, bs->name);
const ItemInst* InvItem;
const Item_Struct *BaseItem;
const ItemInst* InvItem = nullptr;
const Item_Struct *BaseItem = nullptr;
int16 WeaponSlot;
for(int BandolierSlot = bandolierMainHand; BandolierSlot <= bandolierAmmo; BandolierSlot++) {
+3 -3
View File
@@ -145,7 +145,7 @@ void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* iteml
drop_chance = zone->random.Real(0.0, 100.0);
#if EQDEBUG>=11
LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
LogFile->write(EQEmuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
#endif
if (thischance == 100.0 || drop_chance < thischance)
{
@@ -187,7 +187,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
ServerLootItem_Struct* item = new ServerLootItem_Struct;
#if EQDEBUG>=11
LogFile->write(EQEMuLog::Debug, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
LogFile->write(EQEmuLog::Debug, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
#endif
EQApplicationPacket* outapp = nullptr;
@@ -324,7 +324,7 @@ void NPC::AddLootDrop(const Item_Struct *item2, ItemList* itemlist, int16 charge
what was this about???
if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->Slots==24576) || (item2->Slots==8192) || (item2->Slots==16384)){
npc->d_meele_texture2=atoi(newid);
npc->d_melee_texture2=atoi(newid);
wc->wear_slot_id=8;
if (item2->Material >0)
wc->material=item2->Material;
+2 -2
View File
@@ -1354,8 +1354,8 @@ void lua_create_npc(luabind::adl::object table, float x, float y, float z, float
LuaCreateNPCParse(max_dmg, uint32, 4);
LuaCreateNPCParse(attack_count, int16, 0);
LuaCreateNPCParseString(special_abilities, 512, "");
LuaCreateNPCParse(d_meele_texture1, uint16, 0);
LuaCreateNPCParse(d_meele_texture2, uint16, 0);
LuaCreateNPCParse(d_melee_texture1, uint16, 0);
LuaCreateNPCParse(d_melee_texture2, uint16, 0);
LuaCreateNPCParseString(ammo_idfile, 32, "");
LuaCreateNPCParse(prim_melee_type, uint8, 0);
LuaCreateNPCParse(sec_melee_type, uint8, 0);
+8 -8
View File
@@ -12,42 +12,42 @@
Lua_Mob Lua_HateEntry::GetEnt() {
Lua_Safe_Call_Class(Lua_Mob);
return Lua_Mob(self->ent);
return Lua_Mob(self->entity_on_hatelist);
}
void Lua_HateEntry::SetEnt(Lua_Mob e) {
Lua_Safe_Call_Void();
self->ent = e;
self->entity_on_hatelist = e;
}
int Lua_HateEntry::GetDamage() {
Lua_Safe_Call_Int();
return self->damage;
return self->hatelist_damage;
}
void Lua_HateEntry::SetDamage(int value) {
Lua_Safe_Call_Void();
self->damage = value;
self->hatelist_damage = value;
}
int Lua_HateEntry::GetHate() {
Lua_Safe_Call_Int();
return self->hate;
return self->stored_hate_amount;
}
void Lua_HateEntry::SetHate(int value) {
Lua_Safe_Call_Void();
self->hate = value;
self->stored_hate_amount = value;
}
int Lua_HateEntry::GetFrenzy() {
Lua_Safe_Call_Int();
return self->bFrenzy;
return self->is_entity_frenzy;
}
void Lua_HateEntry::SetFrenzy(bool value) {
Lua_Safe_Call_Void();
self->bFrenzy = value;
self->is_entity_frenzy = value;
}
luabind::scope lua_register_hate_entry() {
+4 -4
View File
@@ -5,17 +5,17 @@
#include "lua_ptr.h"
class Lua_Mob;
struct tHateEntry;
struct struct_HateList;
luabind::scope lua_register_hate_entry();
luabind::scope lua_register_hate_list();
class Lua_HateEntry : public Lua_Ptr<tHateEntry>
class Lua_HateEntry : public Lua_Ptr<struct_HateList>
{
typedef tHateEntry NativeType;
typedef struct_HateList NativeType;
public:
Lua_HateEntry() : Lua_Ptr(nullptr) { }
Lua_HateEntry(tHateEntry *d) : Lua_Ptr(d) { }
Lua_HateEntry(struct_HateList *d) : Lua_Ptr(d) { }
virtual ~Lua_HateEntry() { }
Lua_Mob GetEnt();
+9 -3
View File
@@ -576,6 +576,11 @@ int Lua_Mob::GetCorruption() {
return self->GetCorrup();
}
int Lua_Mob::GetPhR() {
Lua_Safe_Call_Int();
return self->GetPhR();
}
int Lua_Mob::GetMaxSTR() {
Lua_Safe_Call_Int();
return self->GetMaxSTR();
@@ -895,17 +900,17 @@ void Lua_Mob::AddToHateList(Lua_Mob other, int hate, int damage, bool yell_for_h
void Lua_Mob::SetHate(Lua_Mob other) {
Lua_Safe_Call_Void();
self->SetHate(other);
self->SetHateAmountOnEnt(other);
}
void Lua_Mob::SetHate(Lua_Mob other, int hate) {
Lua_Safe_Call_Void();
self->SetHate(other, hate);
self->SetHateAmountOnEnt(other, hate);
}
void Lua_Mob::SetHate(Lua_Mob other, int hate, int damage) {
Lua_Safe_Call_Void();
self->SetHate(other, hate, damage);
self->SetHateAmountOnEnt(other, hate, damage);
}
void Lua_Mob::HalveAggro(Lua_Mob other) {
@@ -1962,6 +1967,7 @@ luabind::scope lua_register_mob() {
.def("GetPR", &Lua_Mob::GetPR)
.def("GetCR", &Lua_Mob::GetCR)
.def("GetCorruption", &Lua_Mob::GetCorruption)
.def("GetPhR", &Lua_Mob::GetPhR)
.def("GetMaxSTR", &Lua_Mob::GetMaxSTR)
.def("GetMaxSTA", &Lua_Mob::GetMaxSTA)
.def("GetMaxDEX", &Lua_Mob::GetMaxDEX)
+1
View File
@@ -128,6 +128,7 @@ public:
int GetPR();
int GetCR();
int GetCorruption();
int GetPhR();
int GetMaxSTR();
int GetMaxSTA();
int GetMaxDEX();
+5
View File
@@ -695,6 +695,9 @@ bool LuaParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) {
}
bool LuaParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
if (itm == nullptr) {
return false;
}
evt = ConvertLuaEvent(evt);
if(evt >= _LargestEventID) {
return false;
@@ -738,6 +741,8 @@ void LuaParser::LoadGlobalPlayerScript(std::string filename) {
}
void LuaParser::LoadItemScript(std::string filename, ItemInst *item) {
if (item == nullptr)
return;
std::string package_name = "item_";
package_name += std::to_string(static_cast<long long>(item->GetID()));
+2 -1
View File
@@ -58,6 +58,7 @@ Map::Map() {
Map::~Map() {
if(imp) {
imp->rm->release();
safe_delete(imp);
}
}
@@ -887,4 +888,4 @@ void Map::TranslateVertex(Vertex &v, float tx, float ty, float tz) {
v.x = v.x + tx;
v.y = v.y + ty;
v.z = v.z + tz;
}
}
+11 -16
View File
@@ -884,7 +884,7 @@ int32 Merc::CalcMaxMana()
break;
}
default: {
LogFile->write(EQEMuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
LogFile->write(EQEmuLog::Debug, "Invalid Class '%c' in CalcMaxMana", GetCasterClass());
max_mana = 0;
break;
}
@@ -905,7 +905,7 @@ int32 Merc::CalcMaxMana()
}
#if EQDEBUG >= 11
LogFile->write(EQEMuLog::Debug, "Merc::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
LogFile->write(EQEmuLog::Debug, "Merc::CalcMaxMana() called for %s - returning %d", GetName(), max_mana);
#endif
return max_mana;
}
@@ -1385,7 +1385,7 @@ void Merc::AI_Process() {
rest_timer.Disable();
if(IsRooted())
SetTarget(hate_list.GetClosest(this));
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
FindTarget();
@@ -2454,11 +2454,11 @@ void Merc::CheckHateList() {
Mob* groupMember = g->members[counter];
if(groupMember) {
if(npc->IsOnHatelist(groupMember)) {
if(!hate_list.IsOnHateList(npc)) {
if(!hate_list.IsEntOnHateList(npc)) {
float range = g->HasRole(groupMember, RolePuller) ? RuleI(Mercs, AggroRadiusPuller) : RuleI(Mercs, AggroRadius);
range *= range;
if(npc->DistNoRootNoZ(*this) < range) {
hate_list.Add(npc, 1);
hate_list.AddEntToHateList(npc, 1);
}
}
}
@@ -4450,7 +4450,7 @@ bool Merc::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, boo
{
if (!other) {
SetTarget(nullptr);
LogFile->write(EQEMuLog::Error, "A null Mob object was passed to Merc::Attack() for evaluation!");
LogFile->write(EQEmuLog::Error, "A null Mob object was passed to Merc::Attack() for evaluation!");
return false;
}
@@ -4644,13 +4644,6 @@ const char* Merc::GetRandomName(){
return name;
}
bool Compare_Merc_Spells(MercSpell i, MercSpell j);
bool Compare_Merc_Spells(MercSpell i, MercSpell j)
{
return(i.slot > j.slot);
}
bool Merc::LoadMercSpells() {
// loads mercs spells into list
merc_spells.clear();
@@ -4683,7 +4676,9 @@ bool Merc::LoadMercSpells() {
AddProcToWeapon(mercSpellEntryItr->spellid, true, mercSpellEntryItr->proc_chance);
}
}
std::sort(merc_spells.begin(), merc_spells.end(), Compare_Merc_Spells);
std::sort(merc_spells.begin(), merc_spells.end(), [](const MercSpell& a, const MercSpell& b) {
return a.slot > b.slot;
});
if (merc_spells.size() == 0)
AIautocastspell_timer->Disable();
@@ -5990,7 +5985,7 @@ void NPC::LoadMercTypes() {
auto results = database.QueryDatabase(query);
if (!results.Success())
{
LogFile->write(EQEMuLog::Error, "Error in NPC::LoadMercTypes()");
LogFile->write(EQEmuLog::Error, "Error in NPC::LoadMercTypes()");
return;
}
@@ -6023,7 +6018,7 @@ void NPC::LoadMercs() {
if (!results.Success())
{
LogFile->write(EQEMuLog::Error, "Error in NPC::LoadMercTypes()");
LogFile->write(EQEmuLog::Error, "Error in NPC::LoadMercTypes()");
return;
}
+2 -2
View File
@@ -287,8 +287,8 @@ protected:
uint16 skills[HIGHEST_SKILL+1];
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
uint16 d_meele_texture1; //this is an item Material value
uint16 d_meele_texture2; //this is an item Material value (offhand)
uint16 d_melee_texture1; //this is an item Material value
uint16 d_melee_texture2; //this is an item Material value (offhand)
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation
+28 -15
View File
@@ -375,7 +375,7 @@ Mob::Mob(const char* in_name,
PathingRouteUpdateTimerLong = new Timer(RuleI(Pathing, RouteUpdateFrequencyLong));
DistractedFromGrid = false;
PathingTraversedNodes = 0;
hate_list.SetOwner(this);
hate_list.SetHateOwner(this);
m_AllowBeneficial = false;
m_DisableMelee = false;
@@ -899,7 +899,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
ns->spawn.animation = 0;
ns->spawn.findable = findable?1:0;
ns->spawn.light = light;
ns->spawn.showhelm = 1;
ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0;
ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players
ns->spawn.NPC = IsClient() ? 0 : 1;
@@ -919,11 +919,11 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
ns->spawn.drakkin_heritage = drakkin_heritage;
ns->spawn.drakkin_tattoo = drakkin_tattoo;
ns->spawn.drakkin_details = drakkin_details;
ns->spawn.equip_chest2 = texture;
ns->spawn.equip_chest2 = GetHerosForgeModel(1) != 0 ? 0xff : texture;
// ns->spawn.invis2 = 0xff;//this used to be labeled beard.. if its not FF it will turn mob invis
if(helmtexture && helmtexture != 0xFF)
if (helmtexture && helmtexture != 0xFF && GetHerosForgeModel(0) == 0)
{
ns->spawn.helm=helmtexture;
} else {
@@ -948,7 +948,8 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
for (i = 0; i < _MaterialCount; i++)
//for (i = 0; i < _MaterialCount; i++)
for (i = 0; i < 9; i++)
{
// Only Player Races Wear Armor
if (Mob::IsPlayerRace(race) || i > 6)
@@ -1265,7 +1266,7 @@ void Mob::ShowStats(Client* client)
client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana());
client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus());
client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA());
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup());
client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR());
client->Message(0, " Race: %i BaseRace: %i Texture: %i HelmTexture: %i Gender: %i BaseGender: %i", GetRace(), GetBaseRace(), GetTexture(), GetHelmTexture(), GetGender(), GetBaseGender());
if (client->Admin() >= 100)
client->Message(0, " EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted);
@@ -2523,8 +2524,8 @@ bool Mob::RemoveFromHateList(Mob* mob)
bool bFound = false;
if(IsEngaged())
{
bFound = hate_list.RemoveEnt(mob);
if(hate_list.IsEmpty())
bFound = hate_list.RemoveEntFromHateList(mob);
if(hate_list.IsHateListEmpty())
{
AI_Event_NoLongerEngaged();
zone->DelAggroMob();
@@ -2532,7 +2533,7 @@ bool Mob::RemoveFromHateList(Mob* mob)
}
if(GetTarget() == mob)
{
SetTarget(hate_list.GetTop(this));
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
return bFound;
@@ -2542,12 +2543,12 @@ void Mob::WipeHateList()
{
if(IsEngaged())
{
hate_list.Wipe();
hate_list.WipeHateList();
AI_Event_NoLongerEngaged();
}
else
{
hate_list.Wipe();
hate_list.WipeHateList();
}
}
@@ -2701,7 +2702,6 @@ int32 Mob::GetEquipmentMaterial(uint8 material_slot) const
int32 Mob::GetHerosForgeModel(uint8 material_slot) const
{
uint32 HeroModel = 0;
if (material_slot >= 0 && material_slot < MaterialPrimary)
{
@@ -2712,7 +2712,7 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
if (item != 0 && invslot != INVALID_INDEX)
{
if (this->IsClient())
if (IsClient())
{
const ItemInst* inst = CastToClient()->m_inv[invslot];
if (inst)
@@ -2734,9 +2734,22 @@ int32 Mob::GetHerosForgeModel(uint8 material_slot) const
HeroModel = item->HerosForgeModel;
}
}
if (IsNPC())
{
HeroModel = CastToNPC()->GetHeroForgeModel();
// Robes require full model number, and should only be sent to chest, arms, wrists, and legs slots
if (HeroModel > 1000 && material_slot != 1 && material_slot != 2 && material_slot != 3 && material_slot != 5)
{
HeroModel = 0;
}
}
}
if (HeroModel > 0)
// Auto-Convert Hero Model to match the slot
// Otherwise, use the exact Model if model is > 999
// Robes for example are 11607 to 12107 in RoF
if (HeroModel > 0 && HeroModel < 1000)
{
HeroModel *= 100;
HeroModel += material_slot;
@@ -3446,7 +3459,7 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP
}
else if (IsPet){
int count = hate_list.SummonedPetCount(this);
int count = hate_list.GetSummonedPetCountOnHateList(this);
if ((base2 >= 220 && base2 <= 250) && count >= (base2 - 220)){
use_spell = true;
}
+15 -15
View File
@@ -369,7 +369,7 @@ public:
inline virtual int32 GetPR() const { return PR + itembonuses.PR + spellbonuses.PR; }
inline virtual int32 GetCR() const { return CR + itembonuses.CR + spellbonuses.CR; }
inline virtual int32 GetCorrup() const { return Corrup + itembonuses.Corrup + spellbonuses.Corrup; }
inline virtual int32 GetPhR() const { return PhR; }
inline virtual int32 GetPhR() const { return PhR; } // PhR bonuses not implemented yet
inline StatBonuses GetItemBonuses() const { return itembonuses; }
inline StatBonuses GetSpellBonuses() const { return spellbonuses; }
inline StatBonuses GetAABonuses() const { return aabonuses; }
@@ -451,19 +451,19 @@ public:
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
inline uint32 GetLevelCon(uint8 iOtherLevel) const {
return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; }
virtual void AddToHateList(Mob* other, int32 hate = 0, int32 damage = 0, bool iYellForHelp = true,
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true,
bool bFrenzy = false, bool iBuffTic = false);
bool RemoveFromHateList(Mob* mob);
void SetHate(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.Set(other,hate,damage);}
void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate > 1 ? in_hate / 2 : 1)); }
void DoubleAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHate(other, (in_hate ? in_hate * 2 : 1)); }
uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.GetEntHate(tmob,is_dam);}
uint32 GetDamageAmount(Mob* tmob) { return hate_list.GetEntHate(tmob, true);}
Mob* GetHateTop() { return hate_list.GetTop(this);}
Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTop(other);}
Mob* GetHateRandom() { return hate_list.GetRandom();}
Mob* GetHateMost() { return hate_list.GetMostHate();}
bool IsEngaged() { return(!hate_list.IsEmpty()); }
void SetHateAmountOnEnt(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);}
void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate > 1 ? in_hate / 2 : 1)); }
void DoubleAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate ? in_hate * 2 : 1)); }
uint32 GetHateAmount(Mob* tmob, bool is_dam = false) { return hate_list.GetEntHateAmount(tmob,is_dam);}
uint32 GetDamageAmount(Mob* tmob) { return hate_list.GetEntHateAmount(tmob, true);}
Mob* GetHateTop() { return hate_list.GetEntWithMostHateOnList(this);}
Mob* GetHateDamageTop(Mob* other) { return hate_list.GetDamageTopOnHateList(other);}
Mob* GetHateRandom() { return hate_list.GetRandomEntOnHateList();}
Mob* GetHateMost() { return hate_list.GetEntWithMostHateOnList();}
bool IsEngaged() { return(!hate_list.IsHateListEmpty()); }
bool HateSummon();
void FaceTarget(Mob* MobToFace = 0);
void SetHeading(float iHeading) { if(m_Position.m_Heading != iHeading) { pLastChange = Timer::GetCurrentTime();
@@ -472,8 +472,8 @@ public:
void AddFeignMemory(Client* attacker);
void RemoveFromFeignMemory(Client* attacker);
void ClearFeignMemory();
void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); }
std::list<tHateEntry*>& GetHateList() { return hate_list.GetHateList(); }
void PrintHateListToClient(Client *who) { hate_list.PrintHateListToClient(who); }
std::list<struct_HateList*>& GetHateList() { return hate_list.GetHateList(); }
bool CheckLosFN(Mob* other);
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
@@ -797,7 +797,7 @@ public:
void CheckFlee();
inline bool IsBlind() { return spellbonuses.IsBlind; }
inline bool CheckAggro(Mob* other) {return hate_list.IsOnHateList(other);}
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
float CalculateHeadingToTarget(float in_x, float in_y);
bool CalculateNewPosition(float x, float y, float z, float speed, bool checkZ = false);
virtual bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true);
+12 -16
View File
@@ -491,7 +491,7 @@ void Mob::AI_Start(uint32 iMoveDelay) {
pAggroRange = 70;
if (GetAssistRange() == 0)
pAssistRange = 70;
hate_list.Wipe();
hate_list.WipeHateList();
m_Delta = xyz_heading::Origin();
pRunAnimSpeed = 0;
@@ -548,7 +548,7 @@ void Mob::AI_Stop() {
safe_delete(AIscanarea_timer);
safe_delete(AIfeignremember_timer);
hate_list.Wipe();
hate_list.WipeHateList();
}
void NPC::AI_Stop() {
@@ -811,12 +811,12 @@ void Client::AI_Process()
if (engaged)
{
if (IsRooted())
SetTarget(hate_list.GetClosest(this));
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
{
if(AItarget_check_timer->Check())
{
SetTarget(hate_list.GetTop(this));
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
}
@@ -1036,7 +1036,7 @@ void Mob::AI_Process() {
//
if(RuleB(Combat, EnableFearPathing)){
if(curfp) {
if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosest(this)))) {
if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) {
//make sure everybody knows were not moving, for appearance sake
if(IsMoving())
{
@@ -1086,18 +1086,18 @@ void Mob::AI_Process() {
// we are prevented from getting here if we are blind and don't have a target in range
// from above, so no extra blind checks needed
if ((IsRooted() && !GetSpecialAbility(IGNORE_ROOT_AGGRO_RULES)) || IsBlind())
SetTarget(hate_list.GetClosest(this));
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
{
if(AItarget_check_timer->Check())
{
if (IsFocused()) {
if (!target) {
SetTarget(hate_list.GetTop(this));
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
} else {
if (!ImprovedTaunt())
SetTarget(hate_list.GetTop(this));
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
}
@@ -1373,7 +1373,7 @@ void Mob::AI_Process() {
if(IsNPC() && CastToNPC()->IsUnderwaterOnly() && zone->HasWaterMap()) {
auto targetPosition = xyz_location(target->GetX(), target->GetY(), target->GetZ());
if(!zone->watermap->InLiquid(targetPosition)) {
Mob *tar = hate_list.GetTop(this);
Mob *tar = hate_list.GetEntWithMostHateOnList(this);
if(tar == target) {
WipeHateList();
Heal();
@@ -2333,7 +2333,6 @@ create table npc_spells_entries (
bool IsSpellInList(DBnpcspells_Struct* spell_list, int16 iSpellID);
bool IsSpellEffectInList(DBnpcspellseffects_Struct* spelleffect_list, uint16 iSpellEffectID, int32 base, int32 limit, int32 max);
bool Compare_AI_Spells(AISpells_Struct i, AISpells_Struct j);
bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
// ok, this function should load the list, and the parent list then shove them into the struct and sort
@@ -2458,7 +2457,9 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
spell_list->entries[i].resist_adjust);
}
}
std::sort(AIspells.begin(), AIspells.end(), Compare_AI_Spells);
std::sort(AIspells.begin(), AIspells.end(), [](const AISpells_Struct& a, const AISpells_Struct& b) {
return a.priority > b.priority;
});
if (IsValidSpell(attack_proc_spell))
AddProcToWeapon(attack_proc_spell, true, proc_chance);
@@ -2598,11 +2599,6 @@ bool IsSpellInList(DBnpcspells_Struct* spell_list, int16 iSpellID) {
return false;
}
bool Compare_AI_Spells(AISpells_Struct i, AISpells_Struct j)
{
return(i.priority > j.priority);
}
// adds a spell to the list, taking into account priority and resorting list as needed.
void NPC::AddSpellToNPCList(int16 iPriority, int16 iSpellID, uint16 iType,
int16 iManaCost, int32 iRecastDelay, int16 iResistAdjust)
+1 -1
View File
@@ -609,7 +609,7 @@ void LoadSpells(EQEmu::MemoryMappedFile **mmf) {
spells = reinterpret_cast<SPDat_Spell_Struct*>((*mmf)->Get());
mutex.Unlock();
} catch(std::exception &ex) {
LogFile->write(EQEMuLog::Error, "Error loading spells: %s", ex.what());
LogFile->write(EQEmuLog::Error, "Error loading spells: %s", ex.what());
return;
}
+39 -42
View File
@@ -253,8 +253,10 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int
if(!IsMerc())
AI_Start();
d_meele_texture1 = d->d_meele_texture1;
d_meele_texture2 = d->d_meele_texture2;
d_melee_texture1 = d->d_melee_texture1;
d_melee_texture2 = d->d_melee_texture2;
herosforgemodel = d->herosforgemodel;
ammo_idfile = d->ammo_idfile;
memset(equipment, 0, sizeof(equipment));
prim_melee_type = d->prim_melee_type;
@@ -262,9 +264,9 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, const xyz_heading& position, int
ranged_type = d->ranged_type;
// If Melee Textures are not set, set attack type to Hand to Hand as default
if(!d_meele_texture1)
if(!d_melee_texture1)
prim_melee_type = 28;
if(!d_meele_texture2)
if(!d_melee_texture2)
sec_melee_type = 28;
//give NPCs skill values...
@@ -486,32 +488,27 @@ void NPC::ClearItemList() {
itemlist.clear();
}
void NPC::QueryLoot(Client* to) {
int x = 0;
void NPC::QueryLoot(Client* to)
{
to->Message(0, "Coin: %ip %ig %is %ic", platinum, gold, silver, copper);
ItemList::iterator cur,end;
cur = itemlist.begin();
end = itemlist.end();
for(; cur != end; ++cur) {
int x = 0;
for(ItemList::iterator cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++x) {
const Item_Struct* item = database.GetItem((*cur)->item_id);
if (item)
if (to->GetClientVersion() >= EQClientRoF)
{
to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X0000000000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else if (to->GetClientVersion() >= EQClientSoF)
{
to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X00000000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else
{
to->Message(0, "minlvl: %i maxlvl: %i %i: %c%06X000000000000000000000000000000000000000%s%c",(*cur)->min_level, (*cur)->max_level, (int) item->ID,0x12, item->ID, item->Name, 0x12);
}
else
LogFile->write(EQEMuLog::Error, "Database error, invalid item");
x++;
if (item == nullptr) {
LogFile->write(EQEmuLog::Error, "Database error, invalid item");
continue;
}
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetItemData(item);
auto item_link = linker.GenerateLink();
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), item->ID, (*cur)->min_level, (*cur)->max_level);
}
to->Message(0, "%i items on %s.", x, GetName());
}
@@ -912,8 +909,8 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client
npc_type->texture = atoi(sep.arg[3]);
npc_type->light = 0;
npc_type->runspeed = 1.25;
npc_type->d_meele_texture1 = atoi(sep.arg[7]);
npc_type->d_meele_texture2 = atoi(sep.arg[8]);
npc_type->d_melee_texture1 = atoi(sep.arg[7]);
npc_type->d_melee_texture2 = atoi(sep.arg[8]);
npc_type->merchanttype = atoi(sep.arg[9]);
npc_type->bodytype = atoi(sep.arg[10]);
@@ -945,7 +942,7 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const xyz_heading& position, Client
client->Message(0, "Current/Max HP: %i", npc->max_hp);
client->Message(0, "Gender: %u", npc->gender);
client->Message(0, "Class: %u", npc->class_);
client->Message(0, "Weapon Item Number: %u/%u", npc->d_meele_texture1, npc->d_meele_texture2);
client->Message(0, "Weapon Item Number: %u/%u", npc->d_melee_texture1, npc->d_melee_texture2);
client->Message(0, "MerchantID: %u", npc->MerchantType);
client->Message(0, "Bodytype: %u", npc->bodytype);
}
@@ -995,7 +992,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
npc_type_id = results.LastInsertedID();
@@ -1012,7 +1009,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C
spawn->MerchantType, 0, spawn->GetRunspeed(), 28, 28);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
npc_type_id = results.LastInsertedID();
@@ -1024,7 +1021,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C
query = StringFormat("INSERT INTO spawngroup (id, name) VALUES(%i, '%s-%s')", 0, zone, spawn->GetName());
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
uint32 spawngroupid = results.LastInsertedID();
@@ -1038,7 +1035,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C
spawn->GetHeading(), spawngroupid);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -1049,7 +1046,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char* zone, uint32 zone_version,C
spawngroupid, npc_type_id, 100);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "NPCSpawnDB Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -1066,7 +1063,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve
zone, spawn->GetName(), Timer::GetCurrentTime());
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
last_insert_id = results.LastInsertedID();
@@ -1089,7 +1086,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve
spawn->GetHeading(), last_insert_id);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
spawnid = results.LastInsertedID();
@@ -1101,7 +1098,7 @@ uint32 ZoneDatabase::AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_ve
last_insert_id, spawn->GetNPCTypeID(), 100);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "CreateNewNPCSpawnGroupCommand Error: %s %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1323,9 +1320,9 @@ int32 NPC::GetEquipmentMaterial(uint8 material_slot) const
case MaterialChest:
return texture;
case MaterialPrimary:
return d_meele_texture1;
return d_melee_texture1;
case MaterialSecondary:
return d_meele_texture2;
return d_melee_texture2;
default:
//they have nothing in the slot, and its not a special slot... they get nothing.
return(0);
@@ -1663,7 +1660,7 @@ void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool rem
{
if(database.SetSpecialAttkFlag(this->GetNPCTypeID(), orig_parse))
{
LogFile->write(EQEMuLog::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse);
LogFile->write(EQEmuLog::Normal, "NPCTypeID: %i flagged to '%s' for Special Attacks.\n",this->GetNPCTypeID(),orig_parse);
}
}
}
@@ -2124,10 +2121,10 @@ uint32 NPC::GetSpawnPointID() const
void NPC::NPCSlotTexture(uint8 slot, uint16 texture)
{
if (slot == 7) {
d_meele_texture1 = texture;
d_melee_texture1 = texture;
}
else if (slot == 8) {
d_meele_texture2 = texture;
d_melee_texture2 = texture;
}
else if (slot < 6) {
// Reserved for texturing individual armor slots
+10 -4
View File
@@ -243,8 +243,8 @@ public:
inline int32 GetNPCFactionID() const { return npc_faction_id; }
inline int32 GetPrimaryFaction() const { return primary_faction; }
int32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHate(in_ent);}
bool IsOnHatelist(Mob*p) { return hate_list.IsOnHateList(p);}
int32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHateAmount(in_ent);}
bool IsOnHatelist(Mob*p) { return hate_list.IsEntOnHateList(p);}
void SetNPCFactionID(int32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); }
@@ -260,6 +260,7 @@ public:
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
uint32 GetMaxDamage(uint8 tlevel);
void SetTaunting(bool tog) {taunting = tog;}
bool IsTaunting() const { return taunting; }
void PickPocket(Client* thief);
void StartSwarmTimer(uint32 duration) { swarm_timer.Start(duration); }
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange = false);
@@ -397,6 +398,9 @@ public:
void mod_npc_killed(Mob* oos);
void AISpellsList(Client *c);
uint32 GetHeroForgeModel() const { return herosforgemodel; }
void SetHeroForgeModel(uint32 model) { herosforgemodel = model; }
bool IsRaidTarget() const { return raid_target; };
protected:
@@ -485,8 +489,10 @@ protected:
uint16 skills[HIGHEST_SKILL+1];
uint32 equipment[EmuConstants::EQUIPMENT_SIZE]; //this is an array of item IDs
uint16 d_meele_texture1; //this is an item Material value
uint16 d_meele_texture2; //this is an item Material value (offhand)
uint32 herosforgemodel; //this is the Hero Forge Armor Model (i.e 63 or 84 or 203)
uint16 d_melee_texture1; //this is an item Material value
uint16 d_melee_texture2; //this is an item Material value (offhand)
const char* ammo_idfile; //this determines projectile graphic "IT###" (see item field 'idfile')
uint8 prim_melee_type; //Sets the Primary Weapon attack message and animation
uint8 sec_melee_type; //Sets the Secondary Weapon attack message and animation
+13 -5
View File
@@ -118,7 +118,15 @@ Object::Object(Client* client, const ItemInst* inst)
m_data.heading = client->GetHeading();
m_data.x = client->GetX();
m_data.y = client->GetY();
m_data.z = client->GetZ();
if (client->GetClientVersion() >= EQClientRoF2)
{
// RoF2 places items at player's Z, which is 0.625 of their height.
m_data.z = client->GetZ() - (client->GetSize() * 0.625f);
}
else
{
m_data.z = client->GetZ();
}
m_data.zone_id = zone->GetZoneID();
decay_timer.Start();
@@ -328,7 +336,7 @@ const ItemInst* Object::GetItem(uint8 index) {
void Object::PutItem(uint8 index, const ItemInst* inst)
{
if (index > 9) {
LogFile->write(EQEMuLog::Error, "Object::PutItem: Invalid index specified (%i)", index);
LogFile->write(EQEmuLog::Error, "Object::PutItem: Invalid index specified (%i)", index);
return;
}
@@ -590,7 +598,7 @@ uint32 ZoneDatabase::AddObject(uint32 type, uint32 icon, const Object_Struct& ob
safe_delete_array(object_name);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Unable to insert object: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to insert object: %s", results.ErrorMessage().c_str());
return 0;
}
@@ -627,7 +635,7 @@ void ZoneDatabase::UpdateObject(uint32 id, uint32 type, uint32 icon, const Objec
safe_delete_array(object_name);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Unable to update object: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to update object: %s", results.ErrorMessage().c_str());
return;
}
@@ -672,7 +680,7 @@ void ZoneDatabase::DeleteObject(uint32 id)
std::string query = StringFormat("DELETE FROM object WHERE id = %i", id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Unable to delete object: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to delete object: %s", results.ErrorMessage().c_str());
}
}
+19 -19
View File
@@ -61,19 +61,19 @@ PathManager* PathManager::LoadPathFile(const char* ZoneName)
if(Ret->loadPaths(PathFile))
{
LogFile->write(EQEMuLog::Status, "Path File %s loaded.", ZonePathFileName);
LogFile->write(EQEmuLog::Status, "Path File %s loaded.", ZonePathFileName);
}
else
{
LogFile->write(EQEMuLog::Error, "Path File %s failed to load.", ZonePathFileName);
LogFile->write(EQEmuLog::Error, "Path File %s failed to load.", ZonePathFileName);
safe_delete(Ret);
}
fclose(PathFile);
}
else
{
LogFile->write(EQEMuLog::Error, "Path File %s not found.", ZonePathFileName);
LogFile->write(EQEmuLog::Error, "Path File %s not found.", ZonePathFileName);
}
return Ret;
@@ -103,18 +103,18 @@ bool PathManager::loadPaths(FILE *PathFile)
if(strncmp(Magic, "EQEMUPATH", 9))
{
LogFile->write(EQEMuLog::Error, "Bad Magic String in .path file.");
LogFile->write(EQEmuLog::Error, "Bad Magic String in .path file.");
return false;
}
fread(&Head, sizeof(Head), 1, PathFile);
LogFile->write(EQEMuLog::Status, "Path File Header: Version %ld, PathNodes %ld",
LogFile->write(EQEmuLog::Status, "Path File Header: Version %ld, PathNodes %ld",
(long)Head.version, (long)Head.PathNodeCount);
if(Head.version != 2)
{
LogFile->write(EQEMuLog::Error, "Unsupported path file version.");
LogFile->write(EQEmuLog::Error, "Unsupported path file version.");
return false;
}
@@ -138,7 +138,7 @@ bool PathManager::loadPaths(FILE *PathFile)
{
if(PathNodes[i].Neighbours[j].id > MaxNodeID)
{
LogFile->write(EQEMuLog::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id);
LogFile->write(EQEmuLog::Error, "Path Node %i, Neighbour %i (%i) out of range.", i, j, PathNodes[i].Neighbours[j].id);
PathFileValid = false;
}
@@ -345,10 +345,10 @@ bool CheckLOSBetweenPoints(Map::Vertex start, Map::Vertex end) {
return true;
}
bool SortPathNodesByDistance(PathNodeSortStruct n1, PathNodeSortStruct n2)
auto path_compare = [](const PathNodeSortStruct& a, const PathNodeSortStruct& b)
{
return n1.Distance < n2.Distance;
}
return a.Distance < b.Distance;
};
std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
{
@@ -382,7 +382,7 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare);
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
@@ -420,7 +420,7 @@ std::deque<int> PathManager::FindRoute(Map::Vertex Start, Map::Vertex End)
}
}
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare);
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
@@ -573,8 +573,8 @@ void PathManager::SpawnPathNodes()
npc_type->texture = 1;
npc_type->light = 0;
npc_type->runspeed = 0;
npc_type->d_meele_texture1 = 1;
npc_type->d_meele_texture2 = 1;
npc_type->d_melee_texture1 = 1;
npc_type->d_melee_texture2 = 1;
npc_type->merchanttype = 1;
npc_type->bodytype = 1;
@@ -1120,7 +1120,7 @@ int PathManager::FindNearestPathNode(Map::Vertex Position)
}
}
std::sort(SortedByDistance.begin(), SortedByDistance.end(), SortPathNodesByDistance);
std::sort(SortedByDistance.begin(), SortedByDistance.end(), path_compare);
for(auto Iterator = SortedByDistance.begin(); Iterator != SortedByDistance.end(); ++Iterator)
{
@@ -1563,8 +1563,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
npc_type->texture = 1;
npc_type->light = 0;
npc_type->runspeed = 0;
npc_type->d_meele_texture1 = 1;
npc_type->d_meele_texture2 = 1;
npc_type->d_melee_texture1 = 1;
npc_type->d_melee_texture2 = 1;
npc_type->merchanttype = 1;
npc_type->bodytype = 1;
npc_type->STR = 150;
@@ -1624,8 +1624,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
npc_type->texture = 1;
npc_type->light = 0;
npc_type->runspeed = 0;
npc_type->d_meele_texture1 = 1;
npc_type->d_meele_texture2 = 1;
npc_type->d_melee_texture1 = 1;
npc_type->d_melee_texture2 = 1;
npc_type->merchanttype = 1;
npc_type->bodytype = 1;
npc_type->STR = 150;
+11 -4
View File
@@ -5057,14 +5057,21 @@ XS(XS_Client_UpdateTaskActivity); /* prototype to pass -Wmissing-prototypes */
XS(XS_Client_UpdateTaskActivity)
{
dXSARGS;
if (items != 4)
Perl_croak(aTHX_ "Usage: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count)");
if (items < 4)
Perl_croak(aTHX_ "Usage: Client::UpdateTaskActivity(THIS, TaskID, ActivityID, Count, [ignore_quest_update])");
{
bool ignore_quest_update = false;
Client * THIS;
int TaskID = (int)SvIV(ST(1));
int ActivityID = (int)SvIV(ST(2));
int Count = (int)SvUV(ST(3));
if (items == 5){
ignore_quest_update = (bool)SvTRUE(ST(4));
}
if (sv_derived_from(ST(0), "Client")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Client *,tmp);
@@ -5074,7 +5081,7 @@ XS(XS_Client_UpdateTaskActivity)
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
THIS->UpdateTaskActivity(TaskID, ActivityID, Count);
THIS->UpdateTaskActivity(TaskID, ActivityID, Count, ignore_quest_update);
}
XSRETURN_EMPTY;
}
@@ -6305,7 +6312,7 @@ XS(boot_Client)
newXSproto(strcpy(buf, "ClearCompassMark"), XS_Client_ClearCompassMark, file, "$");
newXSproto(strcpy(buf, "GetFreeSpellBookSlot"), XS_Client_GetFreeSpellBookSlot, file, "$;$");
newXSproto(strcpy(buf, "GetSpellBookSlotBySpellID"), XS_Client_GetSpellBookSlotBySpellID, file, "$$");
newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$");
newXSproto(strcpy(buf, "UpdateTaskActivity"), XS_Client_UpdateTaskActivity, file, "$$$$;$");
newXSproto(strcpy(buf, "AssignTask"), XS_Client_AssignTask, file, "$$$");
newXSproto(strcpy(buf, "FailTask"), XS_Client_FailTask, file, "$$");
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
+9 -9
View File
@@ -40,19 +40,19 @@ XS(XS_HateEntry_GetEnt)
if (items != 1)
Perl_croak(aTHX_ "Usage: HateEntry::GetData(THIS)");
{
tHateEntry * THIS;
struct_HateList * THIS;
Mob * RETVAL;
if (sv_derived_from(ST(0), "HateEntry")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(tHateEntry *,tmp);
THIS = INT2PTR(struct_HateList *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type tHateEntry");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->ent;
RETVAL = THIS->entity_on_hatelist;
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "Mob", (void*)RETVAL);
}
@@ -66,20 +66,20 @@ XS(XS_HateEntry_GetHate)
if (items != 1)
Perl_croak(aTHX_ "Usage: HateEntry::GetHate(THIS)");
{
tHateEntry * THIS;
struct_HateList * THIS;
int32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "HateEntry")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(tHateEntry *,tmp);
THIS = INT2PTR(struct_HateList *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type tHateEntry");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->hate;
RETVAL = THIS->stored_hate_amount;
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
@@ -92,20 +92,20 @@ XS(XS_HateEntry_GetDamage)
if (items != 1)
Perl_croak(aTHX_ "Usage: HateEntry::GetDamage(THIS)");
{
tHateEntry * THIS;
struct_HateList * THIS;
int32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "HateEntry")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(tHateEntry *,tmp);
THIS = INT2PTR(struct_HateList *,tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type tHateEntry");
if(THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->damage;
RETVAL = THIS->hatelist_damage;
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
+30 -3
View File
@@ -2933,6 +2933,32 @@ XS(XS_Mob_GetCorruption)
XSRETURN(1);
}
XS(XS_Mob_GetPhR); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetPhR)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: Mob::GetPhR(THIS)");
{
Mob * THIS;
int32 RETVAL;
dXSTARG;
if (sv_derived_from(ST(0), "Mob")) {
IV tmp = SvIV((SV*)SvRV(ST(0)));
THIS = INT2PTR(Mob *, tmp);
}
else
Perl_croak(aTHX_ "THIS is not of type Mob");
if (THIS == nullptr)
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
RETVAL = THIS->GetPhR();
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
XS(XS_Mob_GetMaxSTR); /* prototype to pass -Wmissing-prototypes */
XS(XS_Mob_GetMaxSTR)
{
@@ -5354,7 +5380,7 @@ XS(XS_Mob_SetHate)
damage = (int32)SvIV(ST(3));
}
THIS->SetHate(other, hate, damage);
THIS->SetHateAmountOnEnt(other, hate, damage);
}
XSRETURN_EMPTY;
}
@@ -6599,7 +6625,7 @@ XS(XS_Mob_GetHateList)
while(iter != hate_list.end())
{
tHateEntry *entry = (*iter);
struct_HateList *entry = (*iter);
ST(0) = sv_newmortal();
sv_setref_pv(ST(0), "HateEntry", (void*)entry);
XPUSHs(ST(0));
@@ -8459,7 +8485,8 @@ XS(boot_Mob)
newXSproto(strcpy(buf, "GetDR"), XS_Mob_GetDR, file, "$");
newXSproto(strcpy(buf, "GetPR"), XS_Mob_GetPR, file, "$");
newXSproto(strcpy(buf, "GetCR"), XS_Mob_GetCR, file, "$");
newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCR, file, "$");
newXSproto(strcpy(buf, "GetCorruption"), XS_Mob_GetCorruption, file, "$");
newXSproto(strcpy(buf, "GetPhR"), XS_Mob_GetPhR, file, "$");
newXSproto(strcpy(buf, "GetMaxSTR"), XS_Mob_GetMaxSTR, file, "$");
newXSproto(strcpy(buf, "GetMaxSTA"), XS_Mob_GetMaxSTA, file, "$");
newXSproto(strcpy(buf, "GetMaxDEX"), XS_Mob_GetMaxDEX, file, "$");
+5 -5
View File
@@ -212,7 +212,7 @@ void ZoneDatabase::DeletePetitionFromDB(Petition* wpet) {
std::string query = StringFormat("DELETE FROM petitions WHERE petid = %i", wpet->GetID());
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in DeletePetitionFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in DeletePetitionFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
@@ -226,7 +226,7 @@ void ZoneDatabase::UpdatePetitionToDB(Petition* wpet) {
wpet->CheckedOut() ? 1: 0, wpet->GetID());
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in UpdatePetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in UpdatePetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
@@ -253,12 +253,12 @@ void ZoneDatabase::InsertPetitionToDB(Petition* wpet)
safe_delete_array(petitiontext);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in InsertPetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in InsertPetitionToDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
#if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "New petition created");
LogFile->write(EQEmuLog::Debug, "New petition created");
#endif
}
@@ -272,7 +272,7 @@ void ZoneDatabase::RefreshPetitionsFromDB()
"FROM petitions ORDER BY petid";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in RefreshPetitionsFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in RefreshPetitionsFromDB query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
+9 -8
View File
@@ -243,7 +243,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
PetRecord record;
if(!database.GetPoweredPetEntry(pettype, act_power, &record)) {
Message(13, "Unable to find data for pet %s", pettype);
LogFile->write(EQEMuLog::Error, "Unable to find data for pet %s, check pets table.", pettype);
LogFile->write(EQEmuLog::Error, "Unable to find data for pet %s, check pets table.", pettype);
return;
}
@@ -251,7 +251,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
const NPCType *base = database.GetNPCType(record.npc_type);
if(base == nullptr) {
Message(13, "Unable to load NPC data for pet %s", pettype);
LogFile->write(EQEMuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
LogFile->write(EQEmuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
return;
}
@@ -372,7 +372,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
auto results = database.QueryDatabase(query);
if (!results.Success()) {
// if the database query failed
LogFile->write(EQEMuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), results.ErrorMessage().c_str());
}
if (results.RowCount() != 0) {
@@ -393,8 +393,9 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
npc_type->gender = monster->gender;
npc_type->luclinface = monster->luclinface;
npc_type->helmtexture = monster->helmtexture;
npc_type->herosforgemodel = monster->herosforgemodel;
} else
LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);
LogFile->write(EQEmuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);
}
@@ -455,7 +456,7 @@ bool ZoneDatabase::GetPoweredPetEntry(const char *pet_type, int16 petpower, PetR
pet_type, petpower);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetPoweredPetEntry query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetPoweredPetEntry query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -655,13 +656,13 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%s'", curset);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
if (results.RowCount() != 1) {
// invalid set reference, it doesn't exist
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset);
LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset);
return false;
}
@@ -671,7 +672,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset);
results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetBasePetItems query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
else {
for (row = results.begin(); row != results.end(); ++row)
{
+31 -20
View File
@@ -1,26 +1,37 @@
#ifndef PETS_H
#define PETS_H
#define PET_BACKOFF 1
#define PET_GETLOST 2
#define PET_HEALTHREPORT 4
#define PET_GUARDHERE 5
#define PET_GUARDME 6
#define PET_ATTACK 7
#define PET_FOLLOWME 8
#define PET_SITDOWN 9
#define PET_STANDUP 10
#define PET_TAUNT 11
#define PET_HOLD 12
#define PET_NOTAUNT 14
#define PET_LEADER 16
#define PET_SLUMBER 17
#define PET_NOCAST 18
#define PET_FOCUS 19
#define PET_FOCUS_ON 25
#define PET_FOCUS_OFF 26
#define PET_HOLD_ON 27
#define PET_HOLD_OFF 28
// Defines based on the RoF2 Client
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
#define PET_SITDOWN 7 // 0x07 - /pet sit on
#define PET_STANDUP 8 // 0x08 - /pet sit off
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
#define PET_SLUMBER 18 // 0x12 - What activates this? - define guessed
#define PET_SLUMBER_ON 19 // 0x13 - What activates this? - define guessed
#define PET_SLUMBER_OFF 20 // 0x14 - What activates this? - define guessed
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
#define PET_BACKOFF 28 // 0x1c - /pet back off
#define PET_GETLOST 29 // 0x1d - /pet get lost
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client
class Mob;
struct NPCType;
+5
View File
@@ -200,6 +200,9 @@ bool QuestParserCollection::SpellHasQuestSub(uint32 spell_id, QuestEventID evt)
}
bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
if (itm == nullptr)
return false;
std::string item_script;
if(itm->GetItem()->ScriptFileID != 0) {
item_script = "script_";
@@ -350,6 +353,8 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s
int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers) {
// needs pointer validation check on 'item' argument
std::string item_script;
if(item->GetItem()->ScriptFileID != 0) {
item_script = "script_";
+44 -48
View File
@@ -154,7 +154,7 @@ void QuestManager::echo(int colour, const char *str) {
void QuestManager::say(const char *str) {
QuestManagerCurrentQuestVars();
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
return;
}
else {
@@ -170,7 +170,7 @@ void QuestManager::say(const char *str) {
void QuestManager::say(const char *str, uint8 language) {
QuestManagerCurrentQuestVars();
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::say called with nullptr owner. Probably syntax error in quest file.");
return;
}
else {
@@ -548,7 +548,7 @@ void QuestManager::stopalltimers(Mob *mob) {
void QuestManager::emote(const char *str) {
QuestManagerCurrentQuestVars();
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::emote called with nullptr owner. Probably syntax error in quest file.");
return;
}
else {
@@ -559,7 +559,7 @@ void QuestManager::emote(const char *str) {
void QuestManager::shout(const char *str) {
QuestManagerCurrentQuestVars();
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::shout called with nullptr owner. Probably syntax error in quest file.");
return;
}
else {
@@ -570,7 +570,7 @@ void QuestManager::shout(const char *str) {
void QuestManager::shout2(const char *str) {
QuestManagerCurrentQuestVars();
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::shout2 called with nullptr owner. Probably syntax error in quest file.");
return;
}
else {
@@ -589,7 +589,7 @@ void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint
void QuestManager::depop(int npc_type) {
QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC()) {
LogFile->write(EQEMuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::depop called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
return;
}
else {
@@ -619,7 +619,7 @@ void QuestManager::depop(int npc_type) {
void QuestManager::depop_withtimer(int npc_type) {
QuestManagerCurrentQuestVars();
if (!owner || !owner->IsNPC()) {
LogFile->write(EQEMuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::depop_withtimer called with nullptr owner or non-NPC owner. Probably syntax error in quest file.");
return;
}
else {
@@ -646,7 +646,7 @@ void QuestManager::depopall(int npc_type) {
entity_list.DepopAll(npc_type);
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::depopall called with nullptr owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file.");
}
}
@@ -655,7 +655,7 @@ void QuestManager::depopzone(bool StartSpawnTimer) {
zone->Depop(StartSpawnTimer);
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::depopzone called with nullptr zone. Probably syntax error in quest file.");
}
}
@@ -664,7 +664,7 @@ void QuestManager::repopzone() {
zone->Repop();
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file.");
LogFile->write(EQEmuLog::Quest, "QuestManager::repopzone called with nullptr zone. Probably syntax error in quest file.");
}
}
@@ -1227,13 +1227,17 @@ void QuestManager::settime(uint8 new_hour, uint8 new_min) {
void QuestManager::itemlink(int item_id) {
QuestManagerCurrentQuestVars();
if (initiator) {
const ItemInst* inst = database.CreateItem(item_id);
char* link = 0;
if (initiator->MakeItemLink(link, inst))
initiator->Message(0, "%s tells you, %c%s%s%c", owner->GetCleanName(),
0x12, link, inst->GetItem()->Name, 0x12);
safe_delete_array(link);
safe_delete(inst);
const Item_Struct* item = database.GetItem(item_id);
if (item == nullptr)
return;
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetItemData(item);
auto item_link = linker.GenerateLink();
initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), item_link.c_str());
}
}
@@ -1642,7 +1646,7 @@ void QuestManager::showgrid(int grid) {
"ORDER BY `number`", grid, zone->GetZoneID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Quest, "Error loading grid %d for showgrid(): %s", grid, results.ErrorMessage().c_str());
return;
}
@@ -2098,11 +2102,12 @@ int QuestManager::gettaskactivitydonecount(int task, int activity) {
}
void QuestManager::updatetaskactivity(int task, int activity, int count) {
void QuestManager::updatetaskactivity(int task, int activity, int count, bool ignore_quest_update /*= false*/)
{
QuestManagerCurrentQuestVars();
if(RuleB(TaskSystem, EnableTaskSystem) && initiator)
initiator->UpdateTaskActivity(task, activity, count);
initiator->UpdateTaskActivity(task, activity, count, ignore_quest_update);
}
void QuestManager::resettaskactivity(int task, int activity) {
@@ -2331,7 +2336,7 @@ int QuestManager::collectitems_processSlot(int16 slot_id, uint32 item_id,
bool remove)
{
QuestManagerCurrentQuestVars();
ItemInst *item;
ItemInst *item = nullptr;
int quantity = 0;
item = initiator->GetInv().GetItem(slot_id);
@@ -2456,16 +2461,17 @@ uint32 QuestManager::MerchantCountItem(uint32 NPCid, uint32 itemid) {
// Item Link for use in Variables - "my $example_link = quest::varlink(item_id);"
const char* QuestManager::varlink(char* perltext, int item_id) {
QuestManagerCurrentQuestVars();
const ItemInst* inst = database.CreateItem(item_id);
if (!inst)
const Item_Struct* item = database.GetItem(item_id);
if (!item)
return "INVALID ITEM ID IN VARLINK";
char* link = 0;
char* tempstr = 0;
if (initiator->MakeItemLink(link, inst)) { // make a link to the item
snprintf(perltext, 250, "%c%s%s%c", 0x12, link, inst->GetItem()->Name, 0x12);
}
safe_delete_array(link); // MakeItemLink() uses new also
safe_delete(inst);
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetItemData(item);
auto item_link = linker.GenerateLink();
strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
return perltext;
}
@@ -2630,7 +2636,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
std::string insert_query = StringFormat("INSERT INTO `saylink` (`phrase`) VALUES ('%s')", escaped_string);
results = database.QueryDatabase(insert_query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
} else {
results = database.QueryDatabase(query);
if (results.Success()) {
@@ -2638,7 +2644,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
for(auto row = results.begin(); row != results.end(); ++row)
sayid = atoi(row[0]);
} else {
LogFile->write(EQEMuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in saylink phrase queries", results.ErrorMessage().c_str());
}
}
}
@@ -2651,24 +2657,14 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
sayid = sayid + 500000;
//Create the say link as an item link hash
char linktext[250];
Client::TextLink linker;
linker.SetProxyItemID(sayid);
linker.SetProxyText(LinkName);
if (initiator) {
if (initiator->GetClientVersion() >= EQClientRoF2)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientRoF)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "0000000000000000000000000000000000000000000000000", LinkName, 0x12);
else if (initiator->GetClientVersion() >= EQClientSoF)
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000", LinkName, 0x12);
else
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "000000000000000000000000000000000000000", LinkName, 0x12);
} else { // If no initiator, create an RoF2 saylink, since older clients handle RoF2 ones better than RoF2 handles older ones.
sprintf(linktext, "%c%06X%s%s%c", 0x12, sayid, "00000000000000000000000000000000000000000000000000", LinkName, 0x12);
}
auto say_link = linker.GenerateLink();
strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
strcpy(Phrase,linktext);
return Phrase;
}
const char* QuestManager::getguildnamebyid(int guild_id) {
@@ -2808,7 +2804,7 @@ void QuestManager::voicetell(const char *str, int macronum, int racenum, int gen
safe_delete(outapp);
}
else
LogFile->write(EQEMuLog::Quest, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str);
LogFile->write(EQEmuLog::Quest, "QuestManager::voicetell from %s. Client %s not found.", owner->GetName(), str);
}
}
+1 -1
View File
@@ -183,7 +183,7 @@ public:
bool istaskactive(int task);
bool istaskactivityactive(int task, int activity);
int gettaskactivitydonecount(int task, int activity);
void updatetaskactivity(int task, int activity, int count);
void updatetaskactivity(int task, int activity, int count, bool ignore_quest_update = false);
void resettaskactivity(int task, int activity);
void taskexploredarea(int exploreid);
void assigntask(int taskid);
+9 -9
View File
@@ -99,7 +99,7 @@ void Raid::AddMember(Client *c, uint32 group, bool rleader, bool groupleader, bo
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error inserting into raid members: %s", results.ErrorMessage().c_str());
}
LearnMembers();
@@ -233,12 +233,12 @@ void Raid::SetRaidLeader(const char *wasLead, const char *name)
std::string query = StringFormat("UPDATE raid_members SET israidleader = 0 WHERE name = '%s'", wasLead);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
query = StringFormat("UPDATE raid_members SET israidleader = 1 WHERE name = '%s'", name);
results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Set Raid Leader error: %s\n", results.ErrorMessage().c_str());
strn0cpy(leadername, name, 64);
@@ -271,7 +271,7 @@ void Raid::SaveGroupLeaderAA(uint32 gid)
safe_delete_array(queryBuffer);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
}
void Raid::SaveRaidLeaderAA()
@@ -285,7 +285,7 @@ void Raid::SaveRaidLeaderAA()
safe_delete_array(queryBuffer);
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to store LeadershipAA: %s\n", results.ErrorMessage().c_str());
}
void Raid::UpdateGroupAAs(uint32 gid)
@@ -1407,7 +1407,7 @@ void Raid::GetRaidDetails()
return;
if (results.RowCount() == 0) {
LogFile->write(EQEMuLog::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error getting raid details for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
return;
}
@@ -1439,7 +1439,7 @@ bool Raid::LearnMembers()
return false;
if(results.RowCount() == 0) {
LogFile->write(EQEMuLog::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error getting raid members for raid %lu: %s", (unsigned long)GetID(), results.ErrorMessage().c_str());
disbandCheck = true;
return false;
}
@@ -1643,7 +1643,7 @@ void Raid::SetGroupMentor(uint32 group_id, int percent, char *name)
name, percent, group_id, GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to set raid group mentor: %s\n", results.ErrorMessage().c_str());
}
void Raid::ClearGroupMentor(uint32 group_id)
@@ -1658,7 +1658,7 @@ void Raid::ClearGroupMentor(uint32 group_id)
group_id, GetID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to clear raid group mentor: %s\n", results.ErrorMessage().c_str());
}
// there isn't a nice place to add this in another function, unlike groups
+11 -11
View File
@@ -364,7 +364,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
zone_name, version);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -392,12 +392,12 @@ Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2
"WHERE id = %i", spawn2id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return nullptr;
}
if (results.RowCount() != 1) {
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return nullptr;
}
@@ -424,7 +424,7 @@ bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* z
respawn, variance, condition, cond_value);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -674,7 +674,7 @@ void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) {
event.strict? 1: 0, event.id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
}
@@ -686,7 +686,7 @@ void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 inst
cond_id, value, zone_name, instance_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
}
@@ -699,7 +699,7 @@ bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std:
"FROM spawn_events WHERE id = %d", event_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -742,7 +742,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
"WHERE zone = '%s'", zone_name);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -764,7 +764,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
zone_name, instance_id);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
spawn_conditions.clear();
return false;
}
@@ -782,7 +782,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
"FROM spawn_events WHERE zone = '%s'", zone_name);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -794,7 +794,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
event.period = atoi(row[2]);
if(event.period == 0) {
LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
LogFile->write(EQEmuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
continue;
}
+1 -1
View File
@@ -51,7 +51,7 @@ SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, floa
uint32 SpawnGroup::GetNPCType() {
#if EQDEBUG >= 10
LogFile->write(EQEMuLog::Debug, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
LogFile->write(EQEmuLog::Debug, "SpawnGroup[%08x]::GetNPCType()", (uint32) this);
#endif
int npcType = 0;
int totalchance = 0;
+4 -4
View File
@@ -106,7 +106,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE))
return; //-5?
int32 hate = max_damage;
uint32 hate = max_damage;
if(hate_override > -1)
hate = hate_override;
@@ -583,7 +583,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
int32 ndamage = 0;
int32 max_hit = 0;
int32 min_hit = 0;
int32 hate = 0;
uint32 hate = 0;
int32 primaryweapondamage = 0;
int32 backstab_dmg = 0;
@@ -889,7 +889,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
if (HeadShot_Dmg)
HeadShot = true;
int32 hate = 0;
uint32 hate = 0;
int32 TotalDmg = 0;
int16 WDmg = 0;
int16 ADmg = 0;
@@ -2354,7 +2354,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
skillinuse = SkillOffense;
int damage = 0;
int32 hate = 0;
uint32 hate = 0;
int Hand = MainPrimary;
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
+23 -19
View File
@@ -475,7 +475,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(!target_zone) {
#ifdef SPELL_EFFECT_SPAM
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell In Same Zone.");
LogFile->write(EQEmuLog::Debug, "Succor/Evacuation Spell In Same Zone.");
#endif
if(IsClient())
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
@@ -484,7 +484,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
}
else {
#ifdef SPELL_EFFECT_SPAM
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell To Another Zone.");
LogFile->write(EQEmuLog::Debug, "Succor/Evacuation Spell To Another Zone.");
#endif
if(IsClient())
CastToClient()->MovePC(target_zone, x, y, z, heading);
@@ -1771,7 +1771,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
}
else {
Message_StringID(4, TARGET_NOT_FOUND);
LogFile->write(EQEMuLog::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id);
LogFile->write(EQEmuLog::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id);
}
}
@@ -1897,10 +1897,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (CalculatePoisonCounters(buffs[j].spellid) == 0)
continue;
if (effect_value >= static_cast<int>(buffs[j].counters)) {
if (caster)
if (caster) {
caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name);
caster->CastOnCurer(buffs[j].spellid);
CastOnCure(buffs[j].spellid);
}
effect_value -= buffs[j].counters;
buffs[j].counters = 0;
BuffFadeBySlot(j);
@@ -1930,10 +1931,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
continue;
if (effect_value >= static_cast<int>(buffs[j].counters))
{
if (caster)
if (caster) {
caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name);
caster->CastOnCurer(buffs[j].spellid);
CastOnCure(buffs[j].spellid);
}
effect_value -= buffs[j].counters;
buffs[j].counters = 0;
BuffFadeBySlot(j);
@@ -1965,10 +1967,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
continue;
if (effect_value >= static_cast<int>(buffs[j].counters))
{
if (caster)
if (caster) {
caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name);
caster->CastOnCurer(buffs[j].spellid);
CastOnCure(buffs[j].spellid);
}
effect_value -= buffs[j].counters;
buffs[j].counters = 0;
BuffFadeBySlot(j);
@@ -1999,10 +2002,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (CalculateCorruptionCounters(buffs[j].spellid) == 0)
continue;
if (effect_value >= static_cast<int>(buffs[j].counters)) {
if (caster)
if (caster) {
caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name);
caster->CastOnCurer(buffs[j].spellid);
CastOnCure(buffs[j].spellid);
}
effect_value -= buffs[j].counters;
buffs[j].counters = 0;
BuffFadeBySlot(j);
@@ -2658,7 +2662,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
caster->Taunt(this->CastToNPC(), false, static_cast<float>(spell.base[i]));
if (spell.base2[i] > 0)
CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i]));
CastToNPC()->SetHateAmountOnEnt(caster, (CastToNPC()->GetHateAmount(caster) + spell.base2[i]));
}
break;
}
@@ -2689,7 +2693,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (new_hate <= 0)
new_hate = 1;
CastToNPC()->SetHate(caster, new_hate);
CastToNPC()->SetHateAmountOnEnt(caster, new_hate);
}
break;
}
@@ -2710,9 +2714,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
}else{
int32 newhate = GetHateAmount(caster) + effect_value;
if (newhate < 1)
SetHate(caster,1);
SetHateAmountOnEnt(caster,1);
else
SetHate(caster,newhate);
SetHateAmountOnEnt(caster,newhate);
}
}
break;
@@ -3321,7 +3325,7 @@ snare has both of them negative, yet their range should work the same:
result = ubase * (caster_level * (formula - 2000) + 1);
}
else
LogFile->write(EQEMuLog::Debug, "Unknown spell effect value forumula %d", formula);
LogFile->write(EQEmuLog::Debug, "Unknown spell effect value forumula %d", formula);
}
}
@@ -3542,9 +3546,9 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
}else{
int32 newhate = GetHateAmount(caster) + effect_value;
if (newhate < 1) {
SetHate(caster,1);
SetHateAmountOnEnt(caster,1);
} else {
SetHate(caster,newhate);
SetHateAmountOnEnt(caster,newhate);
}
}
}
@@ -3724,11 +3728,11 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
case SE_AddHateOverTimePct:
{
if (IsNPC()){
int32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100;
uint32 new_hate = CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100;
if (new_hate <= 0)
new_hate = 1;
CastToNPC()->SetHate(caster, new_hate);
CastToNPC()->SetHateAmountOnEnt(caster, new_hate);
}
break;
}
@@ -4812,7 +4816,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
return 0;
break;
default:
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown limit spelltype %d", focus_spell.base[i]);
}
break;
@@ -5151,7 +5155,7 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
//this spits up a lot of garbage when calculating spell focuses
//since they have all kinds of extra effects on them.
default:
LogFile->write(EQEMuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
LogFile->write(EQEmuLog::Normal, "CalcFocusEffect: unknown effectid %d", focus_spell.effectid[i]);
#endif
}
@@ -6420,7 +6424,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
//Limit to amount of pets
if (value >= 221 && value <= 249){
int count = hate_list.SummonedPetCount(this);
int count = hate_list.GetSummonedPetCountOnHateList(this);
for (int base2_value = 221; base2_value <= 249; ++base2_value){
if (value == base2_value){
+52 -29
View File
@@ -257,7 +257,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
if ((itm->GetItem()->Click.Type == ET_EquipClick) && !(itm->GetItem()->Classes & bitmask)) {
if (CastToClient()->GetClientVersion() < EQClientSoF) {
// They are casting a spell from an item that requires equipping but shouldn't let them equip it
LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!",
LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) which they shouldn't be able to equip!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class");
}
@@ -269,12 +269,20 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
if ((itm->GetItem()->Click.Type == ET_ClickEffect2) && !(itm->GetItem()->Classes & bitmask)) {
if (CastToClient()->GetClientVersion() < EQClientSoF) {
// They are casting a spell from an item that they don't meet the race/class requirements to cast
LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!",
LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click a race/class restricted effect on item %s (id: %d) which they shouldn't be able to click!",
CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking race/class restricted item with an invalid class");
}
else {
Message_StringID(13, CANNOT_USE_ITEM);
if (CastToClient()->GetClientVersion() >= EQClientRoF)
{
// Line 181 in eqstr_us.txt was changed in RoF+
Message(15, "Your race, class, or deity cannot use this item.");
}
else
{
Message_StringID(13, CANNOT_USE_ITEM);
}
}
return(false);
}
@@ -282,7 +290,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
if( itm && (itm->GetItem()->Click.Type == ET_EquipClick) && !(item_slot <= MainAmmo || item_slot == MainPowerSource) ){
if (CastToClient()->GetClientVersion() < EQClientSoF) {
// They are attempting to cast a must equip clicky without having it equipped
LogFile->write(EQEMuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
LogFile->write(EQEmuLog::Error, "HACKER: %s (account: %s) attempted to click an equip-only effect on item %s (id: %d) without equiping it!", CastToClient()->GetCleanName(), CastToClient()->AccountName(), itm->GetItem()->Name, itm->GetItem()->ID);
database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it");
}
else {
@@ -1195,22 +1203,29 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
uint32 recastdelay = 0;
uint32 recasttype = 0;
for (int r = 0; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
const ItemInst* aug_i = inst->GetAugment(r);
if(!aug_i)
continue;
const Item_Struct* aug = aug_i->GetItem();
if(!aug)
continue;
if ( aug->Click.Effect == spell_id )
{
recastdelay = aug_i->GetItem()->RecastDelay;
recasttype = aug_i->GetItem()->RecastType;
fromaug = true;
while (true) {
if (inst == nullptr)
break;
for (int r = AUG_BEGIN; r < EmuConstants::ITEM_COMMON_SIZE; r++) {
const ItemInst* aug_i = inst->GetAugment(r);
if (!aug_i)
continue;
const Item_Struct* aug = aug_i->GetItem();
if (!aug)
continue;
if (aug->Click.Effect == spell_id)
{
recastdelay = aug_i->GetItem()->RecastDelay;
recasttype = aug_i->GetItem()->RecastType;
fromaug = true;
break;
}
}
break;
}
//Test the aug recast delay
@@ -2657,7 +2672,7 @@ int CalcBuffDuration_formula(int level, int formula, int duration)
return duration ? duration : 3600;
default:
LogFile->write(EQEMuLog::Debug, "CalcBuffDuration_formula: unknown formula %d", formula);
LogFile->write(EQEmuLog::Debug, "CalcBuffDuration_formula: unknown formula %d", formula);
return 0;
}
}
@@ -3649,11 +3664,11 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
spelltar->AddToHateList(this, aggro);
}
else{
int32 newhate = spelltar->GetHateAmount(this) + aggro;
uint32 newhate = spelltar->GetHateAmount(this) + aggro;
if (newhate < 1) {
spelltar->SetHate(this,1);
spelltar->SetHateAmountOnEnt(this,1);
} else {
spelltar->SetHate(this,newhate);
spelltar->SetHateAmountOnEnt(this,newhate);
}
}
}
@@ -3681,9 +3696,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
spelltar->AddToHateList(this, aggro_amount); else{
int32 newhate = spelltar->GetHateAmount(this) + aggro_amount;
if (newhate < 1) {
spelltar->SetHate(this,1);
spelltar->SetHateAmountOnEnt(this,1);
} else {
spelltar->SetHate(this,newhate);
spelltar->SetHateAmountOnEnt(this,newhate);
}
}
}
@@ -3896,6 +3911,8 @@ void Mob::BuffFadeDetrimental() {
BuffFadeBySlot(j, false);
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeDetrimentalByCaster(Mob *caster)
@@ -3916,6 +3933,8 @@ void Mob::BuffFadeDetrimentalByCaster(Mob *caster)
}
}
}
//we tell BuffFadeBySlot not to recalc, so we can do it only once when were done
CalcBonuses();
}
void Mob::BuffFadeBySitModifier()
@@ -4195,6 +4214,10 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
//Get resist modifier and adjust it based on focus 2 resist about eq to 1% resist chance
int resist_modifier = (use_resist_override) ? resist_override : spells[spell_id].ResistDiff;
if(caster->GetSpecialAbility(CASTING_RESIST_DIFF))
resist_modifier += caster->GetSpecialAbilityParam(CASTING_RESIST_DIFF, 0);
int focus_resist = caster->GetFocusEffect(focusResistRate, spell_id);
resist_modifier -= 2 * focus_resist;
@@ -4939,7 +4962,7 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) {
"WHERE spellid = %i", spell_ID);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str());
return false; // Query failed, so prevent spell from scribing just in case
}
@@ -4958,12 +4981,12 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) {
char_ID, spell_Global_Name.c_str());
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value);
LogFile->write(EQEmuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value);
return false;
}
if (results.RowCount() != 1) {
LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID);
LogFile->write(EQEmuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID);
return false;
}
@@ -4977,7 +5000,7 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) {
return true; // Check if the qglobal value is greater than the require spellglobal value
// If no matching result found in qglobals, don't scribe this spell
LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID);
LogFile->write(EQEmuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID);
return false;
}
@@ -5016,7 +5039,7 @@ bool Mob::FindType(uint16 type, bool bOffensive, uint16 threshold) {
spells[buffs[i].spellid].base[j],
spells[buffs[i].spellid].max[j],
buffs[i].casterlevel, buffs[i].spellid);
LogFile->write(EQEMuLog::Normal,
LogFile->write(EQEmuLog::Normal,
"FindType: type = %d; value = %d; threshold = %d",
type, value, threshold);
if (value < threshold)
+66 -105
View File
@@ -74,7 +74,7 @@ bool TaskManager::LoadTaskSets() {
MAXTASKSETS, MAXTASKS);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadTaskSets: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadTaskSets: %s", results.ErrorMessage().c_str());
return false;
}
@@ -146,7 +146,7 @@ bool TaskManager::LoadTasks(int singleTask) {
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
return false;
}
@@ -155,7 +155,7 @@ bool TaskManager::LoadTasks(int singleTask) {
if((taskID <= 0) || (taskID >= MAXTASKS)) {
// This shouldn't happen, as the SELECT is bounded by MAXTASKS
LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading tasks from database", taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading tasks from database", taskID);
continue;
}
@@ -203,7 +203,7 @@ bool TaskManager::LoadTasks(int singleTask) {
"ORDER BY taskid, activityid ASC", singleTask, MAXACTIVITIESPERTASK);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
return false;
}
@@ -215,13 +215,13 @@ bool TaskManager::LoadTasks(int singleTask) {
if((taskID <= 0) || (taskID >= MAXTASKS) || (activityID < 0) || (activityID >= MAXACTIVITIESPERTASK)) {
// This shouldn't happen, as the SELECT is bounded by MAXTASKS
LogFile->write(EQEMuLog::Error, "[TASKS]Task or Activity ID (%i, %i) out of range while loading "
LogFile->write(EQEmuLog::Error, "[TASKS]Task or Activity ID (%i, %i) out of range while loading "
"activities from database", taskID, activityID);
continue;
}
if(Tasks[taskID]==nullptr) {
LogFile->write(EQEMuLog::Error, "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", taskID, activityID);
LogFile->write(EQEmuLog::Error, "[TASKS]Activity for non-existent task (%i, %i) while loading activities from database", taskID, activityID);
continue;
}
@@ -238,7 +238,7 @@ bool TaskManager::LoadTasks(int singleTask) {
// ERR_NOTASK errors.
// Change to (activityID != (Tasks[taskID]->ActivityCount + 1)) to index from 1
if(activityID != Tasks[taskID]->ActivityCount) {
LogFile->write(EQEMuLog::Error, "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, activityID);
LogFile->write(EQEmuLog::Error, "[TASKS]Activities for Task %i are not sequential starting at 0. Not loading task.", taskID, activityID);
Tasks[taskID] = nullptr;
continue;
}
@@ -323,7 +323,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) {
characterID, taskID, task, state->ActiveTasks[task].AcceptedTime);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
else
state->ActiveTasks[task].Updated = false;
@@ -362,7 +362,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) {
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
continue;
}
@@ -396,7 +396,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) {
std::string query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, -1);
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
continue;
}
@@ -413,7 +413,7 @@ bool TaskManager::SaveClientState(Client *c, ClientTaskState *state) {
query = StringFormat(completedTaskQuery, characterID, state->CompletedTasks[i].CompletedTime, taskID, j);
results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, results.ErrorMessage().c_str());
}
@@ -466,7 +466,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
"WHERE `charid` = %i ORDER BY acceptedtime", characterID);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Tasks: %s", results.ErrorMessage().c_str());
return false;
}
@@ -475,17 +475,17 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
int slot = atoi(row[1]);
if((taskID<0) || (taskID>=MAXTASKS)) {
LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading character tasks from database", taskID);
continue;
}
if((slot<0) || (slot>=MAXACTIVETASKS)) {
LogFile->write(EQEMuLog::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot);
LogFile->write(EQEmuLog::Error, "[TASKS] Slot %i out of range while loading character tasks from database", slot);
continue;
}
if(state->ActiveTasks[slot].TaskID != TASKSLOTEMPTY) {
LogFile->write(EQEMuLog::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID);
LogFile->write(EQEmuLog::Error, "[TASKS] Slot %i for Task %is is already occupied.", slot, taskID);
continue;
}
@@ -513,20 +513,20 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
"ORDER BY `taskid` ASC, `activityid` ASC", characterID);
results = database.QueryDatabase(query);
if (!results.Success()){
LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load Activities: %s", results.ErrorMessage().c_str());
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]);
if((taskID<0) || (taskID>=MAXTASKS)) {
LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading character activities from database", taskID);
continue;
}
int activityID = atoi(row[1]);
if((activityID<0) || (activityID>=MAXACTIVITIESPERTASK)) {
LogFile->write(EQEMuLog::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID);
LogFile->write(EQEmuLog::Error, "[TASKS]Activity ID %i out of range while loading character activities from database", activityID);
continue;
}
@@ -540,7 +540,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
}
if(activeTaskIndex == -1) {
LogFile->write(EQEMuLog::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Activity %i found for task %i which client does not have.", activityID, taskID);
continue;
}
@@ -566,7 +566,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
characterID);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load completed tasks: %s", results.ErrorMessage().c_str());
return false;
}
@@ -582,7 +582,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
int taskID = atoi(row[0]);
if((taskID <= 0) || (taskID >=MAXTASKS)) {
LogFile->write(EQEMuLog::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Task ID %i out of range while loading completed tasks from database", taskID);
continue;
}
@@ -592,7 +592,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
// completed.
int activityID = atoi(row[1]);
if((activityID<-1) || (activityID>=MAXACTIVITIESPERTASK)) {
LogFile->write(EQEMuLog::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID);
LogFile->write(EQEmuLog::Error, "[TASKS]Activity ID %i out of range while loading completed tasks from database", activityID);
continue;
}
@@ -634,7 +634,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
characterID, MAXTASKS);
results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in TaskManager::LoadClientState load enabled tasks: %s", results.ErrorMessage().c_str());
else
for (auto row = results.begin(); row != results.end(); ++row) {
int taskID = atoi(row[0]);
@@ -652,7 +652,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
c->Message(13, "Active Task Slot %i, references a task (%i), that does not exist. "
"Removing from memory. Contact a GM to resolve this.",i, taskID);
LogFile->write(EQEMuLog::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID);
LogFile->write(EQEmuLog::Error, "[TASKS]Character %i has task %i which does not exist.", characterID, taskID);
state->ActiveTasks[i].TaskID=TASKSLOTEMPTY;
continue;
@@ -664,7 +664,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) {
"Removing from memory. Contact a GM to resolve this.",
taskID, Tasks[taskID]->Title);
LogFile->write(EQEMuLog::Error, "[TASKS]Fatal error in character %i task state. Activity %i for "
LogFile->write(EQEmuLog::Error, "[TASKS]Fatal error in character %i task state. Activity %i for "
"Task %i either missing from client state or from task.", characterID, j, taskID);
state->ActiveTasks[i].TaskID=TASKSLOTEMPTY;
break;
@@ -725,7 +725,7 @@ void ClientTaskState::EnableTask(int characterID, int taskCount, int *tasks) {
_log(TASKS__UPDATE, "Executing query %s", query.c_str());
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "[TASKS]Error in ClientTaskState::EnableTask %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in ClientTaskState::EnableTask %s %s", query.c_str(), results.ErrorMessage().c_str());
}
@@ -774,7 +774,7 @@ void ClientTaskState::DisableTask(int charID, int taskCount, int *taskList) {
_log(TASKS__UPDATE, "Executing query %s", query.c_str());
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "[TASKS]Error in ClientTaskState::DisableTask %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in ClientTaskState::DisableTask %s %s", query.c_str(), results.ErrorMessage().c_str());
}
bool ClientTaskState::IsTaskEnabled(int TaskID) {
@@ -1280,7 +1280,7 @@ static void DeleteCompletedTaskFromDatabase(int charID, int taskID) {
const std::string query = StringFormat("DELETE FROM completed_tasks WHERE charid=%i AND taskid = %i", charID, taskID);
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s, %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s, %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1786,7 +1786,7 @@ void ClientTaskState::UpdateTasksOnTouch(Client *c, int ZoneID) {
return;
}
void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int TaskIndex, int ActivityID, int Count) {
void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int TaskIndex, int ActivityID, int Count, bool ignore_quest_update) {
_log(TASKS__UPDATE, "IncrementDoneCount");
@@ -1795,10 +1795,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
if(ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount > Task->Activity[ActivityID].GoalCount)
ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount = Task->Activity[ActivityID].GoalCount;
char buf[24];
snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID);
buf[23] = '\0';
parse->EventPlayer(EVENT_TASK_UPDATE, c, buf, 0);
if (!ignore_quest_update){
char buf[24];
snprintf(buf, 23, "%d %d %d", ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].TaskID);
buf[23] = '\0';
parse->EventPlayer(EVENT_TASK_UPDATE, c, buf, 0);
}
ActiveTasks[TaskIndex].Activity[ActivityID].Updated=true;
// Have we reached the goal count for this activity ?
@@ -1821,11 +1823,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
c->Message(0, "Your task '%s' has been updated.", Task->Title);
if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) {
char buf[24];
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
buf[23] = '\0';
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
if (!ignore_quest_update){
char buf[24];
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
buf[23] = '\0';
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
}
/* QS: PlayerLogTaskUpdates :: Update */
if (RuleB(QueryServ, PlayerLogTaskUpdates)){
std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID());
@@ -2039,7 +2042,8 @@ bool ClientTaskState::IsTaskActivityActive(int TaskID, int ActivityID) {
}
void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count) {
void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update /*= false*/)
{
_log(TASKS__UPDATE, "ClientTaskState UpdateTaskActivity(%i, %i, %i).", TaskID, ActivityID, Count);
@@ -2048,8 +2052,8 @@ void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID,
int ActiveTaskIndex = -1;
for(int i=0; i<MAXACTIVETASKS; i++) {
if(ActiveTasks[i].TaskID==TaskID) {
for (int i = 0; i < MAXACTIVETASKS; i++) {
if (ActiveTasks[i].TaskID == TaskID) {
ActiveTaskIndex = i;
break;
}
@@ -2069,7 +2073,7 @@ void ClientTaskState::UpdateTaskActivity(Client *c, int TaskID, int ActivityID,
// The Activity is not currently active
if(ActiveTasks[ActiveTaskIndex].Activity[ActivityID].State != ActivityActive) return;
_log(TASKS__UPDATE, "Increment done count on UpdateTaskActivity");
IncrementDoneCount(c, Task, ActiveTaskIndex, ActivityID, Count);
IncrementDoneCount(c, Task, ActiveTaskIndex, ActivityID, Count, ignore_quest_update);
}
@@ -2743,17 +2747,17 @@ void TaskManager::SendSingleActiveTaskToClient(Client *c, int TaskIndex, bool Ta
}
}
void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal) {
if((TaskID<1) || (TaskID>=MAXTASKS) || !Tasks[TaskID]) return;
void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceNumber, int StartTime, int Duration, bool BringUpTaskJournal)
{
if ((TaskID < 1) || (TaskID >= MAXTASKS) || !Tasks[TaskID])
return;
int PacketLength = sizeof(TaskDescriptionHeader_Struct) + strlen(Tasks[TaskID]->Title) + 1
+ sizeof(TaskDescriptionData1_Struct) + strlen(Tasks[TaskID]->Description) + 1
+ sizeof(TaskDescriptionData2_Struct) + 1 + sizeof(TaskDescriptionTrailer_Struct);
std::string RewardText;
int ItemID = 0;
int ItemID = NOT_USED;
// If there is an item make the Reward text into a link to the item (only the first item if a list
// is specified). I have been unable to get multiple item links to work.
@@ -2768,62 +2772,19 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
if(ItemID < 0)
ItemID = 0;
}
if(ItemID) {
char *RewardTmp = 0;
if(strlen(Tasks[TaskID]->Reward) != 0) {
const Item_Struct* reward_item = database.GetItem(ItemID);
switch(c->GetClientVersion()) {
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
break;
}
case EQClientRoF:
{
MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
break;
}
default:
{
// All clients after Titanium
MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Tasks[TaskID]->Reward,0x12);
}
}
Client::TextLink linker;
linker.SetLinkType(linker.linkItemData);
linker.SetItemData(reward_item);
linker.SetTaskUse();
if (strlen(Tasks[TaskID]->Reward) != 0)
linker.SetProxyText(Tasks[TaskID]->Reward);
}
else {
const Item_Struct *Item = database.GetItem(ItemID);
if(Item) {
switch(c->GetClientVersion()) {
case EQClientTitanium:
{
MakeAnyLenString(&RewardTmp, "%c%06X000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
break;
}
case EQClientRoF:
{
MakeAnyLenString(&RewardTmp, "%c%06X0000000000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
break;
}
default:
{
// All clients after Titanium
MakeAnyLenString(&RewardTmp, "%c%06X00000000000000000000000000000000000014505DC2%s%c",
0x12, ItemID, Item->Name ,0x12);
}
}
}
}
if(RewardTmp) RewardText += RewardTmp;
safe_delete_array(RewardTmp);
auto reward_link = linker.GenerateLink();
RewardText += reward_link.c_str();
}
else {
RewardText += Tasks[TaskID]->Reward;
@@ -2977,7 +2938,7 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) {
characterID, ActiveTasks[sequenceNumber].TaskID);
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str());
return;
}
_log(TASKS__UPDATE, "CancelTask: %s", query.c_str());
@@ -2986,7 +2947,7 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber) {
characterID, ActiveTasks[sequenceNumber].TaskID);
results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "[TASKS]Error in CientTaskState::CancelTask %s", results.ErrorMessage().c_str());
_log(TASKS__UPDATE, "CancelTask: %s", query.c_str());
@@ -3127,7 +3088,7 @@ bool TaskGoalListManager::LoadLists() {
"ORDER BY `listid`";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -3161,7 +3122,7 @@ bool TaskGoalListManager::LoadLists() {
listID, size);
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, ERR_MYSQLERROR, query.c_str(), results.ErrorMessage().c_str());
TaskGoalLists[listIndex].Size = 0;
continue;
}
@@ -3298,7 +3259,7 @@ bool TaskProximityManager::LoadProximities(int zoneID) {
"ORDER BY `zoneid` ASC", zoneID);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in TaskProximityManager::LoadProximities %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in TaskProximityManager::LoadProximities %s %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
+2 -2
View File
@@ -175,7 +175,7 @@ public:
bool IsTaskActive(int TaskID);
bool IsTaskActivityActive(int TaskID, int ActivityID);
ActivityState GetTaskActivityState(int index, int ActivityID);
void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count);
void UpdateTaskActivity(Client *c, int TaskID, int ActivityID, int Count, bool ignore_quest_update = false);
void ResetTaskActivity(Client *c, int TaskID, int ActivityID);
void CancelTask(Client *c, int SequenceNumber, bool RemoveFromDB = true);
void CancelAllTasks(Client *c);
@@ -204,7 +204,7 @@ public:
private:
bool UnlockActivities(int CharID, int TaskIndex);
void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count=1);
void IncrementDoneCount(Client *c, TaskInformation *Task, int TaskIndex, int ActivityID, int Count = 1, bool ignore_quest_update = false);
int ActiveTaskCount;
ClientTaskInformation ActiveTasks[MAXACTIVETASKS];
std::vector<int>EnabledTasks;
+6 -6
View File
@@ -40,7 +40,7 @@ bool TitleManager::LoadTitles()
"`status`, `item_id`, `prefix`, `suffix`, `title_set` FROM titles";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Unable to load titles: %s : %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Unable to load titles: %s : %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -263,7 +263,7 @@ void TitleManager::CreateNewPlayerTitle(Client *client, const char *title)
safe_delete_array(escTitle);
results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error adding title: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error adding title: %s %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -296,7 +296,7 @@ void TitleManager::CreateNewPlayerSuffix(Client *client, const char *suffix)
safe_delete_array(escSuffix);
results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error adding title suffix: %s %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error adding title suffix: %s %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -351,7 +351,7 @@ void Client::EnableTitle(int titleSet) {
CharacterID(), titleSet);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID());
LogFile->write(EQEmuLog::Error, "Error in EnableTitle query for titleset %i and charid %i", titleSet, CharacterID());
}
@@ -362,7 +362,7 @@ bool Client::CheckTitle(int titleSet) {
titleSet, CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in CheckTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in CheckTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -382,7 +382,7 @@ void Client::RemoveTitle(int titleSet) {
titleSet, CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in RemoveTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in RemoveTitle query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
+36 -34
View File
@@ -42,7 +42,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
{
if (!user || !in_augment)
{
LogFile->write(EQEMuLog::Error, "Client or AugmentItem_Struct not set in Object::HandleAugmentation");
LogFile->write(EQEmuLog::Error, "Client or AugmentItem_Struct not set in Object::HandleAugmentation");
return;
}
@@ -89,12 +89,12 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
if(!container)
{
LogFile->write(EQEMuLog::Error, "Player tried to augment an item without a container set.");
LogFile->write(EQEmuLog::Error, "Player tried to augment an item without a container set.");
user->Message(13, "Error: This item is not a container!");
return;
}
ItemInst *tobe_auged, *auged_with = nullptr;
ItemInst *tobe_auged = nullptr, *auged_with = nullptr;
int8 slot=-1;
// Verify 2 items in the augmentation device
@@ -243,7 +243,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Object *worldo)
{
if (!user || !in_combine) {
LogFile->write(EQEMuLog::Error, "Client or NewCombine_Struct not set in Object::HandleCombine");
LogFile->write(EQEmuLog::Error, "Client or NewCombine_Struct not set in Object::HandleCombine");
return;
}
@@ -418,7 +418,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob
if(success && spec.replace_container) {
if(worldcontainer){
//should report this error, but we dont have the recipe ID, so its not very useful
LogFile->write(EQEMuLog::Error, "Replace container combine executed in a world container.");
LogFile->write(EQEmuLog::Error, "Replace container combine executed in a world container.");
}
else
user->DeleteItemInInventory(in_combine->container_slot, 0, true);
@@ -444,7 +444,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac
//ask the database for the recipe to make sure it exists...
DBTradeskillRecipe_Struct spec;
if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, rac->some_id, user->CharacterID(), &spec)) {
LogFile->write(EQEMuLog::Error, "Unknown recipe for HandleAutoCombine: %u\n", rac->recipe_id);
LogFile->write(EQEmuLog::Error, "Unknown recipe for HandleAutoCombine: %u\n", rac->recipe_id);
user->QueuePacket(outapp);
safe_delete(outapp);
return;
@@ -467,21 +467,21 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac
rac->recipe_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
user->QueuePacket(outapp);
safe_delete(outapp);
return;
}
if(results.RowCount() < 1) {
LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: no components returned");
LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine: no components returned");
user->QueuePacket(outapp);
safe_delete(outapp);
return;
}
if(results.RowCount() > 10) {
LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: too many components returned (%u)", results.RowCount());
LogFile->write(EQEmuLog::Error, "Error in HandleAutoCombine: too many components returned (%u)", results.RowCount());
user->QueuePacket(outapp);
safe_delete(outapp);
return;
@@ -676,7 +676,7 @@ void Client::TradeskillSearchResults(const std::string query, unsigned long objt
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in TradeskillSearchResults query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -684,7 +684,7 @@ void Client::TradeskillSearchResults(const std::string query, unsigned long objt
return; //search gave no results... not an error
if(results.ColumnCount() != 6) {
LogFile->write(EQEMuLog::Error, "Error in TradeskillSearchResults query '%s': Invalid column count in result", query.c_str());
LogFile->write(EQEmuLog::Error, "Error in TradeskillSearchResults query '%s': Invalid column count in result", query.c_str());
return;
}
@@ -730,17 +730,17 @@ void Client::SendTradeskillDetails(uint32 recipe_id) {
recipe_id);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
if(results.RowCount() < 1) {
LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: no components returned");
LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails: no components returned");
return;
}
if(results.RowCount() > 10) {
LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: too many components returned (%u)", results.RowCount());
LogFile->write(EQEmuLog::Error, "Error in SendTradeskillDetails: too many components returned (%u)", results.RowCount());
return;
}
@@ -1185,6 +1185,8 @@ void Client::CheckIncreaseTradeskill(int16 bonusstat, int16 stat_modifier, float
bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id,
uint32 char_id, DBTradeskillRecipe_Struct *spec)
{
if (container == nullptr)
return false;
std::string containers;// make where clause segment for container(s)
if (some_id == 0)
@@ -1230,8 +1232,8 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3
buf2.c_str(), containers.c_str(), count, sum);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, query: %s", query.c_str());
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, error: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe search, query: %s", query.c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe search, error: %s", results.ErrorMessage().c_str());
return false;
}
@@ -1252,7 +1254,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3
//length limit on buf2
if(index == 214) { //Maximum number of recipe matches (19 * 215 = 4096)
LogFile->write(EQEMuLog::Error, "GetTradeRecipe warning: Too many matches. Unable to search all recipe entries. Searched %u of %u possible entries.", index + 1, results.RowCount());
LogFile->write(EQEmuLog::Error, "GetTradeRecipe warning: Too many matches. Unable to search all recipe entries. Searched %u of %u possible entries.", index + 1, results.RowCount());
break;
}
}
@@ -1264,8 +1266,8 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3
"AND sum(tre.item_id * tre.componentcount) = %u", buf2.c_str(), count, sum);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str());
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
return false;
}
}
@@ -1290,18 +1292,18 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3
"AND tre.item_id = %u;", buf2.c_str(), containerId);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str());
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, re-query: %s", query.c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
return false;
}
if(results.RowCount() == 0) { //Recipe contents matched more than 1 recipe, but not in this container
LogFile->write(EQEMuLog::Error, "Combine error: Incorrect container is being used!");
LogFile->write(EQEmuLog::Error, "Combine error: Incorrect container is being used!");
return false;
}
if (results.RowCount() > 1) //Recipe contents matched more than 1 recipe in this container
LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique! %u matches found for container %u. Continuing with first recipe match.", results.RowCount(), containerId);
LogFile->write(EQEmuLog::Error, "Combine error: Recipe is not unique! %u matches found for container %u. Continuing with first recipe match.", results.RowCount(), containerId);
}
@@ -1318,7 +1320,7 @@ bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint3
recipe_id);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in tradeskill verify query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in tradeskill verify query: '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return GetTradeRecipe(recipe_id, c_type, some_id, char_id, spec);
}
@@ -1373,8 +1375,8 @@ bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id
char_id, (unsigned long)recipe_id, containers.c_str());
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, query: %s", query.c_str());
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, query: %s", query.c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecipe, error: %s", results.ErrorMessage().c_str());
return false;
}
@@ -1405,12 +1407,12 @@ bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id
"WHERE successcount > 0 AND recipe_id = %u", recipe_id);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept success query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecept success query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
if(results.RowCount() < 1) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept success: no success items returned");
LogFile->write(EQEmuLog::Error, "Error in GetTradeRecept success: no success items returned");
return false;
}
@@ -1462,7 +1464,7 @@ void ZoneDatabase::UpdateRecipeMadecount(uint32 recipe_id, uint32 char_id, uint3
recipe_id, char_id, madeCount, madeCount);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in UpdateRecipeMadecount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in UpdateRecipeMadecount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
void Client::LearnRecipe(uint32 recipeID)
@@ -1475,12 +1477,12 @@ void Client::LearnRecipe(uint32 recipeID)
"WHERE tr.id = %u ;", CharacterID(), recipeID);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Client::LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Client::LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
if (results.RowCount() != 1) {
LogFile->write(EQEMuLog::Normal, "Client::LearnRecipe - RecipeID: %d had %d occurences.", recipeID, results.RowCount());
LogFile->write(EQEmuLog::Normal, "Client::LearnRecipe - RecipeID: %d had %d occurences.", recipeID, results.RowCount());
return;
}
@@ -1501,7 +1503,7 @@ void Client::LearnRecipe(uint32 recipeID)
recipeID, CharacterID());
results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LearnRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
@@ -1551,7 +1553,7 @@ bool ZoneDatabase::EnableRecipe(uint32 recipe_id)
"WHERE id = %u;", recipe_id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in EnableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in EnableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return results.RowsAffected() > 0;
}
@@ -1562,7 +1564,7 @@ bool ZoneDatabase::DisableRecipe(uint32 recipe_id)
"WHERE id = %u;", recipe_id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in DisableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in DisableRecipe query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return results.RowsAffected() > 0;
}
+9 -6
View File
@@ -85,7 +85,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) {
if (!owner || !owner->IsClient()) {
// This should never happen
LogFile->write(EQEMuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()");
LogFile->write(EQEmuLog::Debug, "Programming error: NPC's should not call Trade::AddEntity()");
return;
}
@@ -159,6 +159,9 @@ Mob* Trade::With()
// Private Method: Send item data for trade item to other person involved in trade
void Trade::SendItemData(const ItemInst* inst, int16 dest_slot_id)
{
if (inst == nullptr)
return;
// @merth: This needs to be redone with new item classes
Mob* mob = With();
if (!mob->IsClient())
@@ -292,7 +295,7 @@ void Trade::LogTrade()
void Trade::DumpTrade()
{
Mob* with = With();
LogFile->write(EQEMuLog::Debug, "Dumping trade data: '%s' in TradeState %i with '%s'",
LogFile->write(EQEmuLog::Debug, "Dumping trade data: '%s' in TradeState %i with '%s'",
this->owner->GetName(), state, ((with==nullptr)?"(null)":with->GetName()));
if (!owner->IsClient())
@@ -303,7 +306,7 @@ void Trade::DumpTrade()
const ItemInst* inst = trader->GetInv().GetItem(i);
if (inst) {
LogFile->write(EQEMuLog::Debug, "Item %i (Charges=%i, Slot=%i, IsBag=%s)",
LogFile->write(EQEmuLog::Debug, "Item %i (Charges=%i, Slot=%i, IsBag=%s)",
inst->GetItem()->ID, inst->GetCharges(),
i, ((inst->IsType(ItemClassContainer)) ? "True" : "False"));
@@ -311,7 +314,7 @@ void Trade::DumpTrade()
for (uint8 j = SUB_BEGIN; j < EmuConstants::ITEM_CONTAINER_SIZE; j++) {
inst = trader->GetInv().GetItem(i, j);
if (inst) {
LogFile->write(EQEMuLog::Debug, "\tBagItem %i (Charges=%i, Slot=%i)",
LogFile->write(EQEmuLog::Debug, "\tBagItem %i (Charges=%i, Slot=%i)",
inst->GetItem()->ID, inst->GetCharges(),
Inventory::CalcSlotId(i, j));
}
@@ -320,7 +323,7 @@ void Trade::DumpTrade()
}
}
LogFile->write(EQEMuLog::Debug, "\tpp:%i, gp:%i, sp:%i, cp:%i", pp, gp, sp, cp);
LogFile->write(EQEmuLog::Debug, "\tpp:%i, gp:%i, sp:%i, cp:%i", pp, gp, sp, cp);
}
#endif
@@ -1535,7 +1538,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs,Client* Trader,const EQApplicat
if((tbs->Price * outtbs->Quantity) <= 0) {
Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1");
Trader->Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1");
LogFile->write(EQEMuLog::Error, "Bazaar: Zero price transaction between %s and %s aborted."
LogFile->write(EQEmuLog::Error, "Bazaar: Zero price transaction between %s and %s aborted."
"Item: %s, Charges: %i, TBS: Qty %i, Price: %i",
GetName(), Trader->GetName(),
BuyItem->GetItem()->Name, BuyItem->GetCharges(), tbs->Quantity, tbs->Price);
+3 -3
View File
@@ -264,7 +264,7 @@ bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
"FROM traps WHERE zone='%s' AND version=%u", zonename, version);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -307,8 +307,8 @@ void Trap::CreateHiddenTrigger()
make_npc->gender = 0;
make_npc->loottable_id = 0;
make_npc->npc_spells_id = 0;
make_npc->d_meele_texture1 = 0;
make_npc->d_meele_texture2 = 0;
make_npc->d_melee_texture1 = 0;
make_npc->d_melee_texture2 = 0;
make_npc->trackable = 0;
make_npc->level = level;
strcpy(make_npc->special_abilities, "19,1^20,1^24,1^25,1");
+5 -5
View File
@@ -220,7 +220,7 @@ void Client::ChangeTributeSettings(TributeInfo_Struct *t) {
void Client::SendTributeDetails(uint32 client_id, uint32 tribute_id) {
if(tribute_list.count(tribute_id) != 1) {
LogFile->write(EQEMuLog::Error, "Details request for invalid tribute %lu", (unsigned long)tribute_id);
LogFile->write(EQEmuLog::Error, "Details request for invalid tribute %lu", (unsigned long)tribute_id);
return;
}
TributeData &td = tribute_list[tribute_id];
@@ -390,7 +390,7 @@ bool ZoneDatabase::LoadTributes() {
const std::string query = "SELECT id, name, descr, unknown, isguild FROM tributes";
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -407,7 +407,7 @@ bool ZoneDatabase::LoadTributes() {
const std::string query2 = "SELECT tribute_id, level, cost, item_id FROM tribute_levels ORDER BY tribute_id, level";
results = QueryDatabase(query2);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -415,14 +415,14 @@ bool ZoneDatabase::LoadTributes() {
uint32 id = atoul(row[0]);
if(tribute_list.count(id) != 1) {
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
LogFile->write(EQEmuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
continue;
}
TributeData &cur = tribute_list[id];
if(cur.tier_count >= MAX_TRIBUTE_TIERS) {
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
LogFile->write(EQEmuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
continue;
}
+2 -1
View File
@@ -5,6 +5,7 @@
#include "position.h"
#include <string>
enum WaterRegionType {
RegionTypeUnsupported = -2,
RegionTypeUntagged = -1,
@@ -22,7 +23,7 @@ class WaterMap
{
public:
WaterMap() { }
~WaterMap() { }
virtual ~WaterMap() { }
static WaterMap* LoadWaterMapfile(std::string zone_name);
virtual WaterRegionType ReturnRegionType(const xyz_location& location) const { return RegionTypeNormal; }
+27 -25
View File
@@ -116,7 +116,7 @@ void NPC::ResumeWandering()
}
else
{
LogFile->write(EQEMuLog::Error, "NPC not paused - can't resume wandering: %lu", (unsigned long)GetNPCTypeID());
LogFile->write(EQEmuLog::Error, "NPC not paused - can't resume wandering: %lu", (unsigned long)GetNPCTypeID());
return;
}
@@ -131,7 +131,7 @@ void NPC::ResumeWandering()
}
else
{
LogFile->write(EQEMuLog::Error, "NPC not on grid - can't resume wandering: %lu", (unsigned long)GetNPCTypeID());
LogFile->write(EQEmuLog::Error, "NPC not on grid - can't resume wandering: %lu", (unsigned long)GetNPCTypeID());
}
return;
}
@@ -154,7 +154,7 @@ void NPC::PauseWandering(int pausetime)
AIwalking_timer->Start(pausetime*1000); // set the timer
}
} else {
LogFile->write(EQEMuLog::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID());
LogFile->write(EQEmuLog::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID());
}
return;
}
@@ -382,7 +382,9 @@ void NPC::GetClosestWaypoint(std::list<wplist> &wp_list, int count, const xyz_lo
w_dist.index = i;
distances.push_back(w_dist);
}
distances.sort(wp_distance_pred);
distances.sort([](const wp_distance& a, const wp_distance& b) {
return a.dist < b.dist;
});
std::list<wp_distance>::iterator iter = distances.begin();
for(int i = 0; i < count; ++i)
@@ -678,7 +680,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, b
{
Map::Vertex dest(m_Position.m_X, m_Position.m_Y, m_Position.m_Z);
float newz = zone->zonemap->FindBestZ(dest, nullptr); + 2.0f;
float newz = zone->zonemap->FindBestZ(dest, nullptr);
mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.m_X,m_Position.m_Y,m_Position.m_Z);
@@ -852,7 +854,7 @@ void NPC::AssignWaypoints(int32 grid) {
std::string query = StringFormat("SELECT `type`, `type2` FROM `grid` WHERE `id` = %i AND `zoneid` = %i", grid, zone->GetZoneID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
return;
}
@@ -873,7 +875,7 @@ void NPC::AssignWaypoints(int32 grid) {
"ORDER BY `number`", grid, zone->GetZoneID());
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
return;
}
@@ -988,7 +990,7 @@ int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetHighestGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetHighestGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1005,7 +1007,7 @@ uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) {
std::string query = StringFormat("SELECT type2 FROM grid WHERE id = %i AND zoneid = %i", grid, zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1026,7 +1028,7 @@ bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist*
"WHERE gridid = %i AND number = %i AND zoneid = %i", grid, num, zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -1054,7 +1056,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3
zone->GetShortName(), (int)location.m_X, (int)location.m_Y);
auto results = QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1068,7 +1070,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3
zone->GetShortName(), location.m_X, _GASSIGN_TOLERANCE, location.m_Y, _GASSIGN_TOLERANCE);
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1097,7 +1099,7 @@ void ZoneDatabase::AssignGrid(Client *client, const xy_location& location, uint3
results = QueryDatabase(query);
if (!results.Success())
{
LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1135,7 +1137,7 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type
"VALUES (%i, %i, %i, %i)", id, zoneid, type, type2);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1148,14 +1150,14 @@ void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type
std::string query = StringFormat("DELETE FROM grid where id=%i", id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
else if(client)
client->LogSQL(query.c_str());
query = StringFormat("DELETE FROM grid_entries WHERE zoneid = %i AND gridid = %i", zoneid, id);
results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
else if(client)
client->LogSQL(query.c_str());
@@ -1171,7 +1173,7 @@ void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, const xyz_
gridid, zoneid, wpnum, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1197,7 +1199,7 @@ void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num
grid_num, zoneid, wp_num);
auto results = QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1224,7 +1226,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he
auto results = QueryDatabase(query);
if (!results.Success()) {
// Query error
LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1245,14 +1247,14 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he
grid_num, zoneid, type1, type2);
results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
else if(client)
client->LogSQL(query.c_str());
query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id);
results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
else if(client)
client->LogSQL(query.c_str());
}
@@ -1264,7 +1266,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he
results = QueryDatabase(query);
if(!results.Success()) { // Query error
LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1279,7 +1281,7 @@ uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, const xyz_he
grid_num, zoneid, next_wp_num, position.m_X, position.m_Y, position.m_Z, pause, position.m_Heading);
results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
else if(client)
client->LogSQL(query.c_str());
@@ -1291,7 +1293,7 @@ uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) {
std::string query = StringFormat("SELECT max(id) FROM grid WHERE zoneid = %i", zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -1311,7 +1313,7 @@ int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) {
"WHERE zoneid = %i AND gridid = %i", zoneid, gridid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
+1 -1
View File
@@ -1384,7 +1384,7 @@ void WorldServer::Process() {
if(NewCorpse)
NewCorpse->Spawn();
else
LogFile->write(EQEMuLog::Error,"Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName());
LogFile->write(EQEmuLog::Error,"Unable to load player corpse id %u for zone %s.", s->player_corpse_id, zone->GetShortName());
break;
}
+79 -76
View File
@@ -83,7 +83,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
return false;
}
LogFile->write(EQEMuLog::Status, "Booting %s (%d:%d)", zonename, iZoneID, iInstanceID);
LogFile->write(EQEmuLog::Status, "Booting %s (%d:%d)", zonename, iZoneID, iInstanceID);
numclients = 0;
zone = new Zone(iZoneID, iInstanceID, zonename);
@@ -110,13 +110,13 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
log_levels[i]=0; //set to zero on a bogue char
}
zone->loglevelvar = log_levels[0];
LogFile->write(EQEMuLog::Status, "General logging level: %i", zone->loglevelvar);
LogFile->write(EQEmuLog::Status, "General logging level: %i", zone->loglevelvar);
zone->merchantvar = log_levels[1];
LogFile->write(EQEMuLog::Status, "Merchant logging level: %i", zone->merchantvar);
LogFile->write(EQEmuLog::Status, "Merchant logging level: %i", zone->merchantvar);
zone->tradevar = log_levels[2];
LogFile->write(EQEMuLog::Status, "Trade logging level: %i", zone->tradevar);
LogFile->write(EQEmuLog::Status, "Trade logging level: %i", zone->tradevar);
zone->lootvar = log_levels[3];
LogFile->write(EQEMuLog::Status, "Loot logging level: %i", zone->lootvar);
LogFile->write(EQEmuLog::Status, "Loot logging level: %i", zone->lootvar);
}
else {
zone->loglevelvar = uint8(atoi(tmp)); //continue supporting only command logging (for now)
@@ -137,8 +137,8 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
delete pack;
}
LogFile->write(EQEMuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort);
LogFile->write(EQEMuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID);
LogFile->write(EQEmuLog::Normal, "---- Zone server %s, listening on port:%i ----", zonename, ZoneConfig::get()->ZonePort);
LogFile->write(EQEmuLog::Status, "Zone Bootup: %s (%i: %i)", zonename, iZoneID, iInstanceID);
parse->Init();
UpdateWindowTitle();
zone->GetTimeSync();
@@ -156,11 +156,11 @@ bool Zone::LoadZoneObjects() {
zoneid, instanceversion);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error Loading Objects from DB: %s",results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Loading Objects from DB: %s",results.ErrorMessage().c_str());
return false;
}
LogFile->write(EQEMuLog::Status, "Loading Objects from DB...");
LogFile->write(EQEmuLog::Status, "Loading Objects from DB...");
for (auto row = results.begin(); row != results.end(); ++row) {
if (atoi(row[9]) == 0)
{
@@ -277,7 +277,7 @@ bool Zone::LoadGroundSpawns() {
memset(&groundspawn, 0, sizeof(groundspawn));
int gsindex=0;
LogFile->write(EQEMuLog::Status, "Loading Ground Spawns from DB...");
LogFile->write(EQEmuLog::Status, "Loading Ground Spawns from DB...");
database.LoadGroundSpawns(zoneid, GetInstanceVersion(), &groundspawn);
uint32 ix=0;
char* name=0;
@@ -391,7 +391,7 @@ uint32 Zone::GetTempMerchantQuantity(uint32 NPCID, uint32 Slot) {
}
void Zone::LoadTempMerchantData() {
LogFile->write(EQEMuLog::Status, "Loading Temporary Merchant Lists...");
LogFile->write(EQEmuLog::Status, "Loading Temporary Merchant Lists...");
std::string query = StringFormat(
"SELECT "
"DISTINCT ml.npcid, "
@@ -409,7 +409,7 @@ void Zone::LoadTempMerchantData() {
"ORDER BY ml.slot ", GetShortName(), GetInstanceVersion());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadTempMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadTempMerchantData query '%s' %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
std::map<uint32, std::list<TempMerchantList> >::iterator cur;
@@ -442,7 +442,7 @@ void Zone::LoadNewMerchantData(uint32 merchantid) {
"classes_required, probability FROM merchantlist WHERE merchantid=%d ORDER BY slot", merchantid);
auto results = database.QueryDatabase(query);
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());
return;
}
@@ -463,8 +463,8 @@ void Zone::LoadNewMerchantData(uint32 merchantid) {
}
void Zone::GetMerchantDataForZoneLoad() {
LogFile->write(EQEMuLog::Status, "Loading Merchant Lists...");
std::string query = StringFormat(
LogFile->write(EQEmuLog::Status, "Loading Merchant Lists...");
std::string query = StringFormat(
"SELECT "
"DISTINCT ml.merchantid, "
"ml.slot, "
@@ -486,7 +486,7 @@ void Zone::GetMerchantDataForZoneLoad() {
std::map<uint32, std::list<MerchantList> >::iterator cur;
uint32 npcid = 0;
if (results.RowCount() == 0) {
LogFile->write(EQEMuLog::Debug, "No Merchant Data found for %s.", GetShortName());
LogFile->write(EQEmuLog::Debug, "No Merchant Data found for %s.", GetShortName());
return;
}
for (auto row = results.begin(); row != results.end(); ++row) {
@@ -536,7 +536,7 @@ void Zone::LoadMercTemplates(){
"`merc_stance_entries` ORDER BY `class_id`, `proficiency_id`, `stance_id`";
auto results = database.QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()");
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()");
else {
for (auto row = results.begin(); row != results.end(); ++row) {
MercStanceInfo tempMercStanceInfo;
@@ -559,7 +559,7 @@ void Zone::LoadMercTemplates(){
"ORDER BY MTyp.race_id, MS.class_id, MTyp.proficiency_id;";
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()");
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadMercTemplates()");
return;
}
@@ -603,7 +603,7 @@ void Zone::LoadLevelEXPMods(){
const std::string query = "SELECT level, exp_mod, aa_exp_mod FROM level_exp_mods";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::LoadEXPLevelMods()");
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::LoadEXPLevelMods()");
return;
}
@@ -627,7 +627,7 @@ void Zone::LoadMercSpells(){
"ORDER BY msl.class_id, msl.proficiency_id, msle.spell_type, msle.minlevel, msle.slot;";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadMercSpells()");
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadMercSpells()");
return;
}
@@ -649,7 +649,7 @@ void Zone::LoadMercSpells(){
}
if(MERC_DEBUG > 0)
LogFile->write(EQEMuLog::Debug, "Mercenary Debug: Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size());
LogFile->write(EQEmuLog::Debug, "Mercenary Debug: Loaded %i merc spells.", merc_spells_list[1].size() + merc_spells_list[2].size() + merc_spells_list[9].size() + merc_spells_list[12].size());
}
@@ -696,11 +696,11 @@ void Zone::Shutdown(bool quite)
}
zone->ldon_trap_entry_list.clear();
LogFile->write(EQEMuLog::Status, "Zone Shutdown: %s (%i)", zone->GetShortName(), zone->GetZoneID());
LogFile->write(EQEmuLog::Status, "Zone Shutdown: %s (%i)", zone->GetShortName(), zone->GetZoneID());
petition_list.ClearPetitions();
zone->GotCurTime(false);
if (!quite)
LogFile->write(EQEMuLog::Normal, "Zone shutdown: going to sleep");
LogFile->write(EQEmuLog::Normal, "Zone shutdown: going to sleep");
ZoneLoaded = false;
zone->ResetAuth();
@@ -712,19 +712,19 @@ void Zone::Shutdown(bool quite)
void Zone::LoadZoneDoors(const char* zone, int16 version)
{
LogFile->write(EQEMuLog::Status, "Loading doors for %s ...", zone);
LogFile->write(EQEmuLog::Status, "Loading doors for %s ...", zone);
uint32 maxid;
int32 count = database.GetDoorsCount(&maxid, zone, version);
if(count < 1) {
LogFile->write(EQEMuLog::Status, "... No doors loaded.");
LogFile->write(EQEmuLog::Status, "... No doors loaded.");
return;
}
Door *dlist = new Door[count];
if(!database.LoadDoors(count, dlist, zone, version)) {
LogFile->write(EQEMuLog::Error, "... Failed to load doors.");
LogFile->write(EQEmuLog::Error, "... Failed to load doors.");
delete[] dlist;
return;
}
@@ -782,12 +782,12 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
database.GetZoneLongName(short_name, &long_name, file_name, &m_SafePoint.m_X, &m_SafePoint.m_Y, &m_SafePoint.m_Z, &pgraveyard_id, &pMaxClients);
if(graveyard_id() > 0)
{
LogFile->write(EQEMuLog::Debug, "Graveyard ID is %i.", graveyard_id());
LogFile->write(EQEmuLog::Debug, "Graveyard ID is %i.", graveyard_id());
bool GraveYardLoaded = database.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.m_X, &m_Graveyard.m_Y, &m_Graveyard.m_Z, &m_Graveyard.m_Heading);
if(GraveYardLoaded)
LogFile->write(EQEMuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str());
LogFile->write(EQEmuLog::Debug, "Loaded a graveyard for zone %s: graveyard zoneid is %u at %s.", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str());
else
LogFile->write(EQEMuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name);
LogFile->write(EQEmuLog::Error, "Unable to load the graveyard id %i for zone %s.", graveyard_id(), short_name);
}
if (long_name == 0) {
long_name = strcpy(new char[18], "Long zone missing");
@@ -795,7 +795,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
autoshutdown_timer.Start(AUTHENTICATION_TIMEOUT * 1000, false);
Weather_Timer = new Timer(60000);
Weather_Timer->Start();
LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000);
LogFile->write(EQEmuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", short_name, Weather_Timer->GetRemainingTime()/1000);
zone_weather = 0;
weather_intensity = 0;
blocked_spells = nullptr;
@@ -880,56 +880,56 @@ Zone::~Zone() {
bool Zone::Init(bool iStaticZone) {
SetStaticZone(iStaticZone);
LogFile->write(EQEMuLog::Status, "Loading spawn conditions...");
LogFile->write(EQEmuLog::Status, "Loading spawn conditions...");
if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) {
LogFile->write(EQEMuLog::Error, "Loading spawn conditions failed, continuing without them.");
LogFile->write(EQEmuLog::Error, "Loading spawn conditions failed, continuing without them.");
}
LogFile->write(EQEMuLog::Status, "Loading static zone points...");
LogFile->write(EQEmuLog::Status, "Loading static zone points...");
if (!database.LoadStaticZonePoints(&zone_point_list, short_name, GetInstanceVersion())) {
LogFile->write(EQEMuLog::Error, "Loading static zone points failed.");
LogFile->write(EQEmuLog::Error, "Loading static zone points failed.");
return false;
}
LogFile->write(EQEMuLog::Status, "Loading spawn groups...");
LogFile->write(EQEmuLog::Status, "Loading spawn groups...");
if (!database.LoadSpawnGroups(short_name, GetInstanceVersion(), &spawn_group_list)) {
LogFile->write(EQEMuLog::Error, "Loading spawn groups failed.");
LogFile->write(EQEmuLog::Error, "Loading spawn groups failed.");
return false;
}
LogFile->write(EQEMuLog::Status, "Loading spawn2 points...");
LogFile->write(EQEmuLog::Status, "Loading spawn2 points...");
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion()))
{
LogFile->write(EQEMuLog::Error, "Loading spawn2 points failed.");
LogFile->write(EQEmuLog::Error, "Loading spawn2 points failed.");
return false;
}
LogFile->write(EQEMuLog::Status, "Loading player corpses...");
LogFile->write(EQEmuLog::Status, "Loading player corpses...");
if (!database.LoadCharacterCorpses(zoneid, instanceid)) {
LogFile->write(EQEMuLog::Error, "Loading player corpses failed.");
LogFile->write(EQEmuLog::Error, "Loading player corpses failed.");
return false;
}
LogFile->write(EQEMuLog::Status, "Loading traps...");
LogFile->write(EQEmuLog::Status, "Loading traps...");
if (!database.LoadTraps(short_name, GetInstanceVersion()))
{
LogFile->write(EQEMuLog::Error, "Loading traps failed.");
LogFile->write(EQEmuLog::Error, "Loading traps failed.");
return false;
}
LogFile->write(EQEMuLog::Status, "Loading adventure flavor text...");
LogFile->write(EQEmuLog::Status, "Loading adventure flavor text...");
LoadAdventureFlavor();
LogFile->write(EQEMuLog::Status, "Loading ground spawns...");
LogFile->write(EQEmuLog::Status, "Loading ground spawns...");
if (!LoadGroundSpawns())
{
LogFile->write(EQEMuLog::Error, "Loading ground spawns failed. continuing.");
LogFile->write(EQEmuLog::Error, "Loading ground spawns failed. continuing.");
}
LogFile->write(EQEMuLog::Status, "Loading World Objects from DB...");
LogFile->write(EQEmuLog::Status, "Loading World Objects from DB...");
if (!LoadZoneObjects())
{
LogFile->write(EQEMuLog::Error, "Loading World Objects failed. continuing.");
LogFile->write(EQEmuLog::Error, "Loading World Objects failed. continuing.");
}
//load up the zone's doors (prints inside)
@@ -986,10 +986,10 @@ bool Zone::Init(bool iStaticZone) {
}
}
LogFile->write(EQEMuLog::Status, "Loading timezone data...");
LogFile->write(EQEmuLog::Status, "Loading timezone data...");
zone->zone_time.setEQTimeZone(database.GetZoneTZ(zoneid, GetInstanceVersion()));
LogFile->write(EQEMuLog::Status, "Init Finished: ZoneID = %d, Time Offset = %d", zoneid, zone->zone_time.getEQTimeZone());
LogFile->write(EQEmuLog::Status, "Init Finished: ZoneID = %d, Time Offset = %d", zoneid, zone->zone_time.getEQTimeZone());
LoadTickItems();
@@ -1000,32 +1000,32 @@ bool Zone::Init(bool iStaticZone) {
}
void Zone::ReloadStaticData() {
LogFile->write(EQEMuLog::Status, "Reloading Zone Static Data...");
LogFile->write(EQEmuLog::Status, "Reloading Zone Static Data...");
LogFile->write(EQEMuLog::Status, "Reloading static zone points...");
LogFile->write(EQEmuLog::Status, "Reloading static zone points...");
zone_point_list.Clear();
if (!database.LoadStaticZonePoints(&zone_point_list, GetShortName(), GetInstanceVersion())) {
LogFile->write(EQEMuLog::Error, "Loading static zone points failed.");
LogFile->write(EQEmuLog::Error, "Loading static zone points failed.");
}
LogFile->write(EQEMuLog::Status, "Reloading traps...");
LogFile->write(EQEmuLog::Status, "Reloading traps...");
entity_list.RemoveAllTraps();
if (!database.LoadTraps(GetShortName(), GetInstanceVersion()))
{
LogFile->write(EQEMuLog::Error, "Reloading traps failed.");
LogFile->write(EQEmuLog::Error, "Reloading traps failed.");
}
LogFile->write(EQEMuLog::Status, "Reloading ground spawns...");
LogFile->write(EQEmuLog::Status, "Reloading ground spawns...");
if (!LoadGroundSpawns())
{
LogFile->write(EQEMuLog::Error, "Reloading ground spawns failed. continuing.");
LogFile->write(EQEmuLog::Error, "Reloading ground spawns failed. continuing.");
}
entity_list.RemoveAllObjects();
LogFile->write(EQEMuLog::Status, "Reloading World Objects from DB...");
LogFile->write(EQEmuLog::Status, "Reloading World Objects from DB...");
if (!LoadZoneObjects())
{
LogFile->write(EQEMuLog::Error, "Reloading World Objects failed. continuing.");
LogFile->write(EQEmuLog::Error, "Reloading World Objects failed. continuing.");
}
entity_list.RemoveAllDoors();
@@ -1041,7 +1041,7 @@ void Zone::ReloadStaticData() {
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name...
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
LogFile->write(EQEMuLog::Status, "Zone Static Data Reloaded.");
LogFile->write(EQEmuLog::Status, "Zone Static Data Reloaded.");
}
bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDefault)
@@ -1053,7 +1053,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind,
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
{
LogFile->write(EQEMuLog::Error, "Error loading the Zone Config.");
LogFile->write(EQEmuLog::Error, "Error loading the Zone Config.");
return false;
}
}
@@ -1068,7 +1068,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind,
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
{
LogFile->write(EQEMuLog::Error, "Error loading the Zone Config.");
LogFile->write(EQEmuLog::Error, "Error loading the Zone Config.");
return false;
}
}
@@ -1079,7 +1079,7 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDe
strcpy(newzone_data.zone_long_name, GetLongName());
strcpy(newzone_data.zone_short_name2, GetShortName());
LogFile->write(EQEMuLog::Status, "Successfully loaded Zone Config.");
LogFile->write(EQEmuLog::Status, "Successfully loaded Zone Config.");
return true;
}
@@ -1384,11 +1384,11 @@ void Zone::ChangeWeather()
weathertimer = weatherTimerRule*1000;
Weather_Timer->Start(weathertimer);
}
LogFile->write(EQEMuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000);
LogFile->write(EQEmuLog::Debug, "The next weather check for zone: %s will be in %i seconds.", zone->GetShortName(), Weather_Timer->GetRemainingTime()/1000);
}
else
{
LogFile->write(EQEMuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i The next check will be in %i seconds. Rain chance: %i, Rain duration: %i, Snow chance %i, Snow duration: %i", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration);
LogFile->write(EQEmuLog::Debug, "The weather for zone: %s has changed. Old weather was = %i. New weather is = %i The next check will be in %i seconds. Rain chance: %i, Rain duration: %i, Snow chance %i, Snow duration: %i", zone->GetShortName(), tmpOldWeather, zone_weather,Weather_Timer->GetRemainingTime()/1000,rainchance,rainduration,snowchance,snowduration);
this->weatherSend();
}
}
@@ -1473,7 +1473,7 @@ void Zone::Repop(uint32 delay) {
quest_manager.ClearAllTimers();
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, GetInstanceVersion(), delay))
LogFile->write(EQEMuLog::Debug, "Error in Zone::Repop: database.PopulateZoneSpawnList failed");
LogFile->write(EQEmuLog::Debug, "Error in Zone::Repop: database.PopulateZoneSpawnList failed");
initgrids_timer.Start();
@@ -1557,8 +1557,8 @@ ZonePoint* Zone::GetClosestZonePoint(const xyz_location& location, uint32 to, Cl
{
if(client)
client->CheatDetected(MQZoneUnknownDest, location.m_X, location.m_Y, location.m_Z); // Someone is trying to use /zone
LogFile->write(EQEMuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist);
LogFile->write(EQEMuLog::Status, "<Real Zone Points>. %s", to_string(location).c_str());
LogFile->write(EQEmuLog::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist);
LogFile->write(EQEmuLog::Status, "<Real Zone Points>. %s", to_string(location).c_str());
}
if(closest_dist > max_distance2)
@@ -1835,7 +1835,7 @@ void Zone::LoadBlockedSpells(uint32 zoneid)
blocked_spells = new ZoneSpellsBlocked[totalBS];
if(!database.LoadBlockedSpells(totalBS, blocked_spells, zoneid))
{
LogFile->write(EQEMuLog::Error, "... Failed to load blocked spells.");
LogFile->write(EQEmuLog::Error, "... Failed to load blocked spells.");
ClearBlockedSpells();
}
}
@@ -1962,7 +1962,7 @@ void Zone::LoadLDoNTraps()
const std::string query = "SELECT id, type, spell_id, skill, locked FROM ldon_trap_templates";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadLDoNTraps: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadLDoNTraps: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -1983,7 +1983,7 @@ void Zone::LoadLDoNTrapEntries()
const std::string query = "SELECT id, trap_id FROM ldon_trap_entries";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadLDoNTrapEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadLDoNTrapEntries: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2025,7 +2025,7 @@ void Zone::LoadVeteranRewards()
"ORDER by claim_id, reward_slot";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadVeteranRewards: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadVeteranRewards: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2071,7 +2071,7 @@ void Zone::LoadAlternateCurrencies()
const std::string query = "SELECT id, item_id FROM alternate_currency";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadAlternateCurrencies: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadAlternateCurrencies: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2119,7 +2119,7 @@ void Zone::LoadAdventureFlavor()
const std::string query = "SELECT id, text FROM adventure_template_entry_flavor";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadAdventureFlavor: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadAdventureFlavor: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2194,7 +2194,7 @@ void Zone::LoadNPCEmotes(LinkedList<NPC_Emote_Struct*>* NPCEmoteList)
const std::string query = "SELECT emoteid, event_, type, text FROM npc_emotes";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadNPCEmotes: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadNPCEmotes: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2211,7 +2211,10 @@ void Zone::LoadNPCEmotes(LinkedList<NPC_Emote_Struct*>* NPCEmoteList)
}
void Zone::ReloadWorld(uint32 Option){
if(Option == 1){
if (Option == 0) {
entity_list.ClearAreas();
parse->ReloadQuests();
} else if(Option == 1) {
zone->Repop(0);
entity_list.ClearAreas();
parse->ReloadQuests();
@@ -2225,7 +2228,7 @@ void Zone::LoadTickItems()
const std::string query = "SELECT it_itemid, it_chance, it_level, it_qglobal, it_bagslot FROM item_tick";
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in Zone::LoadTickItems: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in Zone::LoadTickItems: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
return;
}
+2 -2
View File
@@ -34,7 +34,7 @@ void log_message_mob(LogType type, Mob *who, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args);
LogFile->writePVA(EQEmuLog::Debug, prefix_buffer, fmt, args);
va_end(args);
}
@@ -46,7 +46,7 @@ void log_message_mobVA(LogType type, Mob *who, const char *fmt, va_list args) {
snprintf(prefix_buffer, 255, "[%s] %s: ", log_type_info[type].name, who->GetName());
prefix_buffer[255] = '\0';
LogFile->writePVA(EQEMuLog::Debug, prefix_buffer, fmt, args);
LogFile->writePVA(EQEmuLog::Debug, prefix_buffer, fmt, args);
}
void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length, uint8 padding) {
+211 -164
View File
@@ -1,4 +1,5 @@
#include "../common/extprofile.h"
#include "../common/item.h"
#include "../common/rulesys.h"
@@ -85,7 +86,7 @@ bool ZoneDatabase::SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
zoneid, instance_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in SaveZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in SaveZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str());
return false;
}
@@ -111,7 +112,7 @@ bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
"FROM zone WHERE zoneidnumber = %i AND version = %i", zoneid, instance_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetZoneCFG query %s: %s", query.c_str(), results.ErrorMessage().c_str());
strcpy(*map_filename, "default");
return false;
}
@@ -200,7 +201,7 @@ void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 ti
"AND instance_id = %lu",(unsigned long)id, (unsigned long)instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -211,7 +212,7 @@ void ZoneDatabase::UpdateSpawn2Timeleft(uint32 id, uint16 instance_id, uint32 ti
(unsigned long)timeleft, (unsigned long)instance_id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in UpdateTimeLeft query %s: %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -224,7 +225,7 @@ uint32 ZoneDatabase::GetSpawnTimeLeft(uint32 id, uint16 instance_id)
(unsigned long)id, (unsigned long)zone->GetInstanceID());
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in GetSpawnTimeLeft query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in GetSpawnTimeLeft query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -254,7 +255,7 @@ void ZoneDatabase::UpdateSpawn2Status(uint32 id, uint8 new_status)
std::string query = StringFormat("UPDATE spawn2 SET enabled = %i WHERE id = %lu", new_status, (unsigned long)id);
auto results = QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error in UpdateSpawn2Status query %s: %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in UpdateSpawn2Status query %s: %s", query.c_str(), results.ErrorMessage().c_str());
}
@@ -425,7 +426,7 @@ void ZoneDatabase::GetEventLogs(const char* name,char* target,uint32 account_id,
void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container)
{
if (!container) {
LogFile->write(EQEMuLog::Error, "Programming error: LoadWorldContainer passed nullptr pointer");
LogFile->write(EQEmuLog::Error, "Programming error: LoadWorldContainer passed nullptr pointer");
return;
}
@@ -433,7 +434,7 @@ void ZoneDatabase::LoadWorldContainer(uint32 parentid, ItemInst* container)
"FROM object_contents WHERE parentid = %i", parentid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in DB::LoadWorldContainer: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in DB::LoadWorldContainer: %s", results.ErrorMessage().c_str());
return;
}
@@ -498,7 +499,7 @@ void ZoneDatabase::SaveWorldContainer(uint32 zone_id, uint32 parent_id, const It
augslot[0], augslot[1], augslot[2], augslot[3], augslot[4], augslot[5]);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::SaveWorldContainer: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::SaveWorldContainer: %s", results.ErrorMessage().c_str());
}
@@ -510,7 +511,7 @@ void ZoneDatabase::DeleteWorldContainer(uint32 parent_id, uint32 zone_id)
std::string query = StringFormat("DELETE FROM object_contents WHERE parentid = %i AND zoneid = %i", parent_id, zone_id);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::DeleteWorldContainer: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::DeleteWorldContainer: %s", results.ErrorMessage().c_str());
}
@@ -1225,7 +1226,7 @@ bool ZoneDatabase::LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Str
bool ZoneDatabase::SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value){
std::string query = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, lang_id, value); QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterLanguage for character ID: %i, lang_id:%u value:%u done", character_id, lang_id, value);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterLanguage for character ID: %i, lang_id:%u value:%u done", character_id, lang_id, value);
return true;
}
@@ -1237,10 +1238,10 @@ bool ZoneDatabase::SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, u
/* Save Home Bind Point */
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)", character_id, zone_id, instance_id, position.m_X, position.m_Y, position.m_Z, position.m_Heading, is_home);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBindPoint for character ID: %i zone_id: %u instance_id: %u position: %s ishome: %u", character_id, zone_id, instance_id, to_string(position).c_str(), is_home);
auto results = QueryDatabase(query);
if (!results.RowsAffected()) {
LogFile->write(EQEMuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str());
LogFile->write(EQEmuLog::Debug, "ERROR Bind Home Save: %s. %s", results.ErrorMessage().c_str(), query.c_str());
}
return true;
}
@@ -1251,20 +1252,20 @@ bool ZoneDatabase::SaveCharacterMaterialColor(uint32 character_id, uint32 slot_i
uint8 blue = (color & 0x000000FF);
std::string query = StringFormat("REPLACE INTO `character_material` (id, slot, red, green, blue, color, use_tint) VALUES (%u, %u, %u, %u, %u, %u, 255)", character_id, slot_id, red, green, blue, color); auto results = QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterMaterialColor for character ID: %i, slot_id: %u color: %u done", character_id, slot_id, color);
return true;
}
bool ZoneDatabase::SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value){
std::string query = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, skill_id, value); auto results = QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterSkill for character ID: %i, skill_id:%u value:%u done", character_id, skill_id, value);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterSkill for character ID: %i, skill_id:%u value:%u done", character_id, skill_id, value);
return true;
}
bool ZoneDatabase::SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id){
std::string query = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, slot_id, disc_id);
auto results = QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterDisc for character ID: %i, slot:%u disc_id:%u done", character_id, slot_id, disc_id);
return true;
}
@@ -1276,7 +1277,7 @@ bool ZoneDatabase::SaveCharacterTribute(uint32 character_id, PlayerProfile_Struc
if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != TRIBUTE_NONE){
std::string query = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterTribute for character ID: %i, tier:%u tribute:%u done", character_id, pp->tributes[i].tier, pp->tributes[i].tribute);
}
}
return true;
@@ -1287,7 +1288,7 @@ bool ZoneDatabase::SaveCharacterBandolier(uint32 character_id, uint8 bandolier_i
DoEscapeString(bandolier_name_esc, bandolier_name, strlen(bandolier_name));
std::string query = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%u, %u, %u, %u, %u,'%s')", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name_esc);
auto results = QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterBandolier for character ID: %i, bandolier_id: %u, bandolier_slot: %u item_id: %u, icon:%u band_name:%s done", character_id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name);
if (!results.RowsAffected()){ std::cout << "ERROR Bandolier Save: " << results.ErrorMessage() << "\n\n" << query << "\n" << std::endl; }
return true;
}
@@ -1602,7 +1603,7 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
m_epp->expended_aa
);
auto results = database.QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
LogFile->write(EQEmuLog::Debug, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
return true;
}
@@ -1642,8 +1643,8 @@ bool ZoneDatabase::SaveCharacterCurrency(uint32 character_id, PlayerProfile_Stru
pp->careerRadCrystals,
pp->currentEbonCrystals,
pp->careerEbonCrystals);
auto results = database.QueryDatabase(query);
LogFile->write(EQEMuLog::Debug, "Saving Currency for character ID: %i, done", character_id);
auto results = database.QueryDatabase(query);
LogFile->write(EQEmuLog::Debug, "Saving Currency for character ID: %i, done", character_id);
return true;
}
@@ -1652,7 +1653,7 @@ bool ZoneDatabase::SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 cur
" VALUES (%u, %u, %u)",
character_id, aa_id, current_level);
auto results = QueryDatabase(rquery);
LogFile->write(EQEMuLog::Debug, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level);
LogFile->write(EQEmuLog::Debug, "Saving AA for character ID: %u, aa_id: %u current_level: %u", character_id, aa_id, current_level);
return true;
}
@@ -1746,15 +1747,15 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
// according to spawn2.
std::string query = StringFormat("SELECT npc_types.id, npc_types.name, npc_types.level, npc_types.race, "
"npc_types.class, npc_types.hp, npc_types.mana, npc_types.gender, "
"npc_types.texture, npc_types.helmtexture, npc_types.size, "
"npc_types.texture, npc_types.helmtexture, npc_types.herosforgemodel, npc_types.size, "
"npc_types.loottable_id, npc_types.merchant_id, npc_types.alt_currency_id, "
"npc_types.adventure_template_id, npc_types.trap_template, npc_types.attack_speed, "
"npc_types.STR, npc_types.STA, npc_types.DEX, npc_types.AGI, npc_types._INT, "
"npc_types.WIS, npc_types.CHA, npc_types.MR, npc_types.CR, npc_types.DR, "
"npc_types.FR, npc_types.PR, npc_types.Corrup, npc_types.PhR,"
"npc_types.mindmg, npc_types.maxdmg, npc_types.attack_count, npc_types.special_abilities,"
"npc_types.npc_spells_id, npc_types.npc_spells_effects_id, npc_types.d_meele_texture1,"
"npc_types.d_meele_texture2, npc_types.ammo_idfile, npc_types.prim_melee_type,"
"npc_types.npc_spells_id, npc_types.npc_spells_effects_id, npc_types.d_melee_texture1,"
"npc_types.d_melee_texture2, npc_types.ammo_idfile, npc_types.prim_melee_type,"
"npc_types.sec_melee_type, npc_types.ranged_type, npc_types.runspeed, npc_types.findable,"
"npc_types.trackable, npc_types.hp_regen_rate, npc_types.mana_regen_rate, "
"npc_types.aggroradius, npc_types.assistradius, npc_types.bodytype, npc_types.npc_faction_id, "
@@ -1796,88 +1797,86 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->gender = atoi(row[7]);
tmpNPCType->texture = atoi(row[8]);
tmpNPCType->helmtexture = atoi(row[9]);
tmpNPCType->size = atof(row[10]);
tmpNPCType->loottable_id = atoi(row[11]);
tmpNPCType->merchanttype = atoi(row[12]);
tmpNPCType->alt_currency_type = atoi(row[13]);
tmpNPCType->adventure_template = atoi(row[14]);
tmpNPCType->trap_template = atoi(row[15]);
tmpNPCType->attack_speed = atof(row[16]);
tmpNPCType->STR = atoi(row[17]);
tmpNPCType->STA = atoi(row[18]);
tmpNPCType->DEX = atoi(row[19]);
tmpNPCType->AGI = atoi(row[20]);
tmpNPCType->INT = atoi(row[21]);
tmpNPCType->WIS = atoi(row[22]);
tmpNPCType->CHA = atoi(row[23]);
tmpNPCType->MR = atoi(row[24]);
tmpNPCType->CR = atoi(row[25]);
tmpNPCType->DR = atoi(row[26]);
tmpNPCType->FR = atoi(row[27]);
tmpNPCType->PR = atoi(row[28]);
tmpNPCType->Corrup = atoi(row[29]);
tmpNPCType->PhR = atoi(row[30]);
tmpNPCType->min_dmg = atoi(row[31]);
tmpNPCType->max_dmg = atoi(row[32]);
tmpNPCType->attack_count = atoi(row[33]);
tmpNPCType->herosforgemodel = atoul(row[10]);
tmpNPCType->size = atof(row[11]);
tmpNPCType->loottable_id = atoi(row[12]);
tmpNPCType->merchanttype = atoi(row[13]);
tmpNPCType->alt_currency_type = atoi(row[14]);
tmpNPCType->adventure_template = atoi(row[15]);
tmpNPCType->trap_template = atoi(row[16]);
tmpNPCType->attack_speed = atof(row[17]);
tmpNPCType->STR = atoi(row[18]);
tmpNPCType->STA = atoi(row[19]);
tmpNPCType->DEX = atoi(row[20]);
tmpNPCType->AGI = atoi(row[21]);
tmpNPCType->INT = atoi(row[22]);
tmpNPCType->WIS = atoi(row[23]);
tmpNPCType->CHA = atoi(row[24]);
tmpNPCType->MR = atoi(row[25]);
tmpNPCType->CR = atoi(row[26]);
tmpNPCType->DR = atoi(row[27]);
tmpNPCType->FR = atoi(row[28]);
tmpNPCType->PR = atoi(row[29]);
tmpNPCType->Corrup = atoi(row[30]);
tmpNPCType->PhR = atoi(row[31]);
tmpNPCType->min_dmg = atoi(row[32]);
tmpNPCType->max_dmg = atoi(row[33]);
tmpNPCType->attack_count = atoi(row[34]);
if (row[34] != nullptr)
strn0cpy(tmpNPCType->special_abilities, row[34], 512);
if (row[35] != nullptr)
strn0cpy(tmpNPCType->special_abilities, row[35], 512);
else
tmpNPCType->special_abilities[0] = '\0';
tmpNPCType->npc_spells_id = atoi(row[35]);
tmpNPCType->npc_spells_effects_id = atoi(row[36]);
tmpNPCType->d_meele_texture1 = atoi(row[37]);
tmpNPCType->d_meele_texture2 = atoi(row[38]);
strn0cpy(tmpNPCType->ammo_idfile, row[39], 30);
tmpNPCType->prim_melee_type = atoi(row[40]);
tmpNPCType->sec_melee_type = atoi(row[41]);
tmpNPCType->ranged_type = atoi(row[42]);
tmpNPCType->runspeed= atof(row[43]);
tmpNPCType->findable = atoi(row[44]) == 0? false : true;
tmpNPCType->trackable = atoi(row[45]) == 0? false : true;
tmpNPCType->hp_regen = atoi(row[46]);
tmpNPCType->mana_regen = atoi(row[47]);
tmpNPCType->npc_spells_id = atoi(row[36]);
tmpNPCType->npc_spells_effects_id = atoi(row[37]);
tmpNPCType->d_melee_texture1 = atoi(row[38]);
tmpNPCType->d_melee_texture2 = atoi(row[39]);
strn0cpy(tmpNPCType->ammo_idfile, row[40], 30);
tmpNPCType->prim_melee_type = atoi(row[41]);
tmpNPCType->sec_melee_type = atoi(row[42]);
tmpNPCType->ranged_type = atoi(row[43]);
tmpNPCType->runspeed= atof(row[44]);
tmpNPCType->findable = atoi(row[45]) == 0? false : true;
tmpNPCType->trackable = atoi(row[46]) == 0? false : true;
tmpNPCType->hp_regen = atoi(row[47]);
tmpNPCType->mana_regen = atoi(row[48]);
// set defaultvalue for aggroradius
tmpNPCType->aggroradius = (int32)atoi(row[48]);
// set default value for aggroradius
tmpNPCType->aggroradius = (int32)atoi(row[49]);
if (tmpNPCType->aggroradius <= 0)
tmpNPCType->aggroradius = 70;
tmpNPCType->assistradius = (int32)atoi(row[49]);
tmpNPCType->assistradius = (int32)atoi(row[50]);
if (tmpNPCType->assistradius <= 0)
tmpNPCType->assistradius = tmpNPCType->aggroradius;
if (row[50] && strlen(row[50]))
tmpNPCType->bodytype = (uint8)atoi(row[50]);
if (row[51] && strlen(row[51]))
tmpNPCType->bodytype = (uint8)atoi(row[51]);
else
tmpNPCType->bodytype = 0;
tmpNPCType->npc_faction_id = atoi(row[51]);
tmpNPCType->npc_faction_id = atoi(row[52]);
tmpNPCType->luclinface = atoi(row[52]);
tmpNPCType->hairstyle = atoi(row[53]);
tmpNPCType->haircolor = atoi(row[54]);
tmpNPCType->eyecolor1 = atoi(row[55]);
tmpNPCType->eyecolor2 = atoi(row[56]);
tmpNPCType->beardcolor = atoi(row[57]);
tmpNPCType->beard = atoi(row[58]);
tmpNPCType->drakkin_heritage = atoi(row[59]);
tmpNPCType->drakkin_tattoo = atoi(row[60]);
tmpNPCType->drakkin_details = atoi(row[61]);
tmpNPCType->luclinface = atoi(row[53]);
tmpNPCType->hairstyle = atoi(row[54]);
tmpNPCType->haircolor = atoi(row[55]);
tmpNPCType->eyecolor1 = atoi(row[56]);
tmpNPCType->eyecolor2 = atoi(row[57]);
tmpNPCType->beardcolor = atoi(row[58]);
tmpNPCType->beard = atoi(row[59]);
tmpNPCType->drakkin_heritage = atoi(row[60]);
tmpNPCType->drakkin_tattoo = atoi(row[61]);
tmpNPCType->drakkin_details = atoi(row[62]);
uint32 armor_tint_id = atoi(row[62]);
uint32 armor_tint_id = atoi(row[63]);
tmpNPCType->armor_tint[0] = (atoi(row[63]) & 0xFF) << 16;
tmpNPCType->armor_tint[0] |= (atoi(row[64]) & 0xFF) << 8;
tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF);
tmpNPCType->armor_tint[0] = (atoi(row[64]) & 0xFF) << 16;
tmpNPCType->armor_tint[0] |= (atoi(row[65]) & 0xFF) << 8;
tmpNPCType->armor_tint[0] |= (atoi(row[66]) & 0xFF);
tmpNPCType->armor_tint[0] |= (tmpNPCType->armor_tint[0]) ? (0xFF << 24) : 0;
if (armor_tint_id == 0)
for (int index = MaterialChest; index <= EmuConstants::MATERIAL_END; index++)
tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0];
else if (tmpNPCType->armor_tint[0] == 0)
if (armor_tint_id != 0)
{
std::string armortint_query = StringFormat("SELECT red1h, grn1h, blu1h, "
"red2c, grn2c, blu2c, "
@@ -1903,35 +1902,42 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
tmpNPCType->armor_tint[index] |= (tmpNPCType->armor_tint[index]) ? (0xFF << 24) : 0;
}
}
} else
armor_tint_id = 0;
}
// Try loading npc_types tint fields if armor tint is 0 or query failed to get results
if (armor_tint_id == 0)
{
for (int index = MaterialChest; index < _MaterialCount; index++)
{
tmpNPCType->armor_tint[index] = tmpNPCType->armor_tint[0];
}
}
tmpNPCType->see_invis = atoi(row[66]);
tmpNPCType->see_invis_undead = atoi(row[67]) == 0? false: true; // Set see_invis_undead flag
if (row[68] != nullptr)
strn0cpy(tmpNPCType->lastname, row[68], 32);
tmpNPCType->see_invis = atoi(row[67]);
tmpNPCType->see_invis_undead = atoi(row[68]) == 0? false: true; // Set see_invis_undead flag
if (row[69] != nullptr)
strn0cpy(tmpNPCType->lastname, row[69], 32);
tmpNPCType->qglobal = atoi(row[69]) == 0? false: true; // qglobal
tmpNPCType->AC = atoi(row[70]);
tmpNPCType->npc_aggro = atoi(row[71]) == 0? false: true;
tmpNPCType->spawn_limit = atoi(row[72]);
tmpNPCType->see_hide = atoi(row[73]) == 0? false: true;
tmpNPCType->see_improved_hide = atoi(row[74]) == 0? false: true;
tmpNPCType->ATK = atoi(row[75]);
tmpNPCType->accuracy_rating = atoi(row[76]);
tmpNPCType->avoidance_rating = atoi(row[77]);
tmpNPCType->slow_mitigation = atoi(row[78]);
tmpNPCType->maxlevel = atoi(row[79]);
tmpNPCType->scalerate = atoi(row[80]);
tmpNPCType->private_corpse = atoi(row[81]) == 1 ? true: false;
tmpNPCType->unique_spawn_by_name = atoi(row[82]) == 1 ? true: false;
tmpNPCType->underwater = atoi(row[83]) == 1 ? true: false;
tmpNPCType->emoteid = atoi(row[84]);
tmpNPCType->spellscale = atoi(row[85]);
tmpNPCType->healscale = atoi(row[86]);
tmpNPCType->no_target_hotkey = atoi(row[87]) == 1 ? true: false;
tmpNPCType->raid_target = atoi(row[88]) == 0 ? false: true;
tmpNPCType->attack_delay = atoi(row[89]);
tmpNPCType->qglobal = atoi(row[70]) == 0? false: true; // qglobal
tmpNPCType->AC = atoi(row[71]);
tmpNPCType->npc_aggro = atoi(row[72]) == 0? false: true;
tmpNPCType->spawn_limit = atoi(row[73]);
tmpNPCType->see_hide = atoi(row[74]) == 0? false: true;
tmpNPCType->see_improved_hide = atoi(row[75]) == 0? false: true;
tmpNPCType->ATK = atoi(row[76]);
tmpNPCType->accuracy_rating = atoi(row[77]);
tmpNPCType->avoidance_rating = atoi(row[78]);
tmpNPCType->slow_mitigation = atoi(row[79]);
tmpNPCType->maxlevel = atoi(row[80]);
tmpNPCType->scalerate = atoi(row[81]);
tmpNPCType->private_corpse = atoi(row[82]) == 1 ? true: false;
tmpNPCType->unique_spawn_by_name = atoi(row[83]) == 1 ? true: false;
tmpNPCType->underwater = atoi(row[84]) == 1 ? true: false;
tmpNPCType->emoteid = atoi(row[85]);
tmpNPCType->spellscale = atoi(row[86]);
tmpNPCType->healscale = atoi(row[87]);
tmpNPCType->no_target_hotkey = atoi(row[88]) == 1 ? true: false;
tmpNPCType->raid_target = atoi(row[89]) == 0 ? false: true;
tmpNPCType->attack_delay = atoi(row[90]);
// If NPC with duplicate NPC id already in table,
// free item we attempted to add.
@@ -1953,39 +1959,81 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
//need to save based on merc_npc_type & client level
uint32 merc_type_id = id * 100 + clientlevel;
// If NPC is already in tree, return it.
// If Merc is already in tree, return it.
auto itr = zone->merctable.find(merc_type_id);
if(itr != zone->merctable.end())
return itr->second;
//If the NPC type is 0, return nullptr. (sanity check)
//If the id is 0, return nullptr. (sanity check)
if(id == 0)
return nullptr;
// Otherwise, get NPCs from database.
// If id is 0, load all npc_types for the current zone,
// according to spawn2.
std::string query = StringFormat("SELECT vwMercNpcTypes.merc_npc_type_id, vwMercNpcTypes.name, "
"vwMercNpcTypes.level, vwMercNpcTypes.race_id, vwMercNpcTypes.class_id, "
"vwMercNpcTypes.hp, vwMercNpcTypes.mana, vwMercNpcTypes.gender, "
"vwMercNpcTypes.texture, vwMercNpcTypes.helmtexture, vwMercNpcTypes.attack_speed, "
"vwMercNpcTypes.STR, vwMercNpcTypes.STA, vwMercNpcTypes.DEX, vwMercNpcTypes.AGI, "
"vwMercNpcTypes._INT, vwMercNpcTypes.WIS, vwMercNpcTypes.CHA, vwMercNpcTypes.MR, "
"vwMercNpcTypes.CR, vwMercNpcTypes.DR, vwMercNpcTypes.FR, vwMercNpcTypes.PR, "
"vwMercNpcTypes.Corrup, vwMercNpcTypes.mindmg, vwMercNpcTypes.maxdmg, "
"vwMercNpcTypes.attack_count, vwMercNpcTypes.special_abilities, "
"vwMercNpcTypes.d_meele_texture1, vwMercNpcTypes.d_meele_texture2, "
"vwMercNpcTypes.prim_melee_type, vwMercNpcTypes.sec_melee_type, "
"vwMercNpcTypes.runspeed, vwMercNpcTypes.hp_regen_rate, vwMercNpcTypes.mana_regen_rate, "
"vwMercNpcTypes.bodytype, vwMercNpcTypes.armortint_id, "
"vwMercNpcTypes.armortint_red, vwMercNpcTypes.armortint_green, vwMercNpcTypes.armortint_blue, "
"vwMercNpcTypes.AC, vwMercNpcTypes.ATK, vwMercNpcTypes.Accuracy, vwMercNpcTypes.spellscale, "
"vwMercNpcTypes.healscale FROM vwMercNpcTypes "
"WHERE merc_npc_type_id = %d AND clientlevel = %d AND race_id = %d",
id, clientlevel, raceid); //dual primary keys. one is ID, one is level.
// Otherwise, load Merc data on demand
std::string query = StringFormat("SELECT "
"m_stats.merc_npc_type_id, "
"'' AS name, "
"m_stats.level, "
"m_types.race_id, "
"m_subtypes.class_id, "
"m_stats.hp, "
"m_stats.mana, "
"0 AS gender, "
"m_armorinfo.texture, "
"m_armorinfo.helmtexture, "
"m_stats.attack_speed, "
"m_stats.STR, "
"m_stats.STA, "
"m_stats.DEX, "
"m_stats.AGI, "
"m_stats._INT, "
"m_stats.WIS, "
"m_stats.CHA, "
"m_stats.MR, "
"m_stats.CR, "
"m_stats.DR, "
"m_stats.FR, "
"m_stats.PR, "
"m_stats.Corrup, "
"m_stats.mindmg, "
"m_stats.maxdmg, "
"m_stats.attack_count, "
"m_stats.special_abilities, "
"m_weaponinfo.d_melee_texture1, "
"m_weaponinfo.d_melee_texture2, "
"m_weaponinfo.prim_melee_type, "
"m_weaponinfo.sec_melee_type, "
"m_stats.runspeed, "
"m_stats.hp_regen_rate, "
"m_stats.mana_regen_rate, "
"1 AS bodytype, "
"m_armorinfo.armortint_id, "
"m_armorinfo.armortint_red, "
"m_armorinfo.armortint_green, "
"m_armorinfo.armortint_blue, "
"m_stats.AC, "
"m_stats.ATK, "
"m_stats.Accuracy, "
"m_stats.spellscale, "
"m_stats.healscale "
"FROM merc_stats m_stats "
"INNER JOIN merc_armorinfo m_armorinfo "
"ON m_stats.merc_npc_type_id = m_armorinfo.merc_npc_type_id "
"AND m_armorinfo.minlevel <= m_stats.level AND m_armorinfo.maxlevel >= m_stats.level "
"INNER JOIN merc_weaponinfo m_weaponinfo "
"ON m_stats.merc_npc_type_id = m_weaponinfo.merc_npc_type_id "
"AND m_weaponinfo.minlevel <= m_stats.level AND m_weaponinfo.maxlevel >= m_stats.level "
"INNER JOIN merc_templates m_templates "
"ON m_templates.merc_npc_type_id = m_stats.merc_npc_type_id "
"INNER JOIN merc_types m_types "
"ON m_templates.merc_type_id = m_types.merc_type_id "
"INNER JOIN merc_subtypes m_subtypes "
"ON m_templates.merc_subtype_id = m_subtypes.merc_subtype_id "
"WHERE m_templates.merc_npc_type_id = %d AND m_stats.clientlevel = %d AND m_types.race_id = %d",
id, clientlevel, raceid); //dual primary keys. one is ID, one is level.
auto results = QueryDatabase(query);
if (!results.Success()) {
std::cerr << "Error loading NPCs from database. Bad query: " << results.ErrorMessage() << std::endl;
std::cerr << "Error loading Mercenaries from database. Bad query: " << results.ErrorMessage() << std::endl;
return nullptr;
}
@@ -2033,8 +2081,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
else
tmpNPCType->special_abilities[0] = '\0';
tmpNPCType->d_meele_texture1 = atoi(row[28]);
tmpNPCType->d_meele_texture2 = atoi(row[29]);
tmpNPCType->d_melee_texture1 = atoi(row[28]);
tmpNPCType->d_melee_texture2 = atoi(row[29]);
tmpNPCType->prim_melee_type = atoi(row[30]);
tmpNPCType->sec_melee_type = atoi(row[31]);
tmpNPCType->runspeed= atof(row[32]);
@@ -2091,16 +2139,16 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
tmpNPCType->accuracy_rating = atoi(row[42]);
tmpNPCType->scalerate = RuleI(Mercs, ScaleRate);
tmpNPCType->spellscale = atoi(row[43]);
tmpNPCType->healscale = atoi(row[4]);
tmpNPCType->healscale = atoi(row[44]);
// If NPC with duplicate NPC id already in table,
// If Merc with duplicate NPC id already in table,
// free item we attempted to add.
if (zone->merctable.find(tmpNPCType->npc_id * 100 + clientlevel) != zone->merctable.end()) {
if (zone->merctable.find(merc_type_id) != zone->merctable.end()) {
delete tmpNPCType;
return nullptr;
}
zone->merctable[tmpNPCType->npc_id * 100 + clientlevel]=tmpNPCType;
zone->merctable[merc_type_id] = tmpNPCType;
npc = tmpNPCType;
}
@@ -2296,7 +2344,7 @@ void ZoneDatabase::SaveMercBuffs(Merc *merc) {
std::string query = StringFormat("DELETE FROM merc_buffs WHERE MercId = %u", merc->GetMercID());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error While Deleting Merc Buffs before save: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error While Deleting Merc Buffs before save: %s", results.ErrorMessage().c_str());
return;
}
@@ -2322,7 +2370,7 @@ void ZoneDatabase::SaveMercBuffs(Merc *merc) {
buffs[buffCount].caston_z, buffs[buffCount].ExtraDIChance);
results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error Saving Merc Buffs: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Saving Merc Buffs: %s", results.ErrorMessage().c_str());
break;
}
}
@@ -2341,7 +2389,7 @@ void ZoneDatabase::LoadMercBuffs(Merc *merc) {
merc->GetMercID());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str());
return;
}
@@ -2386,7 +2434,7 @@ void ZoneDatabase::LoadMercBuffs(Merc *merc) {
query = StringFormat("DELETE FROM merc_buffs WHERE MercId = %u", merc->GetMercID());
results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Loading Merc Buffs: %s", results.ErrorMessage().c_str());
}
@@ -2402,14 +2450,14 @@ bool ZoneDatabase::DeleteMerc(uint32 merc_id) {
auto results = database.QueryDatabase(query);
if(!results.Success())
{
LogFile->write(EQEMuLog::Error, "Error Deleting Merc Buffs: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Deleting Merc Buffs: %s", results.ErrorMessage().c_str());
}
query = StringFormat("DELETE FROM mercs WHERE MercID = '%u'", merc_id);
results = database.QueryDatabase(query);
if(!results.Success())
{
LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Deleting Merc: %s", results.ErrorMessage().c_str());
return false;
}
@@ -2427,7 +2475,7 @@ void ZoneDatabase::LoadMercEquipment(Merc *merc) {
merc->GetLevel(), merc->GetLevel());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error Loading Merc Inventory: %s", results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error Loading Merc Inventory: %s", results.ErrorMessage().c_str());
return;
}
@@ -2602,7 +2650,7 @@ uint8 ZoneDatabase::GroupCount(uint32 groupid) {
std::string query = StringFormat("SELECT count(charid) FROM group_id WHERE groupid = %d", groupid);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::GroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::GroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -2621,7 +2669,7 @@ uint8 ZoneDatabase::RaidGroupCount(uint32 raidid, uint32 groupid) {
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in ZoneDatabase::RaidGroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in ZoneDatabase::RaidGroupCount query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return 0;
}
@@ -2652,7 +2700,7 @@ int32 ZoneDatabase::GetBlockedSpellsCount(uint32 zoneid)
bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid)
{
LogFile->write(EQEMuLog::Status, "Loading Blocked Spells from database...");
LogFile->write(EQEmuLog::Status, "Loading Blocked Spells from database...");
std::string query = StringFormat("SELECT id, spellid, type, x, y, z, x_diff, y_diff, z_diff, message "
"FROM blocked_spells WHERE zoneid = %d ORDER BY id ASC", zoneid);
@@ -2777,7 +2825,7 @@ void ZoneDatabase::LoadAltCurrencyValues(uint32 char_id, std::map<uint32, uint32
"WHERE char_id = '%u'", char_id);
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadAltCurrencyValues query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadAltCurrencyValues query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -2818,7 +2866,7 @@ void ZoneDatabase::SaveBuffs(Client *client) {
buffs[index].ExtraDIChance);
auto results = QueryDatabase(query);
if (!results.Success())
LogFile->write(EQEMuLog::Error, "Error in SaveBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in SaveBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
}
}
@@ -2837,7 +2885,7 @@ void ZoneDatabase::LoadBuffs(Client *client) {
"FROM `character_buffs` WHERE `character_id` = '%u'", client->CharacterID());
auto results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadBuffs query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -3011,7 +3059,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) {
"WHERE `char_id` = %u", client->CharacterID());
auto results = database.QueryDatabase(query);
if(!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -3039,7 +3087,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) {
"WHERE `char_id` = %u", client->CharacterID());
results = QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -3080,7 +3128,7 @@ void ZoneDatabase::LoadPetInfo(Client *client) {
"WHERE `char_id`=%u",client->CharacterID());
results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "Error in LoadPetInfo query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
return;
}
@@ -3688,7 +3736,7 @@ Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_z
corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS));
corpse->Spawn();
if (!UnburyCharacterCorpse(corpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, position))
LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id);
LogFile->write(EQEmuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id);
}
return corpse;
@@ -3727,7 +3775,7 @@ bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id
++CorpseCount;
}
else{
LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id);
LogFile->write(EQEmuLog::Error, "Unable to construct a player corpse for character id %u.", char_id);
}
}
@@ -3844,4 +3892,3 @@ bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) {
return false;
}
+3 -2
View File
@@ -49,6 +49,7 @@ struct NPCType
uint32 npc_id;
uint8 texture;
uint8 helmtexture;
uint32 herosforgemodel;
uint32 loottable_id;
uint32 npc_spells_id;
uint32 npc_spells_effects_id;
@@ -90,8 +91,8 @@ struct NPCType
uint32 max_dmg;
int16 attack_count;
char special_abilities[512];
uint16 d_meele_texture1;
uint16 d_meele_texture2;
uint16 d_melee_texture1;
uint16 d_melee_texture2;
char ammo_idfile[30];
uint8 prim_melee_type;
uint8 sec_melee_type;
+18 -18
View File
@@ -43,12 +43,12 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
zoning = true;
if (app->size != sizeof(ZoneChange_Struct)) {
LogFile->write(EQEMuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct));
LogFile->write(EQEmuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct));
return;
}
#if EQDEBUG >= 5
LogFile->write(EQEMuLog::Debug, "Zone request from %s", GetName());
LogFile->write(EQEmuLog::Debug, "Zone request from %s", GetName());
DumpPacket(app);
#endif
ZoneChange_Struct* zc=(ZoneChange_Struct*)app->pBuffer;
@@ -96,7 +96,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
CheatDetected(MQZone, zc->x, zc->y, zc->z);
Message(13, "Invalid unsolicited zone request.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
SendZoneCancel(zc);
return;
}
@@ -128,7 +128,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
//if we didnt get a zone point, or its to a different zone,
//then we assume this is invalid.
if(!zone_point || zone_point->target_zone_id != target_zone_id) {
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
CheatDetected(MQGate, zc->x, zc->y, zc->z);
SendZoneCancel(zc);
return;
@@ -159,7 +159,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
if(target_zone_name == nullptr) {
//invalid zone...
Message(13, "Invalid target zone ID.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id);
LogFile->write(EQEmuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id);
SendZoneCancel(zc);
return;
}
@@ -172,7 +172,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
if(!database.GetSafePoints(target_zone_name, database.GetInstanceVersion(target_instance_id), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) {
//invalid zone...
Message(13, "Invalid target zone while getting safe points.");
LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name);
LogFile->write(EQEmuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name);
SendZoneCancel(zc);
return;
}
@@ -192,7 +192,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
switch(zone_mode) {
case EvacToSafeCoords:
case ZoneToSafeCoords:
LogFile->write(EQEMuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id);
LogFile->write(EQEmuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id);
dest_x = safe_x;
dest_y = safe_y;
dest_z = safe_z;
@@ -252,7 +252,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
//could not find a valid reason for them to be zoning, stop it.
CheatDetected(MQZoneUnknownDest, 0.0, 0.0, 0.0);
LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name);
LogFile->write(EQEmuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name);
SendZoneCancel(zc);
return;
default:
@@ -287,7 +287,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
//we have successfully zoned
DoZoneSuccess(zc, target_zone_id, target_instance_id, dest_x, dest_y, dest_z, dest_h, ignorerestrictions);
} else {
LogFile->write(EQEMuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name);
LogFile->write(EQEmuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name);
SendZoneError(zc, myerror);
}
}
@@ -311,7 +311,7 @@ void Client::SendZoneCancel(ZoneChange_Struct *zc) {
void Client::SendZoneError(ZoneChange_Struct *zc, int8 err)
{
LogFile->write(EQEMuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID);
LogFile->write(EQEmuLog::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID);
SetPortExemption(true);
@@ -346,7 +346,7 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
if(this->GetPet())
entity_list.RemoveFromHateLists(this->GetPet());
LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z);
LogFile->write(EQEmuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z);
//set the player's coordinates in the new zone so they have them
//when they zone into it
@@ -469,7 +469,7 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y,
ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm);
break;
default:
LogFile->write(EQEMuLog::Error, "Client::ProcessMovePC received a reguest to perform an unsupported client zone operation.");
LogFile->write(EQEmuLog::Error, "Client::ProcessMovePC received a reguest to perform an unsupported client zone operation.");
break;
}
}
@@ -529,19 +529,19 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z
heading = m_pp.binds[0].heading;
zonesummon_ignorerestrictions = 1;
LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
LogFile->write(EQEmuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
break;
case SummonPC:
m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
SetHeading(heading);
break;
case Rewind:
LogFile->write(EQEMuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName());
LogFile->write(EQEmuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), m_Position.m_X, m_Position.m_Y, m_Position.m_Z, m_RewindLocation.m_X, m_RewindLocation.m_Y, m_RewindLocation.m_Z, zone->GetShortName());
m_ZoneSummonLocation = m_Position = xyz_location(x, y, z);
SetHeading(heading);
break;
default:
LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation.");
LogFile->write(EQEmuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation.");
ReadyToZone = false;
break;
}
@@ -756,7 +756,7 @@ void Client::SetZoneFlag(uint32 zone_id) {
std::string query = StringFormat("INSERT INTO zone_flags (charID,zoneID) VALUES(%d,%d)", CharacterID(), zone_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to set zone flag for %s: %s", GetName(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "MySQL Error while trying to set zone flag for %s: %s", GetName(), results.ErrorMessage().c_str());
}
void Client::ClearZoneFlag(uint32 zone_id) {
@@ -769,7 +769,7 @@ void Client::ClearZoneFlag(uint32 zone_id) {
std::string query = StringFormat("DELETE FROM zone_flags WHERE charID=%d AND zoneID=%d", CharacterID(), zone_id);
auto results = database.QueryDatabase(query);
if(!results.Success())
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to clear zone flag for %s: %s", GetName(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "MySQL Error while trying to clear zone flag for %s: %s", GetName(), results.ErrorMessage().c_str());
}
@@ -779,7 +779,7 @@ void Client::LoadZoneFlags() {
std::string query = StringFormat("SELECT zoneID from zone_flags WHERE charID=%d", CharacterID());
auto results = database.QueryDatabase(query);
if (!results.Success()) {
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to load zone flags for %s: %s", GetName(), results.ErrorMessage().c_str());
LogFile->write(EQEmuLog::Error, "MySQL Error while trying to load zone flags for %s: %s", GetName(), results.ErrorMessage().c_str());
return;
}