Skip to content

Instantly share code, notes, and snippets.

@mackal
Created February 22, 2014 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mackal/9150491 to your computer and use it in GitHub Desktop.
Save mackal/9150491 to your computer and use it in GitHub Desktop.
diff --git a/common/ruletypes.h b/common/ruletypes.h
index b610c30..991240f 100644
--- a/common/ruletypes.h
+++ b/common/ruletypes.h
@@ -529,6 +529,11 @@ RULE_BOOL( QueryServ, MerchantLogTransactions, false) // Logs Merchant Transacti
RULE_BOOL( QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
RULE_CATEGORY_END()
+RULE_CATEGORY ( Performance )
+RULE_BOOL ( Performance, LOSCacheEnabled, false )
+RULE_INT ( Performance, LOSCacheEntryMS, 3000 )
+RULE_CATEGORY_END()
+
#undef RULE_CATEGORY
#undef RULE_INT
#undef RULE_REAL
diff --git a/zone/aggro.cpp b/zone/aggro.cpp
index 326e320..508ed22 100644
--- a/zone/aggro.cpp
+++ b/zone/aggro.cpp
@@ -998,14 +998,65 @@ bool Mob::CheckLos(Mob* other) {
return true;
}
+// Added LOSEntry as a cache to slow down the attempts against los on the same mob in a short time frame
+bool Mob::FindLosCacheEntry(Mob *other, bool &inLOS, uint32 &hits)
+{
+ if (!other || !RuleB(Performance, LOSCacheEnabled))
+ return false;
+
+ auto it = m_LOSCache.find(other->GetID());
+ if (it != m_LOSCache.end()) {
+ if (it->second.entry == other) {
+ if (Timer::GetCurrentTime() < it->second.lastChecked) {
+ // Update hits
+ it->second.hits += 1;
+ // if loc still valid, extend
+ if (it->second.lastX == other->GetX() &&
+ it->second.lastY == other->GetY() &&
+ it->second.ourLastX == GetX() &&
+ it->second.ourLastY == GetY())
+ it->second.lastChecked = Timer::GetCurrentTime() + RuleI(Performance, LOSCacheEntryMS);
+ inLOS = it->second.isLOS;
+ hits = it->second.hits;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
//Father Nitwit's LOS code
bool Mob::CheckLosFN(Mob* other) {
bool Result = false;
- if(other)
+ if (other == this) // checking self?
+ return true;
+
+ uint32 hits = 0;
+
+ if (FindLosCacheEntry(other, Result, hits))
+ return Result;
+
+ if (other) {
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
+ if (RuleB(Performance, LOSCacheEnabled)) {
+ LOSEntry newEnt;
+ newEnt.entry = other;
+ newEnt.isLOS = Result;
+ newEnt.lastChecked = Timer::GetCurrentTime() + RuleI(Performance, LOSCacheEntryMS);
+ newEnt.hits = 1;
+ newEnt.lastX = other->GetX();
+ newEnt.lastY = other->GetY();
+ newEnt.lastZ = other->GetZ();
+ newEnt.ourLastX = GetX();
+ newEnt.ourLastY = GetY();
+ newEnt.ourLastZ = GetZ();
+ m_LOSCache[other->GetID()] = newEnt;
+ }
+ }
+
return Result;
}
diff --git a/zone/command.cpp b/zone/command.cpp
index 1b8ce33..fa1de3b 100644
--- a/zone/command.cpp
+++ b/zone/command.cpp
@@ -6468,7 +6468,12 @@ void command_checklos(Client *c, const Seperator *sep)
{
if(c->GetTarget())
{
-// if(c->CheckLos(c->GetTarget()))
+ bool los = false;
+ uint32 hits = 0;
+ if (c->FindLosCacheEntry(c->GetTarget(), los, hits))
+ c->Message(12,"(Client->Mob) Cached entry exists with mob. LOSVisibleStatus: %i. CacheEntryHits: %i.", los, hits);
+ if (c->GetTarget()->FindLosCacheEntry(c, los, hits))
+ c->Message(12,"(Mob->Client) Cached entry exists ON mob. LOSVisibleStatus: %i. CacheEntryHits: %i.", los, hits);
if(c->CheckLosFN(c->GetTarget()))
c->Message(0, "You have LOS to %s", c->GetTarget()->GetName());
else
diff --git a/zone/mob.h b/zone/mob.h
index f636b5e..d2d5084 100644
--- a/zone/mob.h
+++ b/zone/mob.h
@@ -31,6 +31,23 @@ char* strn0cpy(char* dest, const char* source, uint32 size);
#define MAX_SPECIAL_ATTACK_PARAMS 8
+struct LOSEntry {
+ Mob *entry;
+ bool isLOS;
+ uint32 lastChecked; // Timer::GetCurrentTime entry to compare
+ uint32 hits; // times the entry was hit in the timeframe of the cache
+
+ // target last location
+ float lastX;
+ float lastY;
+ float lastZ;
+
+ // our last location when we got this entry
+ float ourLastX;
+ float ourLastY;
+ float ourLastZ;
+};
+
class EGNode;
class MobFearState;
class Mob : public Entity {
@@ -447,6 +464,7 @@ public:
void ClearFeignMemory();
void PrintHateListToClient(Client *who) { hate_list.PrintToClient(who); }
std::list<tHateEntry*>& GetHateList() { return hate_list.GetHateList(); }
+ bool FindLosCacheEntry(Mob *other, bool &inLOS, uint32 &hits);
bool CheckLos(Mob* other);
bool CheckLosFN(Mob* other);
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
@@ -887,6 +905,8 @@ protected:
std::vector<uint16> RampageArray;
std::map<std::string, std::string> m_EntityVariables;
+ std::map<uint16, LOSEntry> m_LOSCache;
+
int16 SkillDmgTaken_Mod[HIGHEST_SKILL+2];
int16 Vulnerability_Mod[HIGHEST_RESIST+2];
bool m_AllowBeneficial;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment