|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11-24-2012, 11:35 AM
|
Sarnak
|
|
Join Date: Oct 2005
Posts: 45
|
|
/pet no cast and /pet focus
Took a little time to dig through the opcodes and figured out how the /pet commands are handled for the newer clients.
Here are the base changes required for /pet no cast and /pet focus to work similar to EQLive for all clients up to Underfoot.
Required Code:
Code:
Index: common/patches/Underfoot.cpp
===================================================================
--- common/patches/Underfoot.cpp (revision 2260)
+++ common/patches/Underfoot.cpp (working copy)
@@ -3260,6 +3260,15 @@
case 0x1d:
emu->command = 0x02; // Leave/Go Away
break;
+ case 0x15:
+ emu->command = 0x12; // No Cast - /command
+ break;
+ case 0x16:
+ emu->command = 0x12; // No Cast - Pet Window
+ break;
+ case 0x18:
+ emu->command = 0x13; // Focus - Pet Window
+ break;
default:
emu->command = eq->command;
}
Code:
Index: zone/attack.cpp
===================================================================
--- zone/attack.cpp (revision 2260)
+++ zone/attack.cpp (working copy)
@@ -2265,6 +2265,7 @@
Mob* owner = other->GetOwner();
Mob* mypet = this->GetPet();
Mob* myowner = this->GetOwner();
+ Mob* targetmob = this->GetTarget();
if(other){
AddRampage(other);
@@ -2274,10 +2275,15 @@
hate = ((hate * (hatemod))/100);
}
- if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld()){
+ if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && !IsFocused()) { //ignore aggro if hold and !focus
return;
- }
+ }
+ if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && GetOwner()->GetAA(aaAdvancedPetDiscipline) >= 1 && IsFocused()) {
+ if (!targetmob)
+ return;
+ }
+
if(IsClient() && !IsAIControlled())
return;
@@ -3214,10 +3220,12 @@
Mob *pet = GetPet();
if (pet && !pet->IsFamiliar() && !pet->SpecAttacks[IMMUNE_AGGRO] && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse())
{
- mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
- pet->AddToHateList(attacker, 1);
- pet->SetTarget(attacker);
- Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+ if (!pet->IsHeld()) {
+ mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
+ pet->AddToHateList(attacker, 1);
+ pet->SetTarget(attacker);
+ Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+ }
}
//see if any runes want to reduce this damage
Code:
Index: zone/client_packet.cpp
===================================================================
--- zone/client_packet.cpp (revision 2260)
+++ zone/client_packet.cpp (working copy)
@@ -6864,9 +6864,15 @@
if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
- mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
- if(mypet->GetPetOrder() != SPO_Guard)
- mypet->SetPetOrder(SPO_Follow);
+ if (mypet->IsHeld()) {
+ if (!mypet->IsFocused()) {
+ mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
+ if(mypet->GetPetOrder() != SPO_Guard)
+ mypet->SetPetOrder(SPO_Follow);
+ } else {
+ mypet->SetTarget(GetTarget());
+ }
+ }
zone->AddAggroMob();
mypet->AddToHateList(GetTarget(), 1);
Message_StringID(10, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
@@ -7012,6 +7018,60 @@
}
break;
}
+ case PET_NOCAST: {
+ if(GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsNoCast()) {
+ Message(0,"%s says, 'I will now cast spells, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetNoCast(false);
+ } else {
+ Message(0,"%s says, 'I will no longer cast spells, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetNoCast(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(false);
+ } else {
+ Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS_ON: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am already focused, Master!",mypet->GetCleanName());
+ } else {
+ Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS_OFF: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(false);
+ } else {
+ Message(0,"%s says, 'I am already not focused, Master!",mypet->GetCleanName());
+ }
+ }
+ break;
+ }
default:
printf("Client attempted to use a unknown pet command:\n");
break;
Code:
Index: zone/mob.cpp
===================================================================
--- zone/mob.cpp (revision 2260)
+++ zone/mob.cpp (working copy)
@@ -306,6 +306,8 @@
typeofpet = petCharmed; //default to charmed...
petpower = 0;
held = false;
+ nocast = false;
+ focused = false;
attacked_count = 0;
mezzed = false;
@@ -2741,6 +2743,10 @@
if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]){ //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging.
return;
}
+
+ if (IsNoCast())
+ return;
+
if(!IsValidSpell(spell_id)){ // Check for a valid spell otherwise it will crash through the function
if(this->IsClient()){
this->Message(0, "Invalid spell proc %u", spell_id);
Code:
Index: zone/mob.h
===================================================================
--- zone/mob.h (revision 2260)
+++ zone/mob.h (working copy)
@@ -1100,6 +1100,10 @@
inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
inline void SetHeld(bool nState) { held = nState; }
inline const bool IsHeld() const { return held; }
+ inline void SetNoCast(bool nState) { nocast = nState; }
+ inline const bool IsNoCast() const { return nocast; }
+ inline void SetFocused(bool nState) { focused = nState; }
+ inline const bool IsFocused() const { return focused; }
inline const bool IsRoamer() const { return roamer; }
inline const bool IsRooted() const { return rooted || permarooted; }
inline const bool HasVirus() const { return has_virus; }
@@ -1332,6 +1336,8 @@
float runspeed;
int32 pLastChange;
bool held;
+ bool nocast;
+ bool focused;
void CalcSpellBonuses(StatBonuses* newbon);
virtual void CalcBonuses();
void TrySkillProc(Mob *on, int16 skill, float chance);
Code:
Index: zone/MobAI.cpp
===================================================================
--- zone/MobAI.cpp (revision 2260)
+++ zone/MobAI.cpp (working copy)
@@ -58,6 +58,9 @@
if (!tar)
return false;
+ if (IsNoCast())
+ return false;
+
if(AI_HasSpells() == false)
return false;
@@ -1064,7 +1067,14 @@
{
if(AItarget_check_timer->Check())
{
- SetTarget(hate_list.GetTop(this));
+ if (IsFocused()) {
+ if (!target) {
+ SetTarget(hate_list.GetTop(this));
+ }
+ } else {
+ SetTarget(hate_list.GetTop(this));
+ }
+
}
}
Code:
Index: zone/pets.h
===================================================================
--- zone/pets.h (revision 2260)
+++ zone/pets.h (working copy)
@@ -15,6 +15,10 @@
#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
class Pet : public NPC {
public:
Required SQL:
Code:
DELETE FROM `aa_effects` WHERE aaid = 288 or aaid = 1129 or aaid = 1130;
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '288', '1', '267', '1', '15');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1129', '1', '267', '1', '0');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1129', '2', '267', '1', '24');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1130', '1', '267', '1', '21');
INSERT INTO `aa_effects` (`id` ,`aaid` ,`slot` ,`effectid` ,`base1` ,`base2`) VALUES (NULL , '1130', '2', '267', '1', '24');
Vaion
|
|
|
|
11-24-2012, 01:05 PM
|
|
Dragon
|
|
Join Date: Aug 2012
Location: Hershey, PA
Posts: 499
|
|
Not quite sure if replies by those other than the contributor and/or emu devs is 'allowed' but this is one addition/fix I have to thank you for. It -was- a project I was in the middle of attempting to resolve as well, appreciate reducing my labor.
|
|
|
|
11-24-2012, 01:40 PM
|
Dragon
|
|
Join Date: May 2010
Posts: 965
|
|
i started to look into this once myself and realized i need to understand eqemu source better unfortunately.
This is built with no errors for me on my test server.
I find it easier to make and apply a single diff for large patches like this.
Code:
Index: trunk/EQEmuServer/common/patches/Underfoot.cpp
===================================================================
--- trunk/EQEmuServer/common/patches/Underfoot.cpp (revision 2260)
+++ trunk/EQEmuServer/common/patches/Underfoot.cpp (working copy)
@@ -3260,6 +3260,15 @@
case 0x1d:
emu->command = 0x02; // Leave/Go Away
break;
+ case 0x15:
+ emu->command = 0x12; // No Cast - /command
+ break;
+ case 0x16:
+ emu->command = 0x12; // No Cast - Pet Window
+ break;
+ case 0x18:
+ emu->command = 0x13; // Focus - Pet Window
+ break;
default:
emu->command = eq->command;
}
Index: trunk/EQEmuServer/zone/attack.cpp
===================================================================
--- trunk/EQEmuServer/zone/attack.cpp (revision 2260)
+++ trunk/EQEmuServer/zone/attack.cpp (working copy)
@@ -2265,6 +2265,7 @@
Mob* owner = other->GetOwner();
Mob* mypet = this->GetPet();
Mob* myowner = this->GetOwner();
+ Mob* targetmob = this->GetTarget();
if(other){
AddRampage(other);
@@ -2274,10 +2275,15 @@
hate = ((hate * (hatemod))/100);
}
- if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld()){
+ if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && !IsFocused()) { //ignore aggro if hold and !focus
return;
- }
+ }
+ if(IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && GetOwner()->GetAA(aaAdvancedPetDiscipline) >= 1 && IsFocused()) {
+ if (!targetmob)
+ return;
+ }
+
if(IsClient() && !IsAIControlled())
return;
@@ -3214,10 +3220,12 @@
Mob *pet = GetPet();
if (pet && !pet->IsFamiliar() && !pet->SpecAttacks[IMMUNE_AGGRO] && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse())
{
- mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
- pet->AddToHateList(attacker, 1);
- pet->SetTarget(attacker);
- Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+ if (!pet->IsHeld()) {
+ mlog(PETS__AGGRO, "Sending pet %s into battle due to attack.", pet->GetName());
+ pet->AddToHateList(attacker, 1);
+ pet->SetTarget(attacker);
+ Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
+ }
}
//see if any runes want to reduce this damage
Index: trunk/EQEmuServer/zone/client_packet.cpp
===================================================================
--- trunk/EQEmuServer/zone/client_packet.cpp (revision 2260)
+++ trunk/EQEmuServer/zone/client_packet.cpp (working copy)
@@ -6864,9 +6864,15 @@
if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
if (GetTarget() != this && mypet->DistNoRootNoZ(*GetTarget()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
- mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
- if(mypet->GetPetOrder() != SPO_Guard)
- mypet->SetPetOrder(SPO_Follow);
+ if (mypet->IsHeld()) {
+ if (!mypet->IsFocused()) {
+ mypet->SetHeld(false); //break the hold and guard if we explicitly tell the pet to attack.
+ if(mypet->GetPetOrder() != SPO_Guard)
+ mypet->SetPetOrder(SPO_Follow);
+ } else {
+ mypet->SetTarget(GetTarget());
+ }
+ }
zone->AddAggroMob();
mypet->AddToHateList(GetTarget(), 1);
Message_StringID(10, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
@@ -7012,6 +7018,60 @@
}
break;
}
+ case PET_NOCAST: {
+ if(GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsNoCast()) {
+ Message(0,"%s says, 'I will now cast spells, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetNoCast(false);
+ } else {
+ Message(0,"%s says, 'I will no longer cast spells, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetNoCast(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(false);
+ } else {
+ Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS_ON: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am already focused, Master!",mypet->GetCleanName());
+ } else {
+ Message(0,"%s says, 'I will now focus my attention, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(true);
+ }
+ }
+ break;
+ }
+ case PET_FOCUS_OFF: {
+ if(GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
+ if (mypet->IsFeared())
+ break;
+ if (mypet->IsFocused()) {
+ Message(0,"%s says, 'I am no longer focused, Master!",mypet->GetCleanName());
+ mypet->CastToNPC()->SetFocused(false);
+ } else {
+ Message(0,"%s says, 'I am already not focused, Master!",mypet->GetCleanName());
+ }
+ }
+ break;
+ }
default:
printf("Client attempted to use a unknown pet command:\n");
break;
Index: trunk/EQEmuServer/zone/mob.cpp
===================================================================
--- trunk/EQEmuServer/zone/mob.cpp (revision 2260)
+++ trunk/EQEmuServer/zone/mob.cpp (working copy)
@@ -306,6 +306,8 @@
typeofpet = petCharmed; //default to charmed...
petpower = 0;
held = false;
+ nocast = false;
+ focused = false;
attacked_count = 0;
mezzed = false;
@@ -2741,6 +2743,10 @@
if(spell_id == SPELL_UNKNOWN || on->SpecAttacks[NO_HARM_FROM_CLIENT]){ //This is so 65535 doesn't get passed to the client message and to logs because it is not relavant information for debugging.
return;
}
+
+ if (IsNoCast())
+ return;
+
if(!IsValidSpell(spell_id)){ // Check for a valid spell otherwise it will crash through the function
if(this->IsClient()){
this->Message(0, "Invalid spell proc %u", spell_id);
Index: trunk/EQEmuServer/zone/mob.h
===================================================================
--- trunk/EQEmuServer/zone/mob.h (revision 2260)
+++ trunk/EQEmuServer/zone/mob.h (working copy)
@@ -1100,6 +1100,10 @@
inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
inline void SetHeld(bool nState) { held = nState; }
inline const bool IsHeld() const { return held; }
+ inline void SetNoCast(bool nState) { nocast = nState; }
+ inline const bool IsNoCast() const { return nocast; }
+ inline void SetFocused(bool nState) { focused = nState; }
+ inline const bool IsFocused() const { return focused; }
inline const bool IsRoamer() const { return roamer; }
inline const bool IsRooted() const { return rooted || permarooted; }
inline const bool HasVirus() const { return has_virus; }
@@ -1332,6 +1336,8 @@
float runspeed;
int32 pLastChange;
bool held;
+ bool nocast;
+ bool focused;
void CalcSpellBonuses(StatBonuses* newbon);
virtual void CalcBonuses();
void TrySkillProc(Mob *on, int16 skill, float chance);
Index: trunk/EQEmuServer/zone/MobAI.cpp
===================================================================
--- trunk/EQEmuServer/zone/MobAI.cpp (revision 2260)
+++ trunk/EQEmuServer/zone/MobAI.cpp (working copy)
@@ -58,6 +58,9 @@
if (!tar)
return false;
+ if (IsNoCast())
+ return false;
+
if(AI_HasSpells() == false)
return false;
@@ -1064,7 +1067,14 @@
{
if(AItarget_check_timer->Check())
{
- SetTarget(hate_list.GetTop(this));
+ if (IsFocused()) {
+ if (!target) {
+ SetTarget(hate_list.GetTop(this));
+ }
+ } else {
+ SetTarget(hate_list.GetTop(this));
+ }
+
}
}
Index: trunk/EQEmuServer/zone/pets.h
===================================================================
--- trunk/EQEmuServer/zone/pets.h (revision 2260)
+++ trunk/EQEmuServer/zone/pets.h (working copy)
@@ -15,6 +15,10 @@
#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
class Pet : public NPC {
public:
|
|
|
|
11-24-2012, 01:42 PM
|
Sarnak
|
|
Join Date: Oct 2005
Posts: 45
|
|
Aye I had it as a single patch, but figured it would be easier for people to read through if I separated it.
|
11-24-2012, 01:53 PM
|
Dragon
|
|
Join Date: May 2010
Posts: 965
|
|
damn was going to test it and realized i lost my x64 test box when i decided to rebuild a new web server.
rebuilding x32 and installing everything on a different test box
|
11-24-2012, 04:11 PM
|
Dragon
|
|
Join Date: May 2010
Posts: 965
|
|
was confused why it did not work then realized i was level 65. upped the level to 70 on my test server and it worked fine.
committed asrev 2262
|
11-24-2012, 04:26 PM
|
Dragon
|
|
Join Date: May 2010
Posts: 965
|
|
on this same subject, one would then assume that the /pet hold toggle would be found around here then. before I go look at how the source is handling it, have you already solved that one too?
|
11-24-2012, 09:43 PM
|
Sarnak
|
|
Join Date: Oct 2005
Posts: 45
|
|
Pet hold was already fixed awhile back. There were a few modification that I made with the SQL to clean up the AA effects that were not required for anything.
In the SQL the effect 267 with base 15 is the pet hold command for the UF client. So this fix already incorporates pet hold.
To use it you just need to purchase the pet discipline AA. To use focus/no cast you need to purchase the advanced pet discipline AAs.
|
11-25-2012, 09:15 PM
|
Dragon
|
|
Join Date: May 2010
Posts: 965
|
|
with a default PEQ database pet hold does not toggle. i tested that to make sure before I posted. Yes pet hold works. no it does not toggle.
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 01:28 AM.
|
|
|
|
|
|
|
|
|
|
|
|
|