Merge branch 'master' of https://github.com/EQEmu/Server into bots_updater

This commit is contained in:
Uleat 2015-10-09 21:39:05 -04:00
commit 531cbf79f5
18 changed files with 367 additions and 315 deletions

View File

@ -493,7 +493,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 10"); system("perl eqemu_update.pl V 11");
/* 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");

View File

@ -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_start = static_cast<float>(atoi(row[194]));
sp[tempid].directional_end = static_cast<float>(atoi(row[195])); sp[tempid].directional_end = static_cast<float>(atoi(row[195]));
sp[tempid].sneak = atoi(row[196]) != 0; 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].suspendable = atoi(row[200]) != 0;
sp[tempid].viral_range = atoi(row[201]); sp[tempid].viral_range = atoi(row[201]);
sp[tempid].songcap = atoi(row[202]); sp[tempid].songcap = atoi(row[202]);
sp[tempid].no_block = atoi(row[205]); sp[tempid].no_block = atoi(row[205]);
sp[tempid].spellgroup=atoi(row[207]); sp[tempid].spellgroup=atoi(row[207]);
sp[tempid].rank = atoi(row[208]); 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].CastRestriction = atoi(row[211]);
sp[tempid].AllowRest = atoi(row[212]) != 0; sp[tempid].AllowRest = atoi(row[212]) != 0;
sp[tempid].InCombat = atoi(row[213]) != 0; sp[tempid].InCombat = atoi(row[213]) != 0;
sp[tempid].OutofCombat = atoi(row[214]) != 0; sp[tempid].OutofCombat = atoi(row[214]) != 0;
sp[tempid].override_crit_chance = atoi(row[217]); sp[tempid].override_crit_chance = atoi(row[217]);
sp[tempid].aemaxtargets = atoi(row[218]); 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].persistdeath = atoi(row[224]) != 0;
sp[tempid].min_dist = atof(row[227]); sp[tempid].min_dist = atof(row[227]);
sp[tempid].min_dist_mod = atof(row[228]); sp[tempid].min_dist_mod = atof(row[228]);
sp[tempid].max_dist = atof(row[229]); sp[tempid].max_dist = atof(row[229]);
sp[tempid].max_dist_mod = atof(row[230]); sp[tempid].max_dist_mod = atof(row[230]);
sp[tempid].min_range = static_cast<float>(atoi(row[231])); sp[tempid].min_range = static_cast<float>(atoi(row[231]));
sp[tempid].no_remove = atoi(row[232]) != 0;
sp[tempid].DamageShieldType = 0; sp[tempid].DamageShieldType = 0;
} }

View File

@ -1092,6 +1092,14 @@ bool DetrimentalSpellAllowsRest(uint16 spell_id)
return false; 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) uint32 GetNimbusEffect(uint16 spell_id)
{ {
if (IsValidSpell(spell_id)) if (IsValidSpell(spell_id))

View File

@ -381,7 +381,7 @@ typedef enum {
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance. #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_TwoHandBash 226 // *not implemented as bonus
#define SE_ReduceSkillTimer 227 // implemented #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_PersistantCasting 229 // implemented
#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability #define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
#define SE_StunBashChance 231 // implemented - increase chance to stun from bash. #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_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_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_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_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_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) #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_FrontalBackstabMinDmg 253 // implemented[AA] - allow a frontal backstab for mininum damage.
#define SE_Blank 254 // implemented #define SE_Blank 254 // implemented
#define SE_ShieldDuration 255 // not implemented as bonus - increases duration of /shield #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_PetDiscipline 257 // not implemented as bonus - /pet hold
#define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab #define SE_TripleBackstab 258 // implemented[AA] - chance to perform a triple backstab
#define SE_CombatStability 259 // implemented[AA] - damage mitigation #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_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_SongModCap 261 // implemented[AA] - Song Mod cap increase (no longer used on live)
#define SE_RaiseStatCap 262 // implemented #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_HastenedAASkill 264 // implemented
#define SE_MasteryofPast 265 // implemented[AA] - Spells less than effect values level can not be fizzled #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_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_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_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_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 #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_GateToHomeCity 322 // implemented
#define SE_DefensiveProc 323 // implemented #define SE_DefensiveProc 323 // implemented
#define SE_HPToMana 324 // 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_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_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 #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_CriticalDamageMob 330 // implemented
#define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine #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_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_BardAEDot 334 // implemented
#define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494) #define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494)
//#define SE_IllusionaryTarget 336 // not used //#define SE_IllusionaryTarget 336 // not used
@ -619,7 +619,7 @@ typedef enum {
//#define SE_Shield_Target 463 // //#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_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_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_Amount 467 //
//#define SE_DS_Mitigation_Percentage 468 // //#define SE_DS_Mitigation_Percentage 468 //
//#define SE_Chance_Best_in_Spell_Grp 469 // //#define SE_Chance_Best_in_Spell_Grp 469 //
@ -744,8 +744,9 @@ struct SPDat_Spell_Struct
/* 194 */ float directional_start; //Cone Start Angle: /* 194 */ float directional_start; //Cone Start Angle:
/* 195 */ float directional_end; // Cone End Angle: /* 195 */ float directional_end; // Cone End Angle:
/* 196 */ bool sneak; // effect can only be used if sneaking (rogue 'Daggerfall' ect) /* 196 */ bool sneak; // effect can only be used if sneaking (rogue 'Daggerfall' ect)
/* 197 */ bool not_extendable; /* 197 */ bool not_focusable; //prevents focus effects from being applied to spell
/* 198- 199 */ /* 198 */ bool no_detrimental_spell_aggro;
/* 199 */
/* 200 */ bool suspendable; // buff is suspended in suspended buff zones /* 200 */ bool suspendable; // buff is suspended in suspended buff zones
/* 201 */ int viral_range; /* 201 */ int viral_range;
/* 202 */ int songcap; // individual song cap /* 202 */ int songcap; // individual song cap
@ -755,7 +756,7 @@ struct SPDat_Spell_Struct
/* 206 */ /* 206 */
/* 207 */ int spellgroup; /* 207 */ int spellgroup;
/* 208 */ int rank; //increments AA effects with same name /* 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; ??? /* 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 /* 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; /* 212 */ bool AllowRest;
@ -764,7 +765,7 @@ struct SPDat_Spell_Struct
/* 215 - 216 */ /* 215 - 216 */
/* 217 */ int override_crit_chance; //Places a cap on the max chance to critical /* 217 */ int override_crit_chance; //Places a cap on the max chance to critical
/* 218 */ int aemaxtargets; //Is used for various AE effects /* 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 */ /* 220 - 223 */
/* 224 */ bool persistdeath; // buff doesn't get stripped on death /* 224 */ bool persistdeath; // buff doesn't get stripped on death
/* 225 - 226 */ /* 225 - 226 */
@ -773,7 +774,8 @@ struct SPDat_Spell_Struct
/* 229 */ float max_dist; //spell power modified by distance from caster (Max Distance) /* 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) /* 230 */ float max_dist_mod; //spell power modified by distance from caster (Modifier at Max Distance)
/* 231 */ float min_range; //Min casting range /* 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 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 GetPartialMagicRuneReduction(uint32 spell_id);
uint32 GetPartialMeleeRuneAmount(uint32 spell_id); uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
uint32 GetPartialMagicRuneAmount(uint32 spell_id); uint32 GetPartialMagicRuneAmount(uint32 spell_id);
bool NoDetrimentalSpellAggro(uint16 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75); int CalcPetHp(int levelb, int classb, int STA = 75);
const char *GetRandPetName(); const char *GetRandPetName();

View File

@ -14,6 +14,7 @@ use POSIX qw(strftime);
use File::Path; use File::Path;
use File::Find; use File::Find;
use URI::Escape; use URI::Escape;
use Time::HiRes qw(usleep);
$time_stamp = strftime('%m-%d-%Y', gmtime()); $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($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 = 10; $current_version = 11;
if($ARGV[0] eq "V"){ if($ARGV[0] eq "V"){
if($ARGV[1] > $current_version){ if($ARGV[1] > $current_version){
@ -49,9 +50,6 @@ no warnings;
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); ($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"); open(F, "<$confile");
my $indb = 0; my $indb = 0;
@ -103,12 +101,40 @@ if($OS eq "Linux"){
} }
#::: Path not found, error and exit #::: 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 "MySQL path not found, please add the path for automatic database upgrading to continue... \n\n";
print "script_exiting...\n"; print "script_exiting...\n";
exit; 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 #::: Create db_update working directory if not created
mkdir('db_update'); 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"; print "Old db_version table present, dropping...\n\n";
} }
if(get_mysql_result("SHOW TABLES LIKE 'db_version'") eq "" && $db){ sub check_db_version_table{
print get_mysql_result(" if(get_mysql_result("SHOW TABLES LIKE 'db_version'") eq "" && $db){
CREATE TABLE db_version ( print get_mysql_result("
version int(11) DEFAULT '0' CREATE TABLE db_version (
) ENGINE=InnoDB DEFAULT CHARSET=latin1; version int(11) DEFAULT '0'
INSERT INTO db_version (version) VALUES ('1000');"); ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
print "Table 'db_version' does not exists.... Creating...\n\n"; 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 "Windows"){ @db_version = split(': ', `world db_version`); }
if($OS eq "Linux"){ @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, 1 => \&database_dump,
2 => \&database_dump_compress, 2 => \&database_dump_compress,
3 => \&main_db_management, 3 => \&main_db_management,
4 => \&aa_fetch, 4 => \&bots_db_management,
5 => \&opcodes_fetch, 5 => \&opcodes_fetch,
6 => \&map_files_fetch, 6 => \&map_files_fetch,
7 => \&plugins_fetch, 7 => \&plugins_fetch,
8 => \&quest_files_fetch, 8 => \&quest_files_fetch,
9 => \&lua_modules_fetch, 9 => \&lua_modules_fetch,
10 => \&bots_db_management, 10 => \&aa_fetch,
20 => \&do_update_self, 20 => \&do_update_self,
0 => \&script_exit, 0 => \&script_exit,
); );
@ -241,31 +271,33 @@ sub menu_options {
$bots_management = "Install bots database pre-requisites (Requires bots server binaries)"; $bots_management = "Install bots database pre-requisites (Requires bots server binaries)";
} }
else{ else{
$bots_management = "Check for Bot pending REQUIRED database updates..."; $bots_management = "Check for Bot pending REQUIRED database updates... (Must have bots enabled)";
} }
} }
} }
else{ else{
$option[3] = "Check and stage pending REQUIRED Database updates"; $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; return <<EO_MENU;
EQEmu Update Utility Menu: ============================================================
1) Backup Database - (Saves to Backups folder) #::: EQEmu Update Utility Menu: (eqemu_update.pl)
2) Backup Database Compressed - (Saves to Backups folder) ============================================================
3) $option[3] 1) [Backup Database] :: (Saves to Backups folder)
4) AAs - Download Latest AA's from PEQ (This overwrites existing data) 2) [Backup Database Compressed] :: (Saves to Backups folder)
5) OPCodes - Download latest opcodes 3) [EQEmu DB Schema] :: $option[3]
6) Maps - Download latest map and water files 4) [EQEmu DB Bots Schema] $bots_management
7) Plugins - Download latest Perl plugins 5) [OPCodes] :: Download latest opcodes for each EQ Client
8) Quests - Download latest PEQ quests and stage updates 6) [Maps] :: Download latest map and water files
9) LUA Modules - Download latest LUA Modules (Required for Lua) 7) [Plugins (Perl)] :: Download latest Perl plugins
10) $bots_management 8) [Quests (Perl/LUA)] :: Download latest PEQ quests and stage updates
20) Force update this script (Redownload) 9) [LUA Modules] :: Download latest LUA Modules (Required for Lua)
0) Exit 10) [DB Data : Alternate Advancement] :: Download Latest AA's from PEQ (This overwrites existing data)
20) [Update the updater] Force update this script (Redownload)
Enter numbered option and press enter... 0) Exit
Enter numbered option and press enter...
EO_MENU EO_MENU
} }
@ -295,7 +327,11 @@ sub database_dump_compress {
print `perl db_dumper.pl database="$db" loc="backups" 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 #::: Returns Tab Delimited MySQL Result from Command Line
sub get_mysql_result{ sub get_mysql_result{
@ -345,35 +381,48 @@ sub get_remote_file{
if($OS eq "Windows"){ if($OS eq "Windows"){
#::: For non-text type requests... #::: For non-text type requests...
if($content_type == 1){ if($content_type == 1){
use LWP::Simple qw(getstore); $break = 0;
if(!getstore($URL, $Dest_File)){ while($break == 0) {
print "Error, no connection or failed request...\n\n"; use LWP::Simple qw(getstore);
} if(!getstore($URL, $Dest_File)){
else{ # print "Error, no connection or failed request...\n\n";
print " o URL: (" . $URL . ")\n"; }
print " o Saved: (" . $Dest_File . ") \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{ else{
require LWP::UserAgent; $break = 0;
my $ua = LWP::UserAgent->new; while($break == 0) {
$ua->timeout(10); require LWP::UserAgent;
$ua->env_proxy; my $ua = LWP::UserAgent->new;
my $response = $ua->get($URL); $ua->timeout(10);
$ua->env_proxy;
if ($response->is_success){ my $response = $ua->get($URL);
open (FILE, '> ' . $Dest_File . ''); if ($response->is_success){
print FILE $response->decoded_content; open (FILE, '> ' . $Dest_File . '');
close (FILE); print FILE $response->decoded_content;
print " o URL: (" . $URL . ")\n"; close (FILE);
print " o Saved: (" . $Dest_File . ") \n"; }
} else {
else { # print "Error, no connection or failed request...\n\n";
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 -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 " o URL: (" . $URL . ")\n"; print " o URL: (" . $URL . ")\n";
@ -461,6 +510,75 @@ sub copy_file{
copy $l_source_file, $l_dest_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{ sub map_files_fetch{
print "\n --- Fetching Latest Maps --- \n"; print "\n --- Fetching Latest Maps --- \n";
@ -549,6 +667,8 @@ sub quest_files_fetch{
} }
} }
rmtree('updates_staged');
if($fc == 0){ if($fc == 0){
print "\nNo Quest Updates found... \n\n"; print "\nNo Quest Updates found... \n\n";
} }

View File

@ -960,6 +960,9 @@ bool Mob::CheckLosFN(float posX, float posY, float posZ, float mobSize) {
//offensive spell aggro //offensive spell aggro
int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc) int32 Mob::CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc)
{ {
if (NoDetrimentalSpellAggro(spell_id))
return 0;
int32 AggroAmount = 0; int32 AggroAmount = 0;
int32 nonModifiedAggro = 0; int32 nonModifiedAggro = 0;
uint16 slevel = GetLevel(); uint16 slevel = GetLevel();
@ -1240,7 +1243,7 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
if(IsCharmSpell(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; return true;
//1: The mob has a default 25% chance of being allowed a resistance check against the charm. //1: The mob has a default 25% chance of being allowed a resistance check against the charm.

View File

@ -2410,7 +2410,7 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
return true; 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) if(!other)
return; return;
@ -2466,6 +2466,9 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
if(IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO)) if(IsFamiliar() || GetSpecialAbility(IMMUNE_AGGRO))
return; return;
if (spell_id != SPELL_UNKNOWN && NoDetrimentalSpellAggro(spell_id))
return;
if (other == myowner) if (other == myowner)
return; return;
@ -3139,15 +3142,15 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
if(!RuleB(Combat, EXPFromDmgShield)) { if(!RuleB(Combat, EXPFromDmgShield)) {
// Damage shield damage shouldn't count towards who gets EXP // Damage shield damage shouldn't count towards who gets EXP
if(!attacker->CastToClient()->GetFeigned() && !FromDamageShield) if(!attacker->CastToClient()->GetFeigned() && !FromDamageShield)
AddToHateList(attacker, 0, damage, true, false, iBuffTic); AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
} }
else { else {
if(!attacker->CastToClient()->GetFeigned()) if(!attacker->CastToClient()->GetFeigned())
AddToHateList(attacker, 0, damage, true, false, iBuffTic); AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
} }
} }
else else
AddToHateList(attacker, 0, damage, true, false, iBuffTic); AddToHateList(attacker, 0, damage, true, false, iBuffTic, spell_id);
} }
if(damage > 0) { if(damage > 0) {
@ -3172,7 +3175,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
{ {
if (!pet->IsHeld()) { if (!pet->IsHeld()) {
Log.Out(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName()); 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); pet->SetTarget(attacker);
Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); 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 // 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 // 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); Attack(target, MainPrimary, false, false, false, opts, special);
if (CanThisClassDoubleAttack() && CheckDoubleAttack()) if (CanThisClassDoubleAttack() && CheckDoubleAttack()){
Attack(target, MainPrimary, false, false, false, opts, special); 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; return;
} }
@ -4811,8 +4821,15 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int speci
GetEquipment(MaterialSecondary) != 0) { GetEquipment(MaterialSecondary) != 0) {
if (CheckDualWield()) { if (CheckDualWield()) {
Attack(target, MainSecondary, false, false, false, opts, special); 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); 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);
}
}
} }
} }
} }

View File

@ -1199,13 +1199,14 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
break; break;
} }
// Kayen: Not sure best way to implement this yet.
// Physically raises skill cap ie if 55/55 it will raise to 55/60 // Physically raises skill cap ie if 55/55 it will raise to 55/60
case SE_RaiseSkillCap: { case SE_RaiseSkillCap: {
if (newbon->RaiseSkillCap[0] < base1) {
newbon->RaiseSkillCap[0] = base1; // value if (base2 > HIGHEST_SKILL)
newbon->RaiseSkillCap[1] = base2; // skill break;
}
if (newbon->RaiseSkillCap[base2] < base1)
newbon->RaiseSkillCap[base2] = base1;
break; break;
} }
@ -1423,22 +1424,45 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
if (newbon->PC_Pet_Rampage[1] < base2) if (newbon->PC_Pet_Rampage[1] < base2)
newbon->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest newbon->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest
break; 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 // to do
case SE_PetDiscipline: case SE_PetDiscipline:
break; break;
case SE_PetDiscipline2: case SE_PetDiscipline2:
break; break;
case SE_ReduceTradeskillFail:
break;
case SE_PotionBeltSlots: case SE_PotionBeltSlots:
break; break;
case SE_BandolierSlots: case SE_BandolierSlots:
break; break;
case SE_ForageSkill: case SE_ForageSkill:
break; break;
case SE_TradeSkillMastery:
break;
case SE_SecondaryForte: case SE_SecondaryForte:
break; break;
case SE_FeignedCastOnChance: case SE_FeignedCastOnChance:
@ -1453,13 +1477,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
break; break;
case SE_TrapCircumvention: case SE_TrapCircumvention:
break; break;
case SE_ShroudofStealth:
break;
case SE_FeignedMinion: case SE_FeignedMinion:
break; break;
// handled client side
case SE_ReduceFallDamage:
// not handled here // not handled here
case SE_HastenedAASkill: case SE_HastenedAASkill:
// not handled here but don't want to clutter debug log -- these may need to be verified to ignore // 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) if (new_bonus->PC_Pet_Rampage[1] < base2)
new_bonus->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest new_bonus->PC_Pet_Rampage[1] = base2; //Damage modifer - take highest
break; 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 //Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
if (IsAISpellEffect) { if (IsAISpellEffect) {

View File

@ -2439,18 +2439,8 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(SkillUseTypes skillid, uint16
} }
} }
// This should possibly be handled by bonuses rather than here.
switch(skillid) Result += spellbonuses.RaiseSkillCap[skillid] + itembonuses.RaiseSkillCap[skillid] + aabonuses.RaiseSkillCap[skillid];
{
case SkillTracking:
{
Result += ((GetAA(aaAdvancedTracking) * 10) + (GetAA(aaTuneofPursuance) * 10));
break;
}
default:
break;
}
return Result; return Result;
} }

View File

@ -3734,7 +3734,7 @@ void Client::Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app)
uint16 SpellID = m->GetSpellIDFromSlot(brrs->SlotID); uint16 SpellID = m->GetSpellIDFromSlot(brrs->SlotID);
if (SpellID && IsBeneficialSpell(SpellID)) if (SpellID && IsBeneficialSpell(SpellID) && !spells[SpellID].no_remove)
m->BuffFadeBySlot(brrs->SlotID, true); 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."); Message(13, "Ability recovery time not yet met.");
return; return;
} }
int reuse = DisarmTrapsReuseTime;
switch (GetAA(aaAdvTrapNegotiation)) { int reuse = DisarmTrapsReuseTime - GetSkillReuseTime(SkillDisarmTraps);
case 1:
reuse -= 1; if (reuse < 1)
break; reuse = 1;
case 2:
reuse -= 3;
break;
case 3:
reuse -= 5;
break;
}
p_timers.Start(pTimerDisarmTraps, reuse - 1); p_timers.Start(pTimerDisarmTraps, reuse - 1);
Trap* trap = entity_list.FindNearbyTrap(this, 60); Trap* trap = entity_list.FindNearbyTrap(this, 60);
@ -5359,17 +5353,9 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app)
if (ed->dmgtype == 252) { 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 int mod = spellbonuses.ReduceFallDamage + itembonuses.ReduceFallDamage + aabonuses.ReduceFallDamage;
case 1:
damage = damage * 95 / 100; damage -= damage * mod / 100;
break;
case 2:
damage = damage * 90 / 100;
break;
case 3:
damage = damage * 80 / 100;
break;
}
} }
if (damage < 0) if (damage < 0)
@ -5443,19 +5429,13 @@ void Client::Handle_OP_FeignDeath(const EQApplicationPacket *app)
Message(13, "Ability recovery time not yet met."); Message(13, "Ability recovery time not yet met.");
return; return;
} }
int reuse = FeignDeathReuseTime; int reuse = FeignDeathReuseTime;
switch (GetAA(aaRapidFeign)) reuse -= GetSkillReuseTime(SkillFeignDeath);
{
case 1: if (reuse < 1)
reuse -= 1; reuse = 1;
break;
case 2:
reuse -= 2;
break;
case 3:
reuse -= 5;
break;
}
p_timers.Start(pTimerFeignDeath, reuse - 1); p_timers.Start(pTimerFeignDeath, reuse - 1);
//BreakInvis(); //BreakInvis();
@ -7762,7 +7742,11 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
Message(13, "Ability recovery time not yet met."); Message(13, "Ability recovery time not yet met.");
return; return;
} }
int reuse = HideReuseTime - GetAA(209); int reuse = HideReuseTime - GetSkillReuseTime(SkillHide);
if (reuse < 1)
reuse = 1;
p_timers.Start(pTimerHide, reuse - 1); p_timers.Start(pTimerHide, reuse - 1);
float hidechance = ((GetSkill(SkillHide) / 250.0f) + .25) * 100; float hidechance = ((GetSkill(SkillHide) / 250.0f) + .25) * 100;
@ -7776,7 +7760,7 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
sa_out->parameter = 1; sa_out->parameter = 1;
entity_list.QueueClients(this, outapp, true); entity_list.QueueClients(this, outapp, true);
safe_delete(outapp); safe_delete(outapp);
if (GetAA(aaShroudofStealth)){ if (spellbonuses.ShroudofStealth || aabonuses.ShroudofStealth || itembonuses.ShroudofStealth){
improved_hidden = true; improved_hidden = true;
hidden = true; hidden = true;
} }
@ -11698,18 +11682,12 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app)
Message(13, "Ability recovery time not yet met."); Message(13, "Ability recovery time not yet met.");
return; return;
} }
int reuse = SenseTrapsReuseTime;
switch (GetAA(aaAdvTrapNegotiation)) { int reuse = SenseTrapsReuseTime - GetSkillReuseTime(SkillSenseTraps);
case 1:
reuse -= 1; if (reuse < 1)
break; reuse = 1;
case 2:
reuse -= 3;
break;
case 3:
reuse -= 5;
break;
}
p_timers.Start(pTimerSenseTraps, reuse - 1); p_timers.Start(pTimerSenseTraps, reuse - 1);
Trap* trap = entity_list.FindNearbyTrap(this, 800); Trap* trap = entity_list.FindNearbyTrap(this, 800);

View File

@ -408,6 +408,7 @@ struct StatBonuses {
uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs. 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 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_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
// AAs // AAs
int8 Packrat; //weight reduction for items, 1 point = 10% int8 Packrat; //weight reduction for items, 1 point = 10%
@ -438,7 +439,7 @@ struct StatBonuses {
int32 CombatStability; // Melee damage mitigation. int32 CombatStability; // Melee damage mitigation.
int32 DoubleRiposte; // Chance to double riposte int32 DoubleRiposte; // Chance to double riposte
int32 GiveDoubleRiposte[3]; // 0=Regular Chance, 1=Skill Attack Chance, 2=Skill 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 Ambidexterity; // Increase chance to duel wield by adding bonus 'skill'.
int32 PetMaxHP; // Increase the max hp of your pet. int32 PetMaxHP; // Increase the max hp of your pet.
int32 PetFlurry; // Chance for pet to flurry. int32 PetFlurry; // Chance for pet to flurry.
@ -466,6 +467,10 @@ struct StatBonuses {
int32 PetMeleeMitigation; // Add AC to owner's pet. int32 PetMeleeMitigation; // Add AC to owner's pet.
bool IllusionPersistence; // Causes illusions not to fade. bool IllusionPersistence; // Causes illusions not to fade.
uint16 extra_xtargets; // extra xtarget entries 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 typedef struct

View File

@ -112,7 +112,7 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) {
value -= GetFocusEffect(focusFcDamageAmt, spell_id); value -= GetFocusEffect(focusFcDamageAmt, spell_id);
value -= GetFocusEffect(focusFcDamageAmt2, 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; value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value)*ratio/100;
else if (IsNPC() && CastToNPC()->GetSpellScale()) 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(focusFcDamageAmt, spell_id);
value -= GetFocusEffect(focusFcDamageAmt2, 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); value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value);
if (IsNPC() && CastToNPC()->GetSpellScale()) if (IsNPC() && CastToNPC()->GetSpellScale())
@ -287,7 +287,7 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) {
value += GetFocusEffect(focusFcHealAmt, spell_id); value += GetFocusEffect(focusFcHealAmt, spell_id);
value += target->GetFocusIncoming(focusFcHealAmtIncoming, SE_FcHealAmtIncoming, this, 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 += GetExtraSpellAmt(spell_id, itembonuses.HealAmt, value) * modifier;
value += value*target->GetHealRate(spell_id, this)/100; 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) int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
{ {
if (spells[spell_id].not_extendable)
return duration;
int increase = 100; int increase = 100;
increase += GetFocusEffect(focusSpellDuration, spell_id); increase += GetFocusEffect(focusSpellDuration, spell_id);
int tic_inc = 0; int tic_inc = 0;

View File

@ -406,7 +406,7 @@ int Lua_Spell::GetSpellGroup() {
int Lua_Spell::GetPowerfulFlag() { int Lua_Spell::GetPowerfulFlag() {
Lua_Safe_Call_Int(); Lua_Safe_Call_Int();
return self->powerful_flag; return self->no_resist;
} }
int Lua_Spell::GetCastRestriction() { int Lua_Spell::GetCastRestriction() {
@ -436,7 +436,7 @@ int Lua_Spell::GetAEMaxTargets() {
int Lua_Spell::GetMaxTargets() { int Lua_Spell::GetMaxTargets() {
Lua_Safe_Call_Int(); Lua_Safe_Call_Int();
return self->maxtargets; return self->no_heal_damage_item_mod;
} }
bool Lua_Spell::GetPersistDeath() { bool Lua_Spell::GetPersistDeath() {

View File

@ -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 == "NimbusEffect") {return spells[spell_id].NimbusEffect; }
else if (id == "directional_start") {return static_cast<int32>(spells[spell_id].directional_start); } 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 == "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 == "suspendable") {return spells[spell_id].suspendable; }
else if (id == "viral_range") {return spells[spell_id].viral_range; } else if (id == "viral_range") {return spells[spell_id].viral_range; }
else if (id == "spellgroup") {return spells[spell_id].spellgroup; } else if (id == "spellgroup") {return spells[spell_id].spellgroup; }
else if (id == "rank") {return spells[spell_id].rank; } 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 == "CastRestriction") {return spells[spell_id].CastRestriction; }
else if (id == "AllowRest") {return spells[spell_id].AllowRest; } else if (id == "AllowRest") {return spells[spell_id].AllowRest; }
else if (id == "InCombat") {return spells[spell_id].InCombat; } else if (id == "InCombat") {return spells[spell_id].InCombat; }
else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; } else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; }
else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; } 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 == "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") {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); } else if (id == "min_dist_mod") {return static_cast<int32>(spells[spell_id].min_dist_mod); }

View File

@ -489,7 +489,7 @@ public:
inline uint32 GetLevelCon(uint8 iOtherLevel) const { inline uint32 GetLevelCon(uint8 iOtherLevel) const {
return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; } return this ? GetLevelCon(GetLevel(), iOtherLevel) : CON_GREEN; }
virtual void AddToHateList(Mob* other, uint32 hate = 0, int32 damage = 0, bool iYellForHelp = true, 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); bool RemoveFromHateList(Mob* mob);
void SetHateAmountOnEnt(Mob* other, int32 hate = 0, int32 damage = 0) { hate_list.SetHateAmountOnEnt(other,hate,damage);} 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)); } void HalveAggro(Mob *other) { uint32 in_hate = GetHateAmount(other); SetHateAmountOnEnt(other, (in_hate > 1 ? in_hate / 2 : 1)); }

View File

@ -780,7 +780,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
// define spells with fixed duration // 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 // 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; bBreak = true;
if (!bBreak) if (!bBreak)
@ -5228,6 +5228,9 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration) if (IsBardSong(spell_id) && type != focusFcBaseEffects && type != focusSpellDuration)
return 0; return 0;
if (spells[spell_id].not_focusable)
return 0;
int16 realTotal = 0; int16 realTotal = 0;
int16 realTotal2 = 0; int16 realTotal2 = 0;
int16 realTotal3 = 0; int16 realTotal3 = 0;
@ -5499,6 +5502,9 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
int16 NPC::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 realTotal = 0;
int16 realTotal2 = 0; int16 realTotal2 = 0;
bool rand_effectiveness = false; bool rand_effectiveness = false;

View File

@ -750,14 +750,6 @@ bool Client::CheckFizzle(uint16 spell_id)
// always at least 1% chance to fail or 5% to succeed // always at least 1% chance to fail or 5% to succeed
fizzlechance = fizzlechance < 1 ? 1 : (fizzlechance > 95 ? 95 : fizzlechance); 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); 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); 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) { if(aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; return true;
} }
@ -4094,7 +4086,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
if(aggro > 0) { if(aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; return true;
} }
@ -4110,7 +4102,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
if(aggro > 0) { if(aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; return true;
} else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) } else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false))
@ -4127,7 +4119,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
if (aggro > 0) { if (aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; return true;
} }
@ -4150,7 +4142,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
if(aggro > 0) { if(aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; return true;
} }
@ -4190,7 +4182,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
if(aggro > 0) { if(aggro > 0) {
AddToHateList(caster, aggro); AddToHateList(caster, aggro);
} else { } else {
AddToHateList(caster, 1); AddToHateList(caster, 1,0,true,false,false,spell_id);
} }
return true; 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 //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"); Log.Out(Logs::Detail, Logs::Spells, "Spell was unresistable");
return 100; return 100;

View File

@ -941,135 +941,10 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
float res = zone->random.Real(0, 99); float res = zone->random.Real(0, 99);
int aa_chance = 0; int aa_chance = 0;
//AA modifiers aa_chance = spellbonuses.ReduceTradeskillFail[spec->tradeskill] + itembonuses.ReduceTradeskillFail[spec->tradeskill] + aabonuses.ReduceTradeskillFail[spec->tradeskill];
//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;
}
}
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; 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); chance = mod_tradeskill_chance(chance, spec);
if (((spec->tradeskill==75) || GetGM() || (chance > res)) || zone->random.Roll(aa_chance)) { 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 Pottery = (GetRawSkill(SkillPottery) > 200) ? 1 : 0;
uint8 Tailoring = (GetRawSkill(SkillTailoring) > 200) ? 1 : 0; uint8 Tailoring = (GetRawSkill(SkillTailoring) > 200) ? 1 : 0;
uint8 SkillTotal = Baking + Smithing + Brewing + Fletching + Jewelry + Pottery + Tailoring; //Tradeskills above 200 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) { switch (tradeskill) {
case SkillBaking: case SkillBaking:
case SkillBlacksmithing: case SkillBlacksmithing: