mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 14:41:28 +00:00
Update to how bonuses are calculated in chance to hit code to be
consistent across all relevant effects (treating avoidance and hit chance bonuses equally). Rule ArcheryHitPenalty will now calc correctly (Was doing basically nothing) New field npc_types 'Avoidance' (add avoidance bonus to npc) Rules for setting min / max chance to hit
This commit is contained in:
parent
152a7410b6
commit
4f07be2343
@ -44,6 +44,10 @@ Param1: Max Ranged distance (default: 250)
|
|||||||
Param2: Percent Chance to Hit modifier
|
Param2: Percent Chance to Hit modifier
|
||||||
Param3: Percent Total Damage modifier
|
Param3: Percent Total Damage modifier
|
||||||
|
|
||||||
|
Kayen: Updated to Chance to Hit code with how bonuses are applied to be consistent for all effects.
|
||||||
|
Added field to npc_types 'Avoidance' which will modify chance to avoid melee
|
||||||
|
Added rules to set max and min chance to hit from melee/ranged (Default 95% / 5%)
|
||||||
|
|
||||||
Required SQL: utils/sql/git/required/2014_07_10_npc_spells.sql
|
Required SQL: utils/sql/git/required/2014_07_10_npc_spells.sql
|
||||||
Optional SQL: utils/sql/git/optional/2014_07_10_AICastingRules.sql
|
Optional SQL: utils/sql/git/optional/2014_07_10_AICastingRules.sql
|
||||||
|
|
||||||
|
|||||||
@ -358,6 +358,8 @@ RULE_REAL ( Combat, HitBonusPerLevel, 1.2) //You gain this % of hit for every le
|
|||||||
RULE_REAL ( Combat, WeaponSkillFalloff, 0.33) //For every weapon skill point that's not maxed you lose this % of hit
|
RULE_REAL ( Combat, WeaponSkillFalloff, 0.33) //For every weapon skill point that's not maxed you lose this % of hit
|
||||||
RULE_REAL ( Combat, ArcheryHitPenalty, 0.25) //Archery has a hit penalty to try to help balance it with the plethora of long term +hit modifiers for it
|
RULE_REAL ( Combat, ArcheryHitPenalty, 0.25) //Archery has a hit penalty to try to help balance it with the plethora of long term +hit modifiers for it
|
||||||
RULE_REAL ( Combat, AgiHitFactor, 0.01)
|
RULE_REAL ( Combat, AgiHitFactor, 0.01)
|
||||||
|
RULE_REAL ( Combat, MinChancetoHit, 5.0) //Minimum % chance to hit with regular melee/ranged
|
||||||
|
RULE_REAL ( Combat, MaxChancetoHit, 95.0) //Maximum % chance to hit with regular melee/ranged
|
||||||
RULE_INT ( Combat, MinRangedAttackDist, 25) //Minimum Distance to use Ranged Attacks
|
RULE_INT ( Combat, MinRangedAttackDist, 25) //Minimum Distance to use Ranged Attacks
|
||||||
RULE_BOOL ( Combat, ArcheryBonusRequiresStationary, true) //does the 2x archery bonus chance require a stationary npc
|
RULE_BOOL ( Combat, ArcheryBonusRequiresStationary, true) //does the 2x archery bonus chance require a stationary npc
|
||||||
RULE_REAL ( Combat, ArcheryBaseDamageBonus, 1) // % Modifier to Base Archery Damage (.5 = 50% base damage, 1 = 100%, 2 = 200%)
|
RULE_REAL ( Combat, ArcheryBaseDamageBonus, 1) // % Modifier to Base Archery Damage (.5 = 50% base damage, 1 = 100%, 2 = 200%)
|
||||||
|
|||||||
@ -10,3 +10,6 @@ INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VAL
|
|||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMinRecast','500','AI spell recast time(MS) check when no spell is cast while idle. (min time in random)');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMinRecast','500','AI spell recast time(MS) check when no spell is cast while idle. (min time in random)');
|
||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMaxRecast','2000','AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleNoSpellMaxRecast','2000','AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)');
|
||||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleBeneficialChance','100','Chance while idle to do a beneficial spell on self or others.');
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:AI_IdleBeneficialChance','100','Chance while idle to do a beneficial spell on self or others.');
|
||||||
|
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MinChancetoHit','5','Minimum % chance to hit with regular melee/ranged.');
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:MaxChancetoHit','95','Maximum % chance to hit with regular melee/ranged.');
|
||||||
@ -1,6 +1,7 @@
|
|||||||
-- npc_types
|
-- npc_types
|
||||||
ALTER TABLE `npc_types` ADD `ammo_idfile` varchar( 30 ) NOT NULL DEFAULT 'IT10' AFTER `d_meele_texture2`;
|
ALTER TABLE `npc_types` ADD `ammo_idfile` varchar( 30 ) NOT NULL DEFAULT 'IT10' AFTER `d_meele_texture2`;
|
||||||
ALTER TABLE `npc_types` ADD `ranged_type` tinyint( 4 ) UNSIGNED NOT NULL DEFAULT '7' AFTER `sec_melee_type`;
|
ALTER TABLE `npc_types` ADD `ranged_type` tinyint( 4 ) UNSIGNED NOT NULL DEFAULT '7' AFTER `sec_melee_type`;
|
||||||
|
ALTER TABLE `npc_types` ADD `Avoidance` mediumint(9) UNSIGNED NOT NULL DEFAULT '0' AFTER `Accuracy`;
|
||||||
|
|
||||||
-- npc spells
|
-- npc spells
|
||||||
ALTER TABLE `npc_spells` ADD `range_proc` smallint(5) NOT NULL DEFAULT '-1';
|
ALTER TABLE `npc_spells` ADD `range_proc` smallint(5) NOT NULL DEFAULT '-1';
|
||||||
|
|||||||
@ -202,7 +202,8 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
|||||||
if (chance_mod >= 10000)
|
if (chance_mod >= 10000)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
float bonus;
|
float avoidanceBonus = 0;
|
||||||
|
float hitBonus = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
// To hit calcs go here
|
// To hit calcs go here
|
||||||
@ -214,6 +215,7 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
|||||||
//Calculate the level difference
|
//Calculate the level difference
|
||||||
|
|
||||||
mlog(COMBAT__TOHIT, "Chance to hit before level diff calc %.2f", chancetohit);
|
mlog(COMBAT__TOHIT, "Chance to hit before level diff calc %.2f", chancetohit);
|
||||||
|
|
||||||
double level_difference = attacker_level - defender_level;
|
double level_difference = attacker_level - defender_level;
|
||||||
double range = defender->GetLevel();
|
double range = defender->GetLevel();
|
||||||
range = ((range / 4) + 3);
|
range = ((range / 4) + 3);
|
||||||
@ -268,37 +270,32 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
|||||||
mlog(COMBAT__TOHIT, "Applied item melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
mlog(COMBAT__TOHIT, "Applied item melee skill bonus %d, yeilding %.2f", attacker->spellbonuses.MeleeSkillCheck, chancetohit);
|
||||||
}
|
}
|
||||||
|
|
||||||
//subtract off avoidance by the defender. (Live AA - Combat Agility)
|
//Avoidance Bonuses on defender decreases baseline hit chance by percent.
|
||||||
bonus = defender->spellbonuses.AvoidMeleeChance + defender->itembonuses.AvoidMeleeChance + (defender->aabonuses.AvoidMeleeChance * 10);
|
avoidanceBonus = defender->spellbonuses.AvoidMeleeChanceEffect +
|
||||||
|
defender->itembonuses.AvoidMeleeChanceEffect +
|
||||||
|
defender->aabonuses.AvoidMeleeChanceEffect +
|
||||||
|
(defender->itembonuses.AvoidMeleeChance / 10.0f); //Item Mod 'Avoidence'
|
||||||
|
|
||||||
//AA Live - Elemental Agility
|
Mob *owner = nullptr;
|
||||||
if (IsPet()) {
|
if (defender->IsPet())
|
||||||
Mob *owner = defender->GetOwner();
|
owner = defender->GetOwner();
|
||||||
if (!owner)return false;
|
else if ((defender->IsNPC() && defender->CastToNPC()->GetSwarmOwner()))
|
||||||
bonus += (owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance)*10;
|
owner = entity_list.GetMobID(defender->CastToNPC()->GetSwarmOwner());
|
||||||
}
|
|
||||||
|
|
||||||
if(bonus) {
|
if (owner)
|
||||||
chancetohit -= ((bonus * chancetohit) / 1000);
|
avoidanceBonus += owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance;
|
||||||
mlog(COMBAT__TOHIT, "Applied avoidance chance %.2f/10, yeilding %.2f", bonus, chancetohit);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(attacker->IsNPC())
|
if(defender->IsNPC())
|
||||||
chancetohit += (chancetohit * attacker->CastToNPC()->GetAccuracyRating() / 1000);
|
avoidanceBonus += (defender->CastToNPC()->GetAvoidanceRating() / 10.0f); //Modifier from database
|
||||||
|
|
||||||
mlog(COMBAT__TOHIT, "Chance to hit after accuracy rating calc %.2f", chancetohit);
|
|
||||||
|
|
||||||
float hitBonus = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Kayen: Unknown if the HitChance and Accuracy effect's should modify 'chancetohit'
|
|
||||||
cumulatively or successively. For now all hitBonuses are cumulative.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
//Hit Chance Bonuses on attacker increases baseline hit chance by percent.
|
||||||
hitBonus += attacker->itembonuses.HitChanceEffect[skillinuse] +
|
hitBonus += attacker->itembonuses.HitChanceEffect[skillinuse] +
|
||||||
attacker->spellbonuses.HitChanceEffect[skillinuse]+
|
attacker->spellbonuses.HitChanceEffect[skillinuse]+
|
||||||
|
attacker->aabonuses.HitChanceEffect[skillinuse]+
|
||||||
attacker->itembonuses.HitChanceEffect[HIGHEST_SKILL+1] +
|
attacker->itembonuses.HitChanceEffect[HIGHEST_SKILL+1] +
|
||||||
attacker->spellbonuses.HitChanceEffect[HIGHEST_SKILL+1];
|
attacker->spellbonuses.HitChanceEffect[HIGHEST_SKILL+1] +
|
||||||
|
attacker->aabonuses.HitChanceEffect[HIGHEST_SKILL+1];
|
||||||
|
|
||||||
|
|
||||||
//Accuracy = Spell Effect , HitChance = 'Accuracy' from Item Effect
|
//Accuracy = Spell Effect , HitChance = 'Accuracy' from Item Effect
|
||||||
//Only AA derived accuracy can be skill limited. ie (Precision of the Pathfinder, Dead Aim)
|
//Only AA derived accuracy can be skill limited. ie (Precision of the Pathfinder, Dead Aim)
|
||||||
@ -306,26 +303,31 @@ bool Mob::CheckHitChance(Mob* other, SkillUseTypes skillinuse, int Hand, int16 c
|
|||||||
attacker->spellbonuses.Accuracy[HIGHEST_SKILL+1] +
|
attacker->spellbonuses.Accuracy[HIGHEST_SKILL+1] +
|
||||||
attacker->aabonuses.Accuracy[HIGHEST_SKILL+1] +
|
attacker->aabonuses.Accuracy[HIGHEST_SKILL+1] +
|
||||||
attacker->aabonuses.Accuracy[skillinuse] +
|
attacker->aabonuses.Accuracy[skillinuse] +
|
||||||
attacker->itembonuses.HitChance) / 15.0f;
|
attacker->itembonuses.HitChance) / 15.0f; //Item Mod 'Accuracy'
|
||||||
|
|
||||||
hitBonus += chance_mod; //Modifier applied from casted/disc skill attacks.
|
hitBonus += chance_mod; //Modifier applied from casted/disc skill attacks.
|
||||||
|
|
||||||
chancetohit += ((chancetohit * hitBonus) / 100.0f);
|
if(attacker->IsNPC())
|
||||||
|
hitBonus += (attacker->CastToNPC()->GetAccuracyRating() / 10.0f); //Modifier from database
|
||||||
|
|
||||||
if(skillinuse == SkillArchery)
|
if(skillinuse == SkillArchery)
|
||||||
chancetohit -= (chancetohit * RuleR(Combat, ArcheryHitPenalty)) / 100.0f;
|
hitBonus -= hitBonus*RuleR(Combat, ArcheryHitPenalty);
|
||||||
|
|
||||||
|
//Calculate final chance to hit
|
||||||
|
chancetohit += ((chancetohit * (hitBonus - avoidanceBonus)) / 100.0f);
|
||||||
|
mlog(COMBAT__TOHIT, "Chance to hit %.2f after accuracy calc %.2f and avoidance calc %.2f", chancetohit, hitBonus, avoidanceBonus);
|
||||||
|
|
||||||
chancetohit = mod_hit_chance(chancetohit, skillinuse, attacker);
|
chancetohit = mod_hit_chance(chancetohit, skillinuse, attacker);
|
||||||
|
|
||||||
// Chance to hit; Max 95%, Min 30%
|
// Chance to hit; Max 95%, Min 5% DEFAULTS
|
||||||
if(chancetohit > 1000 || chancetohit < -1000) {
|
if(chancetohit > 1000 || chancetohit < -1000) {
|
||||||
//if chance to hit is crazy high, that means a discipline is in use, and let it stay there
|
//if chance to hit is crazy high, that means a discipline is in use, and let it stay there
|
||||||
}
|
}
|
||||||
else if(chancetohit > 95) {
|
else if(chancetohit > RuleR(Combat,MaxChancetoHit)) {
|
||||||
chancetohit = 95;
|
chancetohit = RuleR(Combat,MaxChancetoHit);
|
||||||
}
|
}
|
||||||
else if(chancetohit < 5) {
|
else if(chancetohit < RuleR(Combat,MinChancetoHit)) {
|
||||||
chancetohit = 5;
|
chancetohit = RuleR(Combat,MinChancetoHit);
|
||||||
}
|
}
|
||||||
|
|
||||||
//I dont know the best way to handle a garunteed hit discipline being used
|
//I dont know the best way to handle a garunteed hit discipline being used
|
||||||
|
|||||||
@ -879,7 +879,7 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->PetMaxHP += base1;
|
newbon->PetMaxHP += base1;
|
||||||
break;
|
break;
|
||||||
case SE_AvoidMeleeChance:
|
case SE_AvoidMeleeChance:
|
||||||
newbon->AvoidMeleeChance += base1;
|
newbon->AvoidMeleeChanceEffect += base1;
|
||||||
break;
|
break;
|
||||||
case SE_CombatStability:
|
case SE_CombatStability:
|
||||||
newbon->CombatStability += base1;
|
newbon->CombatStability += base1;
|
||||||
@ -989,6 +989,14 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
|||||||
newbon->CrippBlowChance += base1;
|
newbon->CrippBlowChance += base1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_HitChance:
|
||||||
|
{
|
||||||
|
if(base2 == -1)
|
||||||
|
newbon->HitChanceEffect[HIGHEST_SKILL+1] += base1;
|
||||||
|
else
|
||||||
|
newbon->HitChanceEffect[base2] += base1;
|
||||||
|
}
|
||||||
|
|
||||||
case SE_ProcOnKillShot:
|
case SE_ProcOnKillShot:
|
||||||
for(int i = 0; i < MAX_SPELL_TRIGGER*3; i+=3)
|
for(int i = 0; i < MAX_SPELL_TRIGGER*3; i+=3)
|
||||||
{
|
{
|
||||||
@ -1833,16 +1841,14 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
|||||||
|
|
||||||
case SE_AvoidMeleeChance:
|
case SE_AvoidMeleeChance:
|
||||||
{
|
{
|
||||||
//multiplier is to be compatible with item effects, watching for overflow too
|
|
||||||
effect_value = effect_value<3000? effect_value * 10 : 30000;
|
|
||||||
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
|
if (RuleB(Spells, AdditiveBonusValues) && item_bonus)
|
||||||
newbon->AvoidMeleeChance += effect_value;
|
newbon->AvoidMeleeChanceEffect += effect_value;
|
||||||
|
|
||||||
else if((effect_value < 0) && (newbon->AvoidMeleeChance > effect_value))
|
else if((effect_value < 0) && (newbon->AvoidMeleeChanceEffect > effect_value))
|
||||||
newbon->AvoidMeleeChance = effect_value;
|
newbon->AvoidMeleeChanceEffect = effect_value;
|
||||||
|
|
||||||
else if(newbon->AvoidMeleeChance < effect_value)
|
else if(newbon->AvoidMeleeChanceEffect < effect_value)
|
||||||
newbon->AvoidMeleeChance = effect_value;
|
newbon->AvoidMeleeChanceEffect = effect_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3610,9 +3616,9 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_AvoidMeleeChance:
|
case SE_AvoidMeleeChance:
|
||||||
spellbonuses.AvoidMeleeChance = effect_value;
|
spellbonuses.AvoidMeleeChanceEffect = effect_value;
|
||||||
aabonuses.AvoidMeleeChance = effect_value;
|
aabonuses.AvoidMeleeChanceEffect = effect_value;
|
||||||
itembonuses.AvoidMeleeChance = effect_value;
|
itembonuses.AvoidMeleeChanceEffect = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SE_RiposteChance:
|
case SE_RiposteChance:
|
||||||
|
|||||||
@ -275,7 +275,8 @@ struct StatBonuses {
|
|||||||
int16 CriticalHealOverTime; //i
|
int16 CriticalHealOverTime; //i
|
||||||
int16 CriticalDoTChance; //i
|
int16 CriticalDoTChance; //i
|
||||||
int16 CrippBlowChance; //
|
int16 CrippBlowChance; //
|
||||||
int16 AvoidMeleeChance; //AvoidMeleeChance/10 == % chance i = Avoidance
|
int16 AvoidMeleeChance; //AvoidMeleeChance/10 == % chance i = Avoidance (item mod)
|
||||||
|
int16 AvoidMeleeChanceEffect; //AvoidMeleeChance Spell Effect
|
||||||
int16 RiposteChance; //i
|
int16 RiposteChance; //i
|
||||||
int16 DodgeChance; //i
|
int16 DodgeChance; //i
|
||||||
int16 ParryChance; //i
|
int16 ParryChance; //i
|
||||||
|
|||||||
@ -194,6 +194,7 @@ NPC::NPC(const NPCType* d, Spawn2* in_respawn, float x, float y, float z, float
|
|||||||
}
|
}
|
||||||
|
|
||||||
accuracy_rating = d->accuracy_rating;
|
accuracy_rating = d->accuracy_rating;
|
||||||
|
avoidance_rating = d->avoidance_rating;
|
||||||
ATK = d->ATK;
|
ATK = d->ATK;
|
||||||
|
|
||||||
CalcMaxMana();
|
CalcMaxMana();
|
||||||
@ -1927,6 +1928,12 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(id == "avoidance")
|
||||||
|
{
|
||||||
|
avoidance_rating = atoi(val.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(id == "trackable")
|
if(id == "trackable")
|
||||||
{
|
{
|
||||||
trackable = atoi(val.c_str());
|
trackable = atoi(val.c_str());
|
||||||
|
|||||||
@ -333,6 +333,8 @@ public:
|
|||||||
|
|
||||||
int32 GetAccuracyRating() const { return (accuracy_rating); }
|
int32 GetAccuracyRating() const { return (accuracy_rating); }
|
||||||
void SetAccuracyRating(int32 d) { accuracy_rating = d;}
|
void SetAccuracyRating(int32 d) { accuracy_rating = d;}
|
||||||
|
int32 GetAvoidanceRating() const { return (avoidance_rating); }
|
||||||
|
void SetAvoidanceRating(int32 d) { avoidance_rating = d;}
|
||||||
int32 GetRawAC() const { return AC; }
|
int32 GetRawAC() const { return AC; }
|
||||||
|
|
||||||
void ModifyNPCStat(const char *identifier, const char *newValue);
|
void ModifyNPCStat(const char *identifier, const char *newValue);
|
||||||
@ -441,6 +443,7 @@ protected:
|
|||||||
uint32 max_dmg;
|
uint32 max_dmg;
|
||||||
uint32 min_dmg;
|
uint32 min_dmg;
|
||||||
int32 accuracy_rating;
|
int32 accuracy_rating;
|
||||||
|
int32 avoidance_rating;
|
||||||
int16 attack_count;
|
int16 attack_count;
|
||||||
uint32 npc_mana;
|
uint32 npc_mana;
|
||||||
float spellscale;
|
float spellscale;
|
||||||
|
|||||||
@ -1105,6 +1105,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
|
|||||||
"npc_types.see_improved_hide,"
|
"npc_types.see_improved_hide,"
|
||||||
"npc_types.ATK,"
|
"npc_types.ATK,"
|
||||||
"npc_types.Accuracy,"
|
"npc_types.Accuracy,"
|
||||||
|
"npc_types.Avoidance,"
|
||||||
"npc_types.slow_mitigation,"
|
"npc_types.slow_mitigation,"
|
||||||
"npc_types.maxlevel,"
|
"npc_types.maxlevel,"
|
||||||
"npc_types.scalerate,"
|
"npc_types.scalerate,"
|
||||||
@ -1290,6 +1291,7 @@ const NPCType* ZoneDatabase::GetNPCType (uint32 id) {
|
|||||||
tmpNPCType->see_improved_hide = atoi(row[r++])==0?false:true;
|
tmpNPCType->see_improved_hide = atoi(row[r++])==0?false:true;
|
||||||
tmpNPCType->ATK = atoi(row[r++]);
|
tmpNPCType->ATK = atoi(row[r++]);
|
||||||
tmpNPCType->accuracy_rating = atoi(row[r++]);
|
tmpNPCType->accuracy_rating = atoi(row[r++]);
|
||||||
|
tmpNPCType->avoidance_rating = atoi(row[r++]);
|
||||||
tmpNPCType->slow_mitigation = atoi(row[r++]);
|
tmpNPCType->slow_mitigation = atoi(row[r++]);
|
||||||
tmpNPCType->maxlevel = atoi(row[r++]);
|
tmpNPCType->maxlevel = atoi(row[r++]);
|
||||||
tmpNPCType->scalerate = atoi(row[r++]);
|
tmpNPCType->scalerate = atoi(row[r++]);
|
||||||
|
|||||||
@ -112,6 +112,7 @@ struct NPCType
|
|||||||
uint8 mount_color; //only used by horse class
|
uint8 mount_color; //only used by horse class
|
||||||
float attack_speed; //%+- on attack delay of the mob.
|
float attack_speed; //%+- on attack delay of the mob.
|
||||||
int accuracy_rating; //10 = 1% accuracy
|
int accuracy_rating; //10 = 1% accuracy
|
||||||
|
int avoidance_rating; //10 = 1% avoidance
|
||||||
bool findable; //can be found with find command
|
bool findable; //can be found with find command
|
||||||
bool trackable;
|
bool trackable;
|
||||||
int16 slow_mitigation;
|
int16 slow_mitigation;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user