Implemented a better method for developers who want to have additivie

worn bonuses than what was prior implemented.

Removed old rule RuleB(Spells, AdditiveBonusValues)

Replaced with new rule RuleI(AdditiveBonusWornType)

The rule value denotes a specific 'worntype' that is to be
checked on items. If the items 'worntype' matches the rules worntype
then any worn effect on that item will be cacluated additively
instead of taking the highest value. This will also stack with
regular worn effects that take highest value. Unless the value
is set to (2) which is what all live items use. If set to 2 then
all worn effects will be calculated additively (same as what the old
rule did).

In laymans terms. You can take 3 Cleave I items and put them on a character
and they will all add together if you set the worn type = 3 and the rule = 3.
Which would also add to any regular cleave set to worn type = 2.

Hope you enjoyed the novel.
This commit is contained in:
KayenEQ 2015-02-06 02:49:42 -05:00
parent b96e5a7f4d
commit bc6199a86f
8 changed files with 92 additions and 33 deletions

View File

@ -300,7 +300,7 @@ RULE_INT ( Spells, MaxCastTimeReduction, 50) //Max percent your spell cast time
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_INT ( Spells, AdditiveBonusWornType, 0) //Calc worn bonuses to add together (instead of taking highest) if set to THIS worn type. (2=Will covert live items automatically)
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, 70) //Determines chance for a root break check to occur each buff tick.

View File

@ -0,0 +1,4 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AdditiveBonusWornType', '0', 'Calcs worn bonuses to add together (instead of taking highest) if item set to THIS worn type. Will stack with regular worn bonuses. (2=Will cause all live items to use this behavior)');
-- This is no longer used - Set the above value equal to 2 to achieve the same effect.
DELETE FROM `rule_values` WHERE rule_name LIKE "Spells:AdditiveBonusValues";

View File

@ -169,6 +169,17 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
continue;
AddItemBonuses(inst, newbon, false, true);
}
//Optional ability to have worn effects calculate as an addititive bonus instead of highest value
if (RuleI(Spells, AdditiveBonusWornType) && RuleI(Spells, AdditiveBonusWornType) != ET_WornEffect){
for (i = MainCharm; i < MainAmmo; i++) {
const ItemInst* inst = m_inv[i];
if(inst == 0)
continue;
AdditiveWornBonuses(inst, newbon);
}
}
// Caps
if(newbon->HPRegen > CalcHPRegenCap())
newbon->HPRegen = CalcHPRegenCap();
@ -410,12 +421,12 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
else
newbon->DSMitigation += item->DSMitigation;
}
if (item->Worn.Effect>0 && (item->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, true, true);
if (item->Worn.Effect > 0 && item->Worn.Type == ET_WornEffect) {// latent effects
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type);
}
if (item->Focus.Effect>0 && (item->Focus.Type == ET_Focus)) { // focus effects
ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0, true, false);
ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0);
}
switch(item->BardType)
@ -537,6 +548,45 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAu
}
void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug) {
/*
Powerful Non-live like option allows developers to add worn effects on items that
can stack with other worn effects of the same spell effect type, instead of only taking the highest value.
Ie Cleave I = 40 pct cleave - So if you equip 3 cleave I items you will have a 120 pct cleave bonus.
To enable use RuleI(Spells, AdditiveBonusWornType)
Setting value = 2 Will force all live items to automatically be calculated additivily
Setting value to anything else will indicate the item 'worntype' that if set to the same, will cause the bonuses to use this calculation
which will also stack with regular (worntype 2) effects. [Ie set rule = 3 and item worntype = 3]
*/
if(!inst || !inst->IsType(ItemClassCommon))
return;
if(inst->GetAugmentType()==0 && isAug == true)
return;
const Item_Struct *item = inst->GetItem();
if(!inst->IsEquipable(GetBaseRace(),GetClass()))
return;
if(GetLevel() < item->ReqLevel)
return;
if (item->Worn.Effect > 0 && item->Worn.Type == RuleI(Spells, AdditiveBonusWornType))
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type);// Non-live like - Addititive latent effects
if (!isAug)
{
int i;
for (i = 0; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
AdditiveWornBonuses(inst->GetAugment(i),newbon,true);
}
}
}
void Client::CalcEdibleBonuses(StatBonuses* newbon) {
uint32 i;
@ -1393,7 +1443,7 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
int buff_count = GetMaxTotalSlots();
for(i = 0; i < buff_count; i++) {
if(buffs[i].spellid != SPELL_UNKNOWN){
ApplySpellsBonuses(buffs[i].spellid, buffs[i].casterlevel, newbon, buffs[i].casterid, false, false, buffs[i].ticsremaining,i);
ApplySpellsBonuses(buffs[i].spellid, buffs[i].casterlevel, newbon, buffs[i].casterid, false,0, buffs[i].ticsremaining,i);
if (buffs[i].numhits > 0)
Numhits(true);
@ -1416,10 +1466,11 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
if (GetClass() == BARD) newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
}
void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* new_bonus, uint16 casterId, bool item_bonus, bool IsWornEffect, uint32 ticsremaining, int buffslot,
void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* new_bonus, uint16 casterId, uint8 WornType, uint32 ticsremaining, int buffslot,
bool IsAISpellEffect, uint16 effect_id, int32 se_base, int32 se_limit, int32 se_max)
{
int i, effect_value, base2, max, effectid;
bool AdditiveWornBonus = false;
Mob *caster = nullptr;
if(!IsAISpellEffect && !IsValidSpell(spell_id))
@ -1439,15 +1490,19 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
uint8 focus = IsFocusEffect(spell_id, i);
if (focus)
{
if (!IsWornEffect)
new_bonus->FocusEffects[focus] = static_cast<uint8>(spells[spell_id].effectid[i]);
if (WornType){
if (RuleB(Spells, UseAdditiveFocusFromWornSlot))
new_bonus->FocusEffectsWorn[focus] += spells[spell_id].base[i];
}
else if (RuleB(Spells, UseAdditiveFocusFromWornSlot))
new_bonus->FocusEffectsWorn[focus] += spells[spell_id].base[i];
else
new_bonus->FocusEffects[focus] = static_cast<uint8>(spells[spell_id].effectid[i]);
continue;
}
if (WornType && (RuleI(Spells, AdditiveBonusWornType) == WornType))
AdditiveWornBonus = true;
effectid = spells[spell_id].effectid[i];
effect_value = CalcSpellEffectValue(spell_id, i, casterlevel, caster, ticsremaining);
@ -1813,7 +1868,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_CriticalHitChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus) {
if (AdditiveWornBonus) {
if(base2 == -1)
new_bonus->CriticalHitChance[HIGHEST_SKILL+1] += effect_value;
else
@ -1839,7 +1894,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_CrippBlowChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->CrippBlowChance += effect_value;
else if((effect_value < 0) && (new_bonus->CrippBlowChance > effect_value))
@ -1853,7 +1908,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_AvoidMeleeChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->AvoidMeleeChanceEffect += effect_value;
else if((effect_value < 0) && (new_bonus->AvoidMeleeChanceEffect > effect_value))
@ -1866,7 +1921,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_RiposteChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->RiposteChance += effect_value;
else if((effect_value < 0) && (new_bonus->RiposteChance > effect_value))
@ -1879,7 +1934,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_DodgeChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->DodgeChance += effect_value;
else if((effect_value < 0) && (new_bonus->DodgeChance > effect_value))
@ -1892,7 +1947,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_ParryChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->ParryChance += effect_value;
else if((effect_value < 0) && (new_bonus->ParryChance > effect_value))
@ -1905,7 +1960,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_DualWieldChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->DualWieldChance += effect_value;
else if((effect_value < 0) && (new_bonus->DualWieldChance > effect_value))
@ -1919,7 +1974,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_DoubleAttackChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->DoubleAttackChance += effect_value;
else if((effect_value < 0) && (new_bonus->DoubleAttackChance > effect_value))
@ -1933,7 +1988,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_TripleAttackChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->TripleAttackChance += effect_value;
else if((effect_value < 0) && (new_bonus->TripleAttackChance > effect_value))
@ -1946,7 +2001,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_MeleeLifetap:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->MeleeLifetap += spells[spell_id].base[i];
else if((effect_value < 0) && (new_bonus->MeleeLifetap > effect_value))
@ -1995,7 +2050,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_HundredHands:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->HundredHands += effect_value;
if (effect_value > 0 && effect_value > new_bonus->HundredHands)
@ -2017,7 +2072,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_HitChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus){
if (AdditiveWornBonus){
if(base2 == -1)
new_bonus->HitChanceEffect[HIGHEST_SKILL+1] += effect_value;
else
@ -2084,7 +2139,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_ProcChance:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
if (AdditiveWornBonus)
new_bonus->ProcChanceSPA += effect_value;
else if((effect_value < 0) && (new_bonus->ProcChanceSPA > effect_value))
@ -2122,7 +2177,7 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_DivineSave:
{
if (RuleB(Spells, AdditiveBonusValues) && item_bonus) {
if (AdditiveWornBonus) {
new_bonus->DivineSaveChance[0] += effect_value;
new_bonus->DivineSaveChance[1] = 0;
}
@ -2131,7 +2186,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
{
new_bonus->DivineSaveChance[0] = effect_value;
new_bonus->DivineSaveChance[1] = base2;
//SetDeathSaveChance(true);
}
break;
}
@ -3051,12 +3105,12 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
newbon->ProcChance += cur->CombatEffects;
}
if (cur->Worn.Effect>0 && (cur->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(cur->Worn.Effect, cur->Worn.Level, newbon);
ApplySpellsBonuses(cur->Worn.Effect, cur->Worn.Level, newbon, cur->Worn.Type);
}
if (RuleB(Spells, NPC_UseFocusFromItems)){
if (cur->Focus.Effect>0 && (cur->Focus.Type == ET_Focus)){ // focus effects
ApplySpellsBonuses(cur->Focus.Effect, cur->Focus.Level, newbon, 0, true);
ApplySpellsBonuses(cur->Focus.Effect, cur->Focus.Level, newbon);
}
}

View File

@ -10959,7 +10959,7 @@ void Bot::CalcItemBonuses()
}
}
if ((itemtmp->Worn.Effect != 0) && (itemtmp->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(itemtmp->Worn.Effect, itemtmp->Worn.Level, &itembonuses);
ApplySpellsBonuses(itemtmp->Worn.Effect, itemtmp->Worn.Level, &itembonuses,0,itemtmp->Worn.Type);
}
}
}
@ -11043,7 +11043,7 @@ void Bot::CalcItemBonuses()
}
}
if ((itemtmp->Worn.Effect != 0) && (itemtmp->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(itemtmp->Worn.Effect, itemtmp->Worn.Level, &itembonuses);
ApplySpellsBonuses(itemtmp->Worn.Effect, itemtmp->Worn.Level, &itembonuses,0,itemtmp->Worn.Type);
}
}
}

View File

@ -1257,6 +1257,7 @@ protected:
friend class Mob;
void CalcItemBonuses(StatBonuses* newbon);
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false);
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
void CalcEdibleBonuses(StatBonuses* newbon);
void CalcAABonuses(StatBonuses* newbon);

View File

@ -449,11 +449,11 @@ void Merc::AddItemBonuses(const Item_Struct *item, StatBonuses* newbon) {
newbon->DSMitigation += item->DSMitigation;
}
if (item->Worn.Effect>0 && (item->Worn.Type == ET_WornEffect)) { // latent effects
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, true);
ApplySpellsBonuses(item->Worn.Effect, item->Worn.Level, newbon, 0, item->Worn.Type);
}
if (item->Focus.Effect>0 && (item->Focus.Type == ET_Focus)) { // focus effects
ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0, true);
ApplySpellsBonuses(item->Focus.Effect, item->Focus.Level, newbon, 0);
}
switch(item->BardType)

View File

@ -194,7 +194,7 @@ public:
bool IsBeneficialAllowed(Mob *target);
virtual int GetCasterLevel(uint16 spell_id);
void ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* newbon, uint16 casterID = 0,
bool item_bonus = false, bool IsWornEffect = false, uint32 ticsremaining = 0, int buffslot = -1,
uint8 WornType = 0, uint32 ticsremaining = 0, int buffslot = -1,
bool IsAISpellEffect = false, uint16 effect_id = 0, int32 se_base = 0, int32 se_limit = 0, int32 se_max = 0);
void NegateSpellsBonuses(uint16 spell_id);
virtual float GetActSpellRange(uint16 spell_id, float range, bool IsBard = false);

View File

@ -2559,7 +2559,7 @@ void NPC::ApplyAISpellEffects(StatBonuses* newbon)
for(int i=0; i < AIspellsEffects.size(); i++)
{
ApplySpellsBonuses(0, 0, newbon, 0, false, 0,-1,
ApplySpellsBonuses(0, 0, newbon, 0, 0, 0,-1,
true, AIspellsEffects[i].spelleffectid, AIspellsEffects[i].base, AIspellsEffects[i].limit,AIspellsEffects[i].max);
}