/*
This Plugin contains the commands to /zone to a different zone; /warp to locations, waypoints,
targets; call a zoning command to simulate a "Fade"; Produce fake item links; Turns on maps in
all zones. Causes the character to have no drunk effects, 0 encumberance and permanaent EB.
*/
#include "../MQ2Plugin.h"
PreSetup("MQ2MiscPF");
/*Zone Comand*/ VOID ZoneTo(PSPAWNINFO pChar, PCHAR szLine);
/*Fading Memories*/ VOID doFade(PSPAWNINFO pChar, PCHAR szLine);
/*gate*/ VOID Gate(PSPAWNINFO pChar, PCHAR szLine);
/*Warping*/ VOID warp(PSPAWNINFO pChar, PCHAR szLine);
/*Waypoint Management*/ VOID waypoint(PSPAWNINFO pChar, PCHAR szLine);
////////////////////////////////////////////////////////////////////////////////////////
// Variables ///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
// For Zoning and Warping //
/*Warp & Zone*/ DWORD SpawnID;
/*Warp & Zone*/ ZONELIST *GetZone(DWORD ZoneID);
////////////////////////////////////////////////////////////////////////////////////////
// Pluging API Functions ///////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
PLUGIN_API VOID InitializePlugin(VOID)
{
AddCommand("/zone",ZoneTo);
AddCommand("/fade",doFade);
AddCommand("/gate",Gate);
AddCommand("/home",Gate);
AddCommand("/warp",warp);
AddCommand("/waypoint", waypoint);
}
PLUGIN_API VOID ShutdownPlugin(VOID)
{
DebugSpewAlways("Shutting down MQ2MiscPF");
RemoveCommand("/zone");
RemoveCommand("/fade");
RemoveCommand("/gate");
RemoveCommand("/home");
RemoveCommand("/warp");
RemoveCommand("/waypoint");
}
PLUGIN_API VOID OnPulse(VOID)
{
////////////////////////////////////////////////////////////////////////////////////////
// Zoning Command //////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
VOID ZoneTo(PSPAWNINFO pChar, PCHAR szLine)
{
PCHARINFO pCharInfo = GetCharInfo();
char szMsg[MAX_STRING] = {0};
char szZone[MAX_STRING] = {0};
int nZoneID = 0;
GetArg(szZone, szLine, 1);
if (!strnicmp(szZone, "", 1))
{
WriteChatColor("You must specify a zone shortname.",
COLOR_PURPLE);
}
else
{
nZoneID = GetZoneID(szZone);
if (nZoneID < 0)
{
WriteChatColor("Invalid zone shortname.", COLOR_PURPLE);
}
else
{
pCharInfo->ZoneBoundId = nZoneID;
pChar->pCharInfo->ZoneBoundY = 0;
pChar->pCharInfo->ZoneBoundX = 0;
pChar->pCharInfo->ZoneBoundZ = 0;
DWORD ZoneToGoTo;
ZoneToGoTo = GetZoneID(szLine);
sprintf(szMsg,"Going to zone %s, id %d",szLine,ZoneToGoTo);
WriteChatColor(szMsg, COLOR_PURPLE);
pChar->Type = SPAWN_CORPSE;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////
// Fading Memories /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
VOID doFade(PSPAWNINFO pChar, PCHAR szLine) {
PCHARINFO pCharInfo = GetCharInfo();
PZONEINFO Zone = (PZONEINFO)pZoneInfo;
int nZoneID = 0;
nZoneID = GetZoneID(Zone->ShortName);
pCharInfo->ZoneBoundId = nZoneID;
pChar->pCharInfo->ZoneBoundY = 0;
pChar->pCharInfo->ZoneBoundX = 0;
pChar->pCharInfo->ZoneBoundZ = 0;
WriteChatColor("Fading Memories.",
COLOR_PURPLE);
pChar->Type = SPAWN_CORPSE;
}
////////////////////////////////////////////////////////////////////////////////////////
// Gate ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
VOID Gate(PSPAWNINFO pChar, PCHAR szLine)
{
WriteChatColor("Gating.", COLOR_PURPLE);
pChar->Type = SPAWN_CORPSE;
}
////////////////////////////////////////////////////////////////////////////////////////
// Waypoint Management /////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
VOID waypoint(PSPAWNINFO pChar, PCHAR szLine)
{
PZONEINFO Zone = (PZONEINFO)pZoneInfo;
CHAR WaypointsINI[MAX_STRING] = {0};
CHAR szTemp[10] = {0};
CHAR szData[MAX_STRING] = {0};
CHAR szDesc[MAX_STRING] = {0};
CHAR szName[MAX_STRING] = {0};
CHAR szCommand[MAX_STRING] = {0};
CHAR szBuffer[MAX_STRING] = {0};
CHAR szMsg[MAX_STRING] = {0};
CHAR WaypointList[MAX_STRING*10] = {0};
PCHAR pWaypointList = WaypointList;
CHAR szKey[MAX_STRING] = {0};
CHAR szValue[MAX_STRING] = {0};
sprintf(WaypointsINI,"%s\\waypoints.ini",gszINIPath);
GetArg(szCommand, szLine, 1);
if (!strnicmp(szCommand, "add", 3))
{
GetArg(szName, szLine, 2);
if(!strnicmp(szName, "", 1))
{
WriteChatColor("You didn't specify a name for the waypoint.", COLOR_LIGHTGREY);
}
else
{
GetPrivateProfileString(Zone->ShortName,szName,"",szBuffer,MAX_STRING,WaypointsINI);
if (!strnicmp(szBuffer, "", 1))
{
GetArg(szDesc, szLine, 3);
sprintf(szData, "%1.2f %1.2f %1.2f %1.2f:%s", pChar->Y, pChar->X, pChar->Z, (float)pChar->Heading*0.703125f, szDesc);
WritePrivateProfileString(Zone->ShortName,szName,szData,WaypointsINI);
sprintf(szMsg, "Waypoint \'%s\' added.", szName);
WriteChatColor(szMsg, COLOR_LIGHTGREY);
}
else
{
sprintf(szMsg, "Waypoint \'%s\' already exists.", szName);
WriteChatColor(szMsg, COLOR_LIGHTGREY);
}
}
}
else if (!strnicmp(szCommand, "delete", 6))
{
GetArg(szName, szLine, 2);
if(!strnicmp(szName, "", 1))
{
WriteChatColor("You didn't specify a waypoint to delete.", COLOR_LIGHTGREY);
}
else
{
GetPrivateProfileString(Zone->ShortName,szName,"",szBuffer,MAX_STRING,WaypointsINI);
if (!strnicmp(szBuffer, "", 1))
{
sprintf(szMsg, "Waypoint \'%s\' does not exist.", szName);
WriteChatColor(szMsg, COLOR_LIGHTGREY);
}
else
{
WritePrivateProfileString(Zone->ShortName,szName,"",WaypointsINI);
// rewrite the section minus the deleted waypoint
GetPrivateProfileSection(Zone->ShortName,WaypointList,MAX_STRING*10,WaypointsINI);
WritePrivateProfileSection(Zone->ShortName,"",WaypointsINI);
pWaypointList = WaypointList;
while (pWaypointList[0]!=0)
{
GetArg(szKey,pWaypointList,1,0,0,0,'=');
GetArg(szValue,pWaypointList,2,0,0,0,'=');
if (strnicmp(szValue, "", 1))
{
WritePrivateProfileString(Zone->ShortName,szKey,szValue,WaypointsINI);
}
pWaypointList+=strlen(pWaypointList)+1;
}
sprintf(szMsg, "Waypoint \'%s\' deleted.", szName);
WriteChatColor(szMsg, COLOR_LIGHTGREY);
}
}
}
else if (!strnicmp(szCommand, "list", 4))
{
GetPrivateProfileSection(Zone->ShortName,WaypointList,MAX_STRING*10,WaypointsINI);
pWaypointList = WaypointList;
sprintf(szMsg, "Waypoints for %s", Zone->LongName);
WriteChatColor(szMsg, CONCOLOR_YELLOW);
while (pWaypointList[0]!=0)
{
GetArg(szName,pWaypointList,1,0,0,0,'=');
GetArg(szData,pWaypointList,2,0,0,0,'=');
GetArg(szDesc,szData,2,0,0,0,':');
if (strnicmp(szDesc,"",1))
{
sprintf(szMsg, "- %s ( %s )", szName, szDesc);
}
else
{
sprintf(szMsg, "- %s", szName);
}
WriteChatColor(szMsg, COLOR_LIGHTGREY);
pWaypointList+=strlen(pWaypointList)+1;
}
}
else
{
WriteChatColor("Invalid syntax. Usage:", COLOR_LIGHTGREY);
WriteChatColor("/waypoint add name", COLOR_LIGHTGREY);
WriteChatColor("/waypoint delete name", COLOR_LIGHTGREY);
WriteChatColor("/waypoint list", COLOR_LIGHTGREY);
}
}
////////////////////////////////////////////////////////////////////////////////////////
// Warping /////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
void warp(PSPAWNINFO pChar, PCHAR szLine)
{
DOUBLE DegToRad = 57.295779513082320876846364344191;
PZONEINFO Zone = (PZONEINFO)pZoneInfo;
PSPAWNINFO Target = (PSPAWNINFO)pTarget;
char szWarpType[MAX_STRING] = {0};
char szMsg[MAX_STRING] = {0};
char szBuf[MAX_STRING] = {0};
char szDestWarpX[MAX_STRING] = {0};
char szDestWarpY[MAX_STRING] = {0};
char szDestWarpZ[MAX_STRING] = {0};
char szBehindFront[MAX_STRING] = {0};
char szDoorItem[MAX_STRING] = {0};
char szDestZoneID[MAX_STRING] = {0};
char szHeading[MAX_STRING] = {0};
float* SafeYLoc = &Zone->Unknown0x1ec[0];
float* SafeXLoc = &Zone->Unknown0x1ec[1];
float* SafeZLoc = &Zone->Unknown0x1ec[2];
float fSafeX = *SafeXLoc; // get original safe locs
float fSafeY = *SafeYLoc;
float fSafeZ = *SafeZLoc;
float fCharX = pChar->X; // get current char info
float fCharY = pChar->Y;
float fCharZ = pChar->Z;
float fCharHeading = pChar->Heading;
float fCharCameraAngle = pChar->CameraAngle;
GetArg(szWarpType, szLine, 1); // determine type of warp
// warp to target
if (!strnicmp(szWarpType, "target", 6))
{
if (pTarget)
{
GetArg(szBehindFront, szLine, 2);
// set zone safe locations to that of your target
*SafeXLoc = Target->X;
*SafeYLoc = Target->Y;
*SafeZLoc = Target->Z;
// change locs to be 10 steps behind or in front of the target, if necessary
if (!strnicmp(szBehindFront, "behind", 6))
{
*SafeXLoc = Target->X - (float)(10*sin(Target->Heading*0.703125f/DegToRad));
*SafeYLoc = Target->Y - (float)(10*cos(Target->Heading*0.703125f/DegToRad));
}
else if (!strnicmp(szBehindFront, "front", 5))
{
*SafeXLoc = Target->X + (float)(10*sin(Target->Heading*0.703125f/DegToRad));
*SafeYLoc = Target->Y + (float)(10*cos(Target->Heading*0.703125f/DegToRad));
}
//sprintf(szMsg, "Warping to target at: %3.2f, %3.2f, %3.2f.", *SafeYLoc, *SafeXLoc, *SafeZLoc);
//WriteChatColor(szMsg, COLOR_PURPLE);
// do the warp
pDisplay->MoveLocalPlayerToSafeCoords();
// face the target's loc if we moved behind or in front of them
if (!strnicmp(szBehindFront, "behind", 6) || !strnicmp(szBehindFront, "front", 5))
{
Face(pChar, "fast nolook");
}
}
else
{
WriteChatColor("You can't warp to your target when you don't have one.", COLOR_PURPLE);
}
}
// warp to a waypoint
else if (!strnicmp(szWarpType, "wp", 2))
{
CHAR szLoc[MAX_STRING] = {0};
CHAR szName[MAX_STRING] = {0};
CHAR WaypointsINI[MAX_STRING] = {0};
sprintf(WaypointsINI,"%s\\waypoints.ini",gszINIPath);
GetArg(szName, szLine, 2);
if(!strnicmp(szName, "", 1))
{
WriteChatColor("You didn't specify a waypoint.", COLOR_LIGHTGREY);
}
else
{
GetPrivateProfileString(Zone->ShortName,szName,"",szLoc,MAX_STRING,WaypointsINI);
if (!strnicmp(szLoc, "", 1))
{
sprintf(szMsg, "Waypoint \'%s\' does not exist.", szName);
WriteChatColor(szMsg, COLOR_LIGHTGREY);
}
else
{
// get destination locs
GetArg(szDestWarpX, szLoc, 2);
GetArg(szDestWarpY, szLoc, 1);
GetArg(szDestWarpZ, szLoc, 3);
// get heading
GetArg(szBuf, szLoc, 4);
GetArg(szHeading,szBuf,1,0,0,0,':');
if (szDestWarpX[0]!=0 && szDestWarpY[0]!=0 && szDestWarpZ[0]!=0)
{
// set zone safe locs
*SafeXLoc = (float)atof(szDestWarpX);
*SafeYLoc = (float)atof(szDestWarpY);
*SafeZLoc = (float)atof(szDestWarpZ);
sprintf(szMsg, "Warping to waypoint \'%s\' at: %3.2f, %3.2f, %3.2f.", szName, *SafeYLoc, *SafeXLoc, *SafeZLoc);
WriteChatColor(szMsg, COLOR_PURPLE);
// do the warp
pDisplay->MoveLocalPlayerToSafeCoords();
// face heading
if (strnicmp(szHeading, "", 1))
{
sprintf(szBuf, "fast nolook heading %s", szHeading);
Face(pChar, szBuf);
}
}
else
{
WriteChatColor("Invalid location. Verify the location in the ini.");
}
}
}
}
// warp to standard zone safe loc
else if (!strnicmp(szWarpType, "safe", 4))
{
sprintf(szMsg, "Warping to zone safe loc at: %3.2f, %3.2f, %3.2f.", *SafeYLoc, *SafeXLoc, *SafeZLoc);
WriteChatColor(szMsg, COLOR_PURPLE);
// no changes necessary, just warp
pDisplay->MoveLocalPlayerToSafeCoords();
}
// warp to user defined loc
else if (!strnicmp(szWarpType, "loc", 3))
{
// get destination locs
GetArg(szDestWarpX, szLine, 3);
GetArg(szDestWarpY, szLine, 2);
GetArg(szDestWarpZ, szLine, 4);
if (szDestWarpX[0]!=0 && szDestWarpY[0]!=0 && szDestWarpZ[0]!=0)
{
// set zone safe locs
*SafeXLoc = (float)atof(szDestWarpX);
*SafeYLoc = (float)atof(szDestWarpY);
*SafeZLoc = (float)atof(szDestWarpZ);
sprintf(szMsg, "Warping to loc at: %3.2f, %3.2f, %3.2f.", *SafeYLoc, *SafeXLoc, *SafeZLoc);
WriteChatColor(szMsg, COLOR_PURPLE);
// do the warp
pDisplay->MoveLocalPlayerToSafeCoords();
}
else
{
WriteChatColor("Invalid location. Usage: /warp loc x y z");
}
}
// click an item remotely by warping, clicking, and warping back
// doesn't work well with anything other than ground spawns
else if (!strnicmp(szWarpType, "clickitem", 9))
{
if (pTarget)
{
*SafeXLoc = Target->X;
*SafeYLoc = Target->Y;
*SafeZLoc = Target->Z;
if (pDoorTarget || pGroundTarget) // it's valid
{
sprintf(szMsg, "Clicking item at loc: %3.2f, %3.2f, %3.2f.", *SafeYLoc, *SafeXLoc, *SafeZLoc);
WriteChatColor(szMsg, COLOR_PURPLE);
// warp to it
pDisplay->MoveLocalPlayerToSafeCoords();
// click it
GetArg(szDoorItem, szLine, 2);
if (!strnicmp(szDoorItem, "door", 4)) // door
{
Face(pChar, "fast");
//Press(pChar, "u");
// set heading and camera angle back to original since /face fubared it
pChar->Heading = fCharHeading;
pChar->CameraAngle = fCharCameraAngle;
}
else // ground spawn
{
Click(pChar, "left item");
}
// warp back to your original location
*SafeXLoc = fCharX;
*SafeYLoc = fCharY;
*SafeZLoc = fCharZ;
pDisplay->MoveLocalPlayerToSafeCoords();
}
else
{
WriteChatColor("Invalid target.", COLOR_PURPLE);
}
}
else
{
WriteChatColor("You need to target an item first, douchebag.");
}
}
else
{
WriteChatColor("Usage:", COLOR_LIGHTGREY);
WriteChatColor("/warp loc x y z", COLOR_LIGHTGREY);
WriteChatColor("/warp safe", COLOR_LIGHTGREY);
WriteChatColor("/warp target", COLOR_LIGHTGREY);
WriteChatColor("/warp target behind/front", COLOR_LIGHTGREY);
WriteChatColor("/warp clickitem door/item (default item)", COLOR_LIGHTGREY);
WriteChatColor("/warp wp (default item)", COLOR_LIGHTGREY);
WriteChatColor("/waypoint add, delete, list");
}
// cleanup
*SafeXLoc = fSafeX;
*SafeYLoc = fSafeY;
*SafeZLoc = fSafeZ;
}
////////////////////////////////////////////////////////////////////////////////////////
// End of File /////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////