mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +00:00
Merge branch 'master' into luamod
This commit is contained in:
commit
4067397697
12
README.md
12
README.md
@ -8,7 +8,7 @@
|
||||
**EQEmulator is a custom completely from-scratch open source server implementation for EverQuest built mostly on C++**
|
||||
* MySQL/MariaDB is used as the database engine (over 200+ tables)
|
||||
* Perl and LUA are both supported scripting languages for NPC/Player/Quest oriented events
|
||||
* Open source database (Project EQ) has content up to expansion GoD (included in server installs)
|
||||
* Open source database (Project EQ) has content up to expansion OoW (included in server installs)
|
||||
* Game server environments and databases can be heavily customized to create all new experiences
|
||||
* Hundreds of Quests/events created and maintained by Project EQ
|
||||
|
||||
@ -20,14 +20,14 @@
|
||||
* [Easy Install](http://wiki.eqemulator.org/p?Akkas_PEQ_Server_Installer&frm=Main#from-scratch-installation-instructions-windows)
|
||||
* [Advanced Setup](http://wiki.eqemulator.org/p?Complete_Windows-based_Server_Setup_Guide)
|
||||
|
||||
### > Debian/Ubuntu
|
||||
|
||||
|
||||
### > Debian/Ubuntu/CentOS/Fedora
|
||||
* You can use curl or wget to kick off the installer (whichever your OS has)
|
||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||
|
||||
> wget --no-check-certificate https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh -O install.sh && chmod 755 install.sh && ./install.sh
|
||||
|
||||
### > CentOS/Fedora
|
||||
|
||||
> curl -O https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/linux_installer/install.sh install.sh && chmod 755 install.sh && ./install.sh
|
||||
|
||||
## Supported Clients
|
||||
|
||||
|Titanium Edition|Secrets of Faydwer|Seeds of Destruction|Underfoot|Rain of Fear|
|
||||
|
||||
@ -355,6 +355,7 @@ N(OP_OpenTributeMaster),
|
||||
N(OP_PDeletePetition),
|
||||
N(OP_PetBuffWindow),
|
||||
N(OP_PetCommands),
|
||||
N(OP_PetCommandState),
|
||||
N(OP_PetHoTT),
|
||||
N(OP_Petition),
|
||||
N(OP_PetitionBug),
|
||||
|
||||
@ -1116,6 +1116,11 @@ struct PetCommand_Struct {
|
||||
/*004*/ uint32 target;
|
||||
};
|
||||
|
||||
struct PetCommandState_Struct {
|
||||
/*00*/ uint32 button_id;
|
||||
/*04*/ uint32 state;
|
||||
};
|
||||
|
||||
/*
|
||||
** Delete Spawn
|
||||
** Length: 4 Bytes
|
||||
|
||||
@ -332,7 +332,7 @@ namespace EQEmu
|
||||
};
|
||||
|
||||
struct ItemEffect_Struct {
|
||||
int16 Effect;
|
||||
int32 Effect;
|
||||
uint8 Type;
|
||||
uint8 Level;
|
||||
uint8 Level2;
|
||||
|
||||
@ -3291,73 +3291,60 @@ namespace SoD
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
case 1: // back off
|
||||
emu->command = 28;
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
case 2: // get lost
|
||||
emu->command = 29;
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
case 3: // as you were ???
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
case 4: // report HP
|
||||
emu->command = 0;
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
case 5: // guard here
|
||||
emu->command = 5;
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
case 6: // guard me
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
case 7: // attack
|
||||
emu->command = 2;
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
case 8: // follow
|
||||
emu->command = 4;
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // /pet stop
|
||||
case 9: // sit down
|
||||
emu->command = 7;
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
case 10: // stand up
|
||||
emu->command = 8;
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
case 11: // taunt toggle
|
||||
emu->command = 12;
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
case 12: // hold toggle
|
||||
emu->command = 15;
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
case 13: // taunt on
|
||||
emu->command = 13;
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
case 14: // no taunt
|
||||
emu->command = 14;
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
// 15 is target, doesn't send packet
|
||||
case 16: // leader
|
||||
emu->command = 1;
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
case 17: // feign
|
||||
emu->command = 27;
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
case 18: // no cast toggle
|
||||
emu->command = 21;
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
case 19: // focus toggle
|
||||
emu->command = 24;
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
|
||||
@ -2675,73 +2675,60 @@ namespace SoF
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
case 1: // back off
|
||||
emu->command = 28;
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
case 2: // get lost
|
||||
emu->command = 29;
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
case 3: // as you were ???
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
case 4: // report HP
|
||||
emu->command = 0;
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
case 5: // guard here
|
||||
emu->command = 5;
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
case 6: // guard me
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
case 7: // attack
|
||||
emu->command = 2;
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
case 8: // follow
|
||||
emu->command = 4;
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
case 9: // sit down
|
||||
emu->command = 7;
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
case 10: // stand up
|
||||
emu->command = 8;
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
case 11: // taunt toggle
|
||||
emu->command = 12;
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
case 12: // hold toggle
|
||||
emu->command = 15;
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
case 13: // taunt on
|
||||
emu->command = 13;
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
case 14: // no taunt
|
||||
emu->command = 14;
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
// 15 is target, doesn't send packet
|
||||
case 16: // leader
|
||||
emu->command = 1;
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
case 17: // feign
|
||||
emu->command = 27;
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
case 18: // no cast toggle
|
||||
emu->command = 21;
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
case 19: // focus toggle
|
||||
emu->command = 24;
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
|
||||
@ -2030,73 +2030,60 @@ namespace Titanium
|
||||
|
||||
switch (eq->command)
|
||||
{
|
||||
case 0x04:
|
||||
emu->command = 0x00; // /pet health
|
||||
case 1: // back off
|
||||
emu->command = 28;
|
||||
break;
|
||||
case 0x10:
|
||||
emu->command = 0x01; // /pet leader
|
||||
case 2: // get lost
|
||||
emu->command = 29;
|
||||
break;
|
||||
case 0x07:
|
||||
emu->command = 0x02; // /pet attack or Pet Window
|
||||
case 3: // as you were ???
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x03: // Case Guessed
|
||||
emu->command = 0x03; // /pet qattack
|
||||
case 0x08:
|
||||
emu->command = 0x04; // /pet follow or Pet Window
|
||||
case 4: // report HP
|
||||
emu->command = 0;
|
||||
break;
|
||||
case 0x05:
|
||||
emu->command = 0x05; // /pet guard or Pet Window
|
||||
case 5: // guard here
|
||||
emu->command = 5;
|
||||
break;
|
||||
case 0x09:
|
||||
emu->command = 0x07; // /pet sit or Pet Window
|
||||
case 6: // guard me
|
||||
emu->command = 4; // fuck it follow
|
||||
break;
|
||||
case 0x0a:
|
||||
emu->command = 0x08; // /pet stand or Pet Window
|
||||
case 7: // attack
|
||||
emu->command = 2;
|
||||
break;
|
||||
case 0x06:
|
||||
emu->command = 0x1e; // /pet guard me
|
||||
case 8: // follow
|
||||
emu->command = 4;
|
||||
break;
|
||||
case 0x0f: // Case Made Up
|
||||
emu->command = 0x09; // Stop?
|
||||
case 9: // sit down
|
||||
emu->command = 7;
|
||||
break;
|
||||
case 0x0b:
|
||||
emu->command = 0x0d; // /pet taunt or Pet Window
|
||||
case 10: // stand up
|
||||
emu->command = 8;
|
||||
break;
|
||||
case 0x0e:
|
||||
emu->command = 0x0e; // /pet notaunt or Pet Window
|
||||
case 11: // taunt toggle
|
||||
emu->command = 12;
|
||||
break;
|
||||
case 0x0c:
|
||||
emu->command = 0x0f; // /pet hold
|
||||
case 12: // hold toggle
|
||||
emu->command = 15;
|
||||
break;
|
||||
case 0x1b:
|
||||
emu->command = 0x10; // /pet hold on
|
||||
case 13: // taunt on
|
||||
emu->command = 13;
|
||||
break;
|
||||
case 0x1c:
|
||||
emu->command = 0x11; // /pet hold off
|
||||
case 14: // no taunt
|
||||
emu->command = 14;
|
||||
break;
|
||||
case 0x11:
|
||||
emu->command = 0x12; // Slumber?
|
||||
// 15 is target, doesn't send packet
|
||||
case 16: // leader
|
||||
emu->command = 1;
|
||||
break;
|
||||
case 0x12:
|
||||
emu->command = 0x15; // /pet no cast
|
||||
case 17: // feign
|
||||
emu->command = 27;
|
||||
break;
|
||||
case 0x0d: // Case Made Up
|
||||
emu->command = 0x16; // Pet Window No Cast
|
||||
case 18: // no cast toggle
|
||||
emu->command = 21;
|
||||
break;
|
||||
case 0x13:
|
||||
emu->command = 0x18; // /pet focus
|
||||
break;
|
||||
case 0x19:
|
||||
emu->command = 0x19; // /pet focus on
|
||||
break;
|
||||
case 0x1a:
|
||||
emu->command = 0x1a; // /pet focus off
|
||||
break;
|
||||
case 0x01:
|
||||
emu->command = 0x1c; // /pet back off
|
||||
break;
|
||||
case 0x02:
|
||||
emu->command = 0x1d; // /pet get lost
|
||||
case 19: // focus toggle
|
||||
emu->command = 24;
|
||||
break;
|
||||
default:
|
||||
emu->command = eq->command;
|
||||
|
||||
@ -468,7 +468,7 @@ typedef enum {
|
||||
#define SE_Blank 254 // implemented
|
||||
#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
|
||||
#define SE_ShroudofStealth 256 // implemented
|
||||
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
||||
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold - official name is GivePetHold
|
||||
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
|
||||
#define SE_CombatStability 259 // implemented[AA] - damage mitigation
|
||||
#define SE_AddSingingMod 260 // implemented[AA] - Instrument/Singing Mastery, base1 is the mod, base2 is the ItemType
|
||||
@ -478,7 +478,7 @@ typedef enum {
|
||||
#define SE_HastenedAASkill 264 // implemented
|
||||
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled
|
||||
#define SE_ExtraAttackChance 266 // implemented - increase chance to score an extra attack with a 2-Handed Weapon.
|
||||
#define SE_PetDiscipline2 267 // *not implemented - /pet focus, /pet no cast
|
||||
#define SE_AddPetCommand 267 // implemented - sets command base2 to base1
|
||||
#define SE_ReduceTradeskillFail 268 // implemented - reduces chance to fail with given tradeskill by a percent chance
|
||||
#define SE_MaxBindWound 269 // implemented[AA] - Increase max HP you can bind wound.
|
||||
#define SE_BardSongRange 270 // implemented[AA] - increase range of beneficial bard songs (Sionachie's Crescendo)
|
||||
|
||||
@ -196,6 +196,7 @@ OP_Consent=0x400e
|
||||
OP_ConsentDeny=0x34c1
|
||||
OP_AutoFire=0x314e
|
||||
OP_PetCommands=0x0093
|
||||
OP_PetCommandState=0x74ed
|
||||
OP_PetHoTT=0x0df4
|
||||
OP_DeleteSpell=0x305c
|
||||
OP_Surname=0x1a87
|
||||
|
||||
@ -195,6 +195,7 @@ OP_Consent=0x1fd1
|
||||
OP_ConsentDeny=0x7a45
|
||||
OP_AutoFire=0x241e
|
||||
OP_PetCommands=0x0159
|
||||
OP_PetCommandState=0x1dc8
|
||||
OP_PetHoTT=0x794a
|
||||
OP_DeleteSpell=0x3358
|
||||
OP_Surname=0x0423
|
||||
|
||||
@ -198,6 +198,7 @@ OP_Consent=0x6bb9 # C
|
||||
OP_ConsentDeny=0x4cd1 # C
|
||||
OP_AutoFire=0x5db5 # C
|
||||
OP_PetCommands=0x7706 # C
|
||||
OP_PetCommandState=0x1a79
|
||||
OP_PetHoTT=0x2528
|
||||
OP_DeleteSpell=0x0698 # C
|
||||
OP_Surname=0x44ae # C
|
||||
|
||||
@ -49,6 +49,7 @@ if(-e "eqemu_server_skip_update.txt"){
|
||||
|
||||
#::: Check for script self update
|
||||
do_self_update_check_routine() if !$skip_self_update_check;
|
||||
get_windows_wget();
|
||||
get_perl_version();
|
||||
read_eqemu_config_xml();
|
||||
get_mysql_path();
|
||||
@ -517,6 +518,13 @@ sub get_perl_version {
|
||||
no warnings;
|
||||
}
|
||||
|
||||
sub get_windows_wget {
|
||||
if(!-e "wget.exe" && $OS eq "Windows"){
|
||||
eval "use LWP::Simple qw(getstore);";
|
||||
getstore("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/wget.exe", "wget.exe");
|
||||
}
|
||||
}
|
||||
|
||||
sub do_self_update_check_routine {
|
||||
|
||||
#::: Check for internet connection before updating
|
||||
@ -524,7 +532,7 @@ sub do_self_update_check_routine {
|
||||
print "[Update] Cannot check update without internet connection...\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#::: Check for script changes :: eqemu_server.pl
|
||||
get_remote_file($eqemu_repository_request_url . "utils/scripts/eqemu_server.pl", "updates_staged/eqemu_server.pl", 0, 1, 1);
|
||||
|
||||
@ -997,68 +1005,14 @@ sub get_remote_file{
|
||||
}
|
||||
}
|
||||
|
||||
if($OS eq "Windows"){
|
||||
#::: For non-text type requests...
|
||||
if($content_type == 1){
|
||||
$break = 0;
|
||||
while($break == 0) {
|
||||
eval "use LWP::Simple qw(getstore);";
|
||||
# use LWP::Simple qw(getstore);
|
||||
# print "request is " . $request_url . "\n";
|
||||
# print "destination file is supposed to be " . $destination_file . "\n";
|
||||
if(!getstore($request_url, $destination_file)){
|
||||
print "[Download] Error, no connection or failed request...\n\n";
|
||||
}
|
||||
# sleep(1);
|
||||
#::: Make sure the file exists before continuing...
|
||||
if(-e $destination_file) {
|
||||
$break = 1;
|
||||
print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download;
|
||||
} else { $break = 0; }
|
||||
usleep(500);
|
||||
|
||||
if($no_retry){
|
||||
$break = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
$break = 0;
|
||||
while($break == 0) {
|
||||
require LWP::UserAgent;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(10);
|
||||
$ua->env_proxy;
|
||||
my $response = $ua->get($request_url);
|
||||
if ($response->is_success){
|
||||
open (FILE, '> ' . $destination_file . '');
|
||||
print FILE $response->decoded_content;
|
||||
close (FILE);
|
||||
}
|
||||
else {
|
||||
print "[Download] Error, no connection or failed request...\n\n";
|
||||
}
|
||||
if(-e $destination_file) {
|
||||
$break = 1;
|
||||
print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download;
|
||||
} else { $break = 0; }
|
||||
usleep(500);
|
||||
|
||||
if($no_retry){
|
||||
$break = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($OS eq "Linux"){
|
||||
#::: wget -O db_update/db_update_manifest.txt https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||
$wget = `wget --no-check-certificate --quiet -O $destination_file $request_url`;
|
||||
print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download;
|
||||
if($wget=~/unable to resolve/i){
|
||||
print "Error, no connection or failed request...\n\n";
|
||||
#die;
|
||||
}
|
||||
#::: wget -O db_update/db_update_manifest.txt https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt
|
||||
$wget = `wget -N --no-check-certificate --quiet -O $destination_file $request_url`;
|
||||
print "[Download] Saved: (" . $destination_file . ") from " . $request_url . "\n" if !$silent_download;
|
||||
if($wget=~/unable to resolve/i){
|
||||
print "Error, no connection or failed request...\n\n";
|
||||
#die;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#::: Trim Whitespaces
|
||||
|
||||
@ -114,9 +114,24 @@ if [[ "$OS" == "Debian" ]]; then
|
||||
apt-get $apt_options install open-vm-tools
|
||||
apt-get $apt_options install unzip
|
||||
apt-get $apt_options install uuid-dev
|
||||
apt-get $apt_options install wget
|
||||
apt-get $apt_options install zlib-bin
|
||||
apt-get $apt_options install zlibc
|
||||
|
||||
apt-get $apt_options install libsodium-dev
|
||||
apt-get $apt_options install libsodium18
|
||||
|
||||
# If libsodium18 isn't installed (Debian), let's download both that and the dev package and install them.
|
||||
if dpkg-query -s "libsodium18" 1>/dev/null 2>&1; then
|
||||
echo "Sodium library already installed."
|
||||
else
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb
|
||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium18_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium18.deb
|
||||
dpkg -i /home/eqemu/libsodium*.deb
|
||||
# Cleanup after ourselves
|
||||
rm -f /home/eqemu/libsodium-dev.deb
|
||||
rm -f /home/eqemu/libsodium18.deb
|
||||
fi
|
||||
|
||||
#::: Install FTP for remote FTP access
|
||||
echo "proftpd-basic shared/proftpd/inetd_or_standalone select standalone" | debconf-set-selections
|
||||
apt-get -y -q install proftpd
|
||||
@ -149,8 +164,35 @@ EOF
|
||||
|
||||
elif [[ "$OS" == "fedora_core" ]]; then
|
||||
# Do Fedora stuff
|
||||
dnf -y install open-vm-tools vim cmake boost-devel zlib-devel mariadb-server mariadb-devel mariadb-libs perl perl-DBD-MySQL perl-IO-stringy perl-devel lua-devel lua-sql-mysql dos2unix php-mysql proftpd wget compat-lua-libs compat-lua-devel compat-lua perl-Time-HiRes
|
||||
dnf -y groupinstall "Development Tools" "Basic Web Server" "C Development Tools and Libraries"
|
||||
dnf -y install open-vm-tools
|
||||
dnf -y install vim
|
||||
dnf -y install cmake
|
||||
dnf -y install boost-devel
|
||||
dnf -y install zlib-devel
|
||||
dnf -y install mariadb-server
|
||||
dnf -y install mariadb-devel
|
||||
dnf -y install mariadb-libs
|
||||
dnf -y install perl
|
||||
dnf -y install perl-DBD-MySQL
|
||||
dnf -y install perl-IO-stringy
|
||||
dnf -y install perl-devel
|
||||
dnf -y install lua-devel
|
||||
dnf -y install lua-sql-mysql
|
||||
dnf -y install dos2unix
|
||||
dnf -y install php-mysql
|
||||
dnf -y install php-mysqlnd
|
||||
dnf -y install proftpd
|
||||
dnf -y install wget
|
||||
dnf -y install compat-lua-libs
|
||||
dnf -y install compat-lua-devel
|
||||
dnf -y install compat-lua
|
||||
dnf -y install perl-Time-HiRes
|
||||
dnf -y install libuuid-devel
|
||||
dnf -y install libsodium
|
||||
dnf -y install libsodium-devel
|
||||
dnf -y groupinstall "Development Tools"
|
||||
dnf -y groupinstall "Basic Web Server"
|
||||
dnf -y groupinstall "C Development Tools and Libraries"
|
||||
fi
|
||||
|
||||
if [[ "$OS" == "fedora_core" ]] || [[ "$OS" == "red_hat" ]]; then
|
||||
|
||||
10
zone/aa.cpp
10
zone/aa.cpp
@ -46,8 +46,16 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
if (targ != nullptr && targ->IsCorpse())
|
||||
return;
|
||||
|
||||
// yep, even these need pet power!
|
||||
int act_power = 0;
|
||||
|
||||
if (IsClient()) {
|
||||
act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);
|
||||
act_power = CastToClient()->mod_pet_power(act_power, spell_id);
|
||||
}
|
||||
|
||||
PetRecord record;
|
||||
if (!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
|
||||
if (!database.GetPoweredPetEntry(spells[spell_id].teleport_zone, act_power, &record))
|
||||
{
|
||||
Log(Logs::General, Logs::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);
|
||||
|
||||
@ -2529,7 +2529,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/, uint16 spell_id)
|
||||
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/, uint16 spell_id, bool pet_command)
|
||||
{
|
||||
if (!other)
|
||||
return;
|
||||
@ -2568,13 +2568,18 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
}
|
||||
|
||||
if (IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && !IsFocused()) { //ignore aggro if hold and !focus
|
||||
return;
|
||||
}
|
||||
// Pet that is /pet hold on will not add to their hate list if they're not engaged
|
||||
// Pet that is /pet hold on and /pet focus on will not add others to their hate list
|
||||
// Pet that is /pet ghold on will never add to their hate list unless /pet attack or /pet qattack
|
||||
|
||||
if (IsPet() && GetOwner() && GetOwner()->GetAA(aaPetDiscipline) && IsHeld() && GetOwner()->GetAA(aaAdvancedPetDiscipline) >= 1 && IsFocused()) {
|
||||
if (!targetmob)
|
||||
return;
|
||||
// we skip these checks if it's forced through a pet command
|
||||
if (!pet_command) {
|
||||
if (IsPet()) {
|
||||
if ((IsGHeld() || (IsHeld() && IsFocused())) && !on_hatelist) // we want them to be able to climb the hate list
|
||||
return;
|
||||
if ((IsHeld() || IsPetStop() || IsPetRegroup()) && !wasengaged) // not 100% sure on stop/regroup kind of hard to test, but regroup is like "classic hold"
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (other->IsNPC() && (other->IsPet() || other->CastToNPC()->GetSwarmOwner() > 0))
|
||||
@ -2679,7 +2684,7 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
}
|
||||
}
|
||||
|
||||
if (mypet && (!(GetAA(aaPetDiscipline) && mypet->IsHeld()))) { // I have a pet, add other to it
|
||||
if (mypet && !mypet->IsHeld() && !mypet->IsPetStop()) { // I have a pet, add other to it
|
||||
if (!mypet->IsFamiliar() && !mypet->GetSpecialAbility(IMMUNE_AGGRO))
|
||||
mypet->hate_list.AddEntToHateList(other, 0, 0, bFrenzy);
|
||||
}
|
||||
@ -3360,7 +3365,10 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
||||
} //end `if there is some damage being done and theres anattacker person involved`
|
||||
|
||||
Mob *pet = GetPet();
|
||||
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse())
|
||||
// pets that have GHold will never automatically add NPCs
|
||||
// pets that have Hold and no Focus will add NPCs if they're engaged
|
||||
// pets that have Hold and Focus will not add NPCs
|
||||
if (pet && !pet->IsFamiliar() && !pet->GetSpecialAbility(IMMUNE_AGGRO) && !pet->IsEngaged() && attacker && attacker != this && !attacker->IsCorpse() && !pet->IsGHeld())
|
||||
{
|
||||
if (!pet->IsHeld()) {
|
||||
Log(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName());
|
||||
@ -5358,4 +5366,4 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,11 +1442,19 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->FeignedCastOnChance = base1;
|
||||
break;
|
||||
|
||||
case SE_AddPetCommand:
|
||||
if (base1 && base2 < PET_MAXCOMMANDS)
|
||||
newbon->PetCommands[base2] = true;
|
||||
break;
|
||||
|
||||
case SE_FeignedMinion:
|
||||
if (newbon->FeignedMinionChance < base1)
|
||||
newbon->FeignedMinionChance = base1;
|
||||
break;
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
case SE_PetDiscipline2:
|
||||
break;
|
||||
case SE_PotionBeltSlots:
|
||||
break;
|
||||
case SE_BandolierSlots:
|
||||
@ -1465,8 +1473,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
case SE_TrapCircumvention:
|
||||
break;
|
||||
case SE_FeignedMinion:
|
||||
break;
|
||||
|
||||
// not handled here
|
||||
case SE_HastenedAASkill:
|
||||
|
||||
@ -3853,8 +3853,8 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, EQEmu::skills::SkillT
|
||||
}
|
||||
|
||||
//void Bot::AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, bool bFrenzy = false, bool iBuffTic = false)
|
||||
void Bot::AddToHateList(Mob* other, uint32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic) {
|
||||
Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic);
|
||||
void Bot::AddToHateList(Mob* other, uint32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic, bool pet_command) {
|
||||
Mob::AddToHateList(other, hate, damage, iYellForHelp, bFrenzy, iBuffTic, pet_command);
|
||||
}
|
||||
|
||||
bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, bool IsFromSpell, ExtraAttackOptions *opts) {
|
||||
|
||||
@ -325,7 +325,7 @@ public:
|
||||
bool DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQEmu::CastingSlot slot, bool &stopLogic);
|
||||
void SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32 color);
|
||||
void Camp(bool databaseSave = true);
|
||||
virtual void AddToHateList(Mob* other, uint32 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, bool pet_command = false);
|
||||
virtual void SetTarget(Mob* mob);
|
||||
virtual void Zone();
|
||||
std::vector<AISpells_Struct> GetBotSpells() { return AIspells; }
|
||||
|
||||
@ -697,12 +697,13 @@ bool Client::AddPacket(const EQApplicationPacket *pApp, bool bAckreq) {
|
||||
//drop the packet because it will never get sent.
|
||||
return(false);
|
||||
}
|
||||
auto c = new CLIENTPACKET;
|
||||
|
||||
auto c = std::unique_ptr<CLIENTPACKET>(new CLIENTPACKET);
|
||||
|
||||
c->ack_req = bAckreq;
|
||||
c->app = pApp->Copy();
|
||||
|
||||
clientpackets.Append(c);
|
||||
clientpackets.push_back(std::move(c));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -714,26 +715,23 @@ bool Client::AddPacket(EQApplicationPacket** pApp, bool bAckreq) {
|
||||
//drop the packet because it will never get sent.
|
||||
return(false);
|
||||
}
|
||||
auto c = new CLIENTPACKET;
|
||||
auto c = std::unique_ptr<CLIENTPACKET>(new CLIENTPACKET);
|
||||
|
||||
c->ack_req = bAckreq;
|
||||
c->app = *pApp;
|
||||
*pApp = nullptr;
|
||||
|
||||
clientpackets.Append(c);
|
||||
clientpackets.push_back(std::move(c));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Client::SendAllPackets() {
|
||||
LinkedListIterator<CLIENTPACKET*> iterator(clientpackets);
|
||||
|
||||
CLIENTPACKET* cp = nullptr;
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements()) {
|
||||
cp = iterator.GetData();
|
||||
while (!clientpackets.empty()) {
|
||||
cp = clientpackets.front().get();
|
||||
if(eqs)
|
||||
eqs->FastQueuePacket((EQApplicationPacket **)&cp->app, cp->ack_req);
|
||||
iterator.RemoveCurrent();
|
||||
clientpackets.pop_front();
|
||||
Log(Logs::Moderate, Logs::Client_Server_Packet, "Transmitting a packet");
|
||||
}
|
||||
return true;
|
||||
@ -5715,6 +5713,20 @@ void Client::SuspendMinion()
|
||||
Message_StringID(clientMessageTell, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName());
|
||||
|
||||
memset(&m_suspendedminion, 0, sizeof(struct PetInfo));
|
||||
// TODO: These pet command states need to be synced ...
|
||||
// Will just fix them for now
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
|
||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
SetPetCommandState(PET_BUTTON_TAUNT, 1);
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
@ -8937,3 +8949,12 @@ void Client::ProcessAggroMeter()
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SetPetCommandState(int button, int state)
|
||||
{
|
||||
auto app = new EQApplicationPacket(OP_PetCommandState, sizeof(PetCommandState_Struct));
|
||||
auto pcs = (PetCommandState_Struct *)app->pBuffer;
|
||||
pcs->button_id = button;
|
||||
pcs->state = state;
|
||||
FastQueuePacket(&app);
|
||||
}
|
||||
|
||||
|
||||
@ -70,6 +70,7 @@ namespace EQEmu
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
|
||||
#define CLIENT_TIMEOUT 90000
|
||||
@ -351,6 +352,8 @@ public:
|
||||
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
|
||||
void SetPetCommandState(int button, int state);
|
||||
|
||||
bool CheckAccess(int16 iDBLevel, int16 iDefaultLevel);
|
||||
|
||||
void CheckQuests(const char* zonename, const char* message, uint32 npc_id, uint32 item_id, Mob* other);
|
||||
@ -1424,7 +1427,7 @@ private:
|
||||
bool AddPacket(const EQApplicationPacket *, bool);
|
||||
bool AddPacket(EQApplicationPacket**, bool);
|
||||
bool SendAllPackets();
|
||||
LinkedList<CLIENTPACKET *> clientpackets;
|
||||
std::deque<std::unique_ptr<CLIENTPACKET>> clientpackets;
|
||||
|
||||
//Zoning related stuff
|
||||
void SendZoneCancel(ZoneChange_Struct *zc);
|
||||
|
||||
@ -858,6 +858,21 @@ void Client::CompleteConnect()
|
||||
CastToClient()->FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
// TODO: load these states
|
||||
// We at least will set them to the correct state for now
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater && GetPet()) {
|
||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
SetPetCommandState(PET_BUTTON_TAUNT, 1);
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
}
|
||||
|
||||
entity_list.RefreshClientXTargets(this);
|
||||
|
||||
worldserver.RequestTellQueue(GetName());
|
||||
@ -2993,9 +3008,12 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
|
||||
if (!solvent)
|
||||
{
|
||||
Log(Logs::General, Logs::Error, "Player tried to safely remove an augment without a distiller.");
|
||||
Message(13, "Error: Missing an augmentation distiller for safely removing this augment.");
|
||||
return;
|
||||
old_aug = tobe_auged->GetAugment(in_augment->augment_index);
|
||||
if (!old_aug || old_aug->GetItem()->AugDistiller != 0) {
|
||||
Log(Logs::General, Logs::Error, "Player tried to safely remove an augment without a distiller.");
|
||||
Message(13, "Error: Missing an augmentation distiller for safely removing this augment.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (solvent->GetItem()->ItemType == EQEmu::item::ItemTypeAugmentationDistiller)
|
||||
{
|
||||
@ -3159,7 +3177,8 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
|
||||
if (itemOneToPush && itemTwoToPush)
|
||||
{
|
||||
// Consume the augment distiller
|
||||
DeleteItemInInventory(solvent_slot, solvent->IsStackable() ? 1 : 0, true);
|
||||
if (solvent)
|
||||
DeleteItemInInventory(solvent_slot, solvent->IsStackable() ? 1 : 0, true);
|
||||
|
||||
// Remove the augmented item
|
||||
DeleteItemInInventory(item_slot, 0, true);
|
||||
@ -4802,6 +4821,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
mod_consider(tmob, con);
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
// only wanted to check raid target once
|
||||
// and need con to still be around so, do it here!
|
||||
if (tmob->IsRaidTarget()) {
|
||||
@ -4839,7 +4859,15 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
|
||||
SendColoredText(color, std::string("This creature would take an army to defeat!"));
|
||||
}
|
||||
safe_delete(outapp);
|
||||
|
||||
// this could be done better, but this is only called when you con so w/e
|
||||
// Shroud of Stealth has a special message
|
||||
if (improved_hidden && (!tmob->see_improved_hide && (tmob->see_invis || tmob->see_hide)))
|
||||
Message_StringID(10, SOS_KEEPS_HIDDEN);
|
||||
// we are trying to hide but they can see us
|
||||
else if ((invisible || invisible_undead || hidden || invisible_animals) && !IsInvisible(tmob))
|
||||
Message_StringID(10, SUSPECT_SEES_YOU);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -9939,7 +9967,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
Mob *Owner = mypet->GetOwner();
|
||||
if (Owner)
|
||||
mypet->Say_StringID(PET_LEADERIS, Owner->GetCleanName());
|
||||
else
|
||||
else if (mypet->IsNPC())
|
||||
mypet->Say_StringID(I_FOLLOW_NOONE);
|
||||
}
|
||||
}
|
||||
@ -9950,9 +9978,6 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
if (mypet->GetPetType() == petTargetLock && (pet->command != PET_HEALTHREPORT && pet->command != PET_GETLOST))
|
||||
return;
|
||||
|
||||
if (mypet->GetPetType() == petAnimation && (pet->command != PET_HEALTHREPORT && pet->command != PET_GETLOST) && !GetAA(aaAnimationEmpathy))
|
||||
return;
|
||||
|
||||
// just let the command "/pet get lost" work for familiars
|
||||
if (mypet->GetPetType() == petFamiliar && pet->command != PET_GETLOST)
|
||||
return;
|
||||
@ -9982,25 +10007,31 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
break; //prevent pet from attacking stuff while feared
|
||||
|
||||
if (!mypet->IsAttackAllowed(target)) {
|
||||
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
||||
mypet->SayTo_StringID(this, NOT_LEGAL_TARGET);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (target != this && DistanceSquaredNoZ(mypet->GetPosition(), target->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
||||
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(target);
|
||||
}
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
if (mypet->IsPetRegroup()) {
|
||||
mypet->SetPetRegroup(false);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
}
|
||||
zone->AddAggroMob();
|
||||
mypet->AddToHateList(target, 1);
|
||||
// classic acts like qattack
|
||||
int hate = 1;
|
||||
if (mypet->IsEngaged()) {
|
||||
auto top = mypet->GetHateMost();
|
||||
if (top && top != target)
|
||||
hate += mypet->GetHateAmount(top) - mypet->GetHateAmount(target) + 100; // should be enough to cause target change
|
||||
}
|
||||
mypet->AddToHateList(target, hate, 0, true, false, false, SPELL_UNKNOWN, true);
|
||||
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName());
|
||||
SetTarget(target);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -10017,14 +10048,22 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (!mypet->IsAttackAllowed(GetTarget())) {
|
||||
mypet->Say_StringID(NOT_LEGAL_TARGET);
|
||||
mypet->SayTo_StringID(this, NOT_LEGAL_TARGET);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (GetTarget() != this && DistanceSquaredNoZ(mypet->GetPosition(), GetTarget()->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
if (mypet->IsPetRegroup()) {
|
||||
mypet->SetPetRegroup(false);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
}
|
||||
zone->AddAggroMob();
|
||||
mypet->AddToHateList(GetTarget(), 1);
|
||||
mypet->AddToHateList(GetTarget(), 1, 0, true, false, false, SPELL_UNKNOWN, true);
|
||||
Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName());
|
||||
}
|
||||
}
|
||||
@ -10033,17 +10072,22 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_BACKOFF: {
|
||||
if (mypet->IsFeared()) break; //keeps pet running while feared
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->Say_StringID(MT_PetResponse, PET_CALMING);
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_CALMING);
|
||||
mypet->WipeHateList();
|
||||
mypet->SetTarget(nullptr);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_HEALTHREPORT: {
|
||||
Message_StringID(MT_PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1));
|
||||
mypet->ShowBuffList(this);
|
||||
//Message(10,"%s tells you, 'I have %d percent of my hit points left.'",mypet->GetName(),(uint8)mypet->GetHPRatio());
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
Message_StringID(MT_PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1));
|
||||
mypet->ShowBuffList(this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_GETLOST: {
|
||||
@ -10060,7 +10104,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
SetPet(nullptr);
|
||||
}
|
||||
|
||||
mypet->Say_StringID(MT_PetResponse, PET_GETLOST_STRING);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING);
|
||||
mypet->CastToNPC()->Depop();
|
||||
|
||||
//Oddly, the client (Titanium) will still allow "/pet get lost" command despite me adding the code below. If someone can figure that out, you can uncomment this code and use it.
|
||||
@ -10076,12 +10120,17 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_GUARDHERE: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 1) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (mypet->IsNPC()) {
|
||||
mypet->SetHeld(false);
|
||||
mypet->Say_StringID(MT_PetResponse, PET_GUARDINGLIFE);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GUARDINGLIFE);
|
||||
mypet->SetPetOrder(SPO_Guard);
|
||||
mypet->CastToNPC()->SaveGuardSpot();
|
||||
if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down
|
||||
mypet->SetCurrentSpeed(0);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -10089,16 +10138,19 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_FOLLOWME: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 1) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SetHeld(false);
|
||||
mypet->Say_StringID(MT_PetResponse, PET_FOLLOWING);
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_FOLLOWING);
|
||||
mypet->SetPetOrder(SPO_Follow);
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_TAUNT: {
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (mypet->CastToNPC()->IsTaunting())
|
||||
{
|
||||
Message_StringID(MT_PetResponse, PET_NO_TAUNT);
|
||||
@ -10113,14 +10165,14 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
break;
|
||||
}
|
||||
case PET_TAUNT_ON: {
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
Message_StringID(MT_PetResponse, PET_DO_TAUNT);
|
||||
mypet->CastToNPC()->SetTaunting(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_TAUNT_OFF: {
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
Message_StringID(MT_PetResponse, PET_NO_TAUNT);
|
||||
mypet->CastToNPC()->SetTaunting(false);
|
||||
}
|
||||
@ -10129,27 +10181,30 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_GUARDME: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 1) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SetHeld(false);
|
||||
mypet->Say_StringID(MT_PetResponse, PET_GUARDME_STRING);
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GUARDME_STRING);
|
||||
mypet->SetPetOrder(SPO_Follow);
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SIT: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (mypet->GetPetOrder() == SPO_Sit)
|
||||
{
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Follow);
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
}
|
||||
else
|
||||
{
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Sit);
|
||||
mypet->SetRunAnimSpeed(0);
|
||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||
@ -10162,8 +10217,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_STANDUP: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Follow);
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
}
|
||||
@ -10172,8 +10227,8 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
case PET_SITDOWN: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 3) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Sit);
|
||||
mypet->SetRunAnimSpeed(0);
|
||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||
@ -10182,152 +10237,274 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SLUMBER: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (mypet->GetPetType() != petAnimation) {
|
||||
// Needs to have an IsSleeping() check added and this case should toggle on/off
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Sit);
|
||||
mypet->SetRunAnimSpeed(0);
|
||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_DEATH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SLUMBER_ON: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (mypet->GetPetType() != petAnimation) {
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Sit);
|
||||
mypet->SetRunAnimSpeed(0);
|
||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_DEATH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SLUMBER_OFF: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (mypet->GetPetType() != petAnimation) {
|
||||
mypet->Say_StringID(MT_PetResponse, PET_SIT_STRING);
|
||||
mypet->SetPetOrder(SPO_Follow);
|
||||
mypet->SetRunAnimSpeed(mypet->GetBaseRunspeed());
|
||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_HOLD: {
|
||||
if (GetAA(aaPetDiscipline) && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsHeld())
|
||||
{
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF);
|
||||
mypet->SetHeld(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mypet->Say_StringID(MT_PetResponse, PET_ON_HOLD);
|
||||
mypet->WipeHateList();
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_HOLD_SET_ON);
|
||||
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING);
|
||||
else
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
|
||||
|
||||
mypet->SetHeld(true);
|
||||
}
|
||||
mypet->SetGHeld(false);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_HOLD_ON: {
|
||||
if (GetAA(aaPetDiscipline) && mypet->IsNPC() && !mypet->IsHeld()) {
|
||||
if (mypet->IsFeared())
|
||||
break; //could be exploited like PET_BACKOFF
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && !mypet->IsHeld()) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_HOLD_SET_ON);
|
||||
|
||||
mypet->Say_StringID(MT_PetResponse, PET_ON_HOLD);
|
||||
mypet->WipeHateList();
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING);
|
||||
else
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
|
||||
mypet->SetHeld(true);
|
||||
mypet->SetGHeld(false);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_HOLD_OFF: {
|
||||
if (GetAA(aaPetDiscipline) && mypet->IsNPC() && mypet->IsHeld())
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsHeld()) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF);
|
||||
mypet->SetHeld(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_GHOLD: {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsGHeld())
|
||||
{
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_OFF_GHOLD);
|
||||
mypet->SetGHeld(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
|
||||
Message_StringID(MT_PetResponse, PET_ON_GHOLD);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG);
|
||||
} else {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
|
||||
}
|
||||
mypet->SetGHeld(true);
|
||||
}
|
||||
mypet->SetHeld(false);
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_GHOLD_ON: {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater) {
|
||||
Message_StringID(MT_PetResponse, PET_ON_GHOLD);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG);
|
||||
} else {
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD);
|
||||
}
|
||||
mypet->SetGHeld(true);
|
||||
mypet->SetHeld(false);
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_GHOLD_OFF: {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsGHeld()) {
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_OFF_GHOLD);
|
||||
mypet->SetGHeld(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SPELLHOLD: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (mypet->IsNoCast()) {
|
||||
Message_StringID(MT_PetResponse, PET_CASTING);
|
||||
mypet->CastToNPC()->SetNoCast(false);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF);
|
||||
mypet->SetNoCast(false);
|
||||
}
|
||||
else {
|
||||
Message_StringID(MT_PetResponse, PET_NOT_CASTING);
|
||||
mypet->CastToNPC()->SetNoCast(true);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON);
|
||||
mypet->SetNoCast(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SPELLHOLD_ON: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (!mypet->IsNoCast()) {
|
||||
Message_StringID(MT_PetResponse, PET_NOT_CASTING);
|
||||
mypet->CastToNPC()->SetNoCast(true);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON);
|
||||
mypet->SetNoCast(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_SPELLHOLD_OFF: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) == 2 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (mypet->IsNoCast()) {
|
||||
Message_StringID(MT_PetResponse, PET_CASTING);
|
||||
mypet->CastToNPC()->SetNoCast(false);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF);
|
||||
mypet->SetNoCast(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_FOCUS: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (mypet->IsFocused()) {
|
||||
Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
|
||||
mypet->CastToNPC()->SetFocused(false);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF);
|
||||
mypet->SetFocused(false);
|
||||
}
|
||||
else {
|
||||
Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
|
||||
mypet->CastToNPC()->SetFocused(true);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON);
|
||||
mypet->SetFocused(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_FOCUS_ON: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (!mypet->IsFocused()) {
|
||||
Message_StringID(MT_PetResponse, PET_NOW_FOCUSING);
|
||||
mypet->CastToNPC()->SetFocused(true);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON);
|
||||
mypet->SetFocused(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_FOCUS_OFF: {
|
||||
if (GetAA(aaAdvancedPetDiscipline) >= 1 && mypet->IsNPC()) {
|
||||
if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) {
|
||||
if (mypet->IsFeared())
|
||||
break;
|
||||
if (mypet->IsFocused()) {
|
||||
Message_StringID(MT_PetResponse, PET_NOT_FOCUSING);
|
||||
mypet->CastToNPC()->SetFocused(false);
|
||||
if (m_ClientVersionBit & EQEmu::versions::bit_SoDAndLater)
|
||||
Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF);
|
||||
mypet->SetFocused(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_STOP: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
} else {
|
||||
mypet->SetPetStop(true);
|
||||
mypet->SetCurrentSpeed(0);
|
||||
mypet->SetTarget(nullptr);
|
||||
if (mypet->IsPetRegroup()) {
|
||||
mypet->SetPetRegroup(false);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
}
|
||||
}
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_STOP_ON: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SetPetStop(true);
|
||||
mypet->SetCurrentSpeed(0);
|
||||
mypet->SetTarget(nullptr);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING);
|
||||
if (mypet->IsPetRegroup()) {
|
||||
mypet->SetPetRegroup(false);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_STOP_OFF: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||
mypet->SetPetStop(false);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_REGROUP: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (aabonuses.PetCommands[PetCommand]) {
|
||||
if (mypet->IsPetRegroup()) {
|
||||
mypet->SetPetRegroup(false);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_OFF_REGROUPING);
|
||||
} else {
|
||||
mypet->SetPetRegroup(true);
|
||||
mypet->SetTarget(nullptr);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_REGROUPING);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_REGROUP_ON: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (aabonuses.PetCommands[PetCommand]) {
|
||||
mypet->SetPetRegroup(true);
|
||||
mypet->SetTarget(nullptr);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_REGROUPING);
|
||||
if (mypet->IsPetStop()) {
|
||||
mypet->SetPetStop(false);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PET_REGROUP_OFF: {
|
||||
if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF
|
||||
|
||||
if (aabonuses.PetCommands[PetCommand]) {
|
||||
mypet->SetPetRegroup(false);
|
||||
mypet->SayTo_StringID(this, MT_PetResponse, PET_OFF_REGROUPING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Client attempted to use a unknown pet command:\n");
|
||||
break;
|
||||
|
||||
@ -56,6 +56,55 @@
|
||||
//Maximum distance from a zone point if zone was specified
|
||||
#define ZONEPOINT_ZONE_RANGE 40000.0f
|
||||
|
||||
// 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, won't add to hate list unless attacking
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_GHOLD 18 // 0x12 - /pet ghold, will never add to hate list unless told to
|
||||
#define PET_GHOLD_ON 19 // 0x13 - /pet ghold on
|
||||
#define PET_GHOLD_OFF 20 // 0x14 - /pet ghold off
|
||||
#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_FEIGN 27 // 0x1b - /pet feign
|
||||
#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 /pet target in modern clients but doesn't send packet
|
||||
#define PET_REGROUP 31 // 0x1f - /pet regroup, acts like classic hold. Stops attack and moves back to guard/you but doesn't clear hate list
|
||||
#define PET_REGROUP_ON 32 // 0x20 - /pet regroup on, turns on regroup
|
||||
#define PET_REGROUP_OFF 33 // 0x21 - /pet regroup off, turns off regroup
|
||||
#define PET_MAXCOMMANDS PET_REGROUP_OFF + 1
|
||||
|
||||
// can change the state of these buttons with a packet
|
||||
#define PET_BUTTON_SIT 0
|
||||
#define PET_BUTTON_STOP 1
|
||||
#define PET_BUTTON_REGROUP 2
|
||||
#define PET_BUTTON_FOLLOW 3
|
||||
#define PET_BUTTON_GUARD 4
|
||||
#define PET_BUTTON_TAUNT 5
|
||||
#define PET_BUTTON_HOLD 6
|
||||
#define PET_BUTTON_GHOLD 7
|
||||
#define PET_BUTTON_FOCUS 8
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
typedef enum { //focus types
|
||||
focusSpellHaste = 1,
|
||||
focusSpellDuration,
|
||||
@ -485,6 +534,8 @@ struct StatBonuses {
|
||||
uint8 TradeSkillMastery; // Allow number of tradeskills to exceed 200 skill.
|
||||
int16 NoBreakAESneak; // Percent value
|
||||
int16 FeignedCastOnChance; // Percent Value
|
||||
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -648,7 +648,7 @@ bool Group::DelMember(Mob* oldmember, bool ignoresender)
|
||||
}
|
||||
}
|
||||
|
||||
if (GetLeader() == nullptr)
|
||||
if (!GetLeaderName())
|
||||
{
|
||||
DisbandGroup();
|
||||
return true;
|
||||
|
||||
23
zone/mob.cpp
23
zone/mob.cpp
@ -344,8 +344,11 @@ Mob::Mob(const char* in_name,
|
||||
typeofpet = petNone; // default to not a pet
|
||||
petpower = 0;
|
||||
held = false;
|
||||
gheld = false;
|
||||
nocast = false;
|
||||
focused = false;
|
||||
pet_stop = false;
|
||||
pet_regroup = false;
|
||||
_IsTempPet = false;
|
||||
pet_owner_client = false;
|
||||
pet_targetlock_id = 0;
|
||||
@ -3093,6 +3096,26 @@ void Mob::Say_StringID(uint32 type, uint32 string_id, const char *message3, cons
|
||||
);
|
||||
}
|
||||
|
||||
void Mob::SayTo_StringID(Client *to, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9)
|
||||
{
|
||||
if (!to)
|
||||
return;
|
||||
|
||||
auto string_id_str = std::to_string(string_id);
|
||||
|
||||
to->Message_StringID(10, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9);
|
||||
}
|
||||
|
||||
void Mob::SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9)
|
||||
{
|
||||
if (!to)
|
||||
return;
|
||||
|
||||
auto string_id_str = std::to_string(string_id);
|
||||
|
||||
to->Message_StringID(type, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9);
|
||||
}
|
||||
|
||||
void Mob::Shout(const char *format, ...)
|
||||
{
|
||||
char buf[1000];
|
||||
|
||||
15
zone/mob.h
15
zone/mob.h
@ -536,7 +536,7 @@ public:
|
||||
inline uint32 GetLevelCon(uint8 iOtherLevel) const {
|
||||
return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GRAY; }
|
||||
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true,
|
||||
bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN);
|
||||
bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN, bool pet_comand = false);
|
||||
bool RemoveFromHateList(Mob* mob);
|
||||
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)); }
|
||||
@ -645,6 +645,10 @@ public:
|
||||
const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0);
|
||||
void Say_StringID(uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0,
|
||||
const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0);
|
||||
void SayTo_StringID(Client *to, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0,
|
||||
const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0);
|
||||
void SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0,
|
||||
const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0);
|
||||
void Shout(const char *format, ...);
|
||||
void Emote(const char *format, ...);
|
||||
void QuestJournalledSay(Client *QuestInitiator, const char *str);
|
||||
@ -872,10 +876,16 @@ public:
|
||||
inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
|
||||
inline void SetHeld(bool nState) { held = nState; }
|
||||
inline const bool IsHeld() const { return held; }
|
||||
inline void SetGHeld(bool nState) { gheld = nState; }
|
||||
inline const bool IsGHeld() const { return gheld; }
|
||||
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 void SetPetStop(bool nState) { pet_stop = nState; }
|
||||
inline const bool IsPetStop() const { return pet_stop; }
|
||||
inline void SetPetRegroup(bool nState) { pet_regroup = nState; }
|
||||
inline const bool IsPetRegroup() const { return pet_regroup; }
|
||||
inline const bool IsRoamer() const { return roamer; }
|
||||
inline const int GetWanderType() const { return wandertype; }
|
||||
inline const bool IsRooted() const { return rooted || permarooted; }
|
||||
@ -1184,8 +1194,11 @@ protected:
|
||||
|
||||
uint32 pLastChange;
|
||||
bool held;
|
||||
bool gheld;
|
||||
bool nocast;
|
||||
bool focused;
|
||||
bool pet_stop;
|
||||
bool pet_regroup;
|
||||
bool spawned;
|
||||
void CalcSpellBonuses(StatBonuses* newbon);
|
||||
virtual void CalcBonuses();
|
||||
|
||||
@ -935,7 +935,7 @@ void Mob::AI_Process() {
|
||||
bool engaged = IsEngaged();
|
||||
bool doranged = false;
|
||||
|
||||
if (!zone->CanDoCombat()) {
|
||||
if (!zone->CanDoCombat() || IsPetStop() || IsPetRegroup()) {
|
||||
engaged = false;
|
||||
}
|
||||
|
||||
@ -943,7 +943,7 @@ void Mob::AI_Process() {
|
||||
//
|
||||
if(RuleB(Combat, EnableFearPathing)){
|
||||
if(currently_fleeing) {
|
||||
if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) {
|
||||
if((IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) && !IsPetStop() && !IsPetRegroup()) {
|
||||
//make sure everybody knows were not moving, for appearance sake
|
||||
if(IsMoving())
|
||||
{
|
||||
@ -1300,10 +1300,12 @@ void Mob::AI_Process() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
|
||||
SendRemovePlayerState(PlayerState::Aggressive);
|
||||
|
||||
if (IsPetStop()) // pet stop won't be engaged, so we will always get here and we want the above branch to execute
|
||||
return;
|
||||
|
||||
if(zone->CanDoCombat() && AI_feign_remember_timer->Check()) {
|
||||
// 6/14/06
|
||||
// Improved Feign Death Memory
|
||||
@ -1409,6 +1411,8 @@ void Mob::AI_Process() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsPetRegroup())
|
||||
return;
|
||||
}
|
||||
/* Entity has been assigned another entity to follow */
|
||||
else if (GetFollowID())
|
||||
|
||||
@ -706,7 +706,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
|
||||
// all of the result rows. Check if we have something in the slot
|
||||
// already. If no, add the item id to the equipment array.
|
||||
while (curset >= 0 && depth < 5) {
|
||||
std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%s'", curset);
|
||||
std::string query = StringFormat("SELECT nested_set FROM pets_equipmentset WHERE set_id = '%d'", curset);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
return false;
|
||||
@ -721,7 +721,7 @@ bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
|
||||
auto row = results.begin();
|
||||
nextset = atoi(row[0]);
|
||||
|
||||
query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset);
|
||||
query = StringFormat("SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%d'", curset);
|
||||
results = QueryDatabase(query);
|
||||
if (results.Success()) {
|
||||
for (row = results.begin(); row != results.end(); ++row)
|
||||
|
||||
32
zone/pets.h
32
zone/pets.h
@ -1,38 +1,6 @@
|
||||
#ifndef PETS_H
|
||||
#define PETS_H
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
@ -1240,6 +1240,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
else
|
||||
{
|
||||
MakePet(spell_id, spell.teleport_zone);
|
||||
// TODO: we need to sync the states for these clients ...
|
||||
// Will fix buttons for now
|
||||
if (IsClient()) {
|
||||
auto c = CastToClient();
|
||||
if (c->ClientVersionBit() & EQEmu::versions::bit_UFAndLater) {
|
||||
c->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
c->SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_TAUNT, 1);
|
||||
c->SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -6669,23 +6686,26 @@ void Mob::ResourceTap(int32 damage, uint16 spellid)
|
||||
|
||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||
if (spells[spellid].effectid[i] == SE_ResourceTap) {
|
||||
damage += (damage * spells[spellid].base[i]) / 100;
|
||||
|
||||
if (spells[spellid].max[i] && (damage > spells[spellid].max[i]))
|
||||
damage = spells[spellid].max[i];
|
||||
|
||||
if (spells[spellid].base2[i] == 0) { // HP Tap
|
||||
if (damage > 0)
|
||||
HealDamage(damage);
|
||||
else
|
||||
Damage(this, -damage, 0, EQEmu::skills::SkillEvocation, false);
|
||||
damage = (damage * spells[spellid].base[i]) / 1000;
|
||||
|
||||
if (damage) {
|
||||
if (spells[spellid].max[i] && (damage > spells[spellid].max[i]))
|
||||
damage = spells[spellid].max[i];
|
||||
|
||||
if (spells[spellid].base2[i] == 0) { // HP Tap
|
||||
if (damage > 0)
|
||||
HealDamage(damage);
|
||||
else
|
||||
Damage(this, -damage, 0, EQEmu::skills::SkillEvocation, false);
|
||||
}
|
||||
|
||||
if (spells[spellid].base2[i] == 1) // Mana Tap
|
||||
SetMana(GetMana() + damage);
|
||||
|
||||
if (spells[spellid].base2[i] == 2 && IsClient()) // Endurance Tap
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + damage);
|
||||
|
||||
}
|
||||
|
||||
if (spells[spellid].base2[i] == 1) // Mana Tap
|
||||
SetMana(GetMana() + damage);
|
||||
|
||||
if (spells[spellid].base2[i] == 2 && IsClient()) // Endurance Tap
|
||||
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2140,6 +2140,27 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui
|
||||
|
||||
spell_target->CalcSpellPowerDistanceMod(spell_id, dist2);
|
||||
}
|
||||
//AE Duration spells were ignoring distance check from item clickies
|
||||
if(ae_center != nullptr && ae_center != this) {
|
||||
//casting a spell on somebody but ourself, make sure they are in range
|
||||
float dist2 = DistanceSquared(m_Position, ae_center->GetPosition());
|
||||
float range2 = range * range;
|
||||
float min_range2 = spells[spell_id].min_range * spells[spell_id].min_range;
|
||||
if(dist2 > range2) {
|
||||
//target is out of range.
|
||||
Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2);
|
||||
Message_StringID(13, TARGET_OUT_OF_RANGE);
|
||||
return(false);
|
||||
}
|
||||
else if (dist2 < min_range2){
|
||||
//target is too close range.
|
||||
Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2);
|
||||
Message_StringID(13, TARGET_TOO_CLOSE);
|
||||
return(false);
|
||||
}
|
||||
|
||||
ae_center->CalcSpellPowerDistanceMod(spell_id, dist2);
|
||||
}
|
||||
|
||||
//
|
||||
// Switch #2 - execute the spell
|
||||
|
||||
@ -164,6 +164,12 @@
|
||||
#define PVP_ON 552 //You are now player kill and follow the ways of Discord.
|
||||
#define GENERIC_STRINGID_SAY 554 //%1 says '%T2'
|
||||
#define CANNOT_WAKE 555 //%1 tells you, 'I am unable to wake %2, master.'
|
||||
#define PET_HOLD_SET_ON 698 //The pet hold mode has been set to on.
|
||||
#define PET_HOLD_SET_OFF 699 //The pet hold mode has been set to off.
|
||||
#define PET_FOCUS_SET_ON 700 //The pet focus mode has been set to on.
|
||||
#define PET_FOCUS_SET_OFF 701 //The pet focus mode has been set to off.
|
||||
#define PET_SPELLHOLD_SET_ON 702 //The pet spellhold mode has been set to on.
|
||||
#define PET_SPELLHOLD_SET_OFF 703 //The pet spellhold mode has been set to off.
|
||||
#define GUILD_NAME_IN_USE 711 //You cannot create a guild with that name, that guild already exists on this server.
|
||||
#define GM_GAINXP 1002 //[GM] You have gained %1 AXP and %2 EXP (%3).
|
||||
#define MALE_SLAYUNDEAD 1007 //%1's holy blade cleanses his target!(%2)
|
||||
@ -288,6 +294,7 @@
|
||||
#define CORPSEDRAG_BEGIN 4064 //You begin to drag %1.
|
||||
#define CORPSEDRAG_STOPALL 4065 //You stop dragging the corpses.
|
||||
#define CORPSEDRAG_STOP 4066 //You stop dragging the corpse.
|
||||
#define SOS_KEEPS_HIDDEN 4086 //Your Shroud of Stealth keeps you hidden from watchful eyes.␣␣
|
||||
#define TARGET_TOO_CLOSE 4602 //You are too close to your target. Get farther away.
|
||||
#define WHOALL_NO_RESULTS 5029 //There are no players in EverQuest that match those who filters.
|
||||
#define TELL_QUEUED_MESSAGE 5045 //You told %1 '%T2. %3'
|
||||
@ -302,6 +309,7 @@
|
||||
#define PET_ATTACKING 5501 //%1 tells you, 'Attacking %2 Master.'
|
||||
#define AVOID_STUNNING_BLOW 5753 //You avoid the stunning blow.
|
||||
#define FATAL_BOW_SHOT 5745 //%1 performs a FATAL BOW SHOT!!
|
||||
#define SUSPECT_SEES_YOU 5746 //You suspect that this being can see you.
|
||||
#define MELEE_SILENCE 5806 //You *CANNOT* use this melee ability, you are suffering from amnesia!
|
||||
#define DISCIPLINE_REUSE_MSG 5807 //You can use the ability %1 again in %2 hour(s) %3 minute(s) %4 seconds.
|
||||
#define DISCIPLINE_REUSE_MSG2 5808 //You can use the ability %1 again in %2 minute(s) %3 seconds.
|
||||
@ -320,6 +328,12 @@
|
||||
#define SENTINEL_TRIG_YOU 6724 //You have triggered your sentinel.
|
||||
#define SENTINEL_TRIG_OTHER 6725 //%1 has triggered your sentinel.
|
||||
#define IDENTIFY_SPELL 6765 //Item Lore: %1.
|
||||
#define PET_NOW_HOLDING 6834 //Now holding, Master. I will not start attacks until ordered.
|
||||
#define PET_ON_GHOLD 6843 //Pet greater hold has been set to on.
|
||||
#define PET_OFF_GHOLD 6846 //Pet greater hold has been set to off.
|
||||
#define PET_GHOLD_ON_MSG 6847 //Now greater holding master. I will only attack something new if ordered.
|
||||
#define PET_ON_REGROUPING 6854 //Now regrouping, master.
|
||||
#define PET_OFF_REGROUPING 6855 //No longer regrouping, master.
|
||||
#define BUFF_NOT_BLOCKABLE 7608 //You cannot block this effect.
|
||||
#define LDON_DONT_KNOW_TRAPPED 7552 //You do not know if this object is trapped.
|
||||
#define LDON_HAVE_DISARMED 7553 //You have disarmed %1!
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user