読者です 読者をやめる 読者になる 読者になる

めいくりぷとのブログ

技術的なことやゲームのことやら・・・

Portal Teleport

いろいろと雑

Edited

enum PORTALTYPE
{
	PORTALTYPE_STARTPOINT = 0x0,
	PORTALTYPE_INVISIBLE = 0x1,
	PORTALTYPE_VISIBLE = 0x2,
	PORTALTYPE_COLLISION = 0x3,
	PORTALTYPE_CHANGABLE = 0x4,
	PORTALTYPE_CHANGABLE_INVISIBLE = 0x5,
	PORTALTYPE_TOWNPORTAL_POINT = 0x6,
	PORTALTYPE_SCRIPT = 0x7,
	PORTALTYPE_SCRIPT_INVISIBLE = 0x8,
	PORTALTYPE_COLLISION_SCRIPT = 0x9,
	PORTALTYPE_HIDDEN = 0xA,
	PORTALTYPE_SCRIPT_HIDDEN = 0xB,
	PORTALTYPE_COLLISION_VERTICAL_JUMP = 0xC,
	PORTALTYPE_COLLISION_CUSTOM_IMPACT = 0xD,
	PORTALTYPE_SCRIPT_INVISIBLE_CHANGEABLE = 0xE,
	PORTALTYPE_COLLISION_CUSTOM_IMPACT2 = 0xF,
	PORTALTYPE_NONE = 0xFFFFFFFF,
};

namespace MapleStory
{
	void TeleportToPoint(CUserLocal *pUserLocal, POINT pt)
	{
		if (!pUserLocal)
			return;

		CVecCtrl *pVecCtrl = pUserLocal->User.VecCtrl.vfptr->GetVecCtrl(&pUserLocal->User.VecCtrl);
		pVecCtrl->IWzVector2D.vfptr->raw_Move(&pVecCtrl->IWzVector2D, pt.x, pt.y);
	}

	BOOL find_portal(CPortalList *pPortalList, LPPOINT lppt)
	{
		static int nIdx = 0;

		int nCount = 0;
		ZRef<PORTAL> *ref;
		PORTAL *pPortal;

		if (!pPortalList)
			return FALSE;

		ref = pPortalList->m_aPortal.a;
		if (ref)
			ref = (ZRef<PORTAL> *)ref[-1].p;

		nCount = (int)((char *)&ref[-1].p + 3);
		if (nCount < 0)
			return FALSE;

		while (pPortal = pPortalList->m_aPortal.a[nIdx].p)
		{
			nIdx += 1;
			if (nIdx > nCount)
				break;

			if (pPortal->nType == PORTALTYPE_VISIBLE ||
				pPortal->nType == PORTALTYPE_SCRIPT)
			{
				lppt->x = pPortal->ptPos.x;
				lppt->y = pPortal->ptPos.y;
				return TRUE;
			}
		}

		nIdx = 0;

		return FALSE;
	}

}

/////////////////////////////////////////////////////////////////////////////////

#ifndef _MapVirtualKey
#define _MapVirtualKey(uCode) (MapVirtualKey(uCode, MAPVK_VK_TO_VSC) << 16)
#endif

static CUserLocal::UseFuncKeyMappedT _UseFuncKeyMapped =
reinterpret_cast<CUserLocal::UseFuncKeyMappedT>(ADDRESS_UseFuncKeyMapped);
BOOL(__fastcall *UseFuncKeyMapped__Hook)(CUserLocal *, LPVOID, LPARAM, WPARAM) = [](
	CUserLocal *pUserLocal, LPVOID lpvEdx, LPARAM lParam, WPARAM wParam) -> BOOL
{
	if (lParam == _MapVirtualKey(VK_BACK)) // backspace
	{
                POINT pt;

		if (MapleStory::find_portal(CPortalList::GetInstance(), &pt))
                {
                        MapleStory::TeleportToPoint(pUserLocal, pt);
                }
	}

        return _UseFuncKeyMapped(pUserLocal, lParam, wParam);
}

...
CUserLocal *pUserLocal = CUserLocal::GetInstance();
if (pUserLocal)
{
        pUserLocal->UseFuncKeyMapped(_MapVirtualKey(VK_BACK), VK_BACK);
}
...

^-^