mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-01 06:13:54 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into bots_updater
This commit is contained in:
commit
531cbf79f5
@ -493,7 +493,7 @@ bool Database::CheckDatabaseConversions() {
|
||||
/* Check for a new version of this script, the arg passed
|
||||
would have to be higher than the copy they have downloaded
|
||||
locally and they will re fetch */
|
||||
system("perl eqemu_update.pl V 10");
|
||||
system("perl eqemu_update.pl V 11");
|
||||
|
||||
/* Run Automatic Database Upgrade Script */
|
||||
system("perl eqemu_update.pl ran_from_world");
|
||||
|
||||
@ -1659,27 +1659,29 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
||||
sp[tempid].directional_start = static_cast<float>(atoi(row[194]));
|
||||
sp[tempid].directional_end = static_cast<float>(atoi(row[195]));
|
||||
sp[tempid].sneak = atoi(row[196]) != 0;
|
||||
sp[tempid].not_extendable = atoi(row[197]) != 0;
|
||||
sp[tempid].not_focusable = atoi(row[197]) != 0;
|
||||
sp[tempid].no_detrimental_spell_aggro = atoi(row[198]) != 0;
|
||||
sp[tempid].suspendable = atoi(row[200]) != 0;
|
||||
sp[tempid].viral_range = atoi(row[201]);
|
||||
sp[tempid].songcap = atoi(row[202]);
|
||||
sp[tempid].no_block = atoi(row[205]);
|
||||
sp[tempid].spellgroup=atoi(row[207]);
|
||||
sp[tempid].rank = atoi(row[208]);
|
||||
sp[tempid].powerful_flag=atoi(row[209]);
|
||||
sp[tempid].no_resist=atoi(row[209]);
|
||||
sp[tempid].CastRestriction = atoi(row[211]);
|
||||
sp[tempid].AllowRest = atoi(row[212]) != 0;
|
||||
sp[tempid].InCombat = atoi(row[213]) != 0;
|
||||
sp[tempid].OutofCombat = atoi(row[214]) != 0;
|
||||
sp[tempid].override_crit_chance = atoi(row[217]);
|
||||
sp[tempid].aemaxtargets = atoi(row[218]);
|
||||
sp[tempid].maxtargets = atoi(row[219]);
|
||||
sp[tempid].no_heal_damage_item_mod = atoi(row[219]);
|
||||
sp[tempid].persistdeath = atoi(row[224]) != 0;
|
||||
sp[tempid].min_dist = atof(row[227]);
|
||||
sp[tempid].min_dist_mod = atof(row[228]);
|
||||
sp[tempid].max_dist = atof(row[229]);
|
||||
sp[tempid].max_dist_mod = atof(row[230]);
|
||||
sp[tempid].min_range = static_cast<float>(atoi(row[231]));
|
||||
sp[tempid].no_remove = atoi(row[232]) != 0;
|
||||
sp[tempid].DamageShieldType = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1092,6 +1092,14 @@ bool DetrimentalSpellAllowsRest(uint16 spell_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NoDetrimentalSpellAggro(uint16 spell_id)
|
||||
{
|
||||
if (IsValidSpell(spell_id))
|
||||
return spells[spell_id].no_detrimental_spell_aggro;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetNimbusEffect(uint16 spell_id)
|
||||
{
|
||||
if (IsValidSpell(spell_id))
|
||||
|
||||
@ -381,7 +381,7 @@ typedef enum {
|
||||
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance.
|
||||
#define SE_TwoHandBash 226 // *not implemented as bonus
|
||||
#define SE_ReduceSkillTimer 227 // implemented
|
||||
#define SE_ReduceFallDamage 228 // not implented as bonus - reduce the damage that you take from falling
|
||||
#define SE_ReduceFallDamage 228 // implented - reduce the damage that you take from falling
|
||||
#define SE_PersistantCasting 229 // implemented
|
||||
#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
|
||||
#define SE_StunBashChance 231 // implemented - increase chance to stun from bash.
|
||||
@ -400,7 +400,7 @@ typedef enum {
|
||||
#define SE_RootBreakChance 244 // implemented[AA] reduce the chance that your root will break.
|
||||
#define SE_TrapCircumvention 245 // *not implemented[AA] - decreases the chance that you will set off a trap when opening a chest
|
||||
#define SE_SetBreathLevel 246 // *not implemented as bonus
|
||||
#define SE_RaiseSkillCap 247 // *not implemented[AA] - adds skill over the skill cap.
|
||||
#define SE_RaiseSkillCap 247 // implemented[AA] - adds skill over the skill cap.
|
||||
#define SE_SecondaryForte 248 // not implemented as bonus(gives you a 2nd specialize skill that can go past 50 to 100)
|
||||
#define SE_SecondaryDmgInc 249 // implemented[AA] Allows off hand weapon to recieve a damage bonus (Sinister Strikes)
|
||||
#define SE_SpellProcChance 250 // implemented - Increase chance to proc from melee proc spells (ie Spirit of Panther)
|
||||
@ -409,19 +409,19 @@ typedef enum {
|
||||
#define SE_FrontalBackstabMinDmg 253 // implemented[AA] - allow a frontal backstab for mininum damage.
|
||||
#define SE_Blank 254 // implemented
|
||||
#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield
|
||||
#define SE_ShroudofStealth 256 // not implemented as bonus - rogue improved invs
|
||||
#define SE_ShroudofStealth 256 // implemented
|
||||
#define SE_PetDiscipline 257 // not implemented as bonus - /pet hold
|
||||
#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
|
||||
#define SE_SongModCap 261 // implemented[AA] - Song Mod cap increase (no longer used on live)
|
||||
#define SE_RaiseStatCap 262 // implemented
|
||||
#define SE_TradeSkillMastery 263 // not implemented - lets you raise more than one tradeskill above master.
|
||||
#define SE_TradeSkillMastery 263 // implemented - lets you raise more than one tradeskill above master.
|
||||
#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_ReduceTradeskillFail 268 // *not implemented? - reduces chance to fail with given tradeskill by a percent chance
|
||||
#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)
|
||||
#define SE_BaseMovementSpeed 271 // implemented[AA] - mods basemove speed, doesn't stack with other move mods
|
||||
@ -478,7 +478,7 @@ typedef enum {
|
||||
#define SE_GateToHomeCity 322 // implemented
|
||||
#define SE_DefensiveProc 323 // implemented
|
||||
#define SE_HPToMana 324 // implemented
|
||||
//#define SE_ChanceInvsBreakToAoE 325 // *not implemented[AA] - [AA Nerves of Steel] increasing chance to remain hidden when they are an indirect target of an AoE spell.
|
||||
//#define SE_NoBreakAESneak 325 // *not implemented[AA] - [AA Nerves of Steel] increasing chance to remain hidden when they are an indirect target of an AoE spell.
|
||||
#define SE_SpellSlotIncrease 326 // *not implemented as bonus - increases your spell slot availability
|
||||
#define SE_MysticalAttune 327 // implemented - increases amount of buffs that a player can have
|
||||
#define SE_DelayDeath 328 // implemented - increases how far you can fall below 0 hp before you die
|
||||
@ -486,7 +486,7 @@ typedef enum {
|
||||
#define SE_CriticalDamageMob 330 // implemented
|
||||
#define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine
|
||||
//#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
|
||||
#define SE_CastOnRuneFadeEffect 333 // implemented
|
||||
#define SE_CastOnRuneFadeEffect 333 // implemented
|
||||
#define SE_BardAEDot 334 // implemented
|
||||
#define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494)
|
||||
//#define SE_IllusionaryTarget 336 // not used
|
||||
@ -619,7 +619,7 @@ typedef enum {
|
||||
//#define SE_Shield_Target 463 //
|
||||
#define SE_PC_Pet_Rampage 464 // implemented - Base1 % chance to do rampage for base2 % of damage each melee round
|
||||
//#define SE_PC_Pet_AE_Rampage 465 // Would assume as above but need to confirm.
|
||||
//#define SE_PC_Pet_Flurry_Chance 466 //
|
||||
#define SE_PC_Pet_Flurry_Chance 466 // implemented - Base1 % chance to do flurry from double attack hit.
|
||||
//#define SE_DS_Mitigation_Amount 467 //
|
||||
//#define SE_DS_Mitigation_Percentage 468 //
|
||||
//#define SE_Chance_Best_in_Spell_Grp 469 //
|
||||
@ -744,8 +744,9 @@ struct SPDat_Spell_Struct
|
||||
/* 194 */ float directional_start; //Cone Start Angle:
|
||||
/* 195 */ float directional_end; // Cone End Angle:
|
||||
/* 196 */ bool sneak; // effect can only be used if sneaking (rogue 'Daggerfall' ect)
|
||||
/* 197 */ bool not_extendable;
|
||||
/* 198- 199 */
|
||||
/* 197 */ bool not_focusable; //prevents focus effects from being applied to spell
|
||||
/* 198 */ bool no_detrimental_spell_aggro;
|
||||
/* 199 */
|
||||
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones
|
||||
/* 201 */ int viral_range;
|
||||
/* 202 */ int songcap; // individual song cap
|
||||
@ -755,7 +756,7 @@ struct SPDat_Spell_Struct
|
||||
/* 206 */
|
||||
/* 207 */ int spellgroup;
|
||||
/* 208 */ int rank; //increments AA effects with same name
|
||||
/* 209 */ int powerful_flag; // Need more investigation to figure out what to call this, for now we know -1 makes charm spells not break before their duration is complete, it does alot more though
|
||||
/* 209 */ int no_resist; //makes spells unresistable, which makes charms unbreakable as well.
|
||||
/* 210 */ // bool DurationFrozen; ???
|
||||
/* 211 */ int CastRestriction; //Various restriction categories for spells most seem targetable race related but have also seen others for instance only castable if target hp 20% or lower or only if target out of combat
|
||||
/* 212 */ bool AllowRest;
|
||||
@ -764,7 +765,7 @@ struct SPDat_Spell_Struct
|
||||
/* 215 - 216 */
|
||||
/* 217 */ int override_crit_chance; //Places a cap on the max chance to critical
|
||||
/* 218 */ int aemaxtargets; //Is used for various AE effects
|
||||
/* 219 */ int maxtargets; //Is used for beam and ring spells for target # limits (not implemented)
|
||||
/* 219 */ int no_heal_damage_item_mod;
|
||||
/* 220 - 223 */
|
||||
/* 224 */ bool persistdeath; // buff doesn't get stripped on death
|
||||
/* 225 - 226 */
|
||||
@ -773,7 +774,8 @@ struct SPDat_Spell_Struct
|
||||
/* 229 */ float max_dist; //spell power modified by distance from caster (Max Distance)
|
||||
/* 230 */ float max_dist_mod; //spell power modified by distance from caster (Modifier at Max Distance)
|
||||
/* 231 */ float min_range; //Min casting range
|
||||
/* 232 - 236 */
|
||||
/* 232 */ bool no_remove; //prevents buff from being removed by click
|
||||
/* 233 - 236 */
|
||||
uint8 DamageShieldType; // This field does not exist in spells_us.txt
|
||||
};
|
||||
|
||||
@ -879,6 +881,7 @@ uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
|
||||
uint32 GetPartialMagicRuneAmount(uint32 spell_id);
|
||||
bool NoDetrimentalSpellAggro(uint16 spell_id);
|
||||
|
||||
int CalcPetHp(int levelb, int classb, int STA = 75);
|
||||
const char *GetRandPetName();
|
||||
|
||||
@ -14,6 +14,7 @@ use POSIX qw(strftime);
|
||||
use File::Path;
|
||||
use File::Find;
|
||||
use URI::Escape;
|
||||
use Time::HiRes qw(usleep);
|
||||
|
||||
$time_stamp = strftime('%m-%d-%Y', gmtime());
|
||||
|
||||
@ -22,7 +23,7 @@ if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
||||
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||
|
||||
#::: If current version is less than what world is reporting, then download a new one...
|
||||
$current_version = 10;
|
||||
$current_version = 11;
|
||||
|
||||
if($ARGV[0] eq "V"){
|
||||
if($ARGV[1] > $current_version){
|
||||
@ -49,9 +50,6 @@ no warnings;
|
||||
|
||||
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
|
||||
|
||||
#::: Cleanup staged folder...
|
||||
rmtree("updates_staged/");
|
||||
|
||||
my $confile = "eqemu_config.xml"; #default
|
||||
open(F, "<$confile");
|
||||
my $indb = 0;
|
||||
@ -103,12 +101,40 @@ if($OS eq "Linux"){
|
||||
}
|
||||
|
||||
#::: Path not found, error and exit
|
||||
if($path eq ""){
|
||||
if($path eq ""){
|
||||
print "MySQL path not found, please add the path for automatic database upgrading to continue... \n\n";
|
||||
print "script_exiting...\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
if($ARGV[0] eq "installer"){
|
||||
print "Running EQEmu Server installer routines...\n";
|
||||
mkdir('logs');
|
||||
mkdir('updates_staged');
|
||||
fetch_latest_windows_binaries();
|
||||
map_files_fetch_bulk();
|
||||
opcodes_fetch();
|
||||
plugins_fetch();
|
||||
quest_files_fetch();
|
||||
lua_modules_fetch();
|
||||
get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/lua51.dll", "lua51.dll", 1);
|
||||
|
||||
#::: Database Routines
|
||||
print "MariaDB :: Creating Database 'peq'\n";
|
||||
print `"$path" --host $host --user $user --password="$pass" -N -B -e "DROP DATABASE peq;CREATE DATABASE peq"`;
|
||||
if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); }
|
||||
if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); }
|
||||
$bin_db_ver = trim($db_version[1]);
|
||||
check_db_version_table();
|
||||
$local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1"));
|
||||
fetch_peq_db_full();
|
||||
print "\nFetching Latest Database Updates...\n";
|
||||
main_db_management();
|
||||
print "\nApplying Latest Database Updates...\n";
|
||||
main_db_management();
|
||||
exit;
|
||||
}
|
||||
|
||||
#::: Create db_update working directory if not created
|
||||
mkdir('db_update');
|
||||
|
||||
@ -118,15 +144,19 @@ if(trim(get_mysql_result("SHOW COLUMNS FROM db_version LIKE 'Revision'")) ne ""
|
||||
print "Old db_version table present, dropping...\n\n";
|
||||
}
|
||||
|
||||
if(get_mysql_result("SHOW TABLES LIKE 'db_version'") eq "" && $db){
|
||||
print get_mysql_result("
|
||||
CREATE TABLE db_version (
|
||||
version int(11) DEFAULT '0'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
INSERT INTO db_version (version) VALUES ('1000');");
|
||||
print "Table 'db_version' does not exists.... Creating...\n\n";
|
||||
sub check_db_version_table{
|
||||
if(get_mysql_result("SHOW TABLES LIKE 'db_version'") eq "" && $db){
|
||||
print get_mysql_result("
|
||||
CREATE TABLE db_version (
|
||||
version int(11) DEFAULT '0'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
INSERT INTO db_version (version) VALUES ('1000');");
|
||||
print "Table 'db_version' does not exists.... Creating...\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
check_db_version_table();
|
||||
|
||||
if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); }
|
||||
if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); }
|
||||
|
||||
@ -184,13 +214,13 @@ sub show_menu_prompt {
|
||||
1 => \&database_dump,
|
||||
2 => \&database_dump_compress,
|
||||
3 => \&main_db_management,
|
||||
4 => \&aa_fetch,
|
||||
4 => \&bots_db_management,
|
||||
5 => \&opcodes_fetch,
|
||||
6 => \&map_files_fetch,
|
||||
7 => \&plugins_fetch,
|
||||
8 => \&quest_files_fetch,
|
||||
9 => \&lua_modules_fetch,
|
||||
10 => \&bots_db_management,
|
||||
10 => \&aa_fetch,
|
||||
20 => \&do_update_self,
|
||||
0 => \&script_exit,
|
||||
);
|
||||
@ -241,31 +271,33 @@ sub menu_options {
|
||||
$bots_management = "Install bots database pre-requisites (Requires bots server binaries)";
|
||||
}
|
||||
else{
|
||||
$bots_management = "Check for Bot pending REQUIRED database updates...";
|
||||
$bots_management = "Check for Bot pending REQUIRED database updates... (Must have bots enabled)";
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
$option[3] = "Check and stage pending REQUIRED Database updates";
|
||||
$bots_management = "Check for Bot REQUIRED database updates...";
|
||||
$bots_management = "Check for Bot REQUIRED database updates... (Must have bots enabled)";
|
||||
}
|
||||
|
||||
return <<EO_MENU;
|
||||
EQEmu Update Utility Menu:
|
||||
1) Backup Database - (Saves to Backups folder)
|
||||
2) Backup Database Compressed - (Saves to Backups folder)
|
||||
3) $option[3]
|
||||
4) AAs - Download Latest AA's from PEQ (This overwrites existing data)
|
||||
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)
|
||||
10) $bots_management
|
||||
20) Force update this script (Redownload)
|
||||
0) Exit
|
||||
|
||||
Enter numbered option and press enter...
|
||||
============================================================
|
||||
#::: EQEmu Update Utility Menu: (eqemu_update.pl)
|
||||
============================================================
|
||||
1) [Backup Database] :: (Saves to Backups folder)
|
||||
2) [Backup Database Compressed] :: (Saves to Backups folder)
|
||||
3) [EQEmu DB Schema] :: $option[3]
|
||||
4) [EQEmu DB Bots Schema] $bots_management
|
||||
5) [OPCodes] :: Download latest opcodes for each EQ Client
|
||||
6) [Maps] :: Download latest map and water files
|
||||
7) [Plugins (Perl)] :: Download latest Perl plugins
|
||||
8) [Quests (Perl/LUA)] :: Download latest PEQ quests and stage updates
|
||||
9) [LUA Modules] :: Download latest LUA Modules (Required for Lua)
|
||||
10) [DB Data : Alternate Advancement] :: Download Latest AA's from PEQ (This overwrites existing data)
|
||||
20) [Update the updater] Force update this script (Redownload)
|
||||
0) Exit
|
||||
|
||||
Enter numbered option and press enter...
|
||||
|
||||
EO_MENU
|
||||
}
|
||||
@ -295,7 +327,11 @@ sub database_dump_compress {
|
||||
print `perl db_dumper.pl database="$db" loc="backups" compress`;
|
||||
}
|
||||
|
||||
sub script_exit{ }
|
||||
sub script_exit{
|
||||
#::: Cleanup staged folder...
|
||||
rmtree("updates_staged/");
|
||||
exit;
|
||||
}
|
||||
|
||||
#::: Returns Tab Delimited MySQL Result from Command Line
|
||||
sub get_mysql_result{
|
||||
@ -345,35 +381,48 @@ sub get_remote_file{
|
||||
if($OS eq "Windows"){
|
||||
#::: For non-text type requests...
|
||||
if($content_type == 1){
|
||||
use LWP::Simple qw(getstore);
|
||||
if(!getstore($URL, $Dest_File)){
|
||||
print "Error, no connection or failed request...\n\n";
|
||||
}
|
||||
else{
|
||||
print " o URL: (" . $URL . ")\n";
|
||||
print " o Saved: (" . $Dest_File . ") \n";
|
||||
$break = 0;
|
||||
while($break == 0) {
|
||||
use LWP::Simple qw(getstore);
|
||||
if(!getstore($URL, $Dest_File)){
|
||||
# print "Error, no connection or failed request...\n\n";
|
||||
}
|
||||
# sleep(1);
|
||||
#::: Make sure the file exists before continuing...
|
||||
if(-e $Dest_File) {
|
||||
$break = 1;
|
||||
print " [URL] :: " . $URL . "\n";
|
||||
print " [Saved] :: " . $Dest_File . "\n";
|
||||
} else { $break = 0; }
|
||||
usleep(500);
|
||||
}
|
||||
}
|
||||
else{
|
||||
require LWP::UserAgent;
|
||||
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";
|
||||
$break = 0;
|
||||
while($break == 0) {
|
||||
require LWP::UserAgent;
|
||||
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);
|
||||
}
|
||||
else {
|
||||
# print "Error, no connection or failed request...\n\n";
|
||||
}
|
||||
if(-e $Dest_File) {
|
||||
$break = 1;
|
||||
print " [URL] :: " . $URL . "\n";
|
||||
print " [Saved] :: " . $Dest_File . "\n";
|
||||
} else { $break = 0; }
|
||||
usleep(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
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 = `wget --no-check-certificate --quiet -O $Dest_File $URL`;
|
||||
print " o URL: (" . $URL . ")\n";
|
||||
@ -461,6 +510,75 @@ sub copy_file{
|
||||
copy $l_source_file, $l_dest_file;
|
||||
}
|
||||
|
||||
sub fetch_latest_windows_binaries{
|
||||
print "\n --- Fetching Latest Windows Binaries... --- \n";
|
||||
get_remote_file("https://raw.githubusercontent.com/Akkadius/EQEmuInstall/master/master_windows_build.zip", "updates_staged/master_windows_build.zip", 1);
|
||||
print "\n --- Fetched Latest Windows Binaries... --- \n";
|
||||
print "\n --- Extracting... --- \n";
|
||||
unzip('updates_staged/master_windows_build.zip', 'updates_staged/binaries/');
|
||||
my @files;
|
||||
my $start_dir = "updates_staged/binaries";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$dest_file = $file;
|
||||
$dest_file =~s/updates_staged\/binaries\///g;
|
||||
print "Installing :: " . $dest_file . "\n";
|
||||
copy_file($file, $dest_file);
|
||||
}
|
||||
print "\n --- Done... --- \n";
|
||||
|
||||
rmtree('updates_staged');
|
||||
}
|
||||
|
||||
sub fetch_peq_db_full{
|
||||
print "Downloading latest PEQ Database... Please wait...\n";
|
||||
get_remote_file("http://edit.peqtgc.com/weekly/peq_beta.zip", "updates_staged/peq_beta.zip", 1);
|
||||
print "Downloaded latest PEQ Database... Extracting...\n";
|
||||
unzip('updates_staged/peq_beta.zip', 'updates_staged/peq_db/');
|
||||
my $start_dir = "updates_staged\\peq_db";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$dest_file = $file;
|
||||
$dest_file =~s/updates_staged\\peq_db\///g;
|
||||
if($file=~/peqbeta|player_tables/i){
|
||||
print "MariaDB :: Installing :: " . $dest_file . "\n";
|
||||
get_mysql_result_from_file($file);
|
||||
}
|
||||
if($file=~/eqtime/i){
|
||||
print "Installing eqtime.cfg\n";
|
||||
copy_file($file, "eqtime.cfg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub map_files_fetch_bulk{
|
||||
print "\n --- Fetching Latest Maps... (This could take a few minutes...) --- \n";
|
||||
get_remote_file("http://github.com/Akkadius/EQEmuMaps/archive/master.zip", "maps/maps.zip", 1);
|
||||
unzip('maps/maps.zip', 'maps/');
|
||||
my @files;
|
||||
my $start_dir = "maps\\EQEmuMaps-master\\maps";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
$dest_file = $file;
|
||||
$dest_file =~s/maps\\EQEmuMaps-master\\maps\///g;
|
||||
print "Installing :: " . $dest_file . "\n";
|
||||
copy_file($file, "maps/" . $new_file);
|
||||
}
|
||||
print "\n --- Fetched Latest Maps... --- \n";
|
||||
|
||||
rmtree('maps/EQEmuMaps-master');
|
||||
unlink('maps/maps.zip');
|
||||
}
|
||||
|
||||
sub map_files_fetch{
|
||||
print "\n --- Fetching Latest Maps --- \n";
|
||||
|
||||
@ -549,6 +667,8 @@ sub quest_files_fetch{
|
||||
}
|
||||
}
|
||||
|
||||
rmtree('updates_staged');
|
||||
|
||||
if($fc == 0){
|
||||
print "\nNo Quest Updates found... \n\n";
|
||||
}
|
||||
|
||||
@ -960,6 +960,9 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
|
||||
//offensive spell aggro
|
||||
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
|
||||
{
|
||||
if (NoDetrimentalSpellAggro(spell_id))
|
||||
return 0;
|
||||
|
||||
int32 AggroAmount = 0;
|
||||
int32 nonModifiedAggro = 0;
|
||||
uint16 slevel = GetLevel();
|
||||
@ -1240,7 +1243,7 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
|
||||
|
||||
if(IsCharmSpell(spell_id)) {
|
||||
|
||||
if (spells[spell_id].powerful_flag == -1) //If charm spell has this set(-1), it can not break till end of duration.
|
||||
if (spells[spell_id].no_resist) //If charm spell has this set(-1), it can not break till end of duration.
|
||||
return true;
|
||||
|
||||
//1: The mob has a default 25% chance of being allowed a resistance check against the charm.
|
||||
|
||||
@ -2410,7 +2410,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/)
|
||||
void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, bool iYellForHelp /*= true*/, bool bFrenzy /*= false*/, bool iBuffTic /*= false*/, uint16 spell_id)
|
||||
{
|
||||
if(!other)
|
||||
return;
|
||||
@ -2466,6 +2466,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
|
||||
if(IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO))
|
||||
return;
|
||||
|
||||
if (spell_id != SPELL_UNKNOWN && NoDetrimentalSpellAggro(spell_id))
|
||||
return;
|
||||
|
||||
if (other == myowner)
|
||||
return;
|
||||
|
||||
@ -3139,15 +3142,15 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
if(!RuleB(Combat, EXPFromDmgShield)) {
|
||||
// Damage shield damage shouldn't count towards who gets EXP
|
||||
if(!attacker->CastToClient()->GetFeigned() && !FromDamageShield)
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic);
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
|
||||
}
|
||||
else {
|
||||
if(!attacker->CastToClient()->GetFeigned())
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic);
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic);
|
||||
AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
|
||||
}
|
||||
|
||||
if(damage > 0) {
|
||||
@ -3172,7 +3175,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
|
||||
{
|
||||
if (!pet->IsHeld()) {
|
||||
Log.Out(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName());
|
||||
pet->AddToHateList(attacker, 1);
|
||||
pet->AddToHateList(attacker, 1,0, true, false, false, spell_id);
|
||||
pet->SetTarget(attacker);
|
||||
Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName());
|
||||
}
|
||||
@ -4760,8 +4763,15 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int spec
|
||||
// A "quad" on live really is just a successful dual wield where both double attack
|
||||
// The mobs that could triple lost the ability to when the triple attack skill was added in
|
||||
Attack(target, MainPrimary, false, false, false, opts, special);
|
||||
if (CanThisClassDoubleAttack() && CheckDoubleAttack())
|
||||
if (CanThisClassDoubleAttack() && CheckDoubleAttack()){
|
||||
Attack(target, MainPrimary, false, false, false, opts, special);
|
||||
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()){
|
||||
int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry;
|
||||
if (chance && zone->random.Roll(chance))
|
||||
Flurry(nullptr);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4811,8 +4821,15 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int speci
|
||||
GetEquipment(MaterialSecondary) != 0) {
|
||||
if (CheckDualWield()) {
|
||||
Attack(target, MainSecondary, false, false, false, opts, special);
|
||||
if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack())
|
||||
if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack()){
|
||||
Attack(target, MainSecondary, false, false, false, opts, special);
|
||||
|
||||
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()){
|
||||
int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry;
|
||||
if (chance && zone->random.Roll(chance))
|
||||
Flurry(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1199,13 +1199,14 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
// Kayen: Not sure best way to implement this yet.
|
||||
// Physically raises skill cap ie if 55/55 it will raise to 55/60
|
||||
case SE_RaiseSkillCap: {
|
||||
if (newbon->RaiseSkillCap[0] < base1) {
|
||||
newbon->RaiseSkillCap[0] = base1; // value
|
||||
newbon->RaiseSkillCap[1] = base2; // skill
|
||||
}
|
||||
|
||||
if (base2 > HIGHEST_SKILL)
|
||||
break;
|
||||
|
||||
if (newbon->RaiseSkillCap[base2] < base1)
|
||||
newbon->RaiseSkillCap[base2] = base1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1423,22 +1424,45 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
if (newbon->PC_Pet_Rampage[1] < base2)
|
||||
newbon->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case SE_PC_Pet_Flurry_Chance:
|
||||
newbon->PC_Pet_Flurry += base1; //Chance to Flurry
|
||||
break;
|
||||
|
||||
case SE_ShroudofStealth:
|
||||
newbon->ShroudofStealth = true;
|
||||
break;
|
||||
|
||||
case SE_ReduceFallDamage:
|
||||
newbon->ReduceFallDamage += base1;
|
||||
break;
|
||||
|
||||
case SE_ReduceTradeskillFail:{
|
||||
|
||||
if (base2 > HIGHEST_SKILL)
|
||||
break;
|
||||
|
||||
newbon->ReduceTradeskillFail[base2] += base1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_TradeSkillMastery:
|
||||
if (newbon->TradeSkillMastery < base1)
|
||||
newbon->TradeSkillMastery = base1;
|
||||
break;
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
case SE_PetDiscipline2:
|
||||
break;
|
||||
case SE_ReduceTradeskillFail:
|
||||
break;
|
||||
case SE_PotionBeltSlots:
|
||||
break;
|
||||
case SE_BandolierSlots:
|
||||
break;
|
||||
case SE_ForageSkill:
|
||||
break;
|
||||
case SE_TradeSkillMastery:
|
||||
break;
|
||||
case SE_SecondaryForte:
|
||||
break;
|
||||
case SE_FeignedCastOnChance:
|
||||
@ -1453,13 +1477,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
case SE_TrapCircumvention:
|
||||
break;
|
||||
case SE_ShroudofStealth:
|
||||
break;
|
||||
case SE_FeignedMinion:
|
||||
break;
|
||||
|
||||
// handled client side
|
||||
case SE_ReduceFallDamage:
|
||||
// not handled here
|
||||
case SE_HastenedAASkill:
|
||||
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore
|
||||
@ -3132,8 +3152,43 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
if (new_bonus->PC_Pet_Rampage[1] < base2)
|
||||
new_bonus->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case SE_PC_Pet_Flurry_Chance:
|
||||
new_bonus->PC_Pet_Flurry += effect_value; //Chance to Flurry
|
||||
break;
|
||||
|
||||
case SE_ShroudofStealth:
|
||||
new_bonus->ShroudofStealth = true;
|
||||
break;
|
||||
|
||||
case SE_ReduceFallDamage:
|
||||
new_bonus->ReduceFallDamage += effect_value;
|
||||
break;
|
||||
|
||||
case SE_ReduceTradeskillFail:{
|
||||
|
||||
if (base2 > HIGHEST_SKILL)
|
||||
break;
|
||||
|
||||
new_bonus->ReduceTradeskillFail[base2] += effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_TradeSkillMastery:
|
||||
if (new_bonus->TradeSkillMastery < effect_value)
|
||||
new_bonus->TradeSkillMastery = effect_value;
|
||||
break;
|
||||
|
||||
case SE_RaiseSkillCap: {
|
||||
if (base2 > HIGHEST_SKILL)
|
||||
break;
|
||||
|
||||
if (new_bonus->RaiseSkillCap[base2] < effect_value)
|
||||
new_bonus->RaiseSkillCap[base2] = effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
|
||||
|
||||
@ -2439,18 +2439,8 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16
|
||||
|
||||
}
|
||||
}
|
||||
// This should possibly be handled by bonuses rather than here.
|
||||
switch(skillid)
|
||||
{
|
||||
case SkillTracking:
|
||||
{
|
||||
Result += ((GetAA(aaAdvancedTracking) * 10) + (GetAA(aaTuneofPursuance) * 10));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Result += spellbonuses.RaiseSkillCap[skillid] + itembonuses.RaiseSkillCap[skillid] + aabonuses.RaiseSkillCap[skillid];
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@ -3734,7 +3734,7 @@ void Client::Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app)
|
||||
|
||||
uint16 SpellID = m->GetSpellIDFromSlot(brrs->SlotID);
|
||||
|
||||
if (SpellID && IsBeneficialSpell(SpellID))
|
||||
if (SpellID && IsBeneficialSpell(SpellID) && !spells[SpellID].no_remove)
|
||||
m->BuffFadeBySlot(brrs->SlotID, true);
|
||||
}
|
||||
|
||||
@ -5076,18 +5076,12 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app)
|
||||
Message(13, "Ability recovery time not yet met.");
|
||||
return;
|
||||
}
|
||||
int reuse = DisarmTrapsReuseTime;
|
||||
switch (GetAA(aaAdvTrapNegotiation)) {
|
||||
case 1:
|
||||
reuse -= 1;
|
||||
break;
|
||||
case 2:
|
||||
reuse -= 3;
|
||||
break;
|
||||
case 3:
|
||||
reuse -= 5;
|
||||
break;
|
||||
}
|
||||
|
||||
int reuse = DisarmTrapsReuseTime - GetSkillReuseTime(SkillDisarmTraps);
|
||||
|
||||
if (reuse < 1)
|
||||
reuse = 1;
|
||||
|
||||
p_timers.Start(pTimerDisarmTraps, reuse - 1);
|
||||
|
||||
Trap* trap = entity_list.FindNearbyTrap(this, 60);
|
||||
@ -5359,17 +5353,9 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app)
|
||||
|
||||
if (ed->dmgtype == 252) {
|
||||
|
||||
switch (GetAA(aaAcrobatics)) { //Don't know what acrobatics effect is yet but it should be done client side via aa effect.. till then
|
||||
case 1:
|
||||
damage = damage * 95 / 100;
|
||||
break;
|
||||
case 2:
|
||||
damage = damage * 90 / 100;
|
||||
break;
|
||||
case 3:
|
||||
damage = damage * 80 / 100;
|
||||
break;
|
||||
}
|
||||
int mod = spellbonuses.ReduceFallDamage + itembonuses.ReduceFallDamage + aabonuses.ReduceFallDamage;
|
||||
|
||||
damage -= damage * mod / 100;
|
||||
}
|
||||
|
||||
if (damage < 0)
|
||||
@ -5443,19 +5429,13 @@ void Client::Handle_OP_FeignDeath(const EQApplicationPacket *app)
|
||||
Message(13, "Ability recovery time not yet met.");
|
||||
return;
|
||||
}
|
||||
|
||||
int reuse = FeignDeathReuseTime;
|
||||
switch (GetAA(aaRapidFeign))
|
||||
{
|
||||
case 1:
|
||||
reuse -= 1;
|
||||
break;
|
||||
case 2:
|
||||
reuse -= 2;
|
||||
break;
|
||||
case 3:
|
||||
reuse -= 5;
|
||||
break;
|
||||
}
|
||||
reuse -= GetSkillReuseTime(SkillFeignDeath);
|
||||
|
||||
if (reuse < 1)
|
||||
reuse = 1;
|
||||
|
||||
p_timers.Start(pTimerFeignDeath, reuse - 1);
|
||||
|
||||
//BreakInvis();
|
||||
@ -7762,7 +7742,11 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
|
||||
Message(13, "Ability recovery time not yet met.");
|
||||
return;
|
||||
}
|
||||
int reuse = HideReuseTime - GetAA(209);
|
||||
int reuse = HideReuseTime - GetSkillReuseTime(SkillHide);
|
||||
|
||||
if (reuse < 1)
|
||||
reuse = 1;
|
||||
|
||||
p_timers.Start(pTimerHide, reuse - 1);
|
||||
|
||||
float hidechance = ((GetSkill(SkillHide) / 250.0f) + .25) * 100;
|
||||
@ -7776,7 +7760,7 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
|
||||
sa_out->parameter = 1;
|
||||
entity_list.QueueClients(this, outapp, true);
|
||||
safe_delete(outapp);
|
||||
if (GetAA(aaShroudofStealth)){
|
||||
if (spellbonuses.ShroudofStealth || aabonuses.ShroudofStealth || itembonuses.ShroudofStealth){
|
||||
improved_hidden = true;
|
||||
hidden = true;
|
||||
}
|
||||
@ -11698,18 +11682,12 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app)
|
||||
Message(13, "Ability recovery time not yet met.");
|
||||
return;
|
||||
}
|
||||
int reuse = SenseTrapsReuseTime;
|
||||
switch (GetAA(aaAdvTrapNegotiation)) {
|
||||
case 1:
|
||||
reuse -= 1;
|
||||
break;
|
||||
case 2:
|
||||
reuse -= 3;
|
||||
break;
|
||||
case 3:
|
||||
reuse -= 5;
|
||||
break;
|
||||
}
|
||||
|
||||
int reuse = SenseTrapsReuseTime - GetSkillReuseTime(SkillSenseTraps);
|
||||
|
||||
if (reuse < 1)
|
||||
reuse = 1;
|
||||
|
||||
p_timers.Start(pTimerSenseTraps, reuse - 1);
|
||||
|
||||
Trap* trap = entity_list.FindNearbyTrap(this, 800);
|
||||
|
||||
@ -408,6 +408,7 @@ struct StatBonuses {
|
||||
uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
|
||||
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
@ -438,7 +439,7 @@ struct StatBonuses {
|
||||
int32 CombatStability; // Melee damage mitigation.
|
||||
int32 DoubleRiposte; // Chance to double riposte
|
||||
int32 GiveDoubleRiposte[3]; // 0=Regular Chance, 1=Skill Attack Chance, 2=Skill
|
||||
uint32 RaiseSkillCap[2]; // Raise a specific skill cap (1 = value, 2=skill)
|
||||
uint32 RaiseSkillCap[HIGHEST_SKILL+1]; // Raise a specific skill cap (base1= value, base2=skill)
|
||||
int32 Ambidexterity; // Increase chance to duel wield by adding bonus 'skill'.
|
||||
int32 PetMaxHP; // Increase the max hp of your pet.
|
||||
int32 PetFlurry; // Chance for pet to flurry.
|
||||
@ -466,6 +467,10 @@ struct StatBonuses {
|
||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||
bool IllusionPersistence; // Causes illusions not to fade.
|
||||
uint16 extra_xtargets; // extra xtarget entries
|
||||
bool ShroudofStealth; // rogue improved invisiblity
|
||||
uint16 ReduceFallDamage; // reduce fall damage by percent
|
||||
int32 ReduceTradeskillFail[HIGHEST_SKILL+1]; // Reduces chance for trade skills to fail by percent.
|
||||
uint8 TradeSkillMastery; // Allow number of tradeskills to exceed 200 skill.
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
||||
@ -112,7 +112,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
value -= GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
|
||||
|
||||
else if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
@ -145,7 +145,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
|
||||
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
|
||||
value -= GetFocusEffect(focusFcDamageAmt2, spell_id);
|
||||
|
||||
if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
|
||||
|
||||
if (IsNPC() && CastToNPC()->GetSpellScale())
|
||||
@ -287,7 +287,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
|
||||
value += GetFocusEffect(focusFcHealAmt, spell_id);
|
||||
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, spell_id);
|
||||
|
||||
if(itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
if(!spells[spell_id].no_heal_damage_item_mod && itembonuses.HealAmt && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
|
||||
value += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
|
||||
|
||||
value += value*target->GetHealRate(spell_id, this)/100;
|
||||
@ -430,9 +430,6 @@ int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
|
||||
|
||||
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
{
|
||||
if (spells[spell_id].not_extendable)
|
||||
return duration;
|
||||
|
||||
int increase = 100;
|
||||
increase += GetFocusEffect(focusSpellDuration, spell_id);
|
||||
int tic_inc = 0;
|
||||
|
||||
@ -406,7 +406,7 @@ int Lua_Spell::GetSpellGroup() {
|
||||
|
||||
int Lua_Spell::GetPowerfulFlag() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->powerful_flag;
|
||||
return self->no_resist;
|
||||
}
|
||||
|
||||
int Lua_Spell::GetCastRestriction() {
|
||||
@ -436,7 +436,7 @@ int Lua_Spell::GetAEMaxTargets() {
|
||||
|
||||
int Lua_Spell::GetMaxTargets() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->maxtargets;
|
||||
return self->no_heal_damage_item_mod;
|
||||
}
|
||||
|
||||
bool Lua_Spell::GetPersistDeath() {
|
||||
|
||||
@ -5598,18 +5598,18 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot)
|
||||
else if (id == "NimbusEffect") {return spells[spell_id].NimbusEffect; }
|
||||
else if (id == "directional_start") {return static_cast<int32>(spells[spell_id].directional_start); }
|
||||
else if (id == "directional_end") {return static_cast<int32>(spells[spell_id].directional_end); }
|
||||
else if (id == "not_extendable") {return spells[spell_id].not_extendable; }
|
||||
else if (id == "not_focusable") {return spells[spell_id].not_focusable; }
|
||||
else if (id == "suspendable") {return spells[spell_id].suspendable; }
|
||||
else if (id == "viral_range") {return spells[spell_id].viral_range; }
|
||||
else if (id == "spellgroup") {return spells[spell_id].spellgroup; }
|
||||
else if (id == "rank") {return spells[spell_id].rank; }
|
||||
else if (id == "powerful_flag") {return spells[spell_id].powerful_flag; }
|
||||
else if (id == "no_resist") {return spells[spell_id].no_resist; }
|
||||
else if (id == "CastRestriction") {return spells[spell_id].CastRestriction; }
|
||||
else if (id == "AllowRest") {return spells[spell_id].AllowRest; }
|
||||
else if (id == "InCombat") {return spells[spell_id].InCombat; }
|
||||
else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; }
|
||||
else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; }
|
||||
else if (id == "maxtargets") {return spells[spell_id].maxtargets; }
|
||||
else if (id == "no_heal_damage_item_mod") {return spells[spell_id].no_heal_damage_item_mod; }
|
||||
else if (id == "persistdeath") {return spells[spell_id].persistdeath; }
|
||||
else if (id == "min_dist") {return static_cast<int32>(spells[spell_id].min_dist); }
|
||||
else if (id == "min_dist_mod") {return static_cast<int32>(spells[spell_id].min_dist_mod); }
|
||||
|
||||
@ -489,7 +489,7 @@ public:
|
||||
inline uint32 GetLevelCon(uint8 iOtherLevel) const {
|
||||
return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; }
|
||||
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true,
|
||||
bool bFrenzy = false, bool iBuffTic = false);
|
||||
bool bFrenzy = false, bool iBuffTic = false, uint16 spell_id = SPELL_UNKNOWN);
|
||||
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)); }
|
||||
|
||||
@ -780,7 +780,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
|
||||
// define spells with fixed duration
|
||||
// charm spells with -1 in field 209 are all of fixed duration, so lets use that instead of spell_ids
|
||||
if(spells[spell_id].powerful_flag == -1)
|
||||
if(spells[spell_id].no_resist)
|
||||
bBreak = true;
|
||||
|
||||
if (!bBreak)
|
||||
@ -5228,6 +5228,9 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration)
|
||||
return 0;
|
||||
|
||||
if (spells[spell_id].not_focusable)
|
||||
return 0;
|
||||
|
||||
int16 realTotal = 0;
|
||||
int16 realTotal2 = 0;
|
||||
int16 realTotal3 = 0;
|
||||
@ -5499,6 +5502,9 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
|
||||
int16 NPC::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
|
||||
if (spells[spell_id].not_focusable)
|
||||
return 0;
|
||||
|
||||
int16 realTotal = 0;
|
||||
int16 realTotal2 = 0;
|
||||
bool rand_effectiveness = false;
|
||||
|
||||
@ -750,14 +750,6 @@ bool Client::CheckFizzle(uint16 spell_id)
|
||||
// always at least 1% chance to fail or 5% to succeed
|
||||
fizzlechance = fizzlechance < 1 ? 1 : (fizzlechance > 95 ? 95 : fizzlechance);
|
||||
|
||||
/*
|
||||
if(IsBardSong(spell_id))
|
||||
{
|
||||
//This was a channel chance modifier - no evidence for fizzle reduction
|
||||
fizzlechance -= GetAA(aaInternalMetronome) * 1.5f;
|
||||
}
|
||||
*/
|
||||
|
||||
float fizzle_roll = zone->random.Real(0, 100);
|
||||
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Check Fizzle %s spell %d fizzlechance: %0.2f%% diff: %0.2f roll: %0.2f", GetName(), spell_id, fizzlechance, diff, fizzle_roll);
|
||||
@ -4067,7 +4059,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4094,7 +4086,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4110,7 +4102,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
} else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false))
|
||||
@ -4127,7 +4119,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if (aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4150,7 +4142,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4190,7 +4182,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
} else {
|
||||
AddToHateList(caster, 1);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -4298,7 +4290,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
|
||||
}
|
||||
|
||||
//Get the resist chance for the target
|
||||
if(resist_type == RESIST_NONE)
|
||||
if(resist_type == RESIST_NONE || spells[spell_id].no_resist)
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Spell was unresistable");
|
||||
return 100;
|
||||
|
||||
@ -941,135 +941,10 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
||||
float res = zone->random.Real(0, 99);
|
||||
int aa_chance = 0;
|
||||
|
||||
//AA modifiers
|
||||
//can we do this with nested switches?
|
||||
if(spec->tradeskill == SkillAlchemy){
|
||||
switch(GetAA(aaAlchemyMastery)){
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
aa_chance = spellbonuses.ReduceTradeskillFail[spec->tradeskill] + itembonuses.ReduceTradeskillFail[spec->tradeskill] + aabonuses.ReduceTradeskillFail[spec->tradeskill];
|
||||
|
||||
if(spec->tradeskill == SkillJewelryMaking){
|
||||
switch(GetAA(aaJewelCraftMastery)){
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const Item_Struct* item = nullptr;
|
||||
|
||||
if (spec->tradeskill == SkillBlacksmithing) {
|
||||
switch(GetAA(aaBlacksmithingMastery)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillBaking) {
|
||||
switch(GetAA(aaBakingMastery)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillBrewing) {
|
||||
switch(GetAA(aaBrewingMastery)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillFletching) {
|
||||
switch(GetAA(aaFletchingMastery2)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillPottery) {
|
||||
switch(GetAA(aaPotteryMastery)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillTailoring) {
|
||||
switch(GetAA(aaTailoringMastery)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->tradeskill == SkillResearch) {
|
||||
switch(GetAA(aaArcaneTongues)) {
|
||||
case 1:
|
||||
aa_chance = 10;
|
||||
break;
|
||||
case 2:
|
||||
aa_chance = 25;
|
||||
break;
|
||||
case 3:
|
||||
aa_chance = 50;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
chance = mod_tradeskill_chance(chance, spec);
|
||||
|
||||
if (((spec->tradeskill==75) || GetGM() || (chance > res)) || zone->random.Roll(aa_chance)) {
|
||||
@ -1528,8 +1403,9 @@ bool Client::CanIncreaseTradeskill(SkillUseTypes tradeskill) {
|
||||
uint8 Pottery = (GetRawSkill(SkillPottery) > 200) ? 1 : 0;
|
||||
uint8 Tailoring = (GetRawSkill(SkillTailoring) > 200) ? 1 : 0;
|
||||
uint8 SkillTotal = Baking + Smithing + Brewing + Fletching + Jewelry + Pottery + Tailoring; //Tradeskills above 200
|
||||
uint32 aaLevel = GetAA(aaNewTanaanCraftingMastery); //New Tanaan AA: Each level allows an additional tradeskill above 200 (first one is free)
|
||||
|
||||
//New Tanaan AA: Each level allows an additional tradeskill above 200 (first one is free)
|
||||
uint8 aaLevel = spellbonuses.TradeSkillMastery + itembonuses.TradeSkillMastery + aabonuses.TradeSkillMastery;
|
||||
|
||||
switch (tradeskill) {
|
||||
case SkillBaking:
|
||||
case SkillBlacksmithing:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user