zaela-Server/zone/fearpath.cpp

211 lines
5.7 KiB
C++
Raw Permalink Normal View History

2013-05-09 10:44:08 -04:00
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
2013-02-16 16:14:39 -08:00
2013-05-09 10:44:08 -04:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
2013-05-06 13:07:41 -04:00
2013-05-09 10:44:08 -04:00
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
2013-02-16 16:14:39 -08:00
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
2013-05-09 10:44:08 -04:00
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2013-05-06 13:07:41 -04:00
2013-05-09 10:44:08 -04:00
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2013-02-16 16:14:39 -08:00
*/
#include "../common/rulesys.h"
2014-12-15 17:23:13 -06:00
2013-02-16 16:14:39 -08:00
#include "map.h"
2014-12-15 17:23:13 -06:00
#include "zone.h"
2013-02-16 16:14:39 -08:00
#ifdef _WINDOWS
#define snprintf _snprintf
#endif
extern Zone* zone;
#define FEAR_PATHING_DEBUG
//this is called whenever we are damaged to process possible fleeing
2020-01-03 17:23:51 -06:00
void Mob::CheckFlee()
{
// if mob is dead why would you run?
2020-01-03 17:23:51 -06:00
if (GetHP() == 0) {
2013-02-16 16:14:39 -08:00
return;
}
// if were already fleeing, don't need to check more...
2020-01-03 17:23:51 -06:00
if (flee_mode && currently_fleeing) {
return;
}
2013-05-06 13:07:41 -04:00
2013-02-16 16:14:39 -08:00
//dont bother if we are immune to fleeing
2020-01-03 17:23:51 -06:00
if (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) {
LogFlee("Mob [{}] is immune to fleeing via special ability or spell bonus", GetCleanName());
2013-02-16 16:14:39 -08:00
return;
}
2013-02-16 16:14:39 -08:00
// Check if Flee Timer is cleared
2020-01-03 17:23:51 -06:00
if (!flee_timer.Check()) {
return;
}
2013-05-06 13:07:41 -04:00
2020-01-03 17:23:51 -06:00
int hp_ratio = GetIntHPRatio();
int flee_ratio = GetSpecialAbility(FLEE_PERCENT); // if a special flee_percent exists
Mob *hate_top = GetHateTop();
LogFlee("Mob [{}] hp_ratio [{}] flee_ratio [{}]", GetCleanName(), hp_ratio, flee_ratio);
// Sanity Check for race conditions
2020-01-03 17:23:51 -06:00
if (hate_top == nullptr) {
2013-02-16 16:14:39 -08:00
return;
}
2013-05-06 13:07:41 -04:00
// If no special flee_percent check for Gray or Other con rates
2020-01-03 17:23:51 -06:00
if (GetLevelCon(hate_top->GetLevel(), GetLevel()) == CON_GRAY && flee_ratio == 0 && RuleB(Combat, FleeGray) &&
GetLevel() <= RuleI(Combat, FleeGrayMaxLevel)) {
flee_ratio = RuleI(Combat, FleeGrayHPRatio);
LogFlee("Mob [{}] using combat flee gray hp_ratio [{}] flee_ratio [{}]", GetCleanName(), hp_ratio, flee_ratio);
}
else if (flee_ratio == 0) {
flee_ratio = RuleI(Combat, FleeHPRatio);
LogFlee("Mob [{}] using combat flee hp_ratio [{}] flee_ratio [{}]", GetCleanName(), hp_ratio, flee_ratio);
}
bool mob_has_low_enough_health_to_flee = hp_ratio >= flee_ratio;
if (mob_has_low_enough_health_to_flee) {
LogFlee(
"Mob [{}] does not have low enough health to flee | hp_ratio [{}] flee_ratio [{}]",
GetCleanName(),
hp_ratio,
flee_ratio
);
return;
}
// Sanity Check this should never happen...
2020-01-03 17:23:51 -06:00
if (!hate_top) {
currently_fleeing = true;
2013-02-16 16:14:39 -08:00
StartFleeing();
return;
}
2013-05-06 13:07:41 -04:00
int other_ratio = hate_top->GetIntHPRatio();
// If the Client is nearing death the NPC will not flee and instead try to kill the client.
2020-01-03 17:23:51 -06:00
if (other_ratio < 20) {
2013-02-16 16:14:39 -08:00
return;
}
2013-05-06 13:07:41 -04:00
// Flee Chance checking based on con.
2013-02-16 16:14:39 -08:00
uint32 con = GetLevelCon(hate_top->GetLevel(), GetLevel());
2020-01-03 17:23:51 -06:00
int flee_chance;
switch (con) {
2013-02-16 16:14:39 -08:00
//these values are not 100% researched
case CON_GRAY:
flee_chance = 100;
2013-02-16 16:14:39 -08:00
break;
case CON_GREEN:
flee_chance = 90;
break;
2013-02-16 16:14:39 -08:00
case CON_LIGHTBLUE:
flee_chance = 90;
2013-02-16 16:14:39 -08:00
break;
case CON_BLUE:
flee_chance = 80;
2013-02-16 16:14:39 -08:00
break;
default:
flee_chance = 70;
2013-02-16 16:14:39 -08:00
break;
}
2020-01-03 17:23:51 -06:00
LogFlee(
"Post con-switch | Mob [{}] con [{}] hp_ratio [{}] flee_ratio [{}] flee_chance [{}]",
GetCleanName(),
2020-01-03 17:25:53 -06:00
con,
2020-01-03 17:23:51 -06:00
hp_ratio,
2020-01-03 17:25:53 -06:00
flee_ratio,
flee_chance
2020-01-03 17:23:51 -06:00
);
// If we got here we are allowed to roll on flee chance if there is not other hated NPC's in the area.
// ALWAYS_FLEE, skip roll
// if FleeIfNotAlone is true, we skip alone check
// roll chance
if (GetSpecialAbility(ALWAYS_FLEE) ||
2020-01-03 17:23:51 -06:00
((RuleB(Combat, FleeIfNotAlone) || entity_list.GetHatedCount(hate_top, this, true) == 0) &&
zone->random.Roll(flee_chance))) {
LogFlee(
"Passed all checks to flee | Mob [{}] con [{}] hp_ratio [{}] flee_ratio [{}] flee_chance [{}]",
GetCleanName(),
2020-01-03 17:25:53 -06:00
con,
2020-01-03 17:23:51 -06:00
hp_ratio,
flee_ratio,
flee_chance
);
currently_fleeing = true;
StartFleeing();
2013-02-16 16:14:39 -08:00
}
}
void Mob::ProcessFlee()
{
2013-02-16 16:14:39 -08:00
2013-05-06 13:07:41 -04:00
//Stop fleeing if effect is applied after they start to run.
//When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee.
if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) &&
!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
currently_fleeing = false;
2013-02-16 16:14:39 -08:00
return;
}
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
2018-08-27 12:56:46 -04:00
if(hate_top != nullptr && 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) {
2013-02-16 16:14:39 -08:00
return;
}
2013-05-06 13:07:41 -04:00
2013-02-16 16:14:39 -08:00
//we are not dying anymore... see what we do next
2013-05-06 13:07:41 -04:00
2013-02-16 16:14:39 -08:00
flee_mode = false;
2013-05-06 13:07:41 -04:00
//see if we are legitimately feared or blind now
if (!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
//not feared or blind... were done...
currently_fleeing = false;
2013-02-16 16:14:39 -08:00
return;
}
}
2020-01-03 17:23:51 -06:00
void Mob::CalculateNewFearpoint()
{
if (RuleB(Pathing, Fear) && zone->pathing) {
auto Node = zone->pathing->GetRandomLocation(glm::vec3(GetX(), GetY(), GetZ()));
if (Node.x != 0.0f || Node.y != 0.0f || Node.z != 0.0f) {
m_FearWalkTarget = Node;
currently_fleeing = true;
2013-02-16 16:14:39 -08:00
return;
2013-02-16 16:14:39 -08:00
}
2020-01-03 17:23:51 -06:00
LogPathing("No path found to selected node during CalculateNewFearpoint.");
2013-02-16 16:14:39 -08:00
}
}