Conflicts:
	zone/client_packet.cpp
	zone/merc.cpp
	zone/npc.cpp
This commit is contained in:
SecretsOTheP 2013-03-23 05:02:27 -04:00
commit 8e604fd3db
7 changed files with 321 additions and 210 deletions

View File

@ -1,6 +1,14 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 03/21/2013 ==
Bad_Captain: Fixed merc buffing bugs.
Bad_Captain: Added checks before dismissing merc to prevent possible bugged mercs.
Bad_Captain: Merged in Secret's merc memory leak fixes.
== 03/20/2013 ==
demonstar55: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence)
== 03/18/2013 ==
Bad_Captain: Fixed zone crash due to merc focus effects & tribute.
Bad_Captain: Fixed merc aggro issues when client in melee range & spell recast timers.

View File

@ -1100,6 +1100,7 @@ public:
bool CheckCanHireMerc(Mob* merchant, uint32 template_id);
bool CheckCanRetainMerc(uint32 upkeep);
bool CheckCanUnsuspendMerc();
bool CheckCanDismissMerc();
inline uint32 GetMercID() const { return mercid; }
inline uint8 GetMercSlot() const { return mercSlot; }
void SetMercID( uint32 newmercid) { mercid = newmercid; }

View File

@ -6533,15 +6533,12 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
database.RefreshGroupFromDB(inviter->CastToClient());
// Add the merc back into the new group
if (GetMerc())
{
if (GetMerc()->AddMercToGroup(GetMerc(), group))
{
if (GetMerc()) {
if (GetMerc()->AddMercToGroup(GetMerc(), group)) {
database.SetGroupID(GetMerc()->GetName(), group->GetID(), inviter->CastToClient()->CharacterID(), true);
}
}
//send updates to clients out of zone...
ServerPacket* pack = new ServerPacket(ServerOP_GroupJoin, sizeof(ServerGroupJoin_Struct));
ServerGroupJoin_Struct* gj = (ServerGroupJoin_Struct*)pack->pBuffer;
@ -6653,24 +6650,22 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
if(!memberToDisband)
memberToDisband = entity_list.GetMob(gd->name2);
if(memberToDisband )
{
if(group->IsLeader(this)) // the group leader can kick other members out of the group...
{
if(memberToDisband ) {
if(group->IsLeader(this)) {
// the group leader can kick other members out of the group...
//group->DelMember(memberToDisband,false);
if(memberToDisband->IsClient())
{
group->DelMember(memberToDisband,false);
Client* memberClient = memberToDisband->CastToClient();
Merc* memberMerc = memberToDisband->CastToClient()->GetMerc();
if(memberMerc != NULL)
{
memberMerc->RemoveMercFromGroup(memberMerc, group);
if(!memberMerc->IsGrouped() && !memberClient->IsGrouped())
{
if(!memberMerc->IsGrouped() && !memberClient->IsGrouped()) {
Group *g = new Group(memberClient);
if(!g)
{
if(!g) {
delete g;
g = NULL;
return;
@ -6678,8 +6673,7 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
entity_list.AddGroup(g);
if(g->GetID() == 0)
{
if(g->GetID() == 0) {
safe_delete(g);
return;
}
@ -6692,25 +6686,21 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
}
}
}
}
else if(memberToDisband->IsMerc())
{
else if(memberToDisband->IsMerc()) {
memberToDisband->CastToMerc()->RemoveMercFromGroup(memberToDisband->CastToMerc(), group);
memberToDisband->CastToMerc()->RemoveMercFromGroup(memberToDisband->CastToMerc(), group);
memberToDisband->CastToMerc()->Suspend();
}
}
else
{
else {
// ...but other members can only remove themselves
group->DelMember(this,false);
if(!IsGrouped() && GetMerc() != NULL)
{
if(!IsGrouped() && GetMerc() != NULL) {
if(!IsGrouped()) {
Group *g = new Group(this);
if(!g)
{
if(!g) {
delete g;
g = NULL;
return;
@ -6718,8 +6708,7 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
entity_list.AddGroup(g);
if(g->GetID() == 0)
{
if(g->GetID() == 0) {
safe_delete(g);
return;
}
@ -13795,10 +13784,15 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app)
if(GetMercID()) {
Merc* merc = GetMerc();
if(merc)
if(merc) {
if(CheckCanDismissMerc()) {
merc->Dismiss();
}
}
}
//SendMercMerchantResponsePacket(10);
}
void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app)
{

View File

@ -1904,7 +1904,6 @@ void Merc::AI_Process() {
void Merc::AI_Start(int32 iMoveDelay) {
NPC::AI_Start(iMoveDelay);
if (!pAIControlled)
return;
@ -2373,13 +2372,13 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) {
if(selectedMercSpell.spellid > 0) {
if(isDiscipline) {
castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID());
castedSpell = UseDiscipline(selectedMercSpell.spellid, tar->GetID());
}
else {
castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1, &TempDontBuffMeBeforeTime);
castedSpell = AIDoSpellCast(selectedMercSpell.spellid, tar, -1, &TempDontBuffMeBeforeTime);
if(TempDontBuffMeBeforeTime != this->DontBuffMeBefore())
this->SetDontBuffMeBefore(TempDontBuffMeBeforeTime);
if(TempDontBuffMeBeforeTime != tar->DontBuffMeBefore())
tar->SetDontBuffMeBefore(TempDontBuffMeBeforeTime);
}
}
}
@ -2400,13 +2399,13 @@ bool Merc::AICastSpell(int8 iChance, int32 iSpellTypes) {
if(selectedMercSpell.spellid > 0) {
if(isDiscipline) {
castedSpell = UseDiscipline(selectedMercSpell.spellid, GetID());
castedSpell = UseDiscipline(selectedMercSpell.spellid, tar->GetPet()->GetID());
}
else {
castedSpell = AIDoSpellCast(selectedMercSpell.spellid, this, -1, &TempDontBuffMeBeforeTime);
castedSpell = AIDoSpellCast(selectedMercSpell.spellid, tar->GetPet(), -1, &TempDontBuffMeBeforeTime);
if(TempDontBuffMeBeforeTime != this->DontBuffMeBefore())
this->SetDontBuffMeBefore(TempDontBuffMeBeforeTime);
if(TempDontBuffMeBeforeTime != tar->GetPet()->DontBuffMeBefore())
tar->GetPet()->SetDontBuffMeBefore(TempDontBuffMeBeforeTime);
}
}
}
@ -5171,8 +5170,8 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
snprintf(c->GetEPP().merc_name, 64, "%s", c->GetMercInfo().merc_name);
merc->SetSuspended(c->GetMercInfo().IsSuspended);
merc->gender = c->GetMercInfo().Gender;
merc->SetHP(c->GetMercInfo().hp);
merc->SetMana(c->GetMercInfo().mana);
merc->SetHP(c->GetMercInfo().hp <= 0 ? merc->GetMaxHP() : c->GetMercInfo().hp);
merc->SetMana(c->GetMercInfo().hp <= 0 ? merc->GetMaxMana() : c->GetMercInfo().mana);
merc->SetEndurance(c->GetMercInfo().endurance);
merc->luclinface = c->GetMercInfo().face;
merc->hairstyle = c->GetMercInfo().luclinHairStyle;
@ -5357,7 +5356,71 @@ void Client::UpdateMercTimer()
}
bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
bool result = true;
MercTemplate* mercTemplate = zone->GetMercTemplate(template_id);
//invalid merc data
if(!mercTemplate) {
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(9);
else
SendMercMerchantResponsePacket(10);
return false;
}
//check client version
if(GetClientVersion() < mercTemplate->ClientVersion) {
SendMercMerchantResponsePacket(3);
return false;
}
if(GetClientVersion() >= EQClientRoF && GetNumMercs() >= MAXMERCS) {
SendMercMerchantResponsePacket(6);
return false;
}
else if(GetMerc()) { //check for current merc
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(6);
else
SendMercMerchantResponsePacket(6);
return false;
}
else if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) { //has suspended merc
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(7);
else
SendMercMerchantResponsePacket(6);
return false;
}
//check for sufficient funds
if(RuleB(Mercs, ChargeMercPurchaseCost)) {
uint32 cost = Merc::CalcPurchaseCost(template_id, GetLevel()) * 100; // Cost is in gold
if(cost > 0 && !HasMoney(cost)) {
SendMercMerchantResponsePacket(1);
return false;
}
}
//check for raid
if(HasRaid()) {
SendMercMerchantResponsePacket(4);
return false;
}
//check group size
if(HasGroup() && GetGroup()->GroupCount() >= MAX_GROUP_MEMBERS) {
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(8);
else
SendMercMerchantResponsePacket(7);
return false;
}
//check in combat
if(GetClientVersion() >= EQClientRoF && GetAggroCount() > 0) {
SendMercMerchantResponsePacket(8);
return false;
}
//check for valid merchant - can check near area for any merchants
if(!merchant) {
@ -5365,7 +5428,7 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
SendMercMerchantResponsePacket(14);
else
SendMercMerchantResponsePacket(16);
result = false;
return false;
}
//check for merchant too far away
@ -5374,65 +5437,13 @@ bool Client::CheckCanHireMerc(Mob* merchant, uint32 template_id) {
SendMercMerchantResponsePacket(15);
else
SendMercMerchantResponsePacket(17);
result = false;
return false;
}
if(GetClientVersion() >= EQClientRoF && GetNumMercs() >= MAXMERCS) {
SendMercMerchantResponsePacket(6);
result = false;
}
else if(GetMerc()) { //check for current merc
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(6);
else
SendMercMerchantResponsePacket(6);
result = false;
}
else if(GetMercInfo().mercid != 0 && GetMercInfo().IsSuspended) { //has suspended merc
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(7);
else
SendMercMerchantResponsePacket(6);
result = false;
}
//check for sufficient funds
if(RuleB(Mercs, ChargeMercPurchaseCost)) {
uint32 cost = Merc::CalcPurchaseCost(template_id, GetLevel()) * 100; // Cost is in gold
if(cost > 0 && !HasMoney(cost)) {
SendMercMerchantResponsePacket(1);
result = false;
}
}
//check for raid
if(HasRaid()) {
SendMercMerchantResponsePacket(4);
result = false;
}
//check group size
if(HasGroup() && GetGroup()->GroupCount() == 6) {
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(8);
else
SendMercMerchantResponsePacket(7);
result = false;
}
//check in combat
if(GetClientVersion() >= EQClientRoF && GetAggroCount() > 0) {
SendMercMerchantResponsePacket(8);
result = false;
}
return result;
return true;
}
bool Client::CheckCanRetainMerc(uint32 upkeep) {
bool result = true;
Merc* merc = GetMerc();
//check for sufficient funds
@ -5440,30 +5451,45 @@ bool Client::CheckCanRetainMerc(uint32 upkeep) {
if(merc) {
if(upkeep > 0 && !HasMoney(upkeep * 100)) {
SendMercMerchantResponsePacket(1);
result = false;
return false;
}
}
}
return result;
return true;
}
bool Client::CheckCanUnsuspendMerc() {
bool result = true;
MercTemplate* mercTemplate = zone->GetMercTemplate(GetMercInfo().MercTemplateID);
//invalid merc data
if(!mercTemplate) {
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(9);
else
SendMercMerchantResponsePacket(10);
return false;
}
//check client version
if(GetClientVersion() < mercTemplate->ClientVersion) {
SendMercMerchantResponsePacket(3);
return false;
}
//check for raid
if(HasRaid()) {
SendMercMerchantResponsePacket(4);
result = false;
return false;
}
//check group size
if(HasGroup() && GetGroup()->GroupCount() == 6) {
if(HasGroup() && GetGroup()->GroupCount() >= MAX_GROUP_MEMBERS) {
if (GetClientVersion() < EQClientRoF)
SendMercMerchantResponsePacket(8);
else
SendMercMerchantResponsePacket(7);
result = false;
return false;
}
//check if zone allows mercs
@ -5472,15 +5498,30 @@ bool Client::CheckCanUnsuspendMerc() {
SendMercMerchantResponsePacket(4); // ??
else
SendMercMerchantResponsePacket(4); // ??
return false;
}
//check in combat
if(GetClientVersion() >= EQClientRoF && GetAggroCount() > 0) {
SendMercMerchantResponsePacket(8);
result = false;
return false;
}
return result;
return true;
}
bool Client::CheckCanDismissMerc() {
if(!GetMerc()) {
Message(7, "You have no mercenary to dismiss.");
return false;
}
if(GetMerc()->IsCasting()) {
Message(7, "Unable to dismiss mercenary.");
return false;
}
return true;
}
void Client::CheckMercSuspendTimer()
@ -5596,6 +5637,10 @@ bool Merc::Suspend() {
SetSuspended(true);
/*if(HasGroup()) {
RemoveMercFromGroup(this, GetGroup());
}*/
Save();
mercOwner->GetMercInfo().IsSuspended = true;
@ -5645,16 +5690,15 @@ bool Merc::Unsuspend(bool setMaxStats) {
mercOwner->SendMercPersonalInfo();
Group* g = entity_list.GetGroupByClient(mercOwner);
if(!g)
{ //nobody from our group is here... start a new group
if(!g) { //nobody from our group is here... start a new group
g = new Group(mercOwner);
if(!g)
{
if(!g) {
delete g;
g = NULL;
return false;
}
entity_list.AddGroup(g);
if(g->GetID() == 0) {
@ -5663,8 +5707,7 @@ bool Merc::Unsuspend(bool setMaxStats) {
return false;
}
if(AddMercToGroup(this, g))
{
if(AddMercToGroup(this, g)) {
entity_list.AddGroup(g, g->GetID());
database.SetGroupLeaderName(g->GetID(), mercOwner->GetName());
database.SetGroupID(mercOwner->GetName(), g->GetID(), mercOwner->CharacterID());
@ -5673,20 +5716,17 @@ bool Merc::Unsuspend(bool setMaxStats) {
g->SaveGroupLeaderAA();
loaded = true;
}
else
{
else {
g->DisbandGroup();
}
} //else, somebody from our group is already here...
else if (AddMercToGroup(this, mercOwner->GetGroup()))
{
else if (AddMercToGroup(this, mercOwner->GetGroup())) {
database.SetGroupID(GetName(), mercOwner->GetGroup()->GetID(), mercOwner->CharacterID(), true);
database.RefreshGroupFromDB(mercOwner);
loaded = true;
}
else
{
else {
if(MERC_DEBUG > 0)
mercOwner->Message(7, "Mercenary failed to join the group - Suspending");
@ -5913,11 +5953,13 @@ void Client::UpdateMercLevel() {
void Client::SendMercMerchantResponsePacket(int32 response_type) {
// This response packet brings up the Mercenary Manager window
if(GetClientVersion() >= EQClientSoD) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryHire, sizeof(MercenaryMerchantResponse_Struct));
MercenaryMerchantResponse_Struct* mmr = (MercenaryMerchantResponse_Struct*)outapp->pBuffer;
mmr->ResponseType = response_type; // send specified response type
FastQueuePacket(&outapp);
}
}
void Client::SendMercenaryUnknownPacket(uint8 type) {
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MercenaryUnknown1, 1);

View File

@ -248,7 +248,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
npc_aggro = d->npc_aggro;
if(!IsMerc()) //memleak fix, this really shouldn't be here
if(!IsMerc())
AI_Start();
d_meele_texture1 = d->d_meele_texture1;

View File

@ -208,16 +208,29 @@ void QuestManager::echo(int colour, const char *str) {
}
void QuestManager::say(const char *str) {
if(RuleB(NPC, EnableNPCQuestJournal) && initiator)
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with NULL owner. Probably syntax error in quest file.");
return;
}
else {
if(RuleB(NPC, EnableNPCQuestJournal) && initiator) {
owner->QuestJournalledSay(initiator, str);
else
}
else {
owner->Say(str);
}
}
}
void QuestManager::say(const char *str, uint8 language) {
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::say called with NULL owner. Probably syntax error in quest file.");
return;
}
else {
entity_list.ChannelMessage(owner, 8, language, str);
}
}
void QuestManager::me(const char *str) {
if (!initiator)
@ -242,14 +255,14 @@ void QuestManager::write(const char *file, const char *str) {
uint16 QuestManager::spawn2(int npc_type, int grid, int unused, float x, float y, float z, float heading) {
const NPCType* tmp = 0;
if ((tmp = database.GetNPCType(npc_type)))
if (tmp = database.GetNPCType(npc_type))
{
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
npc->AddLootTable();
entity_list.AddNPC(npc,true,true);
// Quag: Sleep in main thread? ICK!
// Sleep in main thread? ICK!
// Sleep(200);
// Quag: check is irrelevent, it's impossible for npc to be 0 here
// check is irrelevent, it's impossible for npc to be 0 here
// (we're in main thread, nothing else can possibly modify it)
if(grid > 0)
{
@ -268,14 +281,14 @@ uint16 QuestManager::unique_spawn(int npc_type, int grid, int unused, float x, f
}
const NPCType* tmp = 0;
if ((tmp = database.GetNPCType(npc_type)))
if (tmp = database.GetNPCType(npc_type))
{
NPC* npc = new NPC(tmp, 0, x, y, z, heading, FlyMode3);
npc->AddLootTable();
entity_list.AddNPC(npc,true,true);
// Quag: Sleep in main thread? ICK!
// Sleep in main thread? ICK!
// Sleep(200);
// Quag: check is irrelevent, it's impossible for npc to be 0 here
// check is irrelevent, it's impossible for npc to be 0 here
// (we're in main thread, nothing else can possibly modify it)
if(grid > 0)
{
@ -514,19 +527,36 @@ void QuestManager::stopalltimers() {
}
void QuestManager::emote(const char *str) {
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::emote called with NULL owner. Probably syntax error in quest file.");
return;
}
else {
owner->Emote(str);
}
}
void QuestManager::shout(const char *str) {
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::shout called with NULL owner. Probably syntax error in quest file.");
return;
}
else {
owner->Shout(str);
}
}
void QuestManager::shout2(const char *str) {
if (!owner) {
LogFile->write(EQEMuLog::Quest, "QuestManager::shout2 called with NULL owner. Probably syntax error in quest file.");
return;
}
else {
worldserver.SendEmoteMessage(0,0,0,13, "%s shouts, '%s'", owner->GetCleanName(), str);
}
}
void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint32 to_guilddbid, uint32 to_minstatus)
{
void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint32 to_guilddbid, uint32 to_minstatus) {
if(send_to_world)
worldserver.SendEmoteMessage(0, to_guilddbid, to_minstatus, color, "%s", str);
else
@ -534,8 +564,11 @@ void QuestManager::gmsay(const char *str, uint32 color, bool send_to_world, uint
}
void QuestManager::depop(int npc_type) { // depop NPC and don't start spawn timer
if (!owner->IsNPC())
if (!owner || !owner->IsNPC()) {
LogFile->write(EQEMuLog::Quest, "QuestManager::depop called with NULL owner or non-NPC owner. Probably syntax error in quest file.");
return;
}
else {
if (npc_type != 0) {
Mob * tmp = entity_list.GetMobByNpcTypeID(npc_type);
if (tmp) {
@ -551,10 +584,14 @@ void QuestManager::depop(int npc_type) { // depop NPC and don't start spawn time
depop_npc = true;
}
}
}
void QuestManager::depop_withtimer(int npc_type) { // depop NPC and start spawn timer
if (!owner->IsNPC())
if (!owner || !owner->IsNPC()) {
LogFile->write(EQEMuLog::Quest, "QuestManager::depop_withtimer called with NULL owner or non-NPC owner. Probably syntax error in quest file.");
return;
}
else {
if (npc_type != 0) {
Mob * tmp = entity_list.GetMobByNpcTypeID(npc_type);
if (tmp) {
@ -570,21 +607,34 @@ void QuestManager::depop_withtimer(int npc_type) { // depop NPC and start spawn
owner->Depop(true);
}
}
}
void QuestManager::depopall(int npc_type) {
if(owner->IsNPC() && npc_type > 0)
if(owner && owner->IsNPC() && (npc_type > 0)) {
entity_list.DepopAll(npc_type);
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::depopall called with NULL owner, non-NPC owner, or invalid NPC Type ID. Probably syntax error in quest file.");
}
}
void QuestManager::depopzone(bool StartSpawnTimer) {
if(zone)
if(zone) {
zone->Depop(StartSpawnTimer);
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::depopzone called with NULL zone. Probably syntax error in quest file.");
}
}
void QuestManager::repopzone() {
if(zone)
if(zone) {
zone->Repop();
}
else {
LogFile->write(EQEMuLog::Quest, "QuestManager::repopzone called with NULL zone. Probably syntax error in quest file.");
}
}
void QuestManager::settarget(const char *type, int target_id) {
if(!owner->IsNPC())
@ -615,7 +665,7 @@ void QuestManager::sfollow() {
}
void QuestManager::changedeity(int diety_id) {
//Cofruben:-Changes the deity.
//Changes the deity.
if(initiator)
{
if(initiator->IsClient())
@ -731,7 +781,7 @@ void QuestManager::snow(int weather) {
}
void QuestManager::surname(const char *name) {
//Cofruben:-Changes the last name.
//Changes the last name.
if(initiator)
{
if(initiator->IsClient())
@ -747,21 +797,21 @@ void QuestManager::surname(const char *name) {
}
void QuestManager::permaclass(int class_id) {
//Cofruben:-Makes the client the class specified
//Makes the client the class specified
initiator->SetBaseClass(class_id);
initiator->Save(2);
initiator->Kick();
}
void QuestManager::permarace(int race_id) {
//Cofruben:-Makes the client the race specified
//Makes the client the race specified
initiator->SetBaseRace(race_id);
initiator->Save(2);
initiator->Kick();
}
void QuestManager::permagender(int gender_id) {
//Cofruben:-Makes the client the gender specified
//Makes the client the gender specified
initiator->SetBaseGender(gender_id);
initiator->Save(2);
initiator->Kick();
@ -1039,7 +1089,7 @@ void QuestManager::save() {
void QuestManager::faction(int faction_id, int faction_value, int temp) {
if (initiator && initiator->IsClient()) {
if(faction_id != 0 && faction_value != 0) {
// SCORPIOUS2K - fixed faction command
// fixed faction command
//Client *p;
initiator->SetFactionLevel2(
initiator->CharacterID(),
@ -1111,7 +1161,7 @@ void QuestManager::itemlink(int item_id) {
}
void QuestManager::signalwith(int npc_id, int signal_id, int wait_ms) {
// SCORPIOUS2K - signal command
// signal command
// signal(npcid) - generates EVENT_SIGNAL on specified npc
if(wait_ms > 0) {
STimerList.push_back(SignalTimer(wait_ms, npc_id, signal_id));
@ -1134,7 +1184,7 @@ void QuestManager::signal(int npc_id, int wait_ms) {
}
void QuestManager::setglobal(const char *varname, const char *newvalue, int options, const char *duration) {
// SCORPIOUS2K - qglobal variable commands
// qglobal variable commands
// setglobal(varname,value,options,duration)
//MYSQL_ROW row;
int qgZoneid=zone->GetZoneID();
@ -1376,7 +1426,7 @@ int QuestManager::QGVarDuration(const char *fmt)
}
void QuestManager::ding() {
//-Cofruben:makes a sound.
//makes a sound.
if (initiator && initiator->IsClient())
initiator->SendSound();
@ -1495,7 +1545,7 @@ void QuestManager::clear_proximity() {
}
void QuestManager::setanim(int npc_type, int animnum) {
//Cisyouc: adds appearance changes
//adds appearance changes
Mob* thenpc = entity_list.GetMobByNpcTypeID(npc_type);
if(animnum < 0 || animnum >= _eaMaxAppearance)
return;

View File

@ -2564,6 +2564,22 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
if(effect1 != effect2)
continue;
/*
Skip check if effect is SE_Limit*
skip checking effect2 since we know they are equal
*/
if(effect1 == SE_LimitMaxLevel ||
effect1 == SE_LimitResist ||
effect1 == SE_LimitTarget ||
effect1 == SE_LimitEffect ||
effect1 == SE_LimitSpellType ||
effect1 == SE_LimitSpell ||
effect1 == SE_LimitMinDur ||
effect1 == SE_LimitInstant ||
effect1 == SE_LimitMinLevel ||
effect1 == SE_LimitCastTime)
continue;
/*
If target is a npc and caster1 and caster2 exist
If Caster1 isn't the same as Caster2 and the effect is a DoT then ignore it.