HardOne
Member
- Joined
- Jan 15, 2006
- RedCents
- 61¢
Rich (BB code):
// MQ2Tracking.cpp : Defines the entry point for the DLL application.
// v0.1 - Initial Release
// v0.2 - Minor bug fixes
// v0.3 - Updated to use new lists for improved performance.
// v0.4 - Added a few more sort options and a couple more filters
// v0.5 - Added customizable timed refresh based on Bushdaka's suggestion and code
// v0.6 - Changed the Cancel button to offer to a refresh function and change its label based on tracking state
// v0.7 - Added customizable entry display to the INI file.
// v0.8 - Added command /tracknames to set the display information while in game.
// v0.9 - Added custom track filter a la MP2Map style
// v0.10 - Cleaned up the commands and moved most inside the /track command. Also added /track help
// v0.11 - Fixed Function errors caused by naming functions the same as MQ2 functions. Bad MacroFiend!
#include "../MQ2Plugin.h"
#include "MQ2Tracking.h"
#include <time.h>
PTRACKSORT pTrackSort;
// Window Declarations
class CMyTrackingWnd : public CCustomWnd
{
public:
CMyTrackingWnd():CCustomWnd("TrackingWnd")
{
FilterRedButton=(CButtonWnd*)GetChildItem("TRW_FilterRedButton");
FilterYellowButton=(CButtonWnd*)GetChildItem("TRW_FilterYellowButton");
FilterWhiteButton=(CButtonWnd*)GetChildItem("TRW_FilterWhiteButton");
FilterBlueButton=(CButtonWnd*)GetChildItem("TRW_FilterBlueButton");
FilterLBlueButton=(CButtonWnd*)GetChildItem("TRW_FilterLightBlueButton");
FilterGreenButton=(CButtonWnd*)GetChildItem("TRW_FilterGreenButton");
TrackingList=(CListWnd*)GetChildItem("TRW_TrackingList");
TrackSortCombo=(CComboWnd*)GetChildItem("TRW_TrackSortCombobox");
TrackPlayersCombo=(CComboWnd*)GetChildItem("TRW_TrackPlayersCombobox");
TrackButton=(CButtonWnd*)GetChildItem("TRW_TrackButton");
DoneButton=(CButtonWnd*)GetChildItem("DoneButton");
SetWndNotification(CMyTrackingWnd);
}
~CMyTrackingWnd()
{
}
int WndNotification(CXWnd *pWnd, unsigned int Message, void *unknown)
{
if (pWnd==(CXWnd*)TrackButton)
{
if (Message==XWM_LCLICK) {
CHAR szLine[MAX_STRING] = {0};
pTrackSpawn = (PSPAWNINFO)GetSpawnByID(pTrackSort[TrackingList->GetCurSel()].SpawnID);
if (pTrackSpawn) {
// sprintf(szLine, "id %d", pTrackSpawn->SpawnID);
// Target((PSPAWNINFO)pCharSpawn, szLine);
WriteChatColor("Tracking started.");
TrackSpawn();
}
}
} else if (pWnd==(CXWnd*)DoneButton) {
if (Message==XWM_LCLICK) {
StopTracking(NULL,NULL);
ReloadSpawn();
}
} else if (pWnd==(CXWnd*)TrackingList) {
if (Message==XWM_RCLICK) {
PSPAWNINFO *psTarget = NULL;
psTarget = (PSPAWNINFO*)ppTarget;
*psTarget = (PSPAWNINFO)GetSpawnByID(pTrackSort[TrackingList->GetCurSel()].SpawnID);
}
} else if (pWnd==(CXWnd*)FilterRedButton || pWnd==(CXWnd*)FilterYellowButton
|| pWnd==(CXWnd*)FilterWhiteButton || pWnd==(CXWnd*)FilterBlueButton
|| pWnd==(CXWnd*)FilterLBlueButton || pWnd==(CXWnd*)FilterGreenButton
|| pWnd==(CXWnd*)TrackPlayersCombo || pWnd==(CXWnd*)TrackSortCombo) {
if (Message==XWM_LCLICK) ReloadSpawn();
}
return CSidlScreenWnd::WndNotification(pWnd,Message,unknown);
};
CButtonWnd *FilterRedButton;
CButtonWnd *FilterYellowButton;
CButtonWnd *FilterWhiteButton;
CButtonWnd *FilterBlueButton;
CButtonWnd *FilterLBlueButton;
CButtonWnd *FilterGreenButton;
CListWnd *TrackingList;
CComboWnd *TrackSortCombo;
CComboWnd *TrackPlayersCombo;
CButtonWnd *TrackButton;
CButtonWnd *DoneButton;
};
CMyTrackingWnd *TrackingWnd=0;
PreSetup("MQ2Tracking");
// Called once, when the plugin is to initialize
PLUGIN_API VOID InitializePlugin(VOID)
{
AddCommand("/track",Track);
}
// Called once, when the plugin is to shutdown
PLUGIN_API VOID ShutdownPlugin(VOID)
{
RemoveCommand("/track");
DestroyTrackingWindow();
free(pTrackSort);
}
PLUGIN_API VOID OnPulse(VOID)
{
if (Update) {
pulsedelay++;
if (pulsedelay>50) {
pulsedelay = 0;
if (pTrackSpawn) TrackSpawn();
}
if (refreshWindow && ((clock() - lastRefresh) > (RefreshTimer * CLOCKS_PER_SEC))) {
if (TrackingWnd) if (TrackingWnd->Show) ReloadSpawn();
lastRefresh = clock();
}
}
}
// This is called each time a spawn is added to a zone (inserted into EQ's list of spawns),
// or for each existing spawn when a plugin first initializes
// NOTE: When you zone, these will come BEFORE OnZoned
PLUGIN_API VOID OnAddSpawn(PSPAWNINFO pNewSpawn)
{
}
PLUGIN_API VOID OnRemoveSpawn(PSPAWNINFO pNewSpawn)
{
if (Update && pTrackSpawn) if (pNewSpawn == pTrackSpawn) {
StopTracking(NULL,NULL);
}
}
// Called once directly before shutdown of the new ui system, and also
// every time the game calls CDisplay::CleanGameUI()
PLUGIN_API VOID OnCleanUI(VOID)
{
DebugSpewAlways("MQ2Tracking::OnCleanUI()");
DestroyTrackingWindow();
}
// Called once directly after the game ui is reloaded, after issuing /loadskin
PLUGIN_API VOID OnReloadUI(VOID)
{
DebugSpewAlways("MQ2Tracking::OnReloadUI()");
DestroyTrackingWindow();
}
// Called once directly after initialization, and then every time the gamestate changes
PLUGIN_API VOID SetGameState(DWORD GameState)
{
DebugSpewAlways("MQ2Tracking::SetGameState()");
if (GameState==GAMESTATE_INGAME)
Update = TRUE;
else
Update = FALSE;
}
PLUGIN_API VOID OnZoned()
{
if (TrackingWnd) ReloadSpawn();
}
void CreateTrackingWindow()
{
DebugSpewAlways("MQ2Tracking::CreateTrackingWindow()");
if (TrackingWnd) return;
if (pSidlMgr->FindScreenPieceTemplate("TrackingWnd")) {
TrackingWnd = new CMyTrackingWnd;
SetCXStr(&(TrackingWnd->DoneButton->WindowText),"Refresh");
TrackingWnd->TrackSortCombo->DeleteAll();
TrackingWnd->TrackSortCombo->SetColors(0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
TrackingWnd->TrackSortCombo->InsertChoice("ID");
TrackingWnd->TrackSortCombo->InsertChoice("Name");
TrackingWnd->TrackSortCombo->InsertChoice("Level (ASC)");
TrackingWnd->TrackSortCombo->InsertChoice("Level (DESC)");
TrackingWnd->TrackSortCombo->InsertChoice("Distance (ASC)");
TrackingWnd->TrackSortCombo->InsertChoice("Distance (DESC)");
TrackingWnd->TrackSortCombo->SetChoice(1);
TrackingWnd->TrackPlayersCombo->DeleteAll();
TrackingWnd->TrackPlayersCombo->SetColors(0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF);
TrackingWnd->TrackPlayersCombo->InsertChoice("All");
TrackingWnd->TrackPlayersCombo->InsertChoice("PC");
TrackingWnd->TrackPlayersCombo->InsertChoice("Group");
TrackingWnd->TrackPlayersCombo->InsertChoice("NPC");
TrackingWnd->TrackPlayersCombo->InsertChoice("Chest");
TrackingWnd->TrackPlayersCombo->SetChoice(0);
ReadWindowINI((PCSIDLWND)TrackingWnd);
WriteWindowINI((PCSIDLWND)TrackingWnd);
}
}
void DestroyTrackingWindow()
{
DebugSpewAlways("MQ2Tracking::DestroyTrackingWindow()");
if (TrackingWnd)
{
WriteWindowINI((PCSIDLWND)TrackingWnd);
delete TrackingWnd;
TrackingWnd=0;
}
}
void ReadWindowINI(PCSIDLWND pWindow)
{
CHAR Buffer[MAX_STRING] = {0};
pWindow->Location.top = GetPrivateProfileInt("Settings","ChatTop", 357,INIFileName);
pWindow->Location.bottom = GetPrivateProfileInt("Settings","ChatBottom", 620,INIFileName);
pWindow->Location.left = GetPrivateProfileInt("Settings","ChatLeft", 164,INIFileName);
pWindow->Location.right = GetPrivateProfileInt("Settings","ChatRight", 375,INIFileName);
pWindow->Locked = GetPrivateProfileInt("Settings","Locked", 0,INIFileName);
pWindow->Fades = GetPrivateProfileInt("Settings","Fades", 1,INIFileName);
pWindow->TimeMouseOver = GetPrivateProfileInt("Settings","Delay", 2000,INIFileName);
pWindow->FadeDuration = GetPrivateProfileInt("Settings","Duration", 500,INIFileName);
pWindow->Alpha = GetPrivateProfileInt("Settings","Alpha", 255,INIFileName);
pWindow->FadeToAlpha = GetPrivateProfileInt("Settings","FadeToAlpha", 255,INIFileName);
pWindow->BGType = GetPrivateProfileInt("Settings","BGType", 1,INIFileName);
pWindow->BGColor.R = GetPrivateProfileInt("Settings","BGTint.red", 255,INIFileName);
pWindow->BGColor.G = GetPrivateProfileInt("Settings","BGTint.green", 255,INIFileName);
pWindow->BGColor.B = GetPrivateProfileInt("Settings","BGTint.blue", 255,INIFileName);
((CMyTrackingWnd*)pWindow)->FilterRedButton->SetCheck (1 & GetPrivateProfileInt("Filters","ShowRed", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->FilterYellowButton->SetCheck(1 & GetPrivateProfileInt("Filters","ShowYellow", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->FilterWhiteButton->SetCheck (1 & GetPrivateProfileInt("Filters","ShowWhite", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->FilterBlueButton->SetCheck (1 & GetPrivateProfileInt("Filters","ShowBlue", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->FilterLBlueButton->SetCheck (1 & GetPrivateProfileInt("Filters","ShowLBlue", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->FilterGreenButton->SetCheck (1 & GetPrivateProfileInt("Filters","ShowGreen", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->TrackPlayersCombo->SetChoice(GetPrivateProfileInt("Filters","Players", 0,INIFileName));
((CMyTrackingWnd*)pWindow)->TrackSortCombo->SetChoice(GetPrivateProfileInt("Filters","Sort", 0,INIFileName));
TrackDist = GetPrivateProfileInt("Settings","TrackDistance", 75,INIFileName);
GetPrivateProfileString("Settings","DisplayTpl", "[%l %C] %N (%R)", szNameTemplate, MAX_STRING, INIFileName);
refreshWindow = 1 & GetPrivateProfileInt("Settings","AutoRefresh", 0,INIFileName);
RefreshTimer = GetPrivateProfileInt("Settings","RefreshDelay", 75,INIFileName);
}
void WriteWindowINI(PCSIDLWND pWindow)
{
CHAR szTemp[MAX_STRING] = {0};
if (pWindow->Minimized)
{
WritePrivateProfileString("Settings","ChatTop", itoa(pWindow->OldLocation.top, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatBottom", itoa(pWindow->OldLocation.bottom, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatLeft", itoa(pWindow->OldLocation.left, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatRight", itoa(pWindow->OldLocation.right, szTemp,10),INIFileName);
}
else
{
WritePrivateProfileString("Settings","ChatTop", itoa(pWindow->Location.top, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatBottom", itoa(pWindow->Location.bottom, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatLeft", itoa(pWindow->Location.left, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","ChatRight", itoa(pWindow->Location.right, szTemp,10),INIFileName);
}
WritePrivateProfileString("Settings","Locked", itoa(pWindow->Locked, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","Fades", itoa(pWindow->Fades, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","Delay", itoa(pWindow->MouseOver, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","Duration", itoa(pWindow->FadeDuration, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","Alpha", itoa(pWindow->Alpha, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","FadeToAlpha", itoa(pWindow->FadeToAlpha, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","BGType", itoa(pWindow->BGType, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","BGTint.red", itoa(pWindow->BGColor.R, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","BGTint.green", itoa(pWindow->BGColor.G, szTemp,10),INIFileName);
WritePrivateProfileString("Settings","BGTint.blue", itoa(pWindow->BGColor.B, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowRed", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterRedButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowYellow", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterYellowButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowWhite", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterWhiteButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowBlue", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterBlueButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowLBlue", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterLBlueButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","ShowGreen", itoa(1 & ((CMyTrackingWnd*)pWindow)->FilterGreenButton->Checked, szTemp,10),INIFileName);
WritePrivateProfileString("Filters","Players", itoa(((CMyTrackingWnd*)pWindow)->TrackPlayersCombo->GetCurChoice(), szTemp,10),INIFileName);
WritePrivateProfileString("Filters","Sort", itoa(((CMyTrackingWnd*)pWindow)->TrackSortCombo->GetCurChoice(), szTemp,10),INIFileName);
WritePrivateProfileString("Settings","TrackDistance", itoa(TrackDist,szTemp,10), INIFileName);
WritePrivateProfileString("Settings","DisplayTpl", szNameTemplate, INIFileName);
WritePrivateProfileString("Settings","AutoRefresh", itoa(1 & refreshWindow,szTemp,10), INIFileName);
WritePrivateProfileString("Settings","RefreshDelay", itoa(RefreshTimer,szTemp,10), INIFileName);
}
DWORD STrackSortValue=0;
PSPAWNINFO SWhoSortOrigin=0;
static int pTrackSORTCompare(const void *A, const void *B)
{
PSPAWNINFO SpawnA=*(PSPAWNINFO*)A;
PSPAWNINFO SpawnB=*(PSPAWNINFO*)B;
switch(STrackSortValue)
{
/*
TrackingWnd->TrackSortCombo->InsertChoice("Spawn ID");
TrackingWnd->TrackSortCombo->InsertChoice("Name");
TrackingWnd->TrackSortCombo->InsertChoice("Level (ASC)");
TrackingWnd->TrackSortCombo->InsertChoice("Level (DESC)");
TrackingWnd->TrackSortCombo->InsertChoice("Distance (ASC)");
TrackingWnd->TrackSortCombo->InsertChoice("Distance (DESC)");
/**/
case 0: // spawnid - ascending
if (SpawnA->SpawnID>SpawnB->SpawnID)
return 1;
if (SpawnA->SpawnID<SpawnB->SpawnID)
return -1;
break;
// case 1://name - done at the bottom ;)
// break;
case 2://level - ascending
if (SpawnA->Level>SpawnB->Level)
return 1;
if (SpawnA->Level<SpawnB->Level)
return -1;
break;
case 3://level - descending
if (SpawnA->Level>SpawnB->Level)
return -1;
if (SpawnA->Level<SpawnB->Level)
return 1;
break;
case 4://distance - ascending
{
FLOAT DistA=GetDistance(SWhoSortOrigin,SpawnA);
FLOAT DistB=GetDistance(SWhoSortOrigin,SpawnB);
if (DistA>DistB)
return 1;
if (DistA<DistB)
return -1;
}
break;
case 5://distance - descending
{
FLOAT DistA=GetDistance(SWhoSortOrigin,SpawnA);
FLOAT DistB=GetDistance(SWhoSortOrigin,SpawnB);
if (DistA>DistB)
return -1;
if (DistA<DistB)
return 1;
}
break;
}
CHAR szNameA[MAX_STRING]={0};
CHAR szNameB[MAX_STRING]={0};
CleanupName(strcpy(szNameA,SpawnA->Name));
CleanupName(strcpy(szNameB,SpawnB->Name));
return stricmp(szNameA,szNameB);
}
VOID ReloadSpawn()
{
SEARCHSPAWN SearchSpawn;
CIndex<PSPAWNINFO> SpawnSet;
PSPAWNINFO pChar = (PSPAWNINFO)pCharSpawn;
PSPAWNINFO pSpawn = (PSPAWNINFO)pSpawnList;
PSPAWNINFO pOrigin=pChar;
PSEARCHSPAWN pSearchSpawn = &SearchSpawn;
DWORD TotalMatching=0;
ClearSearchSpawn(pSearchSpawn);
ParseSearchSpawn(szCustomSearch,pSearchSpawn);
switch (TrackingWnd->TrackPlayersCombo->GetCurChoice()) {
case 1:
pSearchSpawn->SpawnType = PC;
break;
case 2:
pSearchSpawn->bGroup = TRUE;
break;
case 3:
pSearchSpawn->SpawnType = NPC;
break;
case 4:
pSearchSpawn->SpawnType = CHEST;
break;
default:
pSearchSpawn->SpawnType = NONE;
break;
}
pSearchSpawn->SortBy = TrackingWnd->TrackSortCombo->GetCurChoice();
while (pSpawn)
{
DWORD myColor = ConColor(pSpawn);
if (SpawnMatchesSearch(pSearchSpawn,pOrigin,pSpawn) && (
(myColor == CONCOLOR_RED && TrackingWnd->FilterRedButton->Checked & 1) ||
(myColor == CONCOLOR_YELLOW && TrackingWnd->FilterYellowButton->Checked & 1) ||
(myColor == CONCOLOR_BLACK && TrackingWnd->FilterWhiteButton->Checked & 1) ||
(myColor == CONCOLOR_BLUE && TrackingWnd->FilterBlueButton->Checked & 1) ||
(myColor == CONCOLOR_LIGHTBLUE && TrackingWnd->FilterLBlueButton->Checked & 1) ||
(myColor == CONCOLOR_GREEN && TrackingWnd->FilterGreenButton->Checked & 1)
)
) {
TotalMatching++;
SpawnSet+=pSpawn;
}
pSpawn=pSpawn->pNext;
}
if (TotalMatching)
{
if (TotalMatching>1)
{
// sort our list
STrackSortValue=pSearchSpawn->SortBy;
SWhoSortOrigin=pOrigin;
qsort(&SpawnSet.List[0],TotalMatching,sizeof(PSPAWNINFO),pTrackSORTCompare);
}
}
DWORD ListSel = TrackingWnd->TrackingList->GetCurSel();
if (ListSel != -1) {
ListSel = pTrackSort[TrackingWnd->TrackingList->GetCurSel()].SpawnID;
}
TrackingWnd->TrackingList->DeleteAll();
free(pTrackSort);
pTrackSort = (PTRACKSORT)malloc(sizeof(TRACKSORT)*TotalMatching);
for (DWORD N=0 ; N < TotalMatching ; N++)
{
pTrackSort[N].SpawnID = SpawnSet[N]->SpawnID;
strcpy(pTrackSort[N].Name, SpawnSet[N]->Name);
DWORD myColor = ConColor((PSPAWNINFO)(SpawnSet[N]));
TrackingWnd->TrackingList->AddString(
GenerateSpawnName(SpawnSet[N], szNameTemplate),
ConColorToARGB(myColor),0,0);
if (ListSel == (SpawnSet[N]->SpawnID)) {
TrackingWnd->TrackingList->SetCurSel(N);
}
}
// TrackingWnd->TrackingList->SetVScrollPos(ScrollPos);
}
PCHAR GenerateSpawnName(PSPAWNINFO pSpawn, PCHAR NameString)
{
CHAR Name[MAX_STRING]={0};
unsigned long outpos=0;
#define AddMyString(str) {strcpy(&Name[outpos],str);outpos+=strlen(&Name[outpos]);}
#define AddInt(yourint) {_itoa(yourint,&Name[outpos],10);outpos+=strlen(&Name[outpos]);}
#define AddFloat10th(yourfloat) {outpos+=sprintf(&Name[outpos],"%.1f",yourfloat);}
for (unsigned long N = 0 ; NameString[N] ; N++)
{
if (NameString[N]=='%')
{
N++;
switch(NameString[N])
{
case 'N':// cleaned up name
strcpy(&Name[outpos],pSpawn->Name);
CleanupName(&Name[outpos],FALSE);
outpos+=strlen(&Name[outpos]);
break;
case 'n':// original name
AddMyString(pSpawn->Name);
break;
case 'h':// current health %
AddInt(pSpawn->HPCurrent);
break;
case 'i':
AddInt(pSpawn->SpawnID);
break;
case 'x':
AddFloat10th(pSpawn->X);
break;
case 'y':
AddFloat10th(pSpawn->Y);
break;
case 'z':
AddFloat10th(pSpawn->Z);
break;
case 'd':
AddFloat10th(GetDistance(pSpawn->X,pSpawn->Y));
break;
case 'R':
AddMyString(pEverQuest->GetRaceDesc(pSpawn->Race));
break;
case 'C':
AddMyString(pEverQuest->GetClassDesc(pSpawn->Class));
break;
case 'c':
AddMyString(pEverQuest->GetClassThreeLetterCode(pSpawn->Class));
break;
case 'l':
AddInt(pSpawn->Level);
break;
case '%':
Name[outpos++]=NameString[N];
break;
}
}
else
Name[outpos++]=NameString[N];
}
Name[outpos]=0;
PCHAR ret=(PCHAR)malloc(strlen(Name)+1);
strcpy(ret,Name);
return ret;
}
VOID Track(PSPAWNINFO pChar, PCHAR szLine)
{
if (!strcmp(szLine,"help")) {
SyntaxError("Usage: /track [off | target | help]");
SyntaxError("Usage: /track filter [off | <search string>]");
SyntaxError("Usage: /track players [all | pc | group | npc]");
SyntaxError("Usage: /track refresh [on | off | toggle | <refresh>]");
return;
}
if (!strcmp(szLine,"off")) {
StopTracking(NULL,NULL);
return;
}
if (!strcmp(szLine,"target")) {
if ((PSPAWNINFO)pTarget) {
pTrackSpawn = (PSPAWNINFO)pTarget;
TrackSpawn();
IsTracking = true;
return;
} else {
WriteChatColor("Must have a target to track");
return;
}
}
CHAR szMsg[MAX_STRING]={0};
CHAR Arg1[MAX_STRING] = {0};
CHAR Arg2[MAX_STRING] = {0};
GetArg(Arg1,szLine,1);
if (!strcmp(Arg1,"refresh")) {
GetArg(Arg2,szLine,2);
if (!strcmp(Arg2,"off")) {
sprintf(szMsg,"Tracking window refresh: off");
refreshWindow = false;
} else if (!strcmp(Arg2,"on")) {
sprintf(szMsg,"Tracking window refresh: on");
refreshWindow = true;
} else if (!strcmp(Arg2,"toggle")) {
refreshWindow = refreshWindow ^ 1;
sprintf(szMsg,"Tracking window refresh: %s",refreshWindow?"on":"off");
} else {
RefreshTimer = atoi(Arg2);
if (RefreshTimer < 1) RefreshTimer = 1;
if (RefreshTimer > 1000) RefreshTimer = 1000;
sprintf(szMsg,"Tracking window will refresh every %i second(s).", RefreshTimer);
}
WriteChatColor(szMsg,USERCOLOR_CHAT_CHANNEL);
return;
} else if (!strcmp(Arg1,"filter")) {
PCHAR szRest = GetNextArg(szLine);
if (!szRest[0])
{
sprintf(szMsg,"Current custom filter: %s",szCustomSearch);
WriteChatColor(szMsg,USERCOLOR_DEFAULT);
return;
}
if (!stricmp(szRest,"off"))
strcpy(szCustomSearch,"");
else
strcpy(szCustomSearch,szRest);
WritePrivateProfileString("Settings","CustomFilter",szNameTemplate,INIFileName);
ReloadSpawn();
return;
} else if (!strcmp(Arg1,"players")) {
GetArg(Arg2,szLine,2);
if (TrackingWnd)
if (TrackingWnd->Show)
DestroyTrackingWindow();
else {
((CXWnd*)TrackingWnd)->Show(1,1);
ReloadSpawn();
}
else {
CreateTrackingWindow();
ReloadSpawn();
}
if (!strcmp(Arg2,"all")) {
// Track all
TrackingWnd->TrackPlayersCombo->SetChoice(0);
} else if (!strcmp(Arg2,"pc")) {
// Track PCs
TrackingWnd->TrackPlayersCombo->SetChoice(1);
} else if (!strcmp(Arg2,"group")) {
// Track Group
TrackingWnd->TrackPlayersCombo->SetChoice(2);
} else if (!strcmp(Arg2,"npc")) {
// Track NPC
TrackingWnd->TrackPlayersCombo->SetChoice(3);
} else {
WriteChatColor("FORMAT: /track players <all/pc/group/npc>");
return;
}
ReloadSpawn();
return;
}
if (TrackingWnd)
if (TrackingWnd->Show)
DestroyTrackingWindow();
else {
((CXWnd*)TrackingWnd)->Show(1,1);
ReloadSpawn();
}
else {
CreateTrackingWindow();
ReloadSpawn();
}
}
VOID TrackSpawn()
{
CHAR szMsg[MAX_STRING]={0};
CHAR szName[MAX_STRING]={0};
PSPAWNINFO pChar = (PSPAWNINFO)pCharSpawn;
if (!(pTrackSpawn)) {
// sprintf(szMsg,"There were no matches for id: %d", (PSPAWNINFO)(SpawnSet[TrackingWnd->TrackingList->GetCurSel()])->SpawnID);
} else {
if (DistanceToSpawn(pChar,pTrackSpawn) > TrackDist) {
INT Angle = (INT)((atan2f(pChar->X - pTrackSpawn->X, pChar->Y - pTrackSpawn->Y) * 180.0f / PI + 360.0f) / 22.5f + 0.5f) % 16;
INT Heading = (INT)((pChar->Heading / 32.0f) + 8.5f) % 16;
INT Direction = (INT)((32 + (Angle - Heading))/2) % 8;
sprintf(szMsg,"'%s' is %s; %1.2f away.",
CleanupName(strcpy(szName,pTrackSpawn->Name),FALSE),
szDirection[Direction],
DistanceToSpawn(pChar,pTrackSpawn));
SetCXStr(&(TrackingWnd->DoneButton->WindowText),"Cancel");
} else {
sprintf(szMsg,"'%s' reached (within %i). Tracking stopped.",
CleanupName(strcpy(szName,pTrackSpawn->Name),FALSE), TrackDist);
StopTracking(NULL,NULL);
}
}
WriteChatColor(szMsg,USERCOLOR_WHO);
return;
}
VOID StopTracking(PSPAWNINFO pChar, PCHAR szLine) {
SetCXStr(&(TrackingWnd->DoneButton->WindowText),"Refresh");
pTrackSpawn = NULL;
if (IsTracking) {
WriteChatColor("Tracking Stopped.");
IsTracking = false;
}
}
VOID TrackNames(PSPAWNINFO pChar, PCHAR szLine)
{
bRunNextCommand = TRUE;
CHAR szOut[MAX_STRING]={0};
if (!szLine[0])
{
sprintf(szOut,"Normal naming string: %s",szNameTemplate);
WriteChatColor(szOut,USERCOLOR_DEFAULT);
return;
}
if (!stricmp(szLine,"reset"))
strcpy(szNameTemplate,"[%l %C] %N (%R)");
else
strcpy(szNameTemplate,szLine);
sprintf(szOut,"Normal naming string: %s",szNameTemplate);
WriteChatColor(szOut,USERCOLOR_DEFAULT);
SyntaxError("Usage: /tracknames [value|reset]");
WritePrivateProfileString("Settings","DisplayTpl",szNameTemplate,INIFileName);
ReloadSpawn();
}

