<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Samantharp</id>
	<title>AlliedModders Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alliedmods.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Samantharp"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Samantharp"/>
	<updated>2026-06-06T15:39:40Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Virtual_Offsets_(Source_Mods)&amp;diff=7919</id>
		<title>Virtual Offsets (Source Mods)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Virtual_Offsets_(Source_Mods)&amp;diff=7919"/>
		<updated>2011-01-07T03:57:48Z</updated>

		<summary type="html">&lt;p&gt;Samantharp: Added a link to Bernis, VTable offeset list to provide a more updated interference for developers, credit given clearly.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Metamod:Source Development]]&lt;br /&gt;
== Calling virtual functions ==&lt;br /&gt;
I got this method from [[User:Mani|Mani]], who I believe got it from [[User:PM|Pavol Marko]]. Thank you!&lt;br /&gt;
&lt;br /&gt;
I hope to expand on an actual explanation when I have the time (and understand it better). Hopefully, someone can expand on this, but for now I'll just post the examples and a list of the CCSPlayer virtual function table offsets.&lt;br /&gt;
&lt;br /&gt;
== Offset Lists ==&lt;br /&gt;
==== Automated Offsets ====&lt;br /&gt;
You can get automatically updated offsets from Berni's VTable Offset list. It automatically updates the offsets when an update is pushed by valve, making it a very resourceful tool. &lt;br /&gt;
* [http://www.sourcemodplugins.org/gamedumper/vtableoffsets.php Automated Offsets - Thanks to Berni] &lt;br /&gt;
==== Counter-Strike: Source ====&lt;br /&gt;
* [[CCSPlayer Offset List (Counter-Strike: Source)|CCSPlayer]]&lt;br /&gt;
* [[CBaseCombatWeapon Offset List (Counter-Strike: Source)|CBaseCombatWeapon]]&lt;br /&gt;
* [[CCSGameRules Offset List (Counter-Strike: Source) | CCSGameRules]]&lt;br /&gt;
* [[CBaseGrenade Offset List (Counter-Strike: Source) | CBaseGrenade]]&lt;br /&gt;
* [[CDEagle Offset List (Counter-Strike: Source) | CDEagle]]&lt;br /&gt;
&lt;br /&gt;
==== Day of Defeat: Source ====&lt;br /&gt;
* [[CDODPlayer Offset List (Day of Defeat: Source)|CDODPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Dystopia ====&lt;br /&gt;
* [[CDYSPlayer Offset List (Dystopia)|CDYSPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Empires v2.12 ====&lt;br /&gt;
* [[CSDKPlayer Offset List (Empires)|CSDKPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Fortress Forever ====&lt;br /&gt;
* [[CFFPlayer Offset List (Fortress Forever)|CFFPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Half-Life 2: Capture the Flag ====&lt;br /&gt;
* [[CHL2_Player Offset List (Half-Life 2: Capture the Flag)|CHL2_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Half-Life 2: Deathmatch ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Half-Life 2: Deathmatch)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Hidden: Source ====&lt;br /&gt;
* [[CSDKPlayer Offset List (Hidden: Source)|CSDKPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Insurgency ====&lt;br /&gt;
* [[CINSPlayer Offset List (Insurgency)|CINSPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Left 4 Dead ====&lt;br /&gt;
* [[CTerrorPlayer Offset List (Left 4 Dead)|CTerrorPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Left 4 Dead 2 ====&lt;br /&gt;
* [[CTerrorPlayer Offset List (Left 4 Dead 2)|CTerrorPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Obsidian Conflict ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Obsidian Conflict)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Pirates, Vikings, and Knights II ====&lt;br /&gt;
* [[CPVK2Player Offset List (Pirates, Vikings, and Knights II)|CPVK2Player]]&lt;br /&gt;
&lt;br /&gt;
==== The Ship ====&lt;br /&gt;
* [[CShipPlayer Offset List (The Ship)|CShipPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== SourceForts ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (SourceForts)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Synergy ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Synergy)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Synergy SteamWorks (Synergy Orange Box Edition)====&lt;br /&gt;
* [[CHL2MP_Player Offset List (SynergyOB)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Team Fortress 2 ====&lt;br /&gt;
* [[CTFPlayer Offset List (Team Fortress 2)|CTFPlayer]]&lt;br /&gt;
&lt;br /&gt;
==== Zombie Master ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Zombie Master)|CHL2MP_Player]]&lt;br /&gt;
&lt;br /&gt;
==== Zombie Panic: Source ====&lt;br /&gt;
* [[CHL2MP_Player Offset List (Zombie Panic: Source)|CHL2MP_Player]]&lt;br /&gt;
* [[CBasePlayer Offset List (Zombie Panic: Source)|CBasePlayer ]]&lt;br /&gt;
&lt;br /&gt;
==== GoldenEye: Source ====&lt;br /&gt;
* [[CGEPlayer Offset List (GoldenEye: Source)|CGEPlayer]]&lt;br /&gt;
&lt;br /&gt;
== How to use the examples ==&lt;br /&gt;
&lt;br /&gt;
Basically, this lets you call any [[virtual function]] by knowing it's offset. A table is created for each class that lists the address of the function for each virtual function. This method takes advantage of that to call those addresses.&lt;br /&gt;
&lt;br /&gt;
Look at the examples below and edit to match the function you want to call:&lt;br /&gt;
Use the offset for the function you want to call in this line. ([[CCSPlayer_offset_list_(SourceMM)]])&lt;br /&gt;
&amp;lt;cpp&amp;gt;void *func = vtable[m_Off_GiveNamedItem];&amp;lt;/cpp&amp;gt;&lt;br /&gt;
Change this line to match your return type and parameters:&lt;br /&gt;
&amp;lt;cpp&amp;gt;union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );&amp;lt;/cpp&amp;gt;&lt;br /&gt;
Call the original function with your parameters (change the return type to match the function you're calling):&lt;br /&gt;
&amp;lt;cpp&amp;gt;return (CBaseEntity *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ItemName, iSubType);&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You'll need to add an empty class for the union. Something like this:&lt;br /&gt;
&amp;lt;cpp&amp;gt;class VfuncEmptyClass {};&amp;lt;/cpp&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
These examples are for CSS. Mani has created a set of macros to make this easier. If you ask nicely, maybe he'll give them to you or let you post them here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;cpp&amp;gt;datamap_t *VFuncs::GetDataDescMap(CBaseEntity *pThisPtr)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_GetDataDescMap]; &lt;br /&gt;
&lt;br /&gt;
	union {datamap_t *(VfuncEmptyClass::*mfpnew)();&lt;br /&gt;
#ifndef __linux__&lt;br /&gt;
        void *addr;	} u; 	u.addr = func;&lt;br /&gt;
#else /* GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 */&lt;br /&gt;
			struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
	return (datamap_t *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)();&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::SetModel(CBaseEntity *pThisPtr, const char *ModelName)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_SetModel]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(const char *);&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ModelName);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::Teleport(CBaseEntity *pThisPtr, const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_Teleport]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(const Vector *, const QAngle *, const Vector *);&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(newPosition, newAngles, newVelocity);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Vector VFuncs::EyePosition( CBaseEntity *pThisPtr )&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_EyePosition]; &lt;br /&gt;
&lt;br /&gt;
	union {Vector (VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (Vector) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)( );&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
QAngle &amp;amp;VFuncs::EyeAngles( CBaseEntity *pThisPtr )&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_EyeAngles]; &lt;br /&gt;
&lt;br /&gt;
	union {QAngle&amp;amp; (VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (QAngle&amp;amp;) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)( );&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void VFuncs::Ignite(CBaseEntity *pThisPtr, float flFlameLifetime, bool bNPCOnly, float flSize, bool bCalledByLevelDesigner)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_Ignite]; &lt;br /&gt;
&lt;br /&gt;
	union {void (VfuncEmptyClass::*mfpnew)(float , bool , float , bool );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(void) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(flFlameLifetime, bNPCOnly, flSize, bCalledByLevelDesigner);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CBaseEntity *VFuncs::GiveNamedItem(CBaseEntity *pThisPtr, const char *ItemName, int iSubType)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_GiveNamedItem]; &lt;br /&gt;
&lt;br /&gt;
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)(const char *, int );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	return (CBaseEntity *) (reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)(ItemName, iSubType);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void VFuncs::CommitSuicide(CBaseEntity *pThisPtr)&lt;br /&gt;
{&lt;br /&gt;
	void **this_ptr = *(void ***)&amp;amp;pThisPtr;&lt;br /&gt;
	void **vtable = *(void ***)pThisPtr;&lt;br /&gt;
	void *func = vtable[m_Off_CommitSuicide]; &lt;br /&gt;
&lt;br /&gt;
	union {CBaseEntity *(VfuncEmptyClass::*mfpnew)( void );&lt;br /&gt;
	#ifndef __linux__&lt;br /&gt;
			void *addr;	} u; 	u.addr = func;&lt;br /&gt;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 &lt;br /&gt;
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;&lt;br /&gt;
	#endif&lt;br /&gt;
&lt;br /&gt;
	(reinterpret_cast&amp;lt;VfuncEmptyClass*&amp;gt;(this_ptr)-&amp;gt;*u.mfpnew)();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/cpp&amp;gt;&lt;/div&gt;</summary>
		<author><name>Samantharp</name></author>
		
	</entry>
</feed>