merging upstream

This commit is contained in:
Arthur Ice 2014-03-26 15:17:08 -07:00
commit 11fbb86f8b
14 changed files with 499 additions and 51 deletions

View File

@ -1,5 +1,21 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 03/22/2014 ==
Uleat: Moved the existing 'load_bots' and 'drop_bots' sqls into the emu git repository for the time being. Look to the
/utils/sql/git/bots/ folder to find them. The 'load_bots' sql has been updated to include the below fix, as well as
collecting the multiple files into one. This should allow HeidiSQL to now run it properly. (You will still need to
search for the optional scripts for the time being.)
Uleat: Fixed bot guild script failure. For existing bot databases only, use this sql file to update the affected table and view.
Required Bot SQL: 2014_03_22_BotGuildMember_ScriptFailureFix.sql
== 03/19/2014 ==
Kayen: Further refinements to root, charm, mez and fear behaviors - See commit message for full details
New rule for 'Fear' break chance, and updates to default settings of various rules.
Optional SQL: utils/sql/git/optional/2014_03_19_RulesUpdates.sql
== 03/18/2014 ==
Uleat: Fixed the name/account discrepancy in the Client::SummonItem() code as well as the origin of the mistake (thanks K_K!)
Uleat: Condensed and rearranged certain snippets of code in SummonItem(). Added a 'augslotvisible' check to validation check.

View File

@ -290,17 +290,18 @@ RULE_BOOL ( Spells, NPCIgnoreBaseImmunity, true) // Whether or not NPCs get to i
RULE_REAL ( Spells, AvgSpellProcsPerMinute, 6.0) //Adjust rate for sympathetic spell procs
RULE_INT ( Spells, ResistFalloff, 67) //Max that level that will adjust our resist chance based on level modifiers
RULE_INT ( Spells, CharismaEffectiveness, 10) // Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod.
RULE_INT ( Spells, CharismaEffectivenessCap, 200) // Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod.
RULE_INT ( Spells, CharismaEffectivenessCap, 255) // Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod.
RULE_BOOL ( Spells, CharismaCharmDuration, false) // Allow CHA resist mod to extend charm duration.
RULE_INT ( Spells, CharmBreakCheckChance, 25) //Determines chance for a charm break check to occur each buff tick.
RULE_INT ( Spells, MaxCastTimeReduction, 50) //Max percent your spell cast time can be reduced by spell haste
RULE_INT ( Spells, RootBreakFromSpells, 20) //Chance for root to break when cast on.
RULE_INT ( Spells, RootBreakFromSpells, 55) //Chance for root to break when cast on.
RULE_INT ( Spells, DeathSaveCharismaMod, 3) //Determines how much charisma effects chance of death save firing.
RULE_INT ( Spells, DivineInterventionHeal, 8000) //Divine intervention heal amount.
RULE_BOOL ( Spells, AdditiveBonusValues, false) //Allow certain bonuses to be calculated by adding together the value from each item, instead of taking the highest value. (ie Add together all Cleave Effects)
RULE_BOOL ( Spells, UseCHAScribeHack, false) //ScribeSpells and TrainDiscs quest functions will ignore entries where field 12 is CHA. What's the best way to do this?
RULE_BOOL ( Spells, BuffLevelRestrictions, true) //Buffs will not land on low level toons like live
RULE_INT ( Spells, RootBreakCheckChance, 40) //Determines chance for a root break check to occur each buff tick.
RULE_INT ( Spells, RootBreakCheckChance, 70) //Determines chance for a root break check to occur each buff tick.
RULE_INT ( Spells, FearBreakCheckChance, 70) //Determines chance for a fear break check to occur each buff tick.
RULE_CATEGORY_END()
RULE_CATEGORY( Combat )

View File

@ -390,7 +390,7 @@ bool IsPartialCapableSpell(uint16 spell_id)
if (spells[spell_id].no_partial_resist)
return false;
if (IsPureNukeSpell(spell_id) || IsFearSpell(spell_id))
if (IsPureNukeSpell(spell_id))
return true;
return false;

View File

@ -10,3 +10,6 @@ All updates will follow a specific format of YYYY_MM_DD_Desc.sql, this is so it'
So the following is a good example of what I expect to see
2013_02_16_GitConversion.sql
The new bots/ folder contains two sub-folders named optional/ and required/ for updates.

View File

@ -0,0 +1,3 @@
Use this new load_bots.sql to source bot information into your database.
This file now contains all of the script information so that it may be run from inside of HeidiSQL.

View File

@ -0,0 +1,21 @@
DROP TABLE IF EXISTS `botbuffs`;
DROP TABLE IF EXISTS `botpetinventory`;
DROP TABLE IF EXISTS `botpetbuffs`;
DROP TABLE IF EXISTS `botpets`;
DROP TABLE IF EXISTS `botgroupmembers`;
DROP TABLE IF EXISTS `botgroup`;
DROP TABLE IF EXISTS `botgroups`;
DROP TABLE IF EXISTS `botinventory`;
DROP TABLE IF EXISTS `botguildmembers`;
DROP TABLE IF EXISTS `botstances`;
DROP TABLE IF EXISTS `bottimers`;
DROP TABLE IF EXISTS `bots`;
DROP VIEW IF EXISTS `vwGuildMembers`;
DROP VIEW IF EXISTS `vwBotCharacterMobs`;
DROP VIEW IF EXISTS `vwBotGroups`;
delete from rule_values where rule_name like 'Bots%' and ruleset_id = 1;
delete from commands where command = 'bot';
update spawn2 set enabled = 0 where id in (59297,59298);

View File

@ -0,0 +1,307 @@
-- This is pretty much a straight copy of the original files with fixes applied.
-- HeidiSQL does not like sub-directory references, so this should now run from there.
-- The 'headers' are left in place for reference only.
-- FILE:
-- source player_tables/botguildmembers.sql;
CREATE TABLE IF NOT EXISTS `botguildmembers` (
`char_id` int(11) NOT NULL default '0',
`guild_id` mediumint(8) unsigned NOT NULL default '0',
`rank` tinyint(3) unsigned NOT NULL default '0',
`tribute_enable` tinyint(3) unsigned NOT NULL default '0',
`total_tribute` int(10) unsigned NOT NULL default '0',
`last_tribute` int(10) unsigned NOT NULL default '0',
`banker` tinyint(3) unsigned NOT NULL default '0',
`public_note` text NULL,
`alt` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`char_id`)
) ENGINE=InnoDB;
-- FILE:
-- source player_tables/bots.sql;
update spawn2 set enabled = 1 where id in (59297,59298);
INSERT INTO rule_values VALUES ('1', 'Bots:BotManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.');
INSERT INTO rule_values VALUES ('1', 'Bots:BotFinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.');
INSERT INTO rule_values VALUES ('1', 'Bots:CreateBotCount', '150', 'Number of bots that each account can create');
INSERT INTO rule_values VALUES ('1', 'Bots:SpawnBotCount', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid');
INSERT INTO rule_values VALUES ('1', 'Bots:BotQuest', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl');
INSERT INTO rule_values VALUES ('1', 'Bots:BotGroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.');
INSERT INTO rule_values VALUES ('1', 'Bots:BotSpellQuest', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.');
-- this is a hack fix to maintain the original file process
delete from rule_values where rule_name like 'Bots%' and ruleset_id = 1;
INSERT INTO rule_values VALUES ('1', 'Bots:BotAAExpansion', '8', 'The expansion through which bots will obtain AAs');
-- field count has changed
-- INSERT INTO `commands` VALUES ('bot', '0', 'Type \"#bot help\" to the see the list of available commands for bots.');
INSERT INTO `commands` VALUES ('bot', '0');
CREATE TABLE bots (
`BotID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`BotOwnerCharacterID` int(10) unsigned NOT NULL,
`BotSpellsID` int(10) unsigned NOT NULL DEFAULT '0',
`Name` varchar(64) NOT NULL,
`LastName` varchar(32) DEFAULT NULL,
`BotLevel` tinyint(2) unsigned NOT NULL DEFAULT '0',
`Race` smallint(5) NOT NULL DEFAULT '0',
`Class` tinyint(2) NOT NULL DEFAULT '0',
`Gender` tinyint(2) NOT NULL DEFAULT '0',
`Size` float NOT NULL DEFAULT '0',
`Face` int(10) NOT NULL DEFAULT '1',
`LuclinHairStyle` int(10) NOT NULL DEFAULT '1',
`LuclinHairColor` int(10) NOT NULL DEFAULT '1',
`LuclinEyeColor` int(10) NOT NULL DEFAULT '1',
`LuclinEyeColor2` int(10) NOT NULL DEFAULT '1',
`LuclinBeardColor` int(10) NOT NULL DEFAULT '1',
`LuclinBeard` int(10) NOT NULL DEFAULT '0',
`DrakkinHeritage` int(10) NOT NULL DEFAULT '0',
`DrakkinTattoo` int(10) NOT NULL DEFAULT '0',
`DrakkinDetails` int(10) NOT NULL DEFAULT '0',
`HP` INTEGER NOT NULL DEFAULT '0',
`Mana` INTEGER NOT NULL DEFAULT '0',
`MR` smallint(5) NOT NULL DEFAULT '0',
`CR` smallint(5) NOT NULL DEFAULT '0',
`DR` smallint(5) NOT NULL DEFAULT '0',
`FR` smallint(5) NOT NULL DEFAULT '0',
`PR` smallint(5) NOT NULL DEFAULT '0',
`Corrup` SMALLINT(5) NOT NULL DEFAULT '0',
`AC` smallint(5) NOT NULL DEFAULT '0',
`STR` mediumint(8) NOT NULL DEFAULT '75',
`STA` mediumint(8) NOT NULL DEFAULT '75',
`DEX` mediumint(8) NOT NULL DEFAULT '75',
`AGI` mediumint(8) NOT NULL DEFAULT '75',
`_INT` mediumint(8) NOT NULL DEFAULT '80',
`WIS` mediumint(8) NOT NULL DEFAULT '75',
`CHA` mediumint(8) NOT NULL DEFAULT '75',
`ATK` mediumint(9) NOT NULL DEFAULT '0',
`BotCreateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`LastSpawnDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`TotalPlayTime` int(10) unsigned NOT NULL DEFAULT '0',
`LastZoneId` smallint(6) NOT NULL DEFAULT '0',
`BotInspectMessage` VARCHAR(256) NOT NULL DEFAULT '',
PRIMARY KEY (`BotID`)
) ENGINE=InnoDB;
ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`);
ALTER TABLE `guild_members` DROP PRIMARY KEY;
DROP VIEW IF EXISTS `vwGuildMembers`;
CREATE VIEW `vwGuildMembers` AS
select 'C' as mobtype,
cm.char_id,
cm.guild_id,
cm.rank,
cm.tribute_enable,
cm.total_tribute,
cm.last_tribute,
cm.banker,
cm.public_note,
cm.alt
from guild_members as cm
union all
select 'B' as mobtype,
bm.char_id,
bm.guild_id,
bm.rank,
bm.tribute_enable,
bm.total_tribute,
bm.last_tribute,
bm.banker,
bm.public_note,
bm.alt
from botguildmembers as bm;
DROP VIEW IF EXISTS `vwBotCharacterMobs`;
CREATE VIEW `vwBotCharacterMobs` AS
select 'C' as mobtype,
c.id,
c.name,
c.class,
c.level,
c.timelaston,
c.zoneid
from character_ as c
union all
select 'B' as mobtype,
b.BotID as id,
b.Name as name,
b.Class as class,
b.BotLevel as level,
0 as timelaston,
0 as zoneid
from bots as b;
-- FILE:
-- source player_tables/botpetstatepersists.sql;
DROP TABLE IF EXISTS `botpetinventory`;
DROP TABLE IF EXISTS `botpetbuffs`;
DROP TABLE IF EXISTS `botpets`;
CREATE TABLE IF NOT EXISTS `botpets` (
`BotPetsId` integer unsigned NOT NULL AUTO_INCREMENT,
`PetId` integer unsigned NOT NULL DEFAULT '0',
`BotId` integer unsigned NOT NULL DEFAULT '0',
`Name` varchar(64) NULL,
`Mana` integer NOT NULL DEFAULT '0',
`HitPoints` integer NOT NULL DEFAULT '0',
PRIMARY KEY (`BotPetsId`),
KEY `FK_botpets_1` (`BotId`),
CONSTRAINT `FK_botpets_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`),
CONSTRAINT `U_botpets_1` UNIQUE (`BotId`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `botpetbuffs` (
`BotPetBuffId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`BotPetsId` int(10) unsigned NOT NULL DEFAULT '0',
`SpellId` int(10) unsigned NOT NULL DEFAULT '0',
`CasterLevel` int(10) unsigned NOT NULL DEFAULT '0',
`Duration` int(11) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`BotPetBuffId`),
KEY `FK_botpetbuffs_1` (`BotPetsId`),
CONSTRAINT `FK_botpetbuffs_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `botpetinventory` (
`BotPetInventoryId` integer unsigned NOT NULL AUTO_INCREMENT,
`BotPetsId` integer unsigned NOT NULL DEFAULT '0',
`ItemId` integer unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`BotPetInventoryId`),
KEY `FK_botpetinventory_1` (`BotPetsId`),
CONSTRAINT `FK_botpetinventory_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
-- FILE:
-- source player_tables/botinventory.sql;
CREATE TABLE IF NOT EXISTS botinventory (
BotInventoryID integer unsigned NOT NULL auto_increment,
BotID integer unsigned NOT NULL DEFAULT '0',
SlotID integer signed NOT NULL DEFAULT '0',
ItemID integer unsigned NOT NULL DEFAULT '0',
charges tinyint(3) unsigned DEFAULT 0,
color integer unsigned NOT NULL DEFAULT 0,
augslot1 mediumint(7) unsigned NOT NULL DEFAULT 0,
augslot2 mediumint(7) unsigned NOT NULL DEFAULT 0,
augslot3 mediumint(7) unsigned NOT NULL DEFAULT 0,
augslot4 mediumint(7) unsigned NOT NULL DEFAULT 0,
augslot5 mediumint(7) unsigned DEFAULT 0,
instnodrop tinyint(1) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (BotInventoryID),
KEY FK_botinventory_1 (BotID),
CONSTRAINT FK_botinventory_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
) ENGINE=InnoDB;
-- FILE:
-- source player_tables/botbuffs.sql;
DROP TABLE IF EXISTS `botbuffs`;
CREATE TABLE `botbuffs` (
`BotBuffId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`BotId` int(10) unsigned NOT NULL DEFAULT '0',
`SpellId` int(10) unsigned NOT NULL DEFAULT '0',
`CasterLevel` int(10) unsigned NOT NULL DEFAULT '0',
`DurationFormula` int(10) unsigned NOT NULL DEFAULT '0',
`TicsRemaining` int(11) unsigned NOT NULL DEFAULT '0',
`PoisonCounters` int(11) unsigned NOT NULL DEFAULT '0',
`DiseaseCounters` int(11) unsigned NOT NULL DEFAULT '0',
`CurseCounters` int(11) unsigned NOT NULL DEFAULT '0',
`CorruptionCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`HitCount` int(10) unsigned NOT NULL DEFAULT '0',
`MeleeRune` int(10) unsigned NOT NULL DEFAULT '0',
`MagicRune` int(10) unsigned NOT NULL DEFAULT '0',
`DeathSaveSuccessChance` int(10) unsigned NOT NULL DEFAULT '0',
`CasterAARank` int(10) unsigned NOT NULL DEFAULT '0',
`Persistent` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`BotBuffId`),
KEY `FK_botbuff_1` (`BotId`),
CONSTRAINT `FK_botbuff_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
-- FILE:
-- source player_tables/botadventuring.sql;
DELIMITER $$
DROP FUNCTION IF EXISTS `GetMobType` $$
CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)
BEGIN
DECLARE Result CHAR(1);
SET Result = NULL;
IF (select count(*) from character_ where name = mobname) > 0 THEN
SET Result = 'C';
ELSEIF (select count(*) from bots where Name = mobname) > 0 THEN
SET Result = 'B';
END IF;
RETURN Result;
END $$
DELIMITER ;
DROP VIEW IF EXISTS `vwGroups`;
CREATE VIEW `vwGroups` AS
select g.groupid as groupid,
GetMobType(g.name) as mobtype,
g.name as name,
g.charid as mobid,
ifnull(c.level, b.BotLevel) as level
from group_id as g
left join character_ as c on g.name = c.name
left join bots as b on g.name = b.Name;
-- FILE:
-- source player_tables/botgroups.sql;
DROP TABLE IF EXISTS `botgroupmembers`;
DROP TABLE IF EXISTS `botgroup`;
CREATE TABLE IF NOT EXISTS `botgroup` (
`BotGroupId` integer unsigned NOT NULL AUTO_INCREMENT,
`BotGroupLeaderBotId` integer unsigned NOT NULL DEFAULT '0',
`BotGroupName` varchar(64) NOT NULL,
PRIMARY KEY (`BotGroupId`),
KEY FK_botgroup_1 (BotGroupLeaderBotId),
CONSTRAINT FK_botgroup_1 FOREIGN KEY (BotGroupLeaderBotId) REFERENCES bots (BotID)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `botgroupmembers` (
`BotGroupMemberId` integer unsigned NOT NULL AUTO_INCREMENT,
`BotGroupId` integer unsigned NOT NULL DEFAULT '0',
`BotId` integer unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`BotGroupMemberId`),
KEY FK_botgroupmembers_1 (BotGroupId),
CONSTRAINT FK_botgroupmembers_1 FOREIGN KEY (BotGroupId) REFERENCES botgroup (BotGroupId),
KEY FK_botgroupmembers_2 (BotId),
CONSTRAINT FK_botgroupmembers_2 FOREIGN KEY (BotId) REFERENCES bots (BotID)
) ENGINE=InnoDB;
DROP VIEW IF EXISTS `vwBotGroups`;
CREATE VIEW `vwBotGroups` AS
select g.BotGroupId,
g.BotGroupName,
g.BotGroupLeaderBotId,
b.Name as BotGroupLeaderName,
b.BotOwnerCharacterId,
c.name as BotOwnerCharacterName
from botgroup as g
join bots as b on g.BotGroupLeaderBotId = b.BotID
join character_ as c on b.BotOwnerCharacterID = c.id
order by b.BotOwnerCharacterId, g.BotGroupName;
-- FILE:
-- source player_tables/botstances.sql;
CREATE TABLE botstances (
BotID int(10) unsigned NOT NULL default '0',
StanceID tinyint unsigned NOT NULL default '0',
PRIMARY KEY (BotID),
CONSTRAINT FK_botstances_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
);
-- FILE:
-- source player_tables/bottimers.sql;
CREATE TABLE bottimers (
BotID int(10) unsigned NOT NULL default '0',
TimerID int(10) unsigned NOT NULL default '0',
Value int(10) unsigned NOT NULL default '0',
PRIMARY KEY (BotID),
CONSTRAINT FK_bottimers_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
)

View File

@ -0,0 +1,27 @@
ALTER TABLE `botguildmembers` ADD `alt` TINYINT UNSIGNED NOT NULL DEFAULT '0' AFTER `public_note`;
DROP VIEW IF EXISTS `vwGuildMembers`;
CREATE VIEW `vwGuildMembers` AS
select 'C' as mobtype,
cm.char_id,
cm.guild_id,
cm.rank,
cm.tribute_enable,
cm.total_tribute,
cm.last_tribute,
cm.banker,
cm.public_note,
cm.alt
from guild_members as cm
union all
select 'B' as mobtype,
bm.char_id,
bm.guild_id,
bm.rank,
bm.tribute_enable,
bm.total_tribute,
bm.last_tribute,
bm.banker,
bm.public_note,
bm.alt
from botguildmembers as bm;

View File

@ -0,0 +1,6 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:FearBreakCheckChance', '70', 'Chance for fear to do a resist check each tick. Decrease for longer fears.');
-- Updates rule value if server is using the OLD DEFAULT values
UPDATE rule_values SET rule_value = 55 WHERE rule_name LIKE 'Spells:RootBreakFromSpells' AND rule_value = 20;
UPDATE rule_values SET rule_value = 70 WHERE rule_name LIKE 'Spells:RootBreakCheckChance' AND rule_value = 40;
UPDATE rule_values SET rule_value = 255 WHERE rule_name LIKE 'Spells:CharismaResistCap' AND rule_value = 200;

View File

@ -1398,7 +1398,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
/*
Charm formula is correct based on over 50 hours of personal live parsing - Kayen
Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 200 CHA
Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 255 CHA (min ~ 75 CHA)
Charisma DOES NOT extend charm durations.
Base effect value of charm spells in the spell file DOES NOT effect duration OR resist rate (unclear if does anything)
Charm has a lower limit of 5% chance to break per tick, regardless of resist modifiers / level difference.

View File

@ -3680,7 +3680,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
if(spell_id != SPELL_UNKNOWN && !iBuffTic) {
//see if root will break
if (IsRooted() && !FromDamageShield) // neotoyko: only spells cancel root
TryRootFadeByDamage(buffslot);
TryRootFadeByDamage(buffslot, attacker);
}
else if(spell_id == SPELL_UNKNOWN)
{
@ -4548,34 +4548,43 @@ void Mob::TrySkillProc(Mob *on, uint16 skill, float chance)
}
}
bool Mob::TryRootFadeByDamage(int buffslot)
{
/*Dev Quote 2010: http://forums.station.sony.com/eq/posts/list.m?topic_id=161443
The Viscid Roots AA does the following: Reduces the chance for root to break by X percent.
There is no distinction of any kind between the caster inflicted damage, or anyone
else's damage. There is also no distinction between Direct and DOT damage in the root code.
There is however, a provision that if the damage inflicted is greater than 500 per hit, the
chance to break root is increased. My guess is when this code was put in place, the devs at
the time couldn't imagine DOT damage getting that high.
*/
bool Mob::TryRootFadeByDamage(int buffslot, Mob* attacker) {
/* General Mechanics
- Check buffslot to make sure damage from a root does not cancel the root
- If multiple roots on target, always and only checks first root slot and if broken only removes that slots root.
- Only roots on determental spells can be broken by damage.
*/
/*Dev Quote 2010: http://forums.station.sony.com/eq/posts/list.m?topic_id=161443
The Viscid Roots AA does the following: Reduces the chance for root to break by X percent.
There is no distinction of any kind between the caster inflicted damage, or anyone
else's damage. There is also no distinction between Direct and DOT damage in the root code.
if (!spellbonuses.Root[0] || spellbonuses.Root[1] < 0)
return false;
/* General Mechanics
- Check buffslot to make sure damage from a root does not cancel the root
- If multiple roots on target, always and only checks first root slot and if broken only removes that slots root.
- Only roots on determental spells can be broken by damage.
- Root break chance values obtained from live parses.
*/
if (IsDetrimentalSpell(spellbonuses.Root[1]) && spellbonuses.Root[1] != buffslot){
if (!attacker || !spellbonuses.Root[0] || spellbonuses.Root[1] < 0)
return false;
int BreakChance = RuleI(Spells, RootBreakFromSpells);
if (IsDetrimentalSpell(spellbonuses.Root[1]) && spellbonuses.Root[1] != buffslot){
BreakChance -= BreakChance*buffs[spellbonuses.Root[1]].RootBreakChance/100;
int BreakChance = RuleI(Spells, RootBreakFromSpells);
if (BreakChance < 1)
BreakChance = 1;
BreakChance -= BreakChance*buffs[spellbonuses.Root[1]].RootBreakChance/100;
int level_diff = attacker->GetLevel() - GetLevel();
//Use baseline if level difference <= 1 (ie. If target is (1) level less than you, or equal or greater level)
if (level_diff == 2)
BreakChance = (BreakChance * 80) /100; //Decrease by 20%;
else if (level_diff >= 3 && level_diff <= 20)
BreakChance = (BreakChance * 60) /100; //Decrease by 40%;
else if (level_diff > 21)
BreakChance = (BreakChance * 20) /100; //Decrease by 80%;
if (BreakChance < 1)
BreakChance = 1;
if (MakeRandomInt(0, 99) < BreakChance) {

View File

@ -191,7 +191,7 @@ public:
virtual int32 GetActSpellDuration(uint16 spell_id, int32 duration){ return duration;}
virtual int32 GetActSpellCasttime(uint16 spell_id, int32 casttime);
float ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override = false,
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false);
int resist_override = 0, bool CharismaCheck = false, bool CharmTick = false, bool IsRoot = false);
uint16 GetSpecializeSkillValue(uint16 spell_id) const;
void SendSpellBarDisable();
void SendSpellBarEnable(uint16 spellid);
@ -593,7 +593,7 @@ public:
void MeleeLifeTap(int32 damage);
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
bool ImprovedTaunt();
bool TryRootFadeByDamage(int buffslot);
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);

View File

@ -830,15 +830,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Fear: %+i", effect_value);
#endif
//use resistance value for duration...
buffs[buffslot].ticsremaining = ((buffs[buffslot].ticsremaining * partial) / 100);
if(IsClient())
{
if(buffs[buffslot].ticsremaining > RuleI(Character, MaxFearDurationForPlayerCharacter))
buffs[buffslot].ticsremaining = RuleI(Character, MaxFearDurationForPlayerCharacter);
}
if(RuleB(Combat, EnableFearPathing)){
if(IsClient())
{
@ -3327,6 +3325,22 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
if (MakeRandomInt(0, 99) < RuleI(Spells, RootBreakCheckChance)){
float resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster, 0,0,0,0,true);
if(resist_check == 100)
break;
else
if(!TryFadeEffect(slot))
BuffFadeBySlot(slot);
}
break;
}
case SE_Fear:
{
if (MakeRandomInt(0, 99) < RuleI(Spells, FearBreakCheckChance)){
float resist_check = ResistSpell(spells[spell_id].resisttype, spell_id, caster);
if(resist_check == 100)

View File

@ -3409,7 +3409,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r
// not all unresistable, so changing this to only check certain spells
if(IsResistableSpell(spell_id))
{
if (IsCharmSpell(spell_id))
if (IsCharmSpell(spell_id) || IsMezSpell(spell_id) || IsFearSpell(spell_id))
spell_effectiveness = spelltar->ResistSpell(spells[spell_id].resisttype, spell_id, this, use_resist_adjust, resist_adjust,true);
else
spell_effectiveness = spelltar->ResistSpell(spells[spell_id].resisttype, spell_id, this, use_resist_adjust, resist_adjust);
@ -4040,7 +4040,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
// pvp_resist_base
// pvp_resist_calc
// pvp_resist_cap
float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override, int resist_override, bool CharismaCheck, bool CharmTick)
float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use_resist_override, int resist_override, bool CharismaCheck, bool CharmTick, bool IsRoot)
{
if(!caster)
@ -4079,8 +4079,10 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
}
//Check for fear resist
bool IsFear = false;
if(IsFearSpell(spell_id))
{
IsFear = true;
int fear_resist_bonuses = CalcFearResistChance();
if(MakeRandomInt(0, 99) < fear_resist_bonuses)
{
@ -4089,7 +4091,7 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
}
}
if (!CharismaCheck){
if (!CharmTick){
//Check for Spell Effect specific resistance chances (ie AA Mental Fortitude)
int se_resist_bonuses = GetSpellEffectResistChance(spell_id);
@ -4232,15 +4234,38 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
if (CharismaCheck)
{
//Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 200 CHA
//'Lull' spells only check charisma if inital cast is resisted to see if mob will aggro, same modifier/cap as above.
//Charisma DOES NOT extend charm durations.
/*
Charisma ONLY effects the initial resist check when charm is cast with 10 CHA = -1 Resist mod up to 255 CHA (min ~ 75 cha)
Charisma less than ~ 75 gives a postive modifier to resist checks at approximate ratio of -10 CHA = +6 Resist.
Mez spells do same initial resist check as a above.
Lull spells only check charisma if inital cast is resisted to see if mob will aggro, same modifier/cap as above.
Charisma DOES NOT extend charm durations.
Fear resist chance is given a -20 resist modifier if CHA is < 100, from 100-255 it progressively reduces the negative mod to 0.
Fears verse undead DO NOT apply a charisma modifer. (Note: unknown Base1 values defined in undead fears do not effect duration).
*/
int16 charisma = caster->GetCHA();
if (charisma > RuleI(Spells, CharismaEffectivenessCap))
charisma = RuleI(Spells, CharismaEffectivenessCap);
if (IsFear && (spells[spell_id].targettype != 10)){
resist_modifier -= charisma/RuleI(Spells, CharismaEffectiveness);
if (charisma < 100)
resist_modifier -= 20;
else if (charisma <= 255)
resist_modifier += (charisma - 100)/8;
}
else {
if (charisma >= 75){
if (charisma > RuleI(Spells, CharismaEffectivenessCap))
charisma = RuleI(Spells, CharismaEffectivenessCap);
resist_modifier -= (charisma - 75)/RuleI(Spells, CharismaEffectiveness);
}
else
resist_modifier += ((75 - charisma)/10) * 6; //Increase Resist Chance
}
}
//Lull spells DO NOT use regular resists on initial cast, instead they use a flat +15 modifier. Live parses confirm this.
@ -4266,9 +4291,25 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
resist_chance = spells[spell_id].MinResist;
}
//Charm can not have less than 5% chance to fail.
if (CharmTick && (resist_chance < 10))
resist_chance = 10;
//Average charm duration agianst mobs with 0% chance to resist on LIVE is ~ 68 ticks.
//Minimum resist chance should be caclulated factoring in the RuleI(Spells, CharmBreakCheckChance)
if (CharmTick) {
int min_charmbreakchance = ((100/RuleI(Spells, CharmBreakCheckChance))/66 * 100)*2;
if (resist_chance < min_charmbreakchance)
resist_chance = min_charmbreakchance;
}
//Average root duration agianst mobs with 0% chance to resist on LIVE is ~ 22 ticks (6% resist chance).
//Minimum resist chance should be caclulated factoring in the RuleI(Spells, RootBreakCheckChance)
if (IsRoot) {
int min_rootbreakchance = ((100/RuleI(Spells, RootBreakCheckChance))/22 * 100)*2;
if (resist_chance < min_rootbreakchance)
resist_chance = min_rootbreakchance;
}
//Finally our roll
int roll = MakeRandomInt(0, 200);