mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-03 02:52:26 +00:00
Merge branch 'master' into inv2
This commit is contained in:
commit
279ed8d86c
@ -1,5 +1,16 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 03/12/2015 ==
|
||||||
|
Akkadius: [eqemu_update.pl V7] Add Option 9) LUA Modules - Download latest LUA Modules (Required for Lua)
|
||||||
|
|
||||||
|
== 03/11/2015 ==
|
||||||
|
Akkadius: [eqemu_update.pl] Add Option 7) Plugins - Download latest Perl plugins
|
||||||
|
Akkadius: [eqemu_update.pl] Add Option 8) Quests - Download latest PEQ quests and stage updates
|
||||||
|
Akkadius: [eqemu_update.pl] Set version 5 of script
|
||||||
|
|
||||||
|
== 03/10/2015 ==
|
||||||
|
Akkadius: [eqemu_update.pl] Add Option 6) Download Latest map and water files
|
||||||
|
|
||||||
== 03/04/2015 ==
|
== 03/04/2015 ==
|
||||||
Akkadius: Fix Spell Book Deletion
|
Akkadius: Fix Spell Book Deletion
|
||||||
|
|
||||||
|
|||||||
@ -494,7 +494,7 @@ bool Database::CheckDatabaseConversions() {
|
|||||||
/* Check for a new version of this script, the arg passed
|
/* Check for a new version of this script, the arg passed
|
||||||
would have to be higher than the copy they have downloaded
|
would have to be higher than the copy they have downloaded
|
||||||
locally and they will re fetch */
|
locally and they will re fetch */
|
||||||
system("perl eqemu_update.pl V 2");
|
system("perl eqemu_update.pl V 7");
|
||||||
|
|
||||||
/* Run Automatic Database Upgrade Script */
|
/* Run Automatic Database Upgrade Script */
|
||||||
system("perl eqemu_update.pl ran_from_world");
|
system("perl eqemu_update.pl ran_from_world");
|
||||||
|
|||||||
@ -38,6 +38,7 @@
|
|||||||
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
|
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
|
||||||
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
|
#define MaxLimitInclude 16 //Number(x 0.5) of focus Limiters that have inclusive checks used when calcing focus effects
|
||||||
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
|
#define MAX_SKILL_PROCS 4 //Number of spells to check skill procs from. (This is arbitrary) [Single spell can have multiple proc checks]
|
||||||
|
#define MAX_SYMPATHETIC_PROCS 10 // Number of sympathetic procs a client can have (This is arbitrary)
|
||||||
|
|
||||||
|
|
||||||
const int Z_AGGRO=10;
|
const int Z_AGGRO=10;
|
||||||
|
|||||||
@ -9,12 +9,20 @@
|
|||||||
$menu_displayed = 0;
|
$menu_displayed = 0;
|
||||||
|
|
||||||
use Config;
|
use Config;
|
||||||
|
use File::Copy qw(copy);
|
||||||
|
use POSIX qw(strftime);
|
||||||
|
use File::Path;
|
||||||
|
use File::Find;
|
||||||
|
use URI::Escape;
|
||||||
|
|
||||||
|
$time_stamp = strftime('%m-%d-%Y', gmtime());
|
||||||
|
|
||||||
$console_output .= " Operating System is: $Config{osname}\n";
|
$console_output .= " Operating System is: $Config{osname}\n";
|
||||||
if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
||||||
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||||
|
|
||||||
#::: If current version is less than what world is reporting, then download a new one...
|
#::: If current version is less than what world is reporting, then download a new one...
|
||||||
$current_version = 2;
|
$current_version = 7;
|
||||||
|
|
||||||
if($ARGV[0] eq "V"){
|
if($ARGV[0] eq "V"){
|
||||||
if($ARGV[1] > $current_version){
|
if($ARGV[1] > $current_version){
|
||||||
@ -36,8 +44,13 @@ print "Perl Version is " . $perl_version . "\n";
|
|||||||
if($perl_version > 5.12){ no warnings 'uninitialized'; }
|
if($perl_version > 5.12){ no warnings 'uninitialized'; }
|
||||||
no warnings;
|
no warnings;
|
||||||
|
|
||||||
|
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
|
||||||
|
|
||||||
|
#::: Cleanup staged folder...
|
||||||
|
rmtree("updates_staged/");
|
||||||
|
|
||||||
my $confile = "eqemu_config.xml"; #default
|
my $confile = "eqemu_config.xml"; #default
|
||||||
open(F, "<$confile") or die "Unable to open config: $confile\n";
|
open(F, "<$confile");
|
||||||
my $indb = 0;
|
my $indb = 0;
|
||||||
while(<F>) {
|
while(<F>) {
|
||||||
s/\r//g;
|
s/\r//g;
|
||||||
@ -97,12 +110,12 @@ if($path eq ""){
|
|||||||
mkdir('db_update');
|
mkdir('db_update');
|
||||||
|
|
||||||
#::: Check if db_version table exists...
|
#::: Check if db_version table exists...
|
||||||
if(trim(GetMySQLResult("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne ""){
|
if(trim(GetMySQLResult("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne "" && $db){
|
||||||
print GetMySQLResult("DROP TABLE db_version");
|
print GetMySQLResult("DROP TABLE db_version");
|
||||||
print "Old db_version table present, dropping...\n\n";
|
print "Old db_version table present, dropping...\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetMySQLResult("SHOW TABLES LIKE 'db_version'") eq ""){
|
if(GetMySQLResult("SHOW TABLES LIKE 'db_version'") eq "" && $db){
|
||||||
print GetMySQLResult("
|
print GetMySQLResult("
|
||||||
CREATE TABLE db_version (
|
CREATE TABLE db_version (
|
||||||
version int(11) DEFAULT '0'
|
version int(11) DEFAULT '0'
|
||||||
@ -123,24 +136,24 @@ if($bin_db_ver == $local_db_ver && $ARGV[0] eq "ran_from_start"){
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
print $console_output;
|
print $console_output if $db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($db){
|
||||||
|
print " Binary Database Version: (" . $bin_db_ver . ")\n";
|
||||||
|
print " Local Database Version: (" . $local_db_ver . ")\n\n";
|
||||||
|
|
||||||
print " Binary Database Version: (" . $bin_db_ver . ")\n";
|
#::: If World ran this script, and our version is up to date, continue...
|
||||||
print " Local Database Version: (" . $local_db_ver . ")\n\n";
|
if($bin_db_ver <= $local_db_ver && $ARGV[0] eq "ran_from_world"){
|
||||||
|
print " Database up to Date: Continuing World Bootup...\n";
|
||||||
|
print "============================================================\n";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
#::: If World ran this script, and our version is up to date, continue...
|
print "Retrieving latest database manifest...\n";
|
||||||
if($bin_db_ver <= $local_db_ver && $ARGV[0] eq "ran_from_world"){
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
||||||
print " Database up to Date: Continuing World Bootup...\n";
|
|
||||||
print "============================================================\n";
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print "Retrieving latest database manifest...\n";
|
|
||||||
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
|
||||||
# GetRemoteFile("https://dl.dropboxusercontent.com/u/50023467/dl/db_update_manifest.txt", "db_update/db_update_manifest.txt");
|
|
||||||
|
|
||||||
if($local_db_ver < $bin_db_ver && $ARGV[0] eq "ran_from_world"){
|
if($local_db_ver < $bin_db_ver && $ARGV[0] eq "ran_from_world"){
|
||||||
print "You have missing database updates, type 1 or 2 to backup your database before running them as recommended...\n\n";
|
print "You have missing database updates, type 1 or 2 to backup your database before running them as recommended...\n\n";
|
||||||
#::: Display Menu
|
#::: Display Menu
|
||||||
@ -152,6 +165,10 @@ else{
|
|||||||
ShowMenuPrompt();
|
ShowMenuPrompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub UpdateSelf{
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl", "eqemu_update.pl");
|
||||||
|
die "Rerun eqemu_update.pl";
|
||||||
|
}
|
||||||
|
|
||||||
sub ShowMenuPrompt {
|
sub ShowMenuPrompt {
|
||||||
my %dispatch = (
|
my %dispatch = (
|
||||||
@ -160,6 +177,11 @@ sub ShowMenuPrompt {
|
|||||||
3 => \&Run_Database_Check,
|
3 => \&Run_Database_Check,
|
||||||
4 => \&AA_Fetch,
|
4 => \&AA_Fetch,
|
||||||
5 => \&OpCodes_Fetch,
|
5 => \&OpCodes_Fetch,
|
||||||
|
6 => \&MapFiles_Fetch,
|
||||||
|
7 => \&Plugins_Fetch,
|
||||||
|
8 => \&QuestFiles_Fetch,
|
||||||
|
9 => \&LUA_Modules_Fetch,
|
||||||
|
20 => \&UpdateSelf,
|
||||||
0 => \&Exit,
|
0 => \&Exit,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -198,25 +220,30 @@ sub ShowMenuPrompt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub MenuOptions {
|
sub MenuOptions {
|
||||||
|
|
||||||
if(@total_updates){
|
if(@total_updates){
|
||||||
$option[3] = "Run pending REQUIRED updates... (" . scalar (@total_updates) . ")";
|
$option[3] = "Run pending REQUIRED updates... (" . scalar (@total_updates) . ")";
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$option[3] = "Check for pending REQUIRED Database updates
|
$option[3] = "Check and stage pending REQUIRED Database updates";
|
||||||
Stages updates for automatic upgrade...";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <<EO_MENU;
|
return <<EO_MENU;
|
||||||
Database Management Menu (Please Select):
|
EQEmu Update Utility Menu:
|
||||||
1) Backup Database - (Saves to Backups folder)
|
1) Backup Database - (Saves to Backups folder)
|
||||||
Ideal to perform before performing updates
|
|
||||||
2) Backup Database Compressed - (Saves to Backups folder)
|
2) Backup Database Compressed - (Saves to Backups folder)
|
||||||
Ideal to perform before performing updates
|
|
||||||
3) $option[3]
|
3) $option[3]
|
||||||
4) AAs - Get Latest AA's from PEQ (This deletes AA's already in the database)
|
4) AAs - Download Latest AA's from PEQ (This overwrites existing data)
|
||||||
5) OPCodes - Download latest opcodes from repository
|
5) OPCodes - Download latest opcodes
|
||||||
|
6) Maps - Download latest map and water files
|
||||||
|
7) Plugins - Download latest Perl plugins
|
||||||
|
8) Quests - Download latest PEQ quests and stage updates
|
||||||
|
9) LUA Modules - Download latest LUA Modules (Required for Lua)
|
||||||
|
20) Force update this script (Redownload)
|
||||||
0) Exit
|
0) Exit
|
||||||
|
|
||||||
|
Enter numbered option and press enter...
|
||||||
|
|
||||||
EO_MENU
|
EO_MENU
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +276,7 @@ sub Exit{ }
|
|||||||
#::: Returns Tab Delimited MySQL Result from Command Line
|
#::: Returns Tab Delimited MySQL Result from Command Line
|
||||||
sub GetMySQLResult{
|
sub GetMySQLResult{
|
||||||
my $run_query = $_[0];
|
my $run_query = $_[0];
|
||||||
|
if(!$db){ return; }
|
||||||
if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" $db -N -B -e "$run_query"`; }
|
if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" $db -N -B -e "$run_query"`; }
|
||||||
if($OS eq "Linux"){
|
if($OS eq "Linux"){
|
||||||
$run_query =~s/`//g;
|
$run_query =~s/`//g;
|
||||||
@ -258,6 +286,7 @@ sub GetMySQLResult{
|
|||||||
|
|
||||||
sub GetMySQLResultFromFile{
|
sub GetMySQLResultFromFile{
|
||||||
my $update_file = $_[0];
|
my $update_file = $_[0];
|
||||||
|
if(!$db){ return; }
|
||||||
if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; }
|
if($OS eq "Windows"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; }
|
||||||
if($OS eq "Linux"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; }
|
if($OS eq "Linux"){ return `"$path" --host $host --user $user --password="$pass" --force $db < $update_file`; }
|
||||||
}
|
}
|
||||||
@ -267,34 +296,67 @@ sub GetMySQLResultFromFile{
|
|||||||
sub GetRemoteFile{
|
sub GetRemoteFile{
|
||||||
my $URL = $_[0];
|
my $URL = $_[0];
|
||||||
my $Dest_File = $_[1];
|
my $Dest_File = $_[1];
|
||||||
|
my $content_type = $_[2];
|
||||||
|
|
||||||
|
#::: Build file path of the destination file so that we may check for the folder's existence and make it if necessary
|
||||||
|
if($Dest_File=~/\//i){
|
||||||
|
my @dir_path = split('/', $Dest_File);
|
||||||
|
$build_path = "";
|
||||||
|
$di = 0;
|
||||||
|
while($dir_path[$di]){
|
||||||
|
$build_path .= $dir_path[$di] . "/";
|
||||||
|
#::: If path does not exist, create the directory...
|
||||||
|
if (!-d $build_path) {
|
||||||
|
mkdir($build_path);
|
||||||
|
}
|
||||||
|
if(!$dir_path[$di + 2] && $dir_path[$di + 1]){
|
||||||
|
# print $actual_path . "\n";
|
||||||
|
$actual_path = $build_path;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
$di++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if($OS eq "Windows"){
|
if($OS eq "Windows"){
|
||||||
require LWP::UserAgent;
|
#::: For non-text type requests...
|
||||||
my $ua = LWP::UserAgent->new;
|
if($content_type == 1){
|
||||||
$ua->timeout(10);
|
use LWP::Simple qw(getstore);
|
||||||
$ua->env_proxy;
|
if(!getstore($URL, $Dest_File)){
|
||||||
my $response = $ua->get($URL);
|
print "Error, no connection or failed request...\n\n";
|
||||||
|
}
|
||||||
if ($response->is_success){
|
else{
|
||||||
open (FILE, '> ' . $Dest_File . '');
|
print " o URL: (" . $URL . ")\n";
|
||||||
print FILE $response->decoded_content;
|
print " o Saved: (" . $Dest_File . ") \n";
|
||||||
close (FILE);
|
}
|
||||||
print " URL: " . $URL . "\n";
|
|
||||||
print " Saved: " . $Dest_File . " \n";
|
|
||||||
}
|
}
|
||||||
else {
|
else{
|
||||||
print "Error, no connection to the internet...\n\n";
|
require LWP::UserAgent;
|
||||||
die $response->status_line;
|
my $ua = LWP::UserAgent->new;
|
||||||
|
$ua->timeout(10);
|
||||||
|
$ua->env_proxy;
|
||||||
|
my $response = $ua->get($URL);
|
||||||
|
|
||||||
|
if ($response->is_success){
|
||||||
|
open (FILE, '> ' . $Dest_File . '');
|
||||||
|
print FILE $response->decoded_content;
|
||||||
|
close (FILE);
|
||||||
|
print " o URL: (" . $URL . ")\n";
|
||||||
|
print " o Saved: (" . $Dest_File . ") \n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "Error, no connection or failed request...\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($OS eq "Linux"){
|
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 -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 $Dest_File $URL`;
|
$wget = `wget --no-check-certificate --quiet -O $Dest_File $URL`;
|
||||||
print " URL: " . $URL . "\n";
|
print " o URL: (" . $URL . ")\n";
|
||||||
print " Saved: " . $Dest_File . " \n";
|
print " o Saved: (" . $Dest_File . ") \n";
|
||||||
if($wget=~/unable to resolve/i){
|
if($wget=~/unable to resolve/i){
|
||||||
print "Error, no connection to the internet...\n\n";
|
print "Error, no connection or failed request...\n\n";
|
||||||
die;
|
#die;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,6 +371,11 @@ sub trim {
|
|||||||
|
|
||||||
#::: Fetch Latest PEQ AA's
|
#::: Fetch Latest PEQ AA's
|
||||||
sub AA_Fetch{
|
sub AA_Fetch{
|
||||||
|
if(!$db){
|
||||||
|
print "No database present, check your eqemu_config.xml for proper MySQL/MariaDB configuration...\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
print "Pulling down PEQ AA Tables...\n";
|
print "Pulling down PEQ AA Tables...\n";
|
||||||
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/peq_aa_tables.sql", "db_update/peq_aa_tables.sql");
|
GetRemoteFile("https://raw.githubusercontent.com/EQEmu/Server/master/utils/sql/peq_aa_tables.sql", "db_update/peq_aa_tables.sql");
|
||||||
print "\n\nInstalling AA Tables...\n";
|
print "\n\nInstalling AA Tables...\n";
|
||||||
@ -341,13 +408,292 @@ sub OpCodes_Fetch{
|
|||||||
|
|
||||||
print "\nDownloading (" . $opcodes{$loop}[0] . ") File: '" . $file_name . "'...\n\n";
|
print "\nDownloading (" . $opcodes{$loop}[0] . ") File: '" . $file_name . "'...\n\n";
|
||||||
GetRemoteFile($opcodes{$loop}[1], $file_name);
|
GetRemoteFile($opcodes{$loop}[1], $file_name);
|
||||||
$loop++;
|
$loop++;
|
||||||
}
|
}
|
||||||
print "\nDone...\n\n";
|
print "\nDone...\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub CopyFile{
|
||||||
|
$l_source_file = $_[0];
|
||||||
|
$l_dest_file = $_[1];
|
||||||
|
if($l_dest_file=~/\//i){
|
||||||
|
my @dir_path = split('/', $l_dest_file);
|
||||||
|
$build_path = "";
|
||||||
|
$di = 0;
|
||||||
|
while($dir_path[$di]){
|
||||||
|
$build_path .= $dir_path[$di] . "/";
|
||||||
|
#::: If path does not exist, create the directory...
|
||||||
|
if (!-d $build_path) {
|
||||||
|
mkdir($build_path);
|
||||||
|
}
|
||||||
|
if(!$dir_path[$di + 2] && $dir_path[$di + 1]){
|
||||||
|
# print $actual_path . "\n";
|
||||||
|
$actual_path = $build_path;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
$di++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy $l_source_file, $l_dest_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub MapFiles_Fetch{
|
||||||
|
print "\n --- Fetching Latest Maps --- \n";
|
||||||
|
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/Akkadius/EQEmuMaps/master/!eqemu_maps_manifest.txt", "updates_staged/eqemu_maps_manifest.txt");
|
||||||
|
|
||||||
|
#::: Get Data from manifest
|
||||||
|
open (FILE, "updates_staged/eqemu_maps_manifest.txt");
|
||||||
|
$i = 0;
|
||||||
|
while (<FILE>){
|
||||||
|
chomp;
|
||||||
|
$o = $_;
|
||||||
|
@manifest_map_data = split(',', $o);
|
||||||
|
if($manifest_map_data[0] ne ""){
|
||||||
|
$maps_manifest[$i] = [$manifest_map_data[0], $manifest_map_data[1]];
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#::: Download
|
||||||
|
$fc = 0;
|
||||||
|
for($m = 0; $m <= $i; $m++){
|
||||||
|
my $file_existing = $maps_manifest[$m][0];
|
||||||
|
my $file_existing_size = (stat $file_existing)[7];
|
||||||
|
if($file_existing_size != $maps_manifest[$m][1]){
|
||||||
|
print "Updating: '" . $maps_manifest[$m][0] . "'\n";
|
||||||
|
GetRemoteFile("https://raw.githubusercontent.com/Akkadius/EQEmuMaps/master/" . $maps_manifest[$m][0], $maps_manifest[$m][0], 1);
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($fc == 0){
|
||||||
|
print "\nNo Map Updates found... \n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub QuestFiles_Fetch{
|
||||||
|
if (!-e "updates_staged/Quests-Plugins-master/quests/") {
|
||||||
|
print "\n --- Fetching Latest Quests --- \n";
|
||||||
|
GetRemoteFile("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1);
|
||||||
|
print "\nFetched latest quests...\n";
|
||||||
|
mkdir('updates_staged');
|
||||||
|
UnZip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fc = 0;
|
||||||
|
use File::Find;
|
||||||
|
use File::Compare;
|
||||||
|
|
||||||
|
my @files;
|
||||||
|
my $start_dir = "updates_staged/Quests-Plugins-master/quests/";
|
||||||
|
find(
|
||||||
|
sub { push @files, $File::Find::name unless -d; },
|
||||||
|
$start_dir
|
||||||
|
);
|
||||||
|
for my $file (@files) {
|
||||||
|
if($file=~/\.pl|\.lua|\.ext/i){
|
||||||
|
$staged_file = $file;
|
||||||
|
$dest_file = $file;
|
||||||
|
$dest_file =~s/updates_staged\/Quests-Plugins-master\///g;
|
||||||
|
|
||||||
|
if (!-e $dest_file) {
|
||||||
|
CopyFile($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n";
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$diff = Diff($dest_file, $staged_file);
|
||||||
|
if($diff ne ""){
|
||||||
|
$backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file;
|
||||||
|
|
||||||
|
print $diff . "\n";
|
||||||
|
print "\nFile Different :: '" . $dest_file . "'\n";
|
||||||
|
print "\nDo you wish to update this Quest? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n";
|
||||||
|
my $input = <STDIN>;
|
||||||
|
if($input=~/N/i){}
|
||||||
|
else{
|
||||||
|
#::: Make a backup
|
||||||
|
CopyFile($dest_file, $backup_dest);
|
||||||
|
#::: Copy staged to running
|
||||||
|
copy($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n\n";
|
||||||
|
}
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($fc == 0){
|
||||||
|
print "\nNo Quest Updates found... \n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub LUA_Modules_Fetch{
|
||||||
|
if (!-e "updates_staged/Quests-Plugins-master/quests/lua_modules/") {
|
||||||
|
print "\n --- Fetching Latest LUA Modules --- \n";
|
||||||
|
GetRemoteFile("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1);
|
||||||
|
print "\nFetched latest LUA Modules...\n";
|
||||||
|
UnZip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fc = 0;
|
||||||
|
use File::Find;
|
||||||
|
use File::Compare;
|
||||||
|
|
||||||
|
my @files;
|
||||||
|
my $start_dir = "updates_staged/Quests-Plugins-master/quests/lua_modules/";
|
||||||
|
find(
|
||||||
|
sub { push @files, $File::Find::name unless -d; },
|
||||||
|
$start_dir
|
||||||
|
);
|
||||||
|
for my $file (@files) {
|
||||||
|
if($file=~/\.pl|\.lua|\.ext/i){
|
||||||
|
$staged_file = $file;
|
||||||
|
$dest_file = $file;
|
||||||
|
$dest_file =~s/updates_staged\/Quests-Plugins-master\/quests\///g;
|
||||||
|
|
||||||
|
if (!-e $dest_file) {
|
||||||
|
CopyFile($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n";
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$diff = Diff($dest_file, $staged_file);
|
||||||
|
if($diff ne ""){
|
||||||
|
$backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file;
|
||||||
|
print $diff . "\n";
|
||||||
|
print "\nFile Different :: '" . $dest_file . "'\n";
|
||||||
|
print "\nDo you wish to update this LUA Module? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n";
|
||||||
|
my $input = <STDIN>;
|
||||||
|
if($input=~/N/i){}
|
||||||
|
else{
|
||||||
|
#::: Make a backup
|
||||||
|
CopyFile($dest_file, $backup_dest);
|
||||||
|
#::: Copy staged to running
|
||||||
|
copy($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n\n";
|
||||||
|
}
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($fc == 0){
|
||||||
|
print "\nNo LUA Modules Updates found... \n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Plugins_Fetch{
|
||||||
|
if (!-e "updates_staged/Quests-Plugins-master/plugins/") {
|
||||||
|
print "\n --- Fetching Latest Plugins --- \n";
|
||||||
|
GetRemoteFile("https://github.com/EQEmu/Quests-Plugins/archive/master.zip", "updates_staged/Quests-Plugins-master.zip", 1);
|
||||||
|
print "\nFetched latest plugins...\n";
|
||||||
|
UnZip('updates_staged/Quests-Plugins-master.zip', 'updates_staged/');
|
||||||
|
}
|
||||||
|
|
||||||
|
$fc = 0;
|
||||||
|
use File::Find;
|
||||||
|
use File::Compare;
|
||||||
|
|
||||||
|
my @files;
|
||||||
|
my $start_dir = "updates_staged/Quests-Plugins-master/plugins/";
|
||||||
|
find(
|
||||||
|
sub { push @files, $File::Find::name unless -d; },
|
||||||
|
$start_dir
|
||||||
|
);
|
||||||
|
for my $file (@files) {
|
||||||
|
if($file=~/\.pl|\.lua|\.ext/i){
|
||||||
|
$staged_file = $file;
|
||||||
|
$dest_file = $file;
|
||||||
|
$dest_file =~s/updates_staged\/Quests-Plugins-master\///g;
|
||||||
|
|
||||||
|
if (!-e $dest_file) {
|
||||||
|
CopyFile($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n";
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$diff = Diff($dest_file, $staged_file);
|
||||||
|
if($diff ne ""){
|
||||||
|
$backup_dest = "updates_backups/" . $time_stamp . "/" . $dest_file;
|
||||||
|
print $diff . "\n";
|
||||||
|
print "\nFile Different :: '" . $dest_file . "'\n";
|
||||||
|
print "\nDo you wish to update this Plugin? '" . $dest_file . "' [Yes (Enter) - No (N)] \nA backup will be found in '" . $backup_dest . "'\n";
|
||||||
|
my $input = <STDIN>;
|
||||||
|
if($input=~/N/i){}
|
||||||
|
else{
|
||||||
|
#::: Make a backup
|
||||||
|
CopyFile($dest_file, $backup_dest);
|
||||||
|
#::: Copy staged to running
|
||||||
|
copy($staged_file, $dest_file);
|
||||||
|
print "Installing :: '" . $dest_file . "'\n\n";
|
||||||
|
}
|
||||||
|
$fc++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if($fc == 0){
|
||||||
|
print "\nNo Plugin Updates found... \n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Diff{
|
||||||
|
$file_1 = $_[0];
|
||||||
|
$file_2 = $_[1];
|
||||||
|
if($OS eq "Windows"){
|
||||||
|
eval "use Text::Diff";
|
||||||
|
$diff = diff($file_1, $file_2, { STYLE => "Unified" });
|
||||||
|
return $diff;
|
||||||
|
}
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
# print 'diff -u "$file_1" "$file_2"' . "\n";
|
||||||
|
return `diff -u "$file_1" "$file_2"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub UnZip{
|
||||||
|
$archive_to_unzip = $_[0];
|
||||||
|
$dest_folder = $_[1];
|
||||||
|
|
||||||
|
if($OS eq "Windows"){
|
||||||
|
eval "use Archive::Zip qw( :ERROR_CODES :CONSTANTS )";
|
||||||
|
my $zip = Archive::Zip->new();
|
||||||
|
unless ( $zip->read($archive_to_unzip) == AZ_OK ) {
|
||||||
|
die 'read error';
|
||||||
|
}
|
||||||
|
print "Extracting...\n";
|
||||||
|
$zip->extractTree('', $dest_folder);
|
||||||
|
}
|
||||||
|
if($OS eq "Linux"){
|
||||||
|
print `unzip -o "$archive_to_unzip" -d "$dest_folder"`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub AreFileSizesDifferent{
|
||||||
|
$file_1 = $_[0];
|
||||||
|
$file_2 = $_[1];
|
||||||
|
my $file_1 = (stat $file_1)[7];
|
||||||
|
my $file_2 = (stat $file_2)[7];
|
||||||
|
# print $file_1 . " :: " . $file_2 . "\n";
|
||||||
|
if($file_1 != $file_2){
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#::: Responsible for Database Upgrade Routines
|
#::: Responsible for Database Upgrade Routines
|
||||||
sub Run_Database_Check{
|
sub Run_Database_Check{
|
||||||
|
|
||||||
|
if(!$db){
|
||||||
|
print "No database present, check your eqemu_config.xml for proper MySQL/MariaDB configuration...\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#::: Run 2 - Running pending updates...
|
#::: Run 2 - Running pending updates...
|
||||||
if(defined(@total_updates)){
|
if(defined(@total_updates)){
|
||||||
@total_updates = sort @total_updates;
|
@total_updates = sort @total_updates;
|
||||||
|
|||||||
@ -3650,6 +3650,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
|||||||
(frontal_stun_resist && zone->random.Roll(frontal_stun_resist))) &&
|
(frontal_stun_resist && zone->random.Roll(frontal_stun_resist))) &&
|
||||||
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) {
|
!attacker->BehindMob(this, attacker->GetX(), attacker->GetY())) {
|
||||||
Log.Out(Logs::Detail, Logs::Combat, "Frontal stun resisted. %d chance.", frontal_stun_resist);
|
Log.Out(Logs::Detail, Logs::Combat, "Frontal stun resisted. %d chance.", frontal_stun_resist);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Normal stun resist check.
|
// Normal stun resist check.
|
||||||
if (stun_resist && zone->random.Roll(stun_resist)) {
|
if (stun_resist && zone->random.Roll(stun_resist)) {
|
||||||
@ -3994,7 +3995,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const ItemData *weapon, Mob *on, u
|
|||||||
// We can proc once here, either weapon or one aug
|
// We can proc once here, either weapon or one aug
|
||||||
bool proced = false; // silly bool to prevent augs from going if weapon does
|
bool proced = false; // silly bool to prevent augs from going if weapon does
|
||||||
skillinuse = GetSkillByItemType(weapon->ItemType);
|
skillinuse = GetSkillByItemType(weapon->ItemType);
|
||||||
if (weapon->Proc.Type == ET_CombatProc) {
|
if (weapon->Proc.Type == ET_CombatProc && IsValidSpell(weapon->Proc.Effect)) {
|
||||||
float WPC = ProcChance * (100.0f + // Proc chance for this weapon
|
float WPC = ProcChance * (100.0f + // Proc chance for this weapon
|
||||||
static_cast<float>(weapon->ProcRate)) / 100.0f;
|
static_cast<float>(weapon->ProcRate)) / 100.0f;
|
||||||
if (zone->random.Roll(WPC)) { // 255 dex = 0.084 chance of proc. No idea what this number should be really.
|
if (zone->random.Roll(WPC)) { // 255 dex = 0.084 chance of proc. No idea what this number should be really.
|
||||||
@ -4032,7 +4033,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const ItemData *weapon, Mob *on, u
|
|||||||
if (!aug)
|
if (!aug)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (aug->Proc.Type == ET_CombatProc) {
|
if (aug->Proc.Type == ET_CombatProc && IsValidSpell(aug->Proc.Effect)) {
|
||||||
float APC = ProcChance * (100.0f + // Proc chance for this aug
|
float APC = ProcChance * (100.0f + // Proc chance for this aug
|
||||||
static_cast<float>(aug->ProcRate)) / 100.0f;
|
static_cast<float>(aug->ProcRate)) / 100.0f;
|
||||||
if (zone->random.Roll(APC)) {
|
if (zone->random.Roll(APC)) {
|
||||||
|
|||||||
@ -1291,7 +1291,7 @@ protected:
|
|||||||
bool client_data_loaded;
|
bool client_data_loaded;
|
||||||
|
|
||||||
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
int16 GetFocusEffect(focusType type, uint16 spell_id);
|
||||||
int16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
uint16 GetSympatheticFocusEffect(focusType type, uint16 spell_id);
|
||||||
|
|
||||||
Mob* bind_sight_target;
|
Mob* bind_sight_target;
|
||||||
|
|
||||||
|
|||||||
@ -2607,7 +2607,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app)
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item_id == 0) {
|
if (item_id == 0 || reclaim->count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13319,6 +13319,10 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
|
|||||||
if (database.GetItem(gis->Items[i])) {
|
if (database.GetItem(gis->Items[i])) {
|
||||||
database.SaveTraderItem(this->CharacterID(), gis->Items[i], gis->SerialNumber[i],
|
database.SaveTraderItem(this->CharacterID(), gis->Items[i], gis->SerialNumber[i],
|
||||||
gis->Charges[i], ints->ItemCost[i], i);
|
gis->Charges[i], ints->ItemCost[i], i);
|
||||||
|
|
||||||
|
auto inst = FindTraderItemBySerialNumber(gis->SerialNumber[i]);
|
||||||
|
if(inst)
|
||||||
|
inst->SetPrice(ints->ItemCost[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//return; //sony doesnt memset so assume done on first bad item
|
//return; //sony doesnt memset so assume done on first bad item
|
||||||
|
|||||||
@ -3429,6 +3429,16 @@ XS(XS__clear_npctype_cache)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__reloadzonestaticdata);
|
||||||
|
XS(XS__reloadzonestaticdata)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
|
||||||
|
quest_manager.ReloadZoneStaticData();
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__qs_send_query);
|
XS(XS__qs_send_query);
|
||||||
XS(XS__qs_send_query)
|
XS(XS__qs_send_query)
|
||||||
{
|
{
|
||||||
@ -3686,6 +3696,7 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||||
newXS(strcpy(buf, "rain"), XS__rain, file);
|
newXS(strcpy(buf, "rain"), XS__rain, file);
|
||||||
newXS(strcpy(buf, "rebind"), XS__rebind, file);
|
newXS(strcpy(buf, "rebind"), XS__rebind, file);
|
||||||
|
newXS(strcpy(buf, "reloadzonestaticdata"), XS__reloadzonestaticdata, file);
|
||||||
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
newXS(strcpy(buf, "removetitle"), XS__removetitle, file);
|
||||||
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
newXS(strcpy(buf, "repopzone"), XS__repopzone, file);
|
||||||
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
newXS(strcpy(buf, "resettaskactivity"), XS__resettaskactivity, file);
|
||||||
|
|||||||
@ -1242,6 +1242,10 @@ void lua_clear_npctype_cache(int npctype_id) {
|
|||||||
quest_manager.ClearNPCTypeCache(npctype_id);
|
quest_manager.ClearNPCTypeCache(npctype_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_reloadzonestaticdata() {
|
||||||
|
quest_manager.ReloadZoneStaticData();
|
||||||
|
}
|
||||||
|
|
||||||
double lua_clock() {
|
double lua_clock() {
|
||||||
timeval read_time;
|
timeval read_time;
|
||||||
gettimeofday(&read_time, nullptr);
|
gettimeofday(&read_time, nullptr);
|
||||||
@ -1592,6 +1596,7 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("enable_recipe", &lua_enable_recipe),
|
luabind::def("enable_recipe", &lua_enable_recipe),
|
||||||
luabind::def("disable_recipe", &lua_disable_recipe),
|
luabind::def("disable_recipe", &lua_disable_recipe),
|
||||||
luabind::def("clear_npctype_cache", &lua_clear_npctype_cache),
|
luabind::def("clear_npctype_cache", &lua_clear_npctype_cache),
|
||||||
|
luabind::def("reloadzonestaticdata", &lua_reloadzonestaticdata),
|
||||||
luabind::def("clock", &lua_clock),
|
luabind::def("clock", &lua_clock),
|
||||||
luabind::def("create_npc", &lua_create_npc),
|
luabind::def("create_npc", &lua_create_npc),
|
||||||
luabind::def("debug", (void(*)(std::string))&lua_debug),
|
luabind::def("debug", (void(*)(std::string))&lua_debug),
|
||||||
|
|||||||
53
zone/mob.cpp
53
zone/mob.cpp
@ -3616,36 +3616,41 @@ bool Mob::TryFadeEffect(int slot)
|
|||||||
|
|
||||||
void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
|
void Mob::TrySympatheticProc(Mob *target, uint32 spell_id)
|
||||||
{
|
{
|
||||||
if(target == nullptr || !IsValidSpell(spell_id))
|
if(target == nullptr || !IsValidSpell(spell_id) || !IsClient())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int focus_spell = CastToClient()->GetSympatheticFocusEffect(focusSympatheticProc,spell_id);
|
uint16 focus_spell = CastToClient()->GetSympatheticFocusEffect(focusSympatheticProc,spell_id);
|
||||||
|
|
||||||
if(IsValidSpell(focus_spell)){
|
if(!IsValidSpell(focus_spell))
|
||||||
int focus_trigger = spells[focus_spell].base2[0];
|
return;
|
||||||
// For beneficial spells, if the triggered spell is also beneficial then proc it on the target
|
|
||||||
// if the triggered spell is detrimental, then it will trigger on the caster(ie cursed items)
|
|
||||||
if(IsBeneficialSpell(spell_id))
|
|
||||||
{
|
|
||||||
if(IsBeneficialSpell(focus_trigger))
|
|
||||||
SpellFinished(focus_trigger, target);
|
|
||||||
|
|
||||||
else
|
uint16 focus_trigger = GetSympatheticSpellProcID(focus_spell);
|
||||||
SpellFinished(focus_trigger, this, 10, 0, -1, spells[focus_trigger].ResistDiff);
|
|
||||||
}
|
|
||||||
// For detrimental spells, if the triggered spell is beneficial, then it will land on the caster
|
|
||||||
// if the triggered spell is also detrimental, then it will land on the target
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(IsBeneficialSpell(focus_trigger))
|
|
||||||
SpellFinished(focus_trigger, this);
|
|
||||||
|
|
||||||
else
|
if(!IsValidSpell(focus_trigger))
|
||||||
SpellFinished(focus_trigger, target, 10, 0, -1, spells[focus_trigger].ResistDiff);
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
|
// For beneficial spells, if the triggered spell is also beneficial then proc it on the target
|
||||||
}
|
// if the triggered spell is detrimental, then it will trigger on the caster(ie cursed items)
|
||||||
|
if(IsBeneficialSpell(spell_id))
|
||||||
|
{
|
||||||
|
if(IsBeneficialSpell(focus_trigger))
|
||||||
|
SpellFinished(focus_trigger, target);
|
||||||
|
|
||||||
|
else
|
||||||
|
SpellFinished(focus_trigger, this, 10, 0, -1, spells[focus_trigger].ResistDiff);
|
||||||
|
}
|
||||||
|
// For detrimental spells, if the triggered spell is beneficial, then it will land on the caster
|
||||||
|
// if the triggered spell is also detrimental, then it will land on the target
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(IsBeneficialSpell(focus_trigger))
|
||||||
|
SpellFinished(focus_trigger, this);
|
||||||
|
|
||||||
|
else
|
||||||
|
SpellFinished(focus_trigger, target, 10, 0, -1, spells[focus_trigger].ResistDiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckNumHitsRemaining(NumHit::MatchingSpells, -1, focus_spell);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
|
int32 Mob::GetItemStat(uint32 itemid, const char *identifier)
|
||||||
|
|||||||
@ -1067,6 +1067,8 @@ protected:
|
|||||||
void PrintRoute();
|
void PrintRoute();
|
||||||
|
|
||||||
virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0);
|
virtual float GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 ItemProcRate = 0);
|
||||||
|
int16 GetSympatheticSpellProcRate(uint16 spell_id);
|
||||||
|
uint16 GetSympatheticSpellProcID(uint16 spell_id);
|
||||||
|
|
||||||
enum {MAX_PROCS = 4};
|
enum {MAX_PROCS = 4};
|
||||||
tProc PermaProcs[MAX_PROCS];
|
tProc PermaProcs[MAX_PROCS];
|
||||||
|
|||||||
@ -1839,7 +1839,7 @@ void NPC::PetOnSpawn(NewSpawn_Struct* ns)
|
|||||||
if(swarmOwner->IsClient())
|
if(swarmOwner->IsClient())
|
||||||
{
|
{
|
||||||
SetPetOwnerClient(true); //Simple flag to determine if pet belongs to a client
|
SetPetOwnerClient(true); //Simple flag to determine if pet belongs to a client
|
||||||
SetAllowBeneficial(1);//Allow temp pets to receive buffs and heals if owner is client.
|
SetAllowBeneficial(true);//Allow temp pets to receive buffs and heals if owner is client.
|
||||||
//This will allow CLIENT swarm pets NOT to be targeted with F8.
|
//This will allow CLIENT swarm pets NOT to be targeted with F8.
|
||||||
ns->spawn.targetable_with_hotkey = 0;
|
ns->spawn.targetable_with_hotkey = 0;
|
||||||
no_target_hotkey = 1;
|
no_target_hotkey = 1;
|
||||||
@ -2258,8 +2258,6 @@ bool NPC::CanTalk()
|
|||||||
0,0,420,0,0,0,0,425,0,0,0,0,0,0,0,433,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
0,0,420,0,0,0,0,425,0,0,0,0,0,0,0,433,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
0,0,0,0,0,458,0,0,0,0,0,0,0,0,467,0,0,470,0,0,473};
|
0,0,0,0,0,458,0,0,0,0,0,0,0,0,467,0,0,470,0,0,473};
|
||||||
|
|
||||||
int talk_check = TalkRace[GetRace() - 1];
|
|
||||||
|
|
||||||
if (TalkRace[GetRace() - 1] > 0)
|
if (TalkRace[GetRace() - 1] > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@ -1478,6 +1478,11 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
|||||||
{
|
{
|
||||||
for(uint32 i = 0; i < Head.PathNodeCount; ++i)
|
for(uint32 i = 0; i < Head.PathNodeCount; ++i)
|
||||||
{
|
{
|
||||||
|
if(PathNodes[i].id - new_id > 1) {
|
||||||
|
new_id = PathNodes[i].id - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(PathNodes[i].id > new_id)
|
if(PathNodes[i].id > new_id)
|
||||||
new_id = PathNodes[i].id;
|
new_id = PathNodes[i].id;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2530,6 +2530,32 @@ XS(XS_NPC_ClearLastName)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS_NPC_GetCombatState); /* prototype to pass -Wmissing-prototypes */
|
||||||
|
XS(XS_NPC_GetCombatState)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1)
|
||||||
|
Perl_croak(aTHX_ "Usage: NPC::GetCombatState(THIS)");
|
||||||
|
{
|
||||||
|
NPC * THIS;
|
||||||
|
bool RETVAL;
|
||||||
|
|
||||||
|
if (sv_derived_from(ST(0), "NPC")) {
|
||||||
|
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||||
|
THIS = INT2PTR(NPC *,tmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type NPC");
|
||||||
|
if(THIS == nullptr)
|
||||||
|
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||||
|
|
||||||
|
RETVAL = THIS->GetCombatEvent();
|
||||||
|
ST(0) = boolSV(RETVAL);
|
||||||
|
sv_2mortal(ST(0));
|
||||||
|
}
|
||||||
|
XSRETURN(1);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
#endif
|
#endif
|
||||||
@ -2643,6 +2669,7 @@ XS(boot_NPC)
|
|||||||
newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$");
|
newXSproto(strcpy(buf, "RemoveDefensiveProc"), XS_NPC_RemoveDefensiveProc, file, "$$");
|
||||||
newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$");
|
newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$");
|
||||||
newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$");
|
newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$");
|
||||||
|
newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$");
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2927,6 +2927,13 @@ void QuestManager::ClearNPCTypeCache(int npctype_id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::ReloadZoneStaticData()
|
||||||
|
{
|
||||||
|
if (zone) {
|
||||||
|
zone->ReloadStaticData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Client *QuestManager::GetInitiator() const {
|
Client *QuestManager::GetInitiator() const {
|
||||||
if(!quests_running_.empty()) {
|
if(!quests_running_.empty()) {
|
||||||
running_quest e = quests_running_.top();
|
running_quest e = quests_running_.top();
|
||||||
|
|||||||
@ -249,6 +249,7 @@ public:
|
|||||||
bool EnableRecipe(uint32 recipe_id);
|
bool EnableRecipe(uint32 recipe_id);
|
||||||
bool DisableRecipe(uint32 recipe_id);
|
bool DisableRecipe(uint32 recipe_id);
|
||||||
void ClearNPCTypeCache(int npctype_id);
|
void ClearNPCTypeCache(int npctype_id);
|
||||||
|
void ReloadZoneStaticData();
|
||||||
|
|
||||||
Client *GetInitiator() const;
|
Client *GetInitiator() const;
|
||||||
NPC *GetNPC() const;
|
NPC *GetNPC() const;
|
||||||
|
|||||||
@ -5177,13 +5177,12 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
|||||||
return(value*lvlModifier/100);
|
return(value*lvlModifier/100);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
||||||
|
|
||||||
if (IsBardSong(spell_id))
|
if (IsBardSong(spell_id))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint16 proc_spellid = 0;
|
uint16 proc_spellid = 0;
|
||||||
uint8 MAX_SYMPATHETIC = 10;
|
|
||||||
float ProcChance = 0.0f;
|
float ProcChance = 0.0f;
|
||||||
|
|
||||||
std::vector<int> SympatheticProcList;
|
std::vector<int> SympatheticProcList;
|
||||||
@ -5195,7 +5194,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
|
|
||||||
for(int x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::EQUIPMENT_END; x++)
|
for(int x = EmuConstants::EQUIPMENT_BEGIN; x <= EmuConstants::EQUIPMENT_END; x++)
|
||||||
{
|
{
|
||||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC)
|
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TempItem = nullptr;
|
TempItem = nullptr;
|
||||||
@ -5215,7 +5214,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
|
|
||||||
for (int y = AUG_BEGIN; y < EmuConstants::ITEM_COMMON_SIZE; ++y)
|
for (int y = AUG_BEGIN; y < EmuConstants::ITEM_COMMON_SIZE; ++y)
|
||||||
{
|
{
|
||||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC)
|
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ItemInst *aug = nullptr;
|
ItemInst *aug = nullptr;
|
||||||
@ -5243,18 +5242,18 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
int buff_max = GetMaxTotalSlots();
|
int buff_max = GetMaxTotalSlots();
|
||||||
for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
|
for (buff_slot = 0; buff_slot < buff_max; buff_slot++) {
|
||||||
|
|
||||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC)
|
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
focusspellid = buffs[buff_slot].spellid;
|
focusspellid = buffs[buff_slot].spellid;
|
||||||
if (IsValidSpell(focusspellid))
|
if (!IsValidSpell(focusspellid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
proc_spellid = CalcFocusEffect(type, focusspellid, spell_id);
|
proc_spellid = CalcFocusEffect(type, focusspellid, spell_id);
|
||||||
|
|
||||||
if (IsValidSpell(proc_spellid)){
|
if (IsValidSpell(proc_spellid)){
|
||||||
|
|
||||||
ProcChance = GetSympatheticProcChances(spell_id, spells[focusspellid].base[0]);
|
ProcChance = GetSympatheticProcChances(spell_id, GetSympatheticSpellProcRate(spell_id));
|
||||||
if(zone->random.Roll(ProcChance))
|
if(zone->random.Roll(ProcChance))
|
||||||
SympatheticProcList.push_back(proc_spellid);
|
SympatheticProcList.push_back(proc_spellid);
|
||||||
}
|
}
|
||||||
@ -5275,7 +5274,7 @@ int16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
|||||||
if (aa_AA < 1 || aa_value < 1)
|
if (aa_AA < 1 || aa_value < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (SympatheticProcList.size() > MAX_SYMPATHETIC)
|
if (SympatheticProcList.size() > MAX_SYMPATHETIC_PROCS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
proc_spellid = CalcAAFocus(type, aa_AA, spell_id);
|
proc_spellid = CalcAAFocus(type, aa_AA, spell_id);
|
||||||
@ -5930,6 +5929,26 @@ float Mob::GetSympatheticProcChances(uint16 spell_id, int16 ProcRateMod, int32 I
|
|||||||
return ProcChance;
|
return ProcChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16 Mob::GetSympatheticSpellProcRate(uint16 spell_id)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < EFFECT_COUNT; i++){
|
||||||
|
if (spells[spell_id].effectid[i] == SE_SympatheticProc)
|
||||||
|
return spells[spell_id].base[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 Mob::GetSympatheticSpellProcID(uint16 spell_id)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < EFFECT_COUNT; i++){
|
||||||
|
if (spells[spell_id].effectid[i] == SE_SympatheticProc)
|
||||||
|
return spells[spell_id].base2[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool Mob::DoHPToManaCovert(uint16 mana_cost)
|
bool Mob::DoHPToManaCovert(uint16 mana_cost)
|
||||||
{
|
{
|
||||||
if (spellbonuses.HPToManaConvert){
|
if (spellbonuses.HPToManaConvert){
|
||||||
|
|||||||
@ -2151,7 +2151,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
|||||||
// it can affect up to 7 people if the targeted group is not our own
|
// it can affect up to 7 people if the targeted group is not our own
|
||||||
|
|
||||||
// Allow pets who cast group spells to affect the group.
|
// Allow pets who cast group spells to affect the group.
|
||||||
if (spell_target->IsPetOwnerClient()){
|
if (spell_target->IsPetOwnerClient() && IsPetOwnerClient()){
|
||||||
Mob* owner = spell_target->GetOwner();
|
Mob* owner = spell_target->GetOwner();
|
||||||
|
|
||||||
if (owner)
|
if (owner)
|
||||||
|
|||||||
@ -1583,6 +1583,8 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tbs->Price = BuyItem->GetPrice();
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Trading, "Buyitem: Name: %s, IsStackable: %i, Requested Quantity: %i, Charges on Item %i",
|
Log.Out(Logs::Detail, Logs::Trading, "Buyitem: Name: %s, IsStackable: %i, Requested Quantity: %i, Charges on Item %i",
|
||||||
BuyItem->GetItem()->Name, BuyItem->IsStackable(), tbs->Quantity, BuyItem->GetCharges());
|
BuyItem->GetItem()->Name, BuyItem->IsStackable(), tbs->Quantity, BuyItem->GetCharges());
|
||||||
// If the item is not stackable, then we can only be buying one of them.
|
// If the item is not stackable, then we can only be buying one of them.
|
||||||
@ -1650,7 +1652,12 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic
|
|||||||
outtbs->Price = TotalCost;
|
outtbs->Price = TotalCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->TakeMoneyFromPP(TotalCost);
|
if(!TakeMoneyFromPP(TotalCost)) {
|
||||||
|
database.SetHackerFlag(account_name, name, "Attempted to buy something in bazaar but did not have enough money.");
|
||||||
|
TradeRequestFailed(app);
|
||||||
|
safe_delete(outapp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Log.Out(Logs::Detail, Logs::Trading, "Customer Paid: %d in Copper", TotalCost);
|
Log.Out(Logs::Detail, Logs::Trading, "Customer Paid: %d in Copper", TotalCost);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user