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_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_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_BOOL(Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
||||
RULE_BOOL(Combat, AdjustProcPerMinute, true)
|
||||
|
||||
@ -424,7 +424,7 @@ Mob* EntityList::AICheckNPCtoNPCAggro(Mob* sender, float iAggroRange, float iAss
|
||||
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
|
||||
if (!attacker)
|
||||
@ -434,20 +434,25 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
||||
|
||||
for (auto it = npc_list.begin(); it != npc_list.end(); ++it) {
|
||||
NPC *mob = it->second;
|
||||
if (!mob || (mob == exclude))
|
||||
if (!mob || (mob == exclude)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob->IsEngaged())
|
||||
if (!mob->IsEngaged()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->IsFeared() || mob->IsMezzed())
|
||||
if (mob->IsFeared() || mob->IsMezzed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY)
|
||||
if (!inc_gray_con && attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob->CheckAggro(attacker))
|
||||
if (!mob->CheckAggro(attacker)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float AggroRange = mob->GetAggroRange();
|
||||
|
||||
@ -455,14 +460,12 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
||||
|
||||
AggroRange *= AggroRange;
|
||||
|
||||
if (DistanceSquared(mob->GetPosition(), attacker->GetPosition()) > AggroRange)
|
||||
if (DistanceSquared(mob->GetPosition(), attacker->GetPosition()) > AggroRange) {
|
||||
continue;
|
||||
|
||||
}
|
||||
Count++;
|
||||
}
|
||||
|
||||
return Count;
|
||||
|
||||
}
|
||||
|
||||
void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
|
||||
@ -416,7 +416,7 @@ public:
|
||||
|
||||
void CheckClientAggro(Client *around);
|
||||
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);
|
||||
bool AICheckCloseBeneficialSpells(NPC* 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
|
||||
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;
|
||||
}
|
||||
|
||||
// if were already fleeing, don't need to check more...
|
||||
if(flee_mode && currently_fleeing) {
|
||||
return;
|
||||
}
|
||||
|
||||
//dont bother if we are immune to fleeing
|
||||
if(GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee)
|
||||
if(GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!flee_timer.Check())
|
||||
return; //only do all this stuff every little while, since
|
||||
//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)
|
||||
// Check if Flee Timer is cleared
|
||||
if(!flee_timer.Check()) {
|
||||
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();
|
||||
|
||||
// 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) {
|
||||
//this should never happen...
|
||||
StartFleeing();
|
||||
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) {
|
||||
//our hate top is almost dead too... stay and fight
|
||||
return;
|
||||
}
|
||||
|
||||
//base our flee ratio on our con. this is how the
|
||||
//attacker sees the mob, since this is all we can observe
|
||||
// Flee Chance checking based on con.
|
||||
uint32 con = GetLevelCon(hate_top->GetLevel(), GetLevel());
|
||||
float run_ratio;
|
||||
int flee_chance;
|
||||
switch(con) {
|
||||
//these values are not 100% researched
|
||||
case CON_GRAY:
|
||||
run_ratio = fleeratio;
|
||||
flee_chance = 100;
|
||||
break;
|
||||
case CON_GREEN:
|
||||
run_ratio = fleeratio * 9 / 10;
|
||||
flee_chance = 90;
|
||||
break;
|
||||
case CON_LIGHTBLUE:
|
||||
run_ratio = fleeratio * 9 / 10;
|
||||
flee_chance = 90;
|
||||
break;
|
||||
case CON_BLUE:
|
||||
run_ratio = fleeratio * 8 / 10;
|
||||
flee_chance = 80;
|
||||
break;
|
||||
default:
|
||||
run_ratio = fleeratio * 7 / 10;
|
||||
flee_chance = 70;
|
||||
break;
|
||||
}
|
||||
if(ratio < run_ratio)
|
||||
{
|
||||
if (RuleB(Combat, FleeIfNotAlone) ||
|
||||
GetSpecialAbility(ALWAYS_FLEE) ||
|
||||
(!RuleB(Combat, FleeIfNotAlone) && (entity_list.GetHatedCount(hate_top, this) == 0)))
|
||||
|
||||
// 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) || zone->random.Roll(flee_chance) && entity_list.GetHatedCount(hate_top, this, true) == 0) {
|
||||
currently_fleeing = true;
|
||||
StartFleeing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mob::ProcessFlee()
|
||||
{
|
||||
|
||||
@ -107,11 +127,21 @@ void Mob::ProcessFlee()
|
||||
return;
|
||||
}
|
||||
|
||||
//see if we are still dying, if so, do nothing
|
||||
float fleeratio = GetSpecialAbility(FLEE_PERCENT);
|
||||
fleeratio = fleeratio > 0 ? fleeratio : RuleI(Combat, FleeHPRatio);
|
||||
if (GetHPRatio() < fleeratio)
|
||||
int hpratio = GetIntHPRatio();
|
||||
int fleeratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
|
||||
Mob *hate_top = GetHateTop();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
//we are not dying anymore... see what we do next
|
||||
|
||||
|
||||
@ -1414,7 +1414,7 @@ void Merc::AI_Process() {
|
||||
if(DivineAura())
|
||||
return;
|
||||
|
||||
int hateCount = entity_list.GetHatedCount(this, nullptr);
|
||||
int hateCount = entity_list.GetHatedCount(this, nullptr, false);
|
||||
if(GetHatedCount() < hateCount) {
|
||||
SetHatedCount(hateCount);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user