/doors and /doortarget fix

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

User avatar
Stargazer
a lesser mummy
a lesser mummy
Posts: 32
Joined: Mon Sep 30, 2002 3:30 pm

/doors and /doortarget fix

Post by Stargazer » Mon Jul 21, 2003 2:54 am

It looks like SoE has changed the way doors are defined in EQ. Instead of using a nice linked list, they now use a table of pointers. My solution is by no means the most efficient so feel free to make any suggestions that would improve it.

Step 1
In eqgame.ini correct the doors offset:
Doors=006023c0

Step 2
In mq.h, modify the doors structure and add the new table structure:

Code: Select all

typedef struct _DOOR {
/*0x00*/	BYTE Unknown0x00;		
/*0x01*/	BYTE ID;
/*0x02*/	CHAR Name[11];
/*0x0d*/	BYTE Unknown0x0d[7];
/*0x14*/	FLOAT DefaultY;
/*0x18*/	FLOAT DefaultX;
/*0x1c*/	FLOAT DefaultZ;
/*0x20*/	FLOAT DefaultHeading;
/*0x24*/	FLOAT DoorAngle;
/*0x28*/	FLOAT Y;
/*0x2c*/	FLOAT X;
/*0x30*/	FLOAT Z;
/*0x34*/	FLOAT Heading;
} DOOR, *PDOOR; 

typedef struct _DOORTABLE {
	DWORD NumEntries;
	PDOOR pDoor[255];
} DOORTABLE, *PDOORTABLE;

Step 3
Replace the /doors and /doortarget commands in EQLib_Commands.cpp:

Code: Select all

// ***************************************************************************
// Function:    Doors
// Description: Our '/doors' command
//              Lists door info
// Usage:       /doors <filter>
// ***************************************************************************
VOID Doors(PSPAWNINFO pChar, PCHAR szLine)
{
	bRunNextCommand = TRUE;

	if (!EQADDR_DOORS) return;
	if (!*EQADDR_DOORS) return;
    	PDOORTABLE pDoorTable = *EQADDR_DOORS;
	DWORD Count;
	DWORD ActualCount=0;
	CHAR szBuffer[MAX_STRING] = {0};
    
	WriteChatColor("Doors:", USERCOLOR_DEFAULT);
	WriteChatColor("---------------------------", USERCOLOR_DEFAULT);
	size_t slen = strlen(szLine);

	for (Count=0; Count<pDoorTable->NumEntries; Count++) {
		if ((szLine[0]==0) || (!strnicmp(pDoorTable->pDoor[Count]->Name,szLine,slen))) {
			SPAWNINFO TempSpawn;
			FLOAT Distance;
			ZeroMemory(&TempSpawn,sizeof(TempSpawn));
			strcpy(TempSpawn.Name,pDoorTable->pDoor[Count]->Name);
			TempSpawn.Y=pDoorTable->pDoor[Count]->Y;
			TempSpawn.X=pDoorTable->pDoor[Count]->X;
			TempSpawn.Z=pDoorTable->pDoor[Count]->Z;
			TempSpawn.Heading=pDoorTable->pDoor[Count]->Heading;
			Distance = DistanceToSpawn(pChar,&TempSpawn);
			INT Angle = (INT)((atan2f(pChar->X - pDoorTable->pDoor[Count]->X, pChar->Y - pDoorTable->pDoor[Count]->Y) * 180.0f / PI + 360.0f) / 22.5f + 0.5f) % 16;
			sprintf(szBuffer,"%d: %s: %1.2f away to the %s",pDoorTable->pDoor[Count]->ID, pDoorTable->pDoor[Count]->Name, Distance, szHeading[Angle]);
			WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
			ActualCount++;
		}
	}

	if (ActualCount==0) {
		WriteChatColor("No Doors found.",USERCOLOR_DEFAULT);
	} else {
		sprintf(szBuffer,"%d door%s found.",ActualCount,(ActualCount==1)?"":"s");
		WriteChatColor(szBuffer,USERCOLOR_DEFAULT);
	}
}



// ***************************************************************************
// Function:    DoorTarget
// Description: Our '/doortarget' command
//              Targets the nearest specified door
// Usage:       /doortarget <text>
// ***************************************************************************
VOID DoorTarget(PSPAWNINFO pChar, PCHAR szLine)
{
	bRunNextCommand = TRUE;

	if (!EQADDR_DOORS) return;
	if (!*EQADDR_DOORS) return;
    PDOORTABLE pDoorTable = *EQADDR_DOORS;
	DWORD Count;

	CHAR szBuffer[MAX_STRING] = {0};
	CHAR szSearch[MAX_STRING] = {0};
	CHAR Arg1[MAX_STRING] = {0};
	PCHAR Arg2 = szLine;
	FLOAT cDistance = 100000.0f;
	BYTE ID = -1;
	ZeroMemory(&DoorEnviroTarget,sizeof(DoorEnviroTarget));
	pDoorTarget = NULL;

	GetArg(Arg1,Arg2,1);
	Arg2 = GetNextArg(Arg2, 1);
	if (!stricmp(Arg1, "id")) {
		if (Arg2[0]==0) {
			WriteChatBuffer("DoorTarget: id specified but no number provided.", CONCOLOR_RED);
			strcpy(gLastError, "DOORTARGET_BADCOMMAND");
			return;
		}

		ID = atoi(Arg2);
		for (Count=0; Count<pDoorTable->NumEntries; Count++) {
			if (pDoorTable->pDoor[Count]->ID == ID) {
				strcpy(DoorEnviroTarget.Name, pDoorTable->pDoor[Count]->Name);
				DoorEnviroTarget.Y = pDoorTable->pDoor[Count]->Y;
				DoorEnviroTarget.X = pDoorTable->pDoor[Count]->X;
				DoorEnviroTarget.Z = pDoorTable->pDoor[Count]->Z;
				DoorEnviroTarget.Heading = pDoorTable->pDoor[Count]->Heading;
				pDoorTarget = pDoorTable->pDoor[Count];
				break;
			}
		}
	} else {
		strcpy(szSearch, Arg1);
		for (Count=0; Count<pDoorTable->NumEntries; Count++) {
			if (((szSearch[0]==0) ||
				 (!strnicmp(pDoorTable->pDoor[Count]->Name,szSearch,strlen(szSearch)))) &&
				((gZFilter >=10000.0f) ||
				  ((pDoorTable->pDoor[Count]->Z <= pChar->Z + gZFilter) &&
				   (pDoorTable->pDoor[Count]->Z >= pChar->Z - gZFilter)))) {
				SPAWNINFO tSpawn;
				ZeroMemory(&tSpawn,sizeof(tSpawn));
				strcpy(tSpawn.Name,pDoorTable->pDoor[Count]->Name);
				tSpawn.Y=pDoorTable->pDoor[Count]->Y;
				tSpawn.X=pDoorTable->pDoor[Count]->X;
				tSpawn.Z=pDoorTable->pDoor[Count]->Z;
				tSpawn.Heading=pDoorTable->pDoor[Count]->Heading;
				FLOAT Distance = DistanceToSpawn(pChar,&tSpawn);
				if (Distance<cDistance) {
					CopyMemory(&DoorEnviroTarget,&tSpawn,sizeof(DoorEnviroTarget));
					pDoorTarget = pDoorTable->pDoor[Count];
					cDistance=Distance;
				}
			}

		}
	}


	if (DoorEnviroTarget.Name[0]!=0) {
		sprintf(szBuffer,"Door %d '%s' targeted.", pDoorTarget->ID, DoorEnviroTarget.Name);
		gLastError[0]=0;
		WriteChatBuffer(szBuffer,USERCOLOR_DEFAULT);
	} else {
		sprintf(szBuffer,"Couldn't find door '%s'.",szLine);
		strcpy(gLastError,"ITEM_NOTFOUND");
		WriteChatBuffer(szBuffer,CONCOLOR_RED);
	}
}

Step 4
Correct any door references in EQLib_Main.cpp:

Code: Select all

PDOORTABLE *EQADDR_DOORS=0;

Code: Select all

GetPrivateProfileString("Memory Locations","Doors","0",szBuffer,MAX_STRING,ClientINI);	EQADDR_DOORS = (PDOORTABLE*)strtoul(szBuffer,NULL,16);
Step 5
Correct the external reference in EQLib.h:

Code: Select all

extern PDOORTABLE *EQADDR_DOORS;

Step 6
Correct the pdoor debug information in exts2.cpp:

Code: Select all

DECLARE_API ( pdoor )
{
DOOR *p, *pnull=NULL, ci;
    DWORD cb;

    // read param from command line
    p = (DOOR *)GetExpression(args);

    ReadMemory((PARAM1)p,&ci,sizeof(ci),&cb);

	dprintf("\n\n\n");

	KP(Unknown0x00);
	KP(ID);
	KPs(Name);
	KP(Unknown0x0d);
	KPf(DefaultY);
	KPf(DefaultX);
	KPf(DefaultZ);
	KPf(DefaultHeading);
	KPf(DoorAngle);
	KPf(Y);
	KPf(X);
	KPf(Z);
	KPf(Heading);
}
Please let me know if I have missed anything or if you have corrections to this :)
Cromwell Stargazer

sashlar
decaying skeleton
decaying skeleton
Posts: 3
Joined: Mon Jul 21, 2003 11:20 am
Location: florida
Contact:

Post by sashlar » Mon Jul 21, 2003 11:24 am

Thank you ever so much. This explains why apon typing /door in shadow heaven produced no output for me :-D . Was making a faction macro for this area. I will attempt this and if i run into any snags i post what i modified or what not to fix it.

EqMule
Developer
Developer
Posts: 2697
Joined: Fri Jan 03, 2003 9:57 pm
Contact:

Post by EqMule » Wed Jul 23, 2003 8:47 pm

Thank you! very nice JOB! :D
My status o/
If you like MQ2 and would like to contribute, please do. My goal is 25 donations per month.
So far I've received Image donations for this month's patches.

Bitcoin: 1Aq8ackjQ4f7AUvbUL7BE6oPfT8PmNP4Zq
Krono: PM me.
I can always use characters for testing, PM me if you can donate one.

Mckorr
Developer
Developer
Posts: 2326
Joined: Fri Oct 18, 2002 1:16 pm
Location: Texas

Post by Mckorr » Thu Jul 24, 2003 9:21 am

Uploaded to CVS
MQ2: Think of it as Evolution in action.

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Thu Jul 24, 2003 12:47 pm

Thanks! I meant to get to this last night but I fell asleep...

wassup
Official Guardian and Writer of TFM
Official Guardian and Writer of TFM
Posts: 1487
Joined: Sat Oct 26, 2002 5:15 pm

Post by wassup » Thu Jul 31, 2003 1:03 pm

Glad to see it back, but a small question here.

I went to Burning Woods and tried this and BW has 104 doors?!?!

All 104 had the same name also: CRATEG

I am going to try this command in different zones, but I'm not so sure BW has 104 doors.