Merge pull request #762 from fryguy503/green-flee

Allow Separate CON_GRAY Flee rate.
This commit is contained in:
Michael Cook (mackal) 2018-08-25 20:27:04 -04:00 committed by GitHub
commit e816196edb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 48 deletions

View File

@ -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)

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -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);