mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 05:21:29 +00:00
Allow Separate GrayCon Flee rate.
Added following Rules: Combat:FleeGray - If true FleeGrayHPRatio will be used. Combat:FleeGrayHPRatio - HP % when a Gray NPC begins to flee.
This commit is contained in:
parent
f15ba46c24
commit
6b02d50a8c
@ -419,6 +419,8 @@ RULE_BOOL(Combat, UseIntervalAC, true)
|
|||||||
RULE_INT(Combat, PetAttackMagicLevel, 30)
|
RULE_INT(Combat, PetAttackMagicLevel, 30)
|
||||||
RULE_BOOL(Combat, EnableFearPathing, true)
|
RULE_BOOL(Combat, EnableFearPathing, true)
|
||||||
RULE_REAL(Combat, FleeMultiplier, 2.0) // Determines how quickly a NPC will slow down while fleeing. Decrease multiplier to slow NPC down quicker.
|
RULE_REAL(Combat, FleeMultiplier, 2.0) // Determines how quickly a NPC will slow down while fleeing. Decrease multiplier to slow NPC down quicker.
|
||||||
|
RULE_BOOL(Combat, FleeGray, true) // If true FleeGrayHPRatio will be used.
|
||||||
|
RULE_INT(Combat, FleeGrayHPRatio, 50) //HP % when a Gray NPC begins to flee.
|
||||||
RULE_INT(Combat, FleeHPRatio, 25) //HP % when a NPC begins to flee.
|
RULE_INT(Combat, FleeHPRatio, 25) //HP % when a NPC begins to flee.
|
||||||
RULE_BOOL(Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
RULE_BOOL(Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
||||||
RULE_BOOL(Combat, AdjustProcPerMinute, true)
|
RULE_BOOL(Combat, AdjustProcPerMinute, true)
|
||||||
|
|||||||
@ -424,7 +424,7 @@ Mob* EntityList::AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAss
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
int EntityList::GetHatedCount(Mob *attacker, Mob *exclude, bool inc_gray_con)
|
||||||
{
|
{
|
||||||
// Return a list of how many non-feared, non-mezzed, non-green mobs, within aggro range, hate *attacker
|
// Return a list of how many non-feared, non-mezzed, non-green mobs, within aggro range, hate *attacker
|
||||||
if (!attacker)
|
if (!attacker)
|
||||||
@ -434,20 +434,25 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
|||||||
|
|
||||||
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
||||||
NPC *mob = it->second;
|
NPC *mob = it->second;
|
||||||
if (!mob || (mob == exclude))
|
if (!mob || (mob == exclude)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mob->IsEngaged())
|
if (!mob->IsEngaged()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mob->IsFeared() || mob->IsMezzed())
|
if (mob->IsFeared() || mob->IsMezzed()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY)
|
if (!inc_gray_con && attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mob->CheckAggro(attacker))
|
if (!mob->CheckAggro(attacker)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float AggroRange = mob->GetAggroRange();
|
float AggroRange = mob->GetAggroRange();
|
||||||
|
|
||||||
@ -455,14 +460,12 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
|||||||
|
|
||||||
AggroRange *= AggroRange;
|
AggroRange *= AggroRange;
|
||||||
|
|
||||||
if (DistanceSquared(mob->GetPosition(), attacker->GetPosition()) > AggroRange)
|
if (DistanceSquared(mob->GetPosition(), attacker->GetPosition()) > AggroRange) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
Count++;
|
Count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Count;
|
return Count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||||
|
|||||||
@ -416,7 +416,7 @@ public:
|
|||||||
|
|
||||||
void CheckClientAggro(Client *around);
|
void CheckClientAggro(Client *around);
|
||||||
Mob* AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAssistRange);
|
Mob* AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAssistRange);
|
||||||
int GetHatedCount(Mob *attacker, Mob *exclude);
|
int GetHatedCount(Mob *attacker, Mob *exclude, bool inc_gray_con);
|
||||||
void AIYellForHelp(Mob* sender, Mob* attacker);
|
void AIYellForHelp(Mob* sender, Mob* attacker);
|
||||||
bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
||||||
bool Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
bool Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
||||||
|
|||||||
@ -31,71 +31,91 @@ extern Zone* zone;
|
|||||||
|
|
||||||
//this is called whenever we are damaged to process possible fleeing
|
//this is called whenever we are damaged to process possible fleeing
|
||||||
void Mob::CheckFlee() {
|
void Mob::CheckFlee() {
|
||||||
//if were allready fleeing, dont need to check more...
|
|
||||||
if(flee_mode && currently_fleeing)
|
// if mob is dead why would you run?
|
||||||
|
if(GetHP() == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if were already fleeing, don't need to check more...
|
||||||
|
if(flee_mode && currently_fleeing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//dont bother if we are immune to fleeing
|
//dont bother if we are immune to fleeing
|
||||||
if(GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee)
|
if(GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!flee_timer.Check())
|
// Check if Flee Timer is cleared
|
||||||
return; //only do all this stuff every little while, since
|
if(!flee_timer.Check()) {
|
||||||
//its not essential that we start running RIGHT away
|
|
||||||
|
|
||||||
//see if were possibly hurt enough
|
|
||||||
float ratio = GetHPRatio();
|
|
||||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
|
||||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
|
||||||
|
|
||||||
if(ratio >= fleeratio)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//we might be hurt enough, check con now..
|
int hpratio = GetIntHPRatio();
|
||||||
|
int fleeratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
|
||||||
Mob *hate_top = GetHateTop();
|
Mob *hate_top = GetHateTop();
|
||||||
|
|
||||||
|
// Sanity Check for race conditions
|
||||||
|
if(hate_top == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no special flee_percent check for Gray or Other con rates
|
||||||
|
if(GetLevelCon(hate_top->GetLevel(), GetLevel()) == CON_GRAY && fleeratio == 0 && RuleB(Combat, FleeGray)) {
|
||||||
|
fleeratio = RuleI(Combat, FleeGrayHPRatio);
|
||||||
|
} else if(fleeratio == 0) {
|
||||||
|
fleeratio = RuleI(Combat, FleeHPRatio );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mob does not have low enough health to flee
|
||||||
|
if(hpratio >= fleeratio) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity Check this should never happen...
|
||||||
if(!hate_top) {
|
if(!hate_top) {
|
||||||
//this should never happen...
|
|
||||||
StartFleeing();
|
StartFleeing();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float other_ratio = hate_top->GetHPRatio();
|
int other_ratio = hate_top->GetIntHPRatio();
|
||||||
|
// If the Client is nearing death the NPC will not flee and instead try to kill the client.
|
||||||
if(other_ratio < 20) {
|
if(other_ratio < 20) {
|
||||||
//our hate top is almost dead too... stay and fight
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//base our flee ratio on our con. this is how the
|
// Flee Chance checking based on con.
|
||||||
//attacker sees the mob, since this is all we can observe
|
|
||||||
uint32 con = GetLevelCon(hate_top->GetLevel(), GetLevel());
|
uint32 con = GetLevelCon(hate_top->GetLevel(), GetLevel());
|
||||||
float run_ratio;
|
int flee_chance;
|
||||||
switch(con) {
|
switch(con) {
|
||||||
//these values are not 100% researched
|
//these values are not 100% researched
|
||||||
case CON_GRAY:
|
case CON_GRAY:
|
||||||
run_ratio = fleeratio;
|
flee_chance = 100;
|
||||||
break;
|
break;
|
||||||
case CON_GREEN:
|
case CON_GREEN:
|
||||||
run_ratio = fleeratio * 9 / 10;
|
flee_chance = 90;
|
||||||
break;
|
break;
|
||||||
case CON_LIGHTBLUE:
|
case CON_LIGHTBLUE:
|
||||||
run_ratio = fleeratio * 9 / 10;
|
flee_chance = 90;
|
||||||
break;
|
break;
|
||||||
case CON_BLUE:
|
case CON_BLUE:
|
||||||
run_ratio = fleeratio * 8 / 10;
|
flee_chance = 80;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
run_ratio = fleeratio * 7 / 10;
|
flee_chance = 70;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(ratio < run_ratio)
|
|
||||||
{
|
// If we got here we are allowed to roll on flee chance if there is not other hated NPC's in the area.
|
||||||
if (RuleB(Combat, FleeIfNotAlone) ||
|
|
||||||
GetSpecialAbility(ALWAYS_FLEE) ||
|
if(RuleB(Combat, FleeIfNotAlone) || GetSpecialAbility(ALWAYS_FLEE) || zone->random.Roll(flee_chance) && entity_list.GetHatedCount(hate_top, this, true) == 0) {
|
||||||
(!RuleB(Combat, FleeIfNotAlone) && (entity_list.GetHatedCount(hate_top, this) == 0)))
|
currently_fleeing = true;
|
||||||
StartFleeing();
|
StartFleeing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Mob::ProcessFlee()
|
void Mob::ProcessFlee()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -107,11 +127,21 @@ void Mob::ProcessFlee()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//see if we are still dying, if so, do nothing
|
int hpratio = GetIntHPRatio();
|
||||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
int fleeratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
|
||||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
Mob *hate_top = GetHateTop();
|
||||||
if (GetHPRatio() < fleeratio)
|
|
||||||
|
// If no special flee_percent check for Gray or Other con rates
|
||||||
|
if(GetLevelCon(hate_top->GetLevel(), GetLevel()) == CON_GRAY && fleeratio == 0 && RuleB(Combat, FleeGray)) {
|
||||||
|
fleeratio = RuleI(Combat, FleeGrayHPRatio);
|
||||||
|
} else if(fleeratio == 0) {
|
||||||
|
fleeratio = RuleI(Combat, FleeHPRatio );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mob is still too low. Keep Running
|
||||||
|
if(hpratio < fleeratio) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//we are not dying anymore... see what we do next
|
//we are not dying anymore... see what we do next
|
||||||
|
|
||||||
|
|||||||
@ -1414,7 +1414,7 @@ void Merc::AI_Process() {
|
|||||||
if(DivineAura())
|
if(DivineAura())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int hateCount = entity_list.GetHatedCount(this, nullptr);
|
int hateCount = entity_list.GetHatedCount(this, nullptr, false);
|
||||||
if(GetHatedCount() < hateCount) {
|
if(GetHatedCount() < hateCount) {
|
||||||
SetHatedCount(hateCount);
|
SetHatedCount(hateCount);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user