atom0s
8 years ago
7 changed files with 1318 additions and 0 deletions
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
|
||||
#pragma once |
||||
|
||||
#ifndef __COMMANDPARSE_H_INCLUDED__ |
||||
#define __COMMANDPARSE_H_INCLUDED__ |
||||
|
||||
#include <Windows.h> |
||||
#include <string> |
||||
|
||||
#define VALIDATE_COMMAND( s, c ) \ |
||||
if (_strnicmp( s + 1, c, strlen( c ) ) != 0) \ |
||||
return false; |
||||
|
||||
#define HANDLE_ARGUMENT( a, b ) \ |
||||
if (a[1] == b) |
||||
|
||||
/**
|
||||
* GetCommandArgs |
||||
* @param1 : The command to parse for arguments. |
||||
* @param2 : Array of strings to store the found arguments. |
||||
* @returns : Number of arguments found within the command. |
||||
* |
||||
* This function mimics the *nix command 'strsep' to locate and |
||||
* parse strings with inline-quotes. |
||||
* |
||||
* Thanks to: |
||||
* http://stackoverflow.com/questions/9659697/parse-string-into-array-based-on-spaces-or-double-quotes-strings
|
||||
* |
||||
* Modified for Ashita needs with plugin commands. |
||||
* |
||||
*/ |
||||
int __stdcall GetCommandArgs( const char* pszCommand, std::string* args ) |
||||
{ |
||||
enum { |
||||
NONE, |
||||
IN_WORD, |
||||
IN_STRING, |
||||
} state = NONE; |
||||
|
||||
char szCurrentArgument[ 255 ] = { 0 }; |
||||
char szCurrentChar = 0; |
||||
char *pszStart = 0; |
||||
int nArgCount = 0; |
||||
|
||||
for (const char* p = pszCommand; *p != '\0' || state != NONE; ++p) |
||||
{ |
||||
szCurrentChar = (unsigned char)*p; |
||||
switch (state) |
||||
{ |
||||
case NONE: |
||||
{ |
||||
if (isspace( szCurrentChar )) |
||||
continue; |
||||
if (szCurrentChar == '"') |
||||
{ |
||||
state = IN_STRING; |
||||
pszStart = (char*)( p + 1 ); |
||||
continue; |
||||
} |
||||
|
||||
state = IN_WORD; |
||||
pszStart = (char*)p; |
||||
continue; |
||||
} |
||||
|
||||
case IN_STRING: |
||||
if (szCurrentChar == '"') |
||||
{ |
||||
strncpy_s( szCurrentArgument, pszStart, p - pszStart ); |
||||
args[nArgCount] = std::string( szCurrentArgument ); |
||||
nArgCount++; |
||||
|
||||
state = NONE; |
||||
} |
||||
continue; |
||||
|
||||
case IN_WORD: |
||||
if (isspace( szCurrentChar ) || *++p == '\0') |
||||
{ |
||||
strncpy_s( szCurrentArgument, pszStart, p - pszStart ); |
||||
args[nArgCount] = std::string( szCurrentArgument ); |
||||
nArgCount++; |
||||
|
||||
state = NONE; |
||||
} |
||||
*--p; |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
return nArgCount; |
||||
} |
||||
|
||||
#endif // __COMMANDPARSE_H_INCLUDED__
|
@ -0,0 +1,966 @@
@@ -0,0 +1,966 @@
|
||||
#include "WatchEXP.h" |
||||
#include "CommandParse.h" |
||||
|
||||
WatchEXP::WatchEXP(void) |
||||
: m_AshitaCore(nullptr) |
||||
, m_PluginId(0) |
||||
, m_Direct3DDevice(nullptr) |
||||
, m_ExpObj(nullptr) |
||||
, m_AbyTimeStart(0) |
||||
, m_DynTimeStart(0) |
||||
, m_BaseTimeEXP(0) |
||||
, m_BaseTimeCR(0) |
||||
, m_resetTime(NULL) |
||||
, font_size(0) |
||||
, m_reset_min(0) |
||||
, m_CurrentZoneID(0) |
||||
, m_LastZoneRecorded(0) |
||||
, m_Dyna_Crm('X') |
||||
, m_Dyna_Azr('X') |
||||
, m_Dyna_Amb('X') |
||||
, m_Dyna_Alab('X') |
||||
, m_Dyna_Obs('X') |
||||
, m_vTime(0) |
||||
, m_DynaTime(0) |
||||
, m_xpKill(0) |
||||
, m_xpTotal(0) |
||||
, m_xpTest(0) |
||||
, m_crKill(0) |
||||
, m_crTotal(0) |
||||
, m_prl(0) |
||||
, m_gld(0) |
||||
, m_slv(0) |
||||
, m_ebn(0) |
||||
, m_azr(0) |
||||
, m_rby(0) |
||||
, m_amb(0) |
||||
, backTrans(0) |
||||
, m_IsInAbyssea(false) |
||||
, m_IsInDynamis(false) |
||||
, show_XP_M_always(false) |
||||
, m_autoreset(false) |
||||
{ } |
||||
WatchEXP::~WatchEXP(void) |
||||
{ } |
||||
|
||||
plugininfo_t WatchEXP::GetPluginInfo(void) |
||||
{ |
||||
return *g_PluginInformation; |
||||
} |
||||
|
||||
bool WatchEXP::Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) |
||||
{ |
||||
// Store the variables we are passed..
|
||||
this->m_AshitaCore = core; |
||||
this->m_PluginId = id; |
||||
|
||||
this->GetConfig(); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void WatchEXP::Release(void) |
||||
{ |
||||
} |
||||
|
||||
bool WatchEXP::HandleCommand(const char* pszCommand, int nCommandType) |
||||
{ |
||||
if (pszCommand == nullptr) |
||||
return false; |
||||
|
||||
if (_strnicmp(pszCommand, "/wexp", 4) == 0) |
||||
{ |
||||
std::vector<std::string> args; |
||||
Ashita::Commands::GetCommandArgs(pszCommand, &args); |
||||
|
||||
if (args[1] == "reset") |
||||
{ |
||||
m_crTotal = 0, m_xpTotal = 0, m_xpKill = 0, m_crKill = 0; |
||||
m_BaseTimeEXP = time(nullptr), m_BaseTimeCR = time(nullptr); |
||||
|
||||
m_AshitaCore->GetChatManager()->Write("WatchEXP was reset!"); |
||||
return true; |
||||
} |
||||
if (args[1] == "config") |
||||
{ |
||||
this->GetConfig(); |
||||
m_ExpObj->SetFontFamily(font_name); |
||||
m_ExpObj->SetFontHeight(font_size); |
||||
|
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
//bool WatchEXP::HandleNewChatLine(short sMode, char* pszChatLine)
|
||||
bool WatchEXP::HandleIncomingText(int16_t sMode, const char* pszChatLine, int16_t* modifiedMode, char* modifiedMessage, bool blocked) |
||||
{ |
||||
std::string data; |
||||
std::vector< std::string > temp; |
||||
|
||||
data = ScrubChat(pszChatLine); |
||||
|
||||
//Holds matches
|
||||
std::smatch m; |
||||
|
||||
#pragma region Search Pattern |
||||
//Regex Searches
|
||||
std::regex xp_inc("gains\\s\\d+\\s(experience|limit)\\spoints"); |
||||
std::regex xp_chain("EXP\\schain\\s\\d+\\s\\w+\\sgains\\s\\d+\\sexperience\\spoints"); |
||||
std::regex cru_inc("obtained\\s\\d+\\scruor", std::regex_constants::icase); |
||||
std::regex vis_wear("Your\\svisitant\\sstatus\\swill\\swear\\soff\\sin\\s\\d+\\sminutes"); |
||||
std::regex vis_inc("Your\\svisitant\\sstatus\\shas\\sbeen\\sextended\\sby\\s\\d+\\sminutes"); |
||||
std::regex vis_exit("Exiting\\sin\\s\\d+\\sminutes"); |
||||
std::regex vis_pegs("Visitant\\sLight\\sIntensity\\sPearlescent\\s\\d+\\sEbon\\s\\d+\\sGolden\\s\\d+\\sSilvery\\s\\d+"); |
||||
std::regex vis_azram("Azure\\s\\d+\\sRuby\\s\\d+\\sAmber\\s\\d+"); |
||||
std::regex light_pearl("body\\semits\\sa\\sfaint\\spearlescent\\slight"); |
||||
std::regex light_azure("body\\semits\\sa\\sfeeble\\sazure\\slight"); |
||||
std::regex light_ruby("body\\semits\\sa\\sfeeble\\sruby\\slight"); |
||||
std::regex light_amber("body\\semits\\sa\\sfeeble\\samber\\slight"); |
||||
std::regex light_gold("body\\semits\\sa\\sfaint\\sgolden\\slight"); |
||||
std::regex light_silver("body\\semits\\sa\\sfaint\\ssilvery\\slight"); |
||||
std::regex light_ebon("body\\semits\\sa\\sfaint\\sebon\\slight"); |
||||
std::regex dyn_start("sands"); |
||||
std::regex dyn_start2("hourglass"); |
||||
std::regex dyn_extend("Dynamis"); |
||||
std::regex dyn_extend2("extended"); |
||||
std::regex dyn_expelled("expelled"); |
||||
|
||||
//Used to get all the numbers
|
||||
std::regex get_number("\\d+"); |
||||
|
||||
if (sMode == 121) |
||||
{ |
||||
if (std::regex_search(data, xp_chain)) |
||||
{ |
||||
std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; |
||||
|
||||
while (start != end) |
||||
{ |
||||
temp.push_back(*start); |
||||
++start; |
||||
} |
||||
|
||||
if (temp.size() >= 1) |
||||
m_xpKill = std::stoi(temp[temp.size() - 1]); |
||||
else |
||||
m_xpKill = 0; |
||||
|
||||
m_xpTotal += m_xpKill; |
||||
} |
||||
} |
||||
if (sMode == 131) |
||||
{ |
||||
if (std::regex_search(data, xp_inc)) |
||||
{ |
||||
std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; |
||||
temp.clear(); |
||||
|
||||
while (start != end) |
||||
{ |
||||
temp.push_back(*start); |
||||
++start; |
||||
} |
||||
|
||||
if (temp.size() >= 1) |
||||
m_xpKill = std::stoi(temp[temp.size() - 1]); |
||||
else |
||||
m_xpKill = 0; |
||||
|
||||
m_xpTotal += m_xpKill; |
||||
} |
||||
} |
||||
else if (sMode == 633) |
||||
{ |
||||
if (std::regex_search(data, cru_inc)) |
||||
{ |
||||
std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; |
||||
temp.clear(); |
||||
|
||||
while (start != end) |
||||
{ |
||||
temp.push_back(*start); |
||||
++start; |
||||
} |
||||
|
||||
if (temp.size() >= 1) |
||||
m_crKill = std::stoi(temp[temp.size() - 1]); |
||||
else |
||||
m_crKill = 0; |
||||
|
||||
m_crTotal += m_crKill; |
||||
} |
||||
else if (std::regex_search(data, vis_inc)) |
||||
{ |
||||
m_vTime += 10; |
||||
} |
||||
} |
||||
else if (sMode == 653) |
||||
{ |
||||
if ((std::regex_search(data, dyn_expelled)) && (std::regex_search(data, dyn_extend))) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
|
||||
m_DynaTime = std::stoi(m.str()); |
||||
|
||||
m_DynTimeStart = time(nullptr); |
||||
} |
||||
} |
||||
else if (sMode == 658) |
||||
{ |
||||
if ((std::regex_search(data, dyn_extend)) && (std::regex_search(data, dyn_extend2))) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
|
||||
m_DynaTime += std::stoi(m.str()); |
||||
|
||||
m_DynTimeStart = time(nullptr); |
||||
} |
||||
} |
||||
else if (sMode == 660) |
||||
{ |
||||
if ((std::regex_search(data, dyn_start)) && (std::regex_search(data, dyn_start2))) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
|
||||
m_DynaTime = std::stoi(m.str()); |
||||
} |
||||
if (std::regex_search(data, vis_exit)) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
|
||||
m_vTime = std::stoi(m.str()); |
||||
} |
||||
else if (std::regex_search(data, cru_inc)) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
m_crKill = std::stoi(m.str()); |
||||
|
||||
m_crTotal += m_crKill; |
||||
} |
||||
else if (std::regex_search(data, vis_wear)) |
||||
{ |
||||
std::regex_search(data, m, get_number); |
||||
m_vTime = std::stoi(m.str()); |
||||
|
||||
m_AbyTimeStart = time(nullptr); |
||||
} |
||||
else if (std::regex_search(data, vis_pegs)) |
||||
{ |
||||
std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; |
||||
|
||||
while (start != end) |
||||
{ |
||||
temp.push_back(*start); |
||||
++start; |
||||
} |
||||
|
||||
//Corrects Pearlescent Values
|
||||
m_prl = std::stoi(temp[0]); |
||||
|
||||
//Corrects Ebon Values
|
||||
m_ebn = std::stoi(temp[1]); |
||||
|
||||
//Corrects Gold Values
|
||||
m_gld = std::stoi(temp[2]); |
||||
|
||||
//Corrects Silvery Values
|
||||
m_slv = std::stoi(temp[3]); |
||||
|
||||
} |
||||
else if (std::regex_search(data, vis_azram)) |
||||
{ |
||||
std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; |
||||
|
||||
while (start != end) |
||||
{ |
||||
temp.push_back(*start); |
||||
++start; |
||||
} |
||||
|
||||
//Corrects Azure Values
|
||||
m_azr = std::stoi(temp[0]); |
||||
|
||||
//Corrects Ruby Values
|
||||
m_rby = std::stoi(temp[1]); |
||||
|
||||
//Corrects Amber Values
|
||||
m_amb = std::stoi(temp[2]); |
||||
|
||||
} |
||||
else if (std::regex_search(data, light_pearl)) |
||||
{ |
||||
//checks to ensure value does not exceed 230
|
||||
if (m_prl + 5 > 230) |
||||
{ |
||||
m_prl = 230; |
||||
} |
||||
else |
||||
{ |
||||
m_prl += 5; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_gold)) |
||||
{ |
||||
//checks to ensure value does not exceed 200
|
||||
if (m_gld + 5 > 200) |
||||
{ |
||||
m_gld = 200; |
||||
} |
||||
else |
||||
{ |
||||
m_gld += 5; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_silver)) |
||||
{ |
||||
//checks to ensure value does not exceed 200
|
||||
if (m_slv + 5 > 200) |
||||
{ |
||||
m_slv = 200; |
||||
} |
||||
else |
||||
{ |
||||
m_slv += 5; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_ebon)) |
||||
{ |
||||
//checks to ensure value does not exceed 200
|
||||
if (m_ebn + 1 > 200) |
||||
{ |
||||
m_ebn = 200; |
||||
} |
||||
else |
||||
{ |
||||
m_ebn += 1; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_azure)) |
||||
{ |
||||
//checks to ensure value does not exceed 255
|
||||
if (m_azr + 8 > 255) |
||||
{ |
||||
m_azr = 255; |
||||
} |
||||
else |
||||
{ |
||||
m_azr += 8; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_ruby)) |
||||
{ |
||||
//checks to ensure value does not exceed 255
|
||||
if (m_rby + 8 > 255) |
||||
{ |
||||
m_rby = 255; |
||||
} |
||||
else |
||||
{ |
||||
m_rby += 8; |
||||
} |
||||
} |
||||
else if (std::regex_search(data, light_amber)) |
||||
{ |
||||
//checks to ensure value does not exceed 255
|
||||
if (m_amb + 8 > 255) |
||||
{ |
||||
m_amb = 255; |
||||
} |
||||
else |
||||
{ |
||||
m_amb += 8; |
||||
} |
||||
} |
||||
} |
||||
#pragma endregion |
||||
|
||||
return false; |
||||
} |
||||
|
||||
bool WatchEXP::Direct3DInitialize(IDirect3DDevice8* lpDevice) |
||||
{ |
||||
this->m_Direct3DDevice = lpDevice; |
||||
|
||||
m_ExpObj = m_AshitaCore->GetFontManager()->Create("EXP_ID"); |
||||
m_ExpObj->SetText("0/0"); |
||||
m_ExpObj->SetFontFamily(font_name); |
||||
m_ExpObj->SetFontHeight(font_size); |
||||
m_ExpObj->SetColor(0xFFFFFFFF); |
||||
m_ExpObj->SetBold(false); |
||||
m_ExpObj->SetVisibility(true); |
||||
m_ExpObj->SetPositionX(100); |
||||
m_ExpObj->SetPositionY(100); |
||||
m_ExpObj->SetVisibility(false); |
||||
|
||||
m_ExpObj->GetBackground()->SetVisibility(true); |
||||
m_ExpObj->GetBackground()->SetColor(0x80000000); |
||||
|
||||
m_BaseTimeEXP = time(nullptr); |
||||
m_BaseTimeCR = time(nullptr); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void WatchEXP::Direct3DRelease(void) |
||||
{ |
||||
m_AshitaCore->GetFontManager()->Delete("EXP_ID"); |
||||
} |
||||
|
||||
void WatchEXP::Direct3DRender(void) |
||||
{ |
||||
doEXPCalculations(); |
||||
doAbysseaZoneTimings(); |
||||
doDynamisZoneTimings(); |
||||
checkResetTime(); |
||||
} |
||||
|
||||
__declspec(dllexport) double __stdcall GetInterfaceVersion(void) |
||||
{ |
||||
return ASHITA_INTERFACE_VERSION; |
||||
} |
||||
|
||||
__declspec(dllexport) void __stdcall CreatePluginInfo(plugininfo_t* info) |
||||
{ |
||||
g_PluginInformation = info; |
||||
|
||||
strcpy_s(info->Author, sizeof(info->Author), "Praenuntiae (ported by Vicrelant)"); |
||||
strcpy_s(info->Name, sizeof(info->Name), "WatchEXP"); |
||||
info->InterfaceVersion = ASHITA_INTERFACE_VERSION; |
||||
info->PluginVersion = 3.0f; |
||||
info->Priority = 0; |
||||
} |
||||
|
||||
__declspec(dllexport) IPlugin* __stdcall CreatePlugin(void) |
||||
{ |
||||
return (IPlugin*)new WatchEXP(); |
||||
} |
||||
|
||||
#pragma region GetConfig |
||||
void WatchEXP::GetConfig() |
||||
{ |
||||
auto iConfigResult = false; |
||||
auto iTemp = 0; |
||||
|
||||
iConfigResult = m_AshitaCore->GetConfigurationManager()->Load("WatchEXP", "WatchEXP"); |
||||
|
||||
if (iConfigResult != 0) |
||||
{ |
||||
auto szBuffer = m_AshitaCore->GetConfigurationManager()->get_string("WatchEXP", "font_name"); |
||||
strcpy_s(font_name, szBuffer); |
||||
|
||||
font_size = m_AshitaCore->GetConfigurationManager()->get_int32("WatchEXP", "font_size", 11); |
||||
show_XP_M_always = m_AshitaCore->GetConfigurationManager()->get_bool("WatchEXP", "show_both_xp_and_merits_when_capped", false); |
||||
m_reset_min = m_AshitaCore->GetConfigurationManager()->get_int32("WatchEXP", "auto_reset_time", 45); |
||||
m_autoreset = m_AshitaCore->GetConfigurationManager()->get_bool("WatchEXP", "auto_reset_enabled", false); |
||||
} |
||||
else if (iConfigResult == 0) |
||||
{ |
||||
m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "font_name", "Arial"); |
||||
m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "font_size", "11"); |
||||
m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "show_both_xp_and_merits_when_capped", "true"); |
||||
m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "auto_reset_time", "45"); |
||||
m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "auto_reset_enabled", "false"); |
||||
m_AshitaCore->GetConfigurationManager()->Save("WatchEXP", "WatchEXP"); |
||||
|
||||
strcpy_s(font_name, "Arial"); |
||||
font_size = 11; |
||||
show_XP_M_always = false; |
||||
m_reset_min = 45; |
||||
m_autoreset = false; |
||||
} |
||||
} |
||||
#pragma endregion |
||||
|
||||
#pragma region doEXPCalculations |
||||
void WatchEXP::doEXPCalculations() |
||||
{ |
||||
char *p; |
||||
char expIntoLVL[10] = "", expForLVL[10] = "", expTillLVL[10] = "", lmtIntoLVL[10] = "", lmtTillLVL[10] = "", xpTotal[40] = "", crTotal[40] = ""; |
||||
|
||||
m_IsInAbyssea = isInAbyssea(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); |
||||
m_IsInDynamis = isInDynamis(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); |
||||
|
||||
// get the EXP info
|
||||
unsigned short expIN = m_AshitaCore->GetDataManager()->GetPlayer()->GetExpCurrent(); |
||||
unsigned short expMAX = m_AshitaCore->GetDataManager()->GetPlayer()->GetExpNeeded(); |
||||
unsigned short expLEFT = expMAX - expIN; |
||||
|
||||
// get the Merit info
|
||||
unsigned short lmtIN = m_AshitaCore->GetDataManager()->GetPlayer()->GetLimitPoints(); |
||||
unsigned short lmtMAX = 10000; |
||||
unsigned short lmtLEFT = lmtMAX - lmtIN; |
||||
|
||||
p = expIntoLVL; |
||||
makeComma(expIN, p, 0); |
||||
_strrev(expIntoLVL); |
||||
|
||||
p = expForLVL; |
||||
makeComma(expMAX, p, 0); |
||||
_strrev(expForLVL); |
||||
|
||||
p = expTillLVL; |
||||
makeComma(expLEFT, p, 0); |
||||
_strrev(expTillLVL); |
||||
|
||||
p = lmtIntoLVL; |
||||
makeComma(lmtIN, p, 0); |
||||
_strrev(lmtIntoLVL); |
||||
|
||||
p = lmtTillLVL; |
||||
makeComma(lmtLEFT, p, 0); |
||||
_strrev(lmtTillLVL); |
||||
|
||||
p = xpTotal; |
||||
makeComma(m_xpTotal, p, 0); |
||||
_strrev(xpTotal); |
||||
|
||||
p = crTotal; |
||||
makeComma(m_crTotal, p, 0); |
||||
_strrev(crTotal); |
||||
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() < 75) |
||||
{ |
||||
if (m_IsInDynamis) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, |
||||
xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); |
||||
} |
||||
else if (m_IsInAbyssea) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", |
||||
expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), |
||||
m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); |
||||
} |
||||
else |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, |
||||
xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); |
||||
} |
||||
} |
||||
if ((!show_XP_M_always) && (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() >= 75)) |
||||
{ |
||||
unsigned char isMeritMode = m_AshitaCore->GetDataManager()->GetPlayer()->GetLimitMode(); |
||||
|
||||
if ((expLEFT == 1) || (isMeritMode == 224)) |
||||
{ |
||||
if (m_IsInDynamis) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", lmtIntoLVL, lmtTillLVL, |
||||
(int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, |
||||
m_Dyna_Obs, m_DynaTime); |
||||
} |
||||
else if (m_IsInAbyssea) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", lmtIntoLVL, lmtTillLVL, |
||||
(int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), |
||||
m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); |
||||
} |
||||
else |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr ", |
||||
lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, |
||||
m_xpKill, returnProjectedEXPperHour(m_xpTotal)); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (m_IsInDynamis) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, |
||||
xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); |
||||
} |
||||
else if (m_IsInAbyssea) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", |
||||
expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, |
||||
m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); |
||||
} |
||||
else |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); |
||||
} |
||||
} |
||||
} |
||||
if ((show_XP_M_always) && (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() >= 75)) |
||||
{ |
||||
if (m_IsInDynamis) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, |
||||
lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, |
||||
m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); |
||||
} |
||||
else if (m_IsInAbyssea) |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", |
||||
expIntoLVL, expForLVL, expTillLVL, lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), |
||||
crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); |
||||
} |
||||
else |
||||
{ |
||||
sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, |
||||
lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); |
||||
} |
||||
} |
||||
|
||||
// double check the size of the text
|
||||
if (m_ExpObjSize.cy == 0) |
||||
{ |
||||
int window_y = m_AshitaCore->GetConfigurationManager()->get_int32("boot_config", "window_y", 600); |
||||
m_ExpObj->GetTextSize(&m_ExpObjSize); |
||||
m_ExpObj->SetPositionX(15.0f); |
||||
m_ExpObj->SetPositionY((float)(window_y - m_ExpObjSize.cy)); |
||||
} |
||||
|
||||
// set the object information
|
||||
m_ExpObj->SetText(TextObjectBuffer); |
||||
m_ExpObj->SetVisibility(true); |
||||
} |
||||
#pragma endregion |
||||
#pragma region returnProjectedEXPperHour |
||||
float WatchEXP::returnProjectedEXPperHour(unsigned int expIntoLevel) |
||||
{ |
||||
float changeInTime = (float(time(nullptr) - m_BaseTimeEXP)); |
||||
float changeInTimeHR = ((changeInTime / 60) / 60); |
||||
|
||||
if (expIntoLevel == 0) |
||||
{ |
||||
m_BaseTimeEXP = time(nullptr); |
||||
} |
||||
|
||||
// just in case we don't do a divide by zero
|
||||
if (changeInTime == 0.0f) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
return ((((float)expIntoLevel) / changeInTimeHR) / 1000); |
||||
} |
||||
#pragma endregion |
||||
#pragma region returnProjectedCRUORperHour |
||||
float WatchEXP::returnProjectedCRUORperHour(unsigned int cruorLVL) |
||||
{ |
||||
float changeInTime = (float(time(nullptr) - m_BaseTimeCR)); |
||||
float changeInTimeHR = ((changeInTime / 60) / 60); |
||||
|
||||
if (cruorLVL == 0) |
||||
{ |
||||
m_BaseTimeCR = time(nullptr); |
||||
} |
||||
|
||||
// just in case we don't do a divide by zero
|
||||
if (changeInTime == 0.0f) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
return ((((float)cruorLVL) / changeInTimeHR) / 1000); |
||||
} |
||||
#pragma endregion |
||||
#pragma region isInAbyssea |
||||
bool WatchEXP::isInAbyssea(int zoneID) |
||||
{ |
||||
// look for it
|
||||
for (auto& x : AbysseaZoneIDs) |
||||
{ |
||||
// Yes!
|
||||
if (x == zoneID) |
||||
return true; |
||||
} |
||||
|
||||
m_prl = 0, m_gld = 0, m_amb = 0, m_slv = 0, m_azr = 0, m_ebn = 0, m_rby = 0, m_vTime = 0; |
||||
|
||||
return false; |
||||
} |
||||
#pragma endregion |
||||
#pragma region isInDynamis |
||||
bool WatchEXP::isInDynamis(int zoneID) |
||||
{ |
||||
// look for it
|
||||
for (auto& x : DynamisZoneIDs) |
||||
{ |
||||
// Yes!
|
||||
if (x == zoneID) |
||||
return true; |
||||
} |
||||
|
||||
m_Dyna_Crm = 'X', m_Dyna_Azr = 'X', m_Dyna_Alab = 'X', m_Dyna_Amb = 'X', m_Dyna_Obs = 'X'; |
||||
// Nope
|
||||
return false; |
||||
} |
||||
#pragma endregion |
||||
#pragma region doAbysseaZoneTimings |
||||
void WatchEXP::doAbysseaZoneTimings() |
||||
{ |
||||
// check to see if we are in Abyssea
|
||||
m_IsInAbyssea = isInAbyssea(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); |
||||
|
||||
if (m_IsInAbyssea && (time(nullptr) - m_AbyTimeStart) > 60) |
||||
{ |
||||
m_AbyTimeStart = time(nullptr); |
||||
if (m_vTime != 0) |
||||
{ |
||||
m_vTime -= 1; |
||||
} |
||||
} |
||||
} |
||||
#pragma endregion |
||||
#pragma region doDynamisZoneTimings |
||||
void WatchEXP::doDynamisZoneTimings() |
||||
{ |
||||
// check to see if we are in Abyssea
|
||||
m_IsInDynamis = isInDynamis(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); |
||||
|
||||
doDynamisKItemCheck(); |
||||
|
||||
if (m_IsInDynamis && (time(nullptr) - m_DynTimeStart) > 60) |
||||
{ |
||||
m_DynTimeStart = time(nullptr); |
||||
if (m_DynaTime != 0) |
||||
{ |
||||
m_DynaTime -= 1; |
||||
} |
||||
} |
||||
} |
||||
#pragma endregion |
||||
#pragma region doDynamisKItemCheck |
||||
void WatchEXP::doDynamisKItemCheck() |
||||
{ |
||||
//Checks for Crimson Granule of Time
|
||||
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1545)) |
||||
{ |
||||
m_Dyna_Crm = 'O'; |
||||
} |
||||
//Checks for Azure Granule of Time
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1546)) |
||||
{ |
||||
m_Dyna_Azr = 'O'; |
||||
} |
||||
//Checks for Amber Granule of Time
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1547)) |
||||
{ |
||||
m_Dyna_Amb = 'O'; |
||||
} |
||||
//Checks for Alabaster Granule of Time
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1548)) |
||||
{ |
||||
m_Dyna_Alab = 'O'; |
||||
} |
||||
//Checks for Obsidian Granule of Time
|
||||
if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1549)) |
||||
{ |
||||
m_Dyna_Obs = 'O'; |
||||
} |
||||
} |
||||
#pragma endregion |
||||
#pragma region makeComma |
||||
void WatchEXP::makeComma(int n, char *p, int count) |
||||
{ |
||||
int d; |
||||
// Get least significant digit
|
||||
d = n % 10; |
||||
// Convert to ascii character and store
|
||||
*p++ = d + '0'; |
||||
// Remove least significant digit
|
||||
// Test for finished
|
||||
if (n /= 10) |
||||
{ |
||||
// Not finished, increase digit count,
|
||||
// test for comma position
|
||||
count++; |
||||
if (count >= 3) |
||||
{ |
||||
// Add the comma and reset the count
|
||||
*p++ = ','; |
||||
count = 0; |
||||
} |
||||
// Call this procedure to work on
|
||||
// remaining part of number
|
||||
makeComma(n, p, count); |
||||
} |
||||
return; |
||||
} |
||||
#pragma endregion |
||||
|
||||
#pragma region convertFromHex |
||||
int WatchEXP::convertFromHex(std::string hex) |
||||
{ |
||||
int value = 0; |
||||
int a = 0; |
||||
int b = hex.length() - 1; |
||||
|
||||
for (; b >= 0; a++, b--) |
||||
{ |
||||
if (hex[b] >= '0' && hex[b] <= '9') |
||||
{ |
||||
value += (hex[b] - '0') * (1 << (a * 4)); |
||||
} |
||||
else |
||||
{ |
||||
switch (hex[b]) |
||||
{ |
||||
case 'A': |
||||
|
||||
case 'a': |
||||
value += 10 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
case 'B': |
||||
|
||||
case 'b': |
||||
value += 11 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
case 'C': |
||||
|
||||
case 'c': |
||||
value += 12 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
case 'D': |
||||
|
||||
case 'd': |
||||
value += 13 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
case 'E': |
||||
|
||||
case 'e': |
||||
value += 14 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
case 'F': |
||||
|
||||
case 'f': |
||||
value += 15 * (1 << (a * 4)); |
||||
break; |
||||
|
||||
default: |
||||
|
||||
break; |
||||
|
||||
} |
||||
} |
||||
} |
||||
return value; |
||||
} |
||||
#pragma endregion |
||||
#pragma region hextodec |
||||
void WatchEXP::hextodec(std::string hex, std::vector<unsigned char>& rgb) |
||||
{ |
||||
std::string redString, greenString, blueString; |
||||
|
||||
if (hex.compare(0, 1, "#") == 0) |
||||
{ |
||||
//If the prefix # was attached to hex, use the following code
|
||||
redString = hex.substr(1, 2); |
||||
greenString = hex.substr(3, 2); |
||||
blueString = hex.substr(5, 2); |
||||
} |
||||
else if (hex.compare(0, 2, "0x") == 0) |
||||
{ |
||||
//If the prefix 0x was attached to hex, use the following code
|
||||
redString = hex.substr(2, 2); |
||||
greenString = hex.substr(4, 2); |
||||
blueString = hex.substr(6, 2); |
||||
} |
||||
else |
||||
{ |
||||
//If there is no prefix attached to hex, use this code
|
||||
redString = hex.substr(0, 2); |
||||
greenString = hex.substr(2, 2); |
||||
blueString = hex.substr(4, 2); |
||||
} |
||||
|
||||
unsigned char red = (unsigned char)(convertFromHex(redString)); |
||||
unsigned char green = (unsigned char)(convertFromHex(greenString)); |
||||
unsigned char blue = (unsigned char)(convertFromHex(blueString)); |
||||
|
||||
rgb[0] = red; |
||||
rgb[1] = green; |
||||
rgb[2] = blue; |
||||
} |
||||
#pragma endregion |
||||
#pragma region convertTrans |
||||
void WatchEXP::convertTrans(unsigned char& trans) |
||||
{ |
||||
float temp1, temp2; |
||||
|
||||
temp1 = (float)trans; |
||||
|
||||
temp2 = temp1 * (float)2.55; |
||||
|
||||
if (temp2 > 255) |
||||
{ |
||||
trans = (unsigned char)255; |
||||
} |
||||
else |
||||
{ |
||||
trans = (unsigned char)temp2; |
||||
} |
||||
} |
||||
#pragma endregion |
||||
#pragma region checkResetTime |
||||
void WatchEXP::checkResetTime() |
||||
{ |
||||
if (time(nullptr) - m_resetTime > 60) |
||||
{ |
||||
if (m_xpTest != m_xpTotal) |
||||
{ |
||||
m_xpTest = m_xpTotal; |
||||
m_resetTime = time(nullptr); |
||||
} |
||||
else if ((m_xpTest == m_xpTotal) && (m_autoreset)) |
||||
{ |
||||
if (((time(nullptr) - m_resetTime) / 60) >= m_reset_min) |
||||
{ |
||||
m_resetTime = time(nullptr); |
||||
|
||||
m_crTotal = 0, m_xpTotal = 0, m_xpKill = 0, m_crKill = 0; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#pragma endregion |
||||
#pragma region ScrubChat |
||||
std::string WatchEXP::ScrubChat(const char* chat_line) |
||||
{ |
||||
//strings to hold the chat data through the various scrubbing stages
|
||||
std::string chat_raw; |
||||
std::string clean_chat_pass1; |
||||
std::string clean_chat_pass2; |
||||
std::string clean_chat_pass3; |
||||
std::string clean_chat_final; |
||||
|
||||
char szClean[1024]; |
||||
|
||||
//regex expressions for parsing the raw chat until it's clean
|
||||
std::regex parse1("\\x1E\\x05|\\x1E(\\x03|\\x02|\\x01)|\\x7F\\x31|\\x1F(\\x79|\\x7F|\\x7B|\\W)"); |
||||
std::regex parse2("[[:cntrl:]]|\\W\\W"); |
||||
std::regex time_stamp("\\x1E\\x03((\\[\\d+(:|/)\\d+(:|/)\\d+(\\]| [AMP]+\\]))|\\[\\d+(:|/)\\d+(:|/)\\d+ - \\d+:\\d+:\\d+(\\]| [AMP]+\\]))\\x1E\\x01\\s+"); |
||||
std::regex multi_space("\\s+"); |
||||
|
||||
memset(szClean, 0, 1024); |
||||
|
||||
//Cleans up any auto translate data so it can be properly parsed
|
||||
m_AshitaCore->GetChatManager()->ParseAutoTranslate(chat_line, szClean, 1024, false); |
||||
|
||||
chat_raw = chat_line; |
||||
|
||||
//Removes TimeStamp data from beginning of line
|
||||
std::regex_replace(std::back_inserter(clean_chat_pass1), chat_raw.begin(), chat_raw.end(), time_stamp, ""); |
||||
|
||||
//Removes some control characters from the beginning and end of the string that print as garbage
|
||||
std::regex_replace(std::back_inserter(clean_chat_pass2), clean_chat_pass1.begin(), clean_chat_pass1.end(), parse1, ""); |
||||
|
||||
//Removes any remaining control characters and replaces them with spaces
|
||||
std::regex_replace(std::back_inserter(clean_chat_pass3), clean_chat_pass2.begin(), clean_chat_pass2.end(), parse2, " "); |
||||
|
||||
//Changes any multi space areas to single spaces
|
||||
std::regex_replace(std::back_inserter(clean_chat_final), clean_chat_pass3.begin(), clean_chat_pass3.end(), multi_space, " "); |
||||
|
||||
return clean_chat_final; |
||||
} |
||||
#pragma endregion |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
#ifndef __ASHITA_WATCHEXP_H_INCLUDED__ |
||||
#define __ASHITA_WATCHEXP_H_INCLUDED__ |
||||
|
||||
#if defined (_MSC_VER) && (_MSC_VER >= 1020) |
||||
#pragma once |
||||
#endif |
||||
|
||||
#include "G:\Code\git.ashita.atom0s.com\Ashita v3\Ashita-src\build\plugins\ADK\Ashita.h" |
||||
#include <tuple> |
||||
#include <stdint.h> |
||||
#include <regex> |
||||
#include <time.h> |
||||
#include <string> |
||||
#include <sstream> |
||||
#include <vector> |
||||
|
||||
plugininfo_t* g_PluginInformation = nullptr; |
||||
|
||||
int AbysseaZoneIDs[] = { 15,45,132,215,216,217,218,253,254,255 }; |
||||
int DynamisZoneIDs[] = { 39,40,41,42,134,135,185,186,187,188 }; |
||||
|
||||
class WatchEXP : IPlugin |
||||
{ |
||||
WatchEXP(const WatchEXP & cpy); |
||||
WatchEXP & operator=(WatchEXP & rhs); |
||||
|
||||
IAshitaCore* m_AshitaCore; |
||||
DWORD m_PluginId; |
||||
IDirect3DDevice8* m_Direct3DDevice; |
||||
|
||||
public: |
||||
WatchEXP(void); |
||||
virtual ~WatchEXP(void); |
||||
|
||||
public: |
||||
plugininfo_t GetPluginInfo(void) override; |
||||
|
||||
private: |
||||
IFontObject* m_ExpObj; |
||||
|
||||
char TextObjectBuffer[MAX_PATH]; |
||||
|
||||
time_t m_AbyTimeStart, m_DynTimeStart, m_BaseTimeEXP, m_BaseTimeCR, m_resetTime; |
||||
|
||||
SIZE m_ExpObjSize; |
||||
int font_size, m_reset_min; |
||||
int m_CurrentZoneID, m_LastZoneRecorded; |
||||
char font_name[128]; |
||||
char m_Dyna_Crm, m_Dyna_Azr, m_Dyna_Amb, m_Dyna_Alab, m_Dyna_Obs; |
||||
std::string hexColor; |
||||
unsigned int m_vTime; |
||||
unsigned int m_DynaTime; |
||||
unsigned int m_xpKill, m_xpTotal, m_xpTest; |
||||
unsigned int m_crKill, m_crTotal; |
||||
unsigned int m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb; |
||||
unsigned char backTrans; |
||||
bool m_IsInAbyssea, m_IsInDynamis, show_XP_M_always, m_autoreset; |
||||
public: |
||||
bool Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) override; |
||||
void Release(void) override; |
||||
bool HandleCommand(const char* pszCommand, int nCommandType) override; |
||||
bool HandleIncomingText(int16_t mode, const char* message, int16_t* modifiedMode, char* modifiedMessage, bool blocked) override; |
||||
bool Direct3DInitialize(IDirect3DDevice8* lpDevice) override; |
||||
void Direct3DRelease(void) override; |
||||
void Direct3DRender(void) override; |
||||
|
||||
void GetConfig(void); |
||||
|
||||
float returnProjectedEXPperHour(unsigned int expIntoLevel); |
||||
float returnProjectedCRUORperHour(unsigned int expIntoLevel); |
||||
void doAbysseaZoneTimings(); |
||||
void doDynamisZoneTimings(); |
||||
void doDynamisKItemCheck(); |
||||
void doEXPCalculations(); |
||||
bool isInAbyssea(int zoneID); |
||||
bool isInDynamis(int zoneID); |
||||
void makeComma(int n, char *p, int count); |
||||
int convertFromHex(std::string hex); |
||||
void hextodec(std::string hex, std::vector<unsigned char>& rgb); |
||||
void convertTrans(unsigned char& trans); |
||||
void checkResetTime(); |
||||
std::string ScrubChat(const char* chat_line); |
||||
}; |
||||
|
||||
#endif |
Loading…
Reference in new issue