This commit is contained in:
badcaptain 2013-04-02 19:10:18 -04:00
commit 15e31d1c03
10 changed files with 90 additions and 62 deletions

View File

@ -1,6 +1,13 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) EQEMu Changelog (Started on Sept 24, 2003 15:50)
------------------------------------------------------- -------------------------------------------------------
== 04/01/2013 ==
demonstar55: AA reuse timers now start when you hit the button and are reset upon failure
demonstar55: Instant Cast bard AAs can now be used while singing a song
== 03/30/2013 ==
demonstar55: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts.
== 03/23/2013 == == 03/23/2013 ==
demonstar55: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data. demonstar55: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data.
Escape now uses just the spell and not the AA Actoin Escape now uses just the spell and not the AA Actoin

View File

@ -257,7 +257,7 @@ void Client::ActivateAA(aaID activate){
if(caa->action != aaActionNone) { if(caa->action != aaActionNone) {
if(caa->mana_cost > 0) { if(caa->mana_cost > 0) {
if(GetMana() < caa->mana_cost) { if(GetMana() < caa->mana_cost) {
Message(0, "Not enough mana to use this skill."); Message_StringID(13, INSUFFICIENT_MANA);
return; return;
} }
SetMana(GetMana() - caa->mana_cost); SetMana(GetMana() - caa->mana_cost);
@ -271,8 +271,7 @@ void Client::ActivateAA(aaID activate){
p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime); p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime);
} }
p_timers.Start(AATimerID + pTimerAAStart, timer_base); p_timers.Start(AATimerID + pTimerAAStart, timer_base);
time_t timestamp = time(NULL); SendAATimer(AATimerID, 0, 0);
SendAATimer(AATimerID, static_cast<uint32>(timestamp), static_cast<uint32>(timestamp));
} }
} }
@ -282,13 +281,30 @@ void Client::ActivateAA(aaID activate){
if(caa->reuse_time > 0) if(caa->reuse_time > 0)
{ {
uint32 timer_base = CalcAAReuseTimer(caa); uint32 timer_base = CalcAAReuseTimer(caa);
SendAATimer(AATimerID, 0, 0);
p_timers.Start(AATimerID + pTimerAAStart, timer_base);
if(activate == aaImprovedHarmTouch || activate == aaLeechTouch) if(activate == aaImprovedHarmTouch || activate == aaLeechTouch)
{ {
p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime); p_timers.Start(pTimerHarmTouch, HarmTouchReuseTime);
} }
// Bards can cast instant cast AAs while they are casting another song
if(!CastSpell(caa->spell_id, target_id, 10, -1, -1, 0, -1, AATimerID + pTimerAAStart, timer_base, 1)) if (spells[caa->spell_id].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
return; if(!SpellFinished(caa->spell_id, entity_list.GetMob(target_id), 10, -1, -1, spells[caa->spell_id].ResistDiff, false)) {
//Reset on failed cast
SendAATimer(AATimerID, 0, 0xFFFFFF);
Message_StringID(15,ABILITY_FAILED);
p_timers.Clear(&database, AATimerID + pTimerAAStart);
return;
}
} else {
if(!CastSpell(caa->spell_id, target_id, 10, -1, -1, 0, -1, AATimerID + pTimerAAStart, timer_base, 1)) {
//Reset on failed cast
SendAATimer(AATimerID, 0, 0xFFFFFF);
Message_StringID(15,ABILITY_FAILED);
p_timers.Clear(&database, AATimerID + pTimerAAStart);
return;
}
}
} }
else else
{ {

View File

@ -10,6 +10,7 @@
#define SPELL_DOES_NOT_WORK_PLANE 107 //This spell does not work on this plane. #define SPELL_DOES_NOT_WORK_PLANE 107 //This spell does not work on this plane.
#define CANT_SEE_TARGET 108 //You cannot see your target. #define CANT_SEE_TARGET 108 //You cannot see your target.
#define MGB_STRING 113 //The next group buff you cast will hit all targets in range. #define MGB_STRING 113 //The next group buff you cast will hit all targets in range.
#define ABILITY_FAILED 116 //Your ability failed. Timer has been reset.
#define ESCAPE 114 //You escape from combat, hiding yourself from view. #define ESCAPE 114 //You escape from combat, hiding yourself from view.
#define TARGET_TOO_FAR 124 //Your target is too far away, get closer! #define TARGET_TOO_FAR 124 //Your target is too far away, get closer!
#define PROC_TOOLOW 126 //Your will is not sufficient to command this weapon. #define PROC_TOOLOW 126 //Your will is not sufficient to command this weapon.
@ -125,6 +126,7 @@
#define OTHER_HIT_NONMELEE 434 //%1 was hit by non-melee for %2 points of damage. #define OTHER_HIT_NONMELEE 434 //%1 was hit by non-melee for %2 points of damage.
#define SPELL_WORN_OFF_OF 436 //Your %1 spell has worn off of %2. #define SPELL_WORN_OFF_OF 436 //Your %1 spell has worn off of %2.
#define SPELL_WORN_OFF 437 //Your %1 spell has worn off. #define SPELL_WORN_OFF 437 //Your %1 spell has worn off.
#define PET_TAUNTING 438 //Taunting attacker, Master.
#define INTERRUPT_SPELL 439 //Your spell is interrupted. #define INTERRUPT_SPELL 439 //Your spell is interrupted.
#define LOSE_LEVEL 442 //You LOST a level! You are now level %1! #define LOSE_LEVEL 442 //You LOST a level! You are now level %1!
#define GAIN_ABILITY_POINT 446 //You have gained an ability point! You now have %1 ability point%2. #define GAIN_ABILITY_POINT 446 //You have gained an ability point! You now have %1 ability point%2.
@ -137,6 +139,8 @@
#define FACTION_BEST 471 //Your faction standing with %1 could not possibly get any better. #define FACTION_BEST 471 //Your faction standing with %1 could not possibly get any better.
#define FACTION_BETTER 472 //Your faction standing with %1 got better. #define FACTION_BETTER 472 //Your faction standing with %1 got better.
#define PET_REPORT_HP 488 //I have %1 percent of my hit points left. #define PET_REPORT_HP 488 //I have %1 percent of my hit points left.
#define PET_NO_TAUNT 489 //No longer taunting attackers, Master.
#define PET_DO_TAUNT 490 //Taunting attackers as normal, Master.
#define CORPSE_DECAY1 495 //This corpse will decay in %1 minute(s) %2 seconds. #define CORPSE_DECAY1 495 //This corpse will decay in %1 minute(s) %2 seconds.
#define DISC_LEVEL_ERROR 503 //You must be a level %1 ... to use this discipline. #define DISC_LEVEL_ERROR 503 //You must be a level %1 ... to use this discipline.
#define DISCIPLINE_CANUSEIN 504 //You can use a new discipline in %1 minutes %2 seconds. #define DISCIPLINE_CANUSEIN 504 //You can use a new discipline in %1 minutes %2 seconds.
@ -176,6 +180,8 @@
#define PET_GETLOST_STRING 1135 //As you wish, oh great one. #define PET_GETLOST_STRING 1135 //As you wish, oh great one.
#define PET_LEADERIS 1136 //My leader is %3. #define PET_LEADERIS 1136 //My leader is %3.
#define I_FOLLOW_NOONE 1137 //I follow no one. #define I_FOLLOW_NOONE 1137 //I follow no one.
#define PET_ON_HOLD 1138 //Waiting for your order to attack, Master.
#define NOT_LEGAL_TARGET 1139 //I beg forgiveness, Master. That is not a legal target.
#define MERCHANT_BUSY 1143 //I'm sorry, I am busy right now. #define MERCHANT_BUSY 1143 //I'm sorry, I am busy right now.
#define MERCHANT_GREETING 1144 //Welcome to my shop, %3. #define MERCHANT_GREETING 1144 //Welcome to my shop, %3.
#define MERCHANT_HANDY_ITEM1 1145 //Hello there, %3. How about a nice %4? #define MERCHANT_HANDY_ITEM1 1145 //Hello there, %3. How about a nice %4?
@ -273,6 +279,10 @@
#define STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses! #define STRIKETHROUGH_STRING 9078 //You strike through your opponent's defenses!
#define SPELL_REFLECT 9082 //%1's spell has been reflected by %2. #define SPELL_REFLECT 9082 //%1's spell has been reflected by %2.
#define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master. #define NEW_SPELLS_AVAIL 9149 //You have new spells available to you. Check the merchants near your guild master.
#define PET_NOW_FOCUSING 9254 //Focusing on one target, Master.
#define PET_NOT_FOCUSING 9263 //No longer focusing on one target, Master.
#define PET_NOT_CASTING 9264 //Not casting spells, Master.
#define PET_CASTING 9291 //Casting spells normally, Master.
#define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE! #define AE_RAMPAGE 11015 //%1 goes on a WILD RAMPAGE!
#define FACE_ACCEPTED 12028 //Facial features accepted. #define FACE_ACCEPTED 12028 //Facial features accepted.
#define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2. #define SPELL_LEVEL_TO_LOW 12048 //You will have to achieve level %1 before you can scribe the %2.

View File

@ -1714,8 +1714,10 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
//Check that we can attack before we calc heading and face our target //Check that we can attack before we calc heading and face our target
if (!IsAttackAllowed(other)) { if (!IsAttackAllowed(other)) {
if (this->GetOwnerID()) if (this->GetOwnerID())
entity_list.MessageClose(this, 1, 200, 10, "%s says, 'That is not a legal target master.'", this->GetCleanName()); this->Say_StringID(NOT_LEGAL_TARGET);
if(other) { if(other) {
if (other->IsClient())
other->CastToClient()->RemoveXTarget(this, false);
RemoveFromHateList(other); RemoveFromHateList(other);
mlog(COMBAT__ATTACKS, "I am not allowed to attack %s", other->GetName()); mlog(COMBAT__ATTACKS, "I am not allowed to attack %s", other->GetName());
} }
@ -4339,4 +4341,4 @@ int32 Mob::RuneAbsorb(int32 damage, uint16 type)
} }
return damage; return damage;
} }
} }

View File

@ -6459,15 +6459,6 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
} }
} }
// Remove the merc from the old group
if (GetMerc())
{
if(GetMerc()->GetGroup())
{
Merc::RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
}
}
Group* group = entity_list.GetGroupByClient(inviter->CastToClient()); Group* group = entity_list.GetGroupByClient(inviter->CastToClient());
if(!group){ if(!group){
@ -6539,8 +6530,9 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
// Add the merc back into the new group // Add the merc back into the new group
if (GetMerc()) { if (GetMerc()) {
if (GetMerc()->AddMercToGroup(GetMerc(), group)) { if (Merc::AddMercToGroup(GetMerc(), group)) {
database.SetGroupID(GetMerc()->GetName(), group->GetID(), inviter->CastToClient()->CharacterID(), true); database.SetGroupID(GetMerc()->GetName(), group->GetID(), inviter->CastToClient()->CharacterID(), true);
database.RefreshGroupFromDB(this);
} }
} }
@ -6667,8 +6659,6 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
Merc* memberMerc = memberToDisband->CastToClient()->GetMerc(); Merc* memberMerc = memberToDisband->CastToClient()->GetMerc();
if(memberClient && memberMerc && group) if(memberClient && memberMerc && group)
{ {
Merc::RemoveMercFromGroup(memberMerc, group);
if(!memberMerc->IsGrouped() && !memberClient->IsGrouped()) { if(!memberMerc->IsGrouped() && !memberClient->IsGrouped()) {
Group *g = new Group(memberClient); Group *g = new Group(memberClient);
@ -6713,13 +6703,18 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
return; return;
} }
if(GetMerc()->AddMercToGroup(GetMerc(), g)) { if(Merc::AddMercToGroup(GetMerc(), g)) {
database.SetGroupLeaderName(g->GetID(), this->GetName()); database.SetGroupLeaderName(g->GetID(), this->GetName());
g->SaveGroupLeaderAA(); g->SaveGroupLeaderAA();
database.SetGroupID(this->GetName(), g->GetID(), this->CharacterID()); database.SetGroupID(this->GetName(), g->GetID(), this->CharacterID());
database.SetGroupID(GetMerc()->GetName(), g->GetID(), this->CharacterID(), true); database.SetGroupID(GetMerc()->GetName(), g->GetID(), this->CharacterID(), true);
database.RefreshGroupFromDB(this); database.RefreshGroupFromDB(this);
} }
else
{
if(GetMerc())
GetMerc()->Depop();
}
} }
} }
} }
@ -7082,7 +7077,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
} }
zone->AddAggroMob(); zone->AddAggroMob();
mypet->AddToHateList(GetTarget(), 1); mypet->AddToHateList(GetTarget(), 1);
Message_StringID(10, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
} }
} }
break; break;
@ -7098,7 +7093,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
break; break;
} }
case PET_HEALTHREPORT: { case PET_HEALTHREPORT: {
Message_StringID(10, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); Message_StringID(MT_PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1));
mypet->ShowBuffList(this); mypet->ShowBuffList(this);
//Message(10,"%s tells you, 'I have %d percent of my hit points left.'",mypet->GetName(),(uint8)mypet->GetHPRatio()); //Message(10,"%s tells you, 'I have %d percent of my hit points left.'",mypet->GetName(),(uint8)mypet->GetHPRatio());
break; break;
@ -7155,14 +7150,14 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
} }
case PET_TAUNT: { case PET_TAUNT: {
if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
Message(0,"%s says, 'Now taunting foes, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_DO_TAUNT);
mypet->CastToNPC()->SetTaunting(true); mypet->CastToNPC()->SetTaunting(true);
} }
break; break;
} }
case PET_NOTAUNT: { case PET_NOTAUNT: {
if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) { if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
Message(0,"%s says, 'No longer taunting foes, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NO_TAUNT);
mypet->CastToNPC()->SetTaunting(false); mypet->CastToNPC()->SetTaunting(false);
} }
break; break;
@ -7219,7 +7214,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (mypet->IsFeared()) if (mypet->IsFeared())
break; //could be exploited like PET_BACKOFF break; //could be exploited like PET_BACKOFF
mypet->Say("I will hold until given an order, master."); mypet->Say_StringID(PET_ON_HOLD);
mypet->WipeHateList(); mypet->WipeHateList();
mypet->SetHeld(true); mypet->SetHeld(true);
} }
@ -7230,10 +7225,10 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (mypet->IsFeared()) if (mypet->IsFeared())
break; break;
if (mypet->IsNoCast()) { if (mypet->IsNoCast()) {
Message(0,"%s says, 'I will now cast spells, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_CASTING);
mypet->CastToNPC()->SetNoCast(false); mypet->CastToNPC()->SetNoCast(false);
} else { } else {
Message(0,"%s says, 'I will no longer cast spells, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NOT_CASTING);
mypet->CastToNPC()->SetNoCast(true); mypet->CastToNPC()->SetNoCast(true);
} }
} }
@ -7244,10 +7239,10 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (mypet->IsFeared()) if (mypet->IsFeared())
break; break;
if (mypet->IsFocused()) { if (mypet->IsFocused()) {
Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
mypet->CastToNPC()->SetFocused(false); mypet->CastToNPC()->SetFocused(false);
} else { } else {
Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
mypet->CastToNPC()->SetFocused(true); mypet->CastToNPC()->SetFocused(true);
} }
} }
@ -7257,10 +7252,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) { if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
if (mypet->IsFeared()) if (mypet->IsFeared())
break; break;
if (mypet->IsFocused()) { if (!mypet->IsFocused()) {
Message(0,"%s says, 'I am already focused, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
} else {
Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
mypet->CastToNPC()->SetFocused(true); mypet->CastToNPC()->SetFocused(true);
} }
} }
@ -7271,10 +7264,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
if (mypet->IsFeared()) if (mypet->IsFeared())
break; break;
if (mypet->IsFocused()) { if (mypet->IsFocused()) {
Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName()); Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
mypet->CastToNPC()->SetFocused(false); mypet->CastToNPC()->SetFocused(false);
} else {
Message(0,"%s says, 'I am already not focused, Master!",mypet->GetCleanName());
} }
} }
break; break;

View File

@ -50,7 +50,6 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
_lost_confidence = false; _lost_confidence = false;
_hatedCount = 0; _hatedCount = 0;
ourNPCData = d;
memset(equipment, 0, sizeof(equipment)); memset(equipment, 0, sizeof(equipment));
SetMercID(0); SetMercID(0);
@ -74,7 +73,6 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
Merc::~Merc() { Merc::~Merc() {
AI_Stop(); AI_Stop();
safe_delete(ourNPCData); //Since mercs are dynamically alloc'd we should probably safe_delete the data they were made from. I'm not entirely sure this is safe to delete a const.
entity_list.RemoveMerc(this->GetID()); entity_list.RemoveMerc(this->GetID());
UninitializeBuffSlots(); UninitializeBuffSlots();
} }
@ -1915,9 +1913,9 @@ void Merc::AI_Start(int32 iMoveDelay) {
AIautocastspell_timer->Start(RandomTimer(0, 2000), false); AIautocastspell_timer->Start(RandomTimer(0, 2000), false);
} }
if (ourNPCData) { if (NPCTypedata_ours) {
//AI_AddNPCSpells(ourNPCData->npc_spells_id); //AI_AddNPCSpells(ourNPCData->npc_spells_id);
NPCSpecialAttacks(ourNPCData->npc_attacks,0); NPCSpecialAttacks(NPCTypedata_ours->npc_attacks,0);
} }
SendTo(GetX(), GetY(), GetZ()); SendTo(GetX(), GetY(), GetZ());
@ -5836,16 +5834,15 @@ bool Merc::AddMercToGroup(Merc* merc, Group* group) {
if(merc->HasGroup()) { if(merc->HasGroup()) {
Merc::RemoveMercFromGroup(merc, merc->GetGroup()); Merc::RemoveMercFromGroup(merc, merc->GetGroup());
} }
// Add merc to this group //Try and add the member, followed by checking if the merc owner exists.
if(group->AddMember(merc)) { if(group->AddMember(merc) && merc->GetMercOwner() != NULL) {
merc->SetFollowID(merc->GetMercOwner()->GetID()); merc->SetFollowID(merc->GetMercOwner()->GetID());
Result = true; Result = true;
} }
else else {
{ //Suspend it if the member is not added and the merc's owner is not valid.
merc->Suspend(); merc->Suspend();
} }
} }
return Result; return Result;

View File

@ -379,8 +379,6 @@ private:
bool _lost_confidence; bool _lost_confidence;
int _hatedCount; int _hatedCount;
uint32 owner_char_id; uint32 owner_char_id;
const NPCType* ourNPCData;
Timer endupkeep_timer; Timer endupkeep_timer;
Timer rest_timer; Timer rest_timer;
Timer confidence_timer; Timer confidence_timer;

View File

@ -158,6 +158,14 @@ void PerlXSParser::SendCommands(const char * pkgprefix, const char *event, uint3
//now call the requested sub //now call the requested sub
perl->dosub(std::string(pkgprefix).append("::").append(event).c_str()); perl->dosub(std::string(pkgprefix).append("::").append(event).c_str());
#ifdef EMBPERL_XS_CLASSES
std::string eval_str = (std::string)"$" + (std::string)pkgprefix + (std::string)"::client = undef;";
eval_str += (std::string)"$" + (std::string)pkgprefix + (std::string)"::npc = undef;";
eval_str += (std::string)"$" + (std::string)pkgprefix + (std::string)"::questitem = undef;";
eval_str += (std::string)"$" + (std::string)pkgprefix + (std::string)"::entity_list = undef;";
perl->eval(eval_str.c_str());
#endif
} catch(const char * err) { } catch(const char * err) {
//try to reduce some of the console spam... //try to reduce some of the console spam...

View File

@ -1397,6 +1397,7 @@ void NPC::DoClassAttacks(Mob *target) {
//general stuff, for all classes.... //general stuff, for all classes....
//only gets used when their primary ability get used too //only gets used when their primary ability get used too
if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) { if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) {
this->GetOwner()->Message_StringID(MT_PetResponse, PET_TAUNTING);
Taunt(target->CastToNPC(), false); Taunt(target->CastToNPC(), false);
} }

View File

@ -707,23 +707,26 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid)
CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot); CastToNPC()->AI_Event_SpellCastFinished(false, casting_spell_slot);
} }
if(casting_spell_type == 1 && IsClient()) //Rest AA Timer on failed cast if(casting_spell_type == 1 && IsClient()) { //Rest AA Timer on failed cast
CastToClient()->GetPTimers().Clear(&database, casting_spell_timer); CastToClient()->SendAATimer(casting_spell_timer - pTimerAAStart, 0, 0xFFFFFF);
CastToClient()->Message_StringID(15,ABILITY_FAILED);
CastToClient()->GetPTimers().Clear(&database, casting_spell_timer);
}
ZeroCastingVars(); // resets all the state keeping stuff ZeroCastingVars(); // resets all the state keeping stuff
mlog(SPELLS__CASTING, "Spell %d has been interrupted.", spellid); mlog(SPELLS__CASTING, "Spell %d has been interrupted.", spellid);
if(!spellid) if(!spellid)
return; return;
if (bardsong || IsBardSong(casting_spell_id)) if (bardsong || IsBardSong(casting_spell_id))
_StopSong(); _StopSong();
if(bard_song_mode) { if(bard_song_mode) {
return; return;
} }
if(!message) if(!message)
message = IsBardSong(spellid) ? SONG_ENDS_ABRUPTLY : INTERRUPT_SPELL; message = IsBardSong(spellid) ? SONG_ENDS_ABRUPTLY : INTERRUPT_SPELL;
@ -1971,11 +1974,6 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
{ {
CastToClient()->GetPTimers().Start(casting_spell_timer, casting_spell_timer_duration); CastToClient()->GetPTimers().Start(casting_spell_timer, casting_spell_timer_duration);
mlog(SPELLS__CASTING, "Spell %d: Setting custom reuse timer %d to %d", spell_id, casting_spell_timer, casting_spell_timer_duration); mlog(SPELLS__CASTING, "Spell %d: Setting custom reuse timer %d to %d", spell_id, casting_spell_timer, casting_spell_timer_duration);
if(casting_spell_type == 1) //AA
{
time_t timestamp = time(NULL);
CastToClient()->SendAATimer((casting_spell_timer - pTimerAAStart), timestamp, timestamp);
}
} }
else if(spells[spell_id].recast_time > 1000) { else if(spells[spell_id].recast_time > 1000) {
int recast = spells[spell_id].recast_time/1000; int recast = spells[spell_id].recast_time/1000;