#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "basemonster.h"
#include "player.h"

#include <tuple>

#ifdef CLIENT_DLL
namespace cl {
#else
namespace sv {
#endif

template<class T> constexpr std::tuple ExportMember = {};

template<> constexpr auto ExportMember<CBaseEntity> = std::tuple {
	&CBaseEntity::Spawn,
	&CBaseEntity::Precache,
	&CBaseEntity::KeyValue,
	&CBaseEntity::ObjectCaps,
	&CBaseEntity::Activate,
	&CBaseEntity::SetObjectCollisionBox,
	&CBaseEntity::Classify,
	&CBaseEntity::DeathNotice,
	&CBaseEntity::TraceAttack,
	&CBaseEntity::TakeDamage,
	&CBaseEntity::TakeHealth,
	&CBaseEntity::Killed,
	&CBaseEntity::BloodColor,
	&CBaseEntity::TraceBleed,
	&CBaseEntity::IsTriggered,
	&CBaseEntity::MyMonsterPointer,
	&CBaseEntity::MySquadMonsterPointer,
	&CBaseEntity::GetToggleState,
	&CBaseEntity::AddPoints,
	&CBaseEntity::AddPointsToTeam,
	&CBaseEntity::AddPlayerItem,
	&CBaseEntity::RemovePlayerItem,
	&CBaseEntity::GiveAmmo,
	&CBaseEntity::GetDelay,
	&CBaseEntity::IsMoving,
	&CBaseEntity::OverrideReset,
	&CBaseEntity::DamageDecal,
	&CBaseEntity::SetToggleState,
#if 0
	&CBaseEntity::StartSneaking,
	&CBaseEntity::StopSneaking,
#else
	&CBaseEntity::SUB_DoNothing,
	&CBaseEntity::SUB_DoNothing,
#endif
	&CBaseEntity::OnControls,
	&CBaseEntity::IsSneaking,
	&CBaseEntity::IsAlive,
	&CBaseEntity::IsBSPModel,
	&CBaseEntity::ReflectGauss,
	&CBaseEntity::HasTarget,
	&CBaseEntity::IsInWorld,
	&CBaseEntity::IsPlayer,
	&CBaseEntity::IsNetClient,
	&CBaseEntity::TeamID,
	&CBaseEntity::GetNextTarget,
	&CBaseEntity::Think,
	&CBaseEntity::Touch,
	&CBaseEntity::Use,
	&CBaseEntity::Blocked,
	&CBaseEntity::Respawn,
	&CBaseEntity::UpdateOwner,
	&CBaseEntity::FBecomeProne,
	&CBaseEntity::Center,
	&CBaseEntity::EyePosition,
	&CBaseEntity::EarPosition,
	&CBaseEntity::BodyTarget,
	&CBaseEntity::Illumination,
	static_cast<BOOL(CBaseEntity::*)(CBaseEntity*)>(&CBaseEntity::FVisible),
	static_cast<BOOL(CBaseEntity::*)(const Vector&)>(&CBaseEntity::FVisible),
	&CBaseEntity::Restart,

	&CBaseEntity::pev,
	&CBaseEntity::m_pGoalEnt,
	&CBaseEntity::m_pLink,
	&CBaseEntity::m_pfnThink,
	&CBaseEntity::m_pfnTouch,
	&CBaseEntity::m_pfnUse,
	&CBaseEntity::m_pfnBlocked,
	&CBaseEntity::current_ammo,
	&CBaseEntity::currentammo,
	&CBaseEntity::maxammo_buckshot,
	&CBaseEntity::ammo_buckshot,
	&CBaseEntity::maxammo_9mm,
	&CBaseEntity::ammo_9mm,
	&CBaseEntity::maxammo_556nato,
	&CBaseEntity::ammo_556nato,
	&CBaseEntity::maxammo_556natobox,
	&CBaseEntity::ammo_556natobox,
	&CBaseEntity::maxammo_762nato,
	&CBaseEntity::ammo_762nato,
	&CBaseEntity::maxammo_45acp,
	&CBaseEntity::ammo_45acp,
	&CBaseEntity::maxammo_50ae,
	&CBaseEntity::ammo_50ae,
	&CBaseEntity::maxammo_338mag,
	&CBaseEntity::ammo_338mag,
	&CBaseEntity::maxammo_57mm,
	&CBaseEntity::ammo_57mm,
	&CBaseEntity::maxammo_357sig,
	&CBaseEntity::ammo_357sig,
	&CBaseEntity::m_flStartThrow,
	&CBaseEntity::m_flReleaseThrow,
	&CBaseEntity::m_iSwing,
	&CBaseEntity::has_disconnected,
};

template<> constexpr auto ExportMember<CBaseDelay> = std::tuple {
	ExportMember<CBaseEntity>,
	&CBaseDelay::m_flDelay,
	&CBaseDelay::m_iszKillTarget,
};

template<> constexpr auto ExportMember<CBaseAnimating> = std::tuple {
	ExportMember<CBaseDelay>,
	&CBaseAnimating::m_flFrameRate,
	&CBaseAnimating::m_flGroundSpeed,
	&CBaseAnimating::m_flLastEventCheck,
	&CBaseAnimating::m_fSequenceFinished,
	&CBaseAnimating::m_fSequenceLoops,
};

template<> constexpr auto ExportMember<CBaseToggle> = std::tuple {
	ExportMember<CBaseAnimating>,
	&CBaseToggle::m_toggle_state,
	&CBaseToggle::m_flActivateFinished,
	&CBaseToggle::m_flMoveDistance,
	&CBaseToggle::m_flWait,
	&CBaseToggle::m_flLip,
	&CBaseToggle::m_flTWidth,
	&CBaseToggle::m_flTLength,
	&CBaseToggle::m_vecPosition1,
	&CBaseToggle::m_vecPosition2,
	&CBaseToggle::m_vecAngle1,
	&CBaseToggle::m_vecAngle2,
	&CBaseToggle::m_cTriggersLeft,
	&CBaseToggle::m_flHeight,
	&CBaseToggle::m_hActivator,
	&CBaseToggle::m_pfnCallWhenMoveDone,
	&CBaseToggle::m_vecFinalDest,
	&CBaseToggle::m_vecFinalAngle,
	&CBaseToggle::m_bitsDamageInflict,
	&CBaseToggle::m_sMaster,
};
	
template<> constexpr auto ExportMember<CBaseMonster> = std::tuple {
	ExportMember<CBaseToggle>,
	&CBaseMonster::ChangeYaw,
	&CBaseMonster::HasHumanGibs,
	&CBaseMonster::HasAlienGibs,
	&CBaseMonster::FadeMonster,
	&CBaseMonster::GibMonster,
	&CBaseMonster::GetDeathActivity,
	&CBaseMonster::BecomeDead,
	&CBaseMonster::IRelationship,
	&CBaseMonster::PainSound,
	&CBaseMonster::ReportAIState,
	&CBaseMonster::MonsterInitDead,
	&CBaseMonster::Look,
	&CBaseMonster::BestVisibleEnemy,
	static_cast<BOOL(CBaseMonster::*)(CBaseEntity*)>(&CBaseMonster::FInViewCone),
	static_cast<BOOL(CBaseMonster::*)(const Vector*)>(&CBaseMonster::FInViewCone),

	&CBaseMonster::m_Activity,
	&CBaseMonster::m_IdealActivity,
	&CBaseMonster::m_LastHitGroup,
	&CBaseMonster::m_bitsDamageType,
	&CBaseMonster::m_rgbTimeBasedDamage,
	&CBaseMonster::m_MonsterState,
	&CBaseMonster::m_IdealMonsterState,
	&CBaseMonster::m_afConditions,
	&CBaseMonster::m_afMemory,
	&CBaseMonster::m_flNextAttack,
	&CBaseMonster::m_hEnemy,
	&CBaseMonster::m_hTargetEnt,
	&CBaseMonster::m_flFieldOfView,
	&CBaseMonster::m_bloodColor,
	&CBaseMonster::m_HackedGunPos,
	&CBaseMonster::m_vecEnemyLKP,
	&CBaseMonster::m_timeNextAttack,
};

template<> constexpr auto ExportMember<CBasePlayer> = std::tuple {
	ExportMember<CBaseMonster>,
	&CBasePlayer::Jump,
	&CBasePlayer::Duck,
	&CBasePlayer::PreThink,
	&CBasePlayer::PostThink,
	&CBasePlayer::GetGunPosition,
	&CBasePlayer::ShouldFadeOnDeath,
	&CBasePlayer::ImpulseCommands,
	&CBasePlayer::UpdateClientData,
	&CBasePlayer::RoundRespawn,
	&CBasePlayer::ResetMaxSpeed,
	&CBasePlayer::IsBot,
	&CBasePlayer::GetAutoaimVector,
	&CBasePlayer::Blind,
	&CBasePlayer::OnTouchingWeapon,
	
	&CBasePlayer::random_seed,
	&CBasePlayer::m_usPlayerBleed,
	&CBasePlayer::m_hObserverTarget,
	&CBasePlayer::m_flNextObserverInput,
	&CBasePlayer::m_iObserverWeapon,
	&CBasePlayer::m_iObserverC4State,
	&CBasePlayer::m_bObserverHasDefuser,
	&CBasePlayer::m_iObserverLastMode,
	&CBasePlayer::m_flFlinchTime,
	&CBasePlayer::m_flAnimTime,
	&CBasePlayer::m_bHighDamage,
	&CBasePlayer::m_flVelocityModifier,
	&CBasePlayer::m_iLastZoom,
	&CBasePlayer::m_bResumeZoom,
	&CBasePlayer::m_flEjectBrass,
	&CBasePlayer::m_iKevlar,
	&CBasePlayer::m_bNotKilled,
	&CBasePlayer::m_iTeam,
	&CBasePlayer::m_iAccount,
	&CBasePlayer::m_bHasPrimary,
	&CBasePlayer::m_flDeathThrowTime,
	&CBasePlayer::m_iThrowDirection,
	&CBasePlayer::m_flLastTalk,
	&CBasePlayer::m_bJustConnected,
	&CBasePlayer::m_bContextHelp,
	&CBasePlayer::m_iJoiningState,
	&CBasePlayer::m_pIntroCamera,
	&CBasePlayer::m_fIntroCamTime,
	&CBasePlayer::m_fLastMovement,
	&CBasePlayer::m_bMissionBriefing,
	&CBasePlayer::m_bTeamChanged,
	&CBasePlayer::m_iModelName,
	&CBasePlayer::m_iTeamKills,
	&CBasePlayer::m_iIgnoreGlobalChat,
	&CBasePlayer::m_bHasNightVision,
	&CBasePlayer::m_bNightVisionOn,
	&CBasePlayer::m_vRecentPath,
	&CBasePlayer::m_flIdleCheckTime,
	&CBasePlayer::m_flRadioTime,
	&CBasePlayer::m_iRadioMessages,
	&CBasePlayer::m_bIgnoreRadio,
	&CBasePlayer::m_bHasC4,
	&CBasePlayer::m_bHasDefuser,
	&CBasePlayer::m_bKilledByBomb,
	&CBasePlayer::m_vBlastVector,
	&CBasePlayer::m_bKilledByGrenade,
	&CBasePlayer::m_hintMessageQueue,
	&CBasePlayer::m_flDisplayHistory,
	&CBasePlayer::m_iMenu,
	&CBasePlayer::m_iChaseTarget,
	&CBasePlayer::m_pChaseTarget,
	&CBasePlayer::m_fCamSwitch,
	&CBasePlayer::m_bEscaped,
	&CBasePlayer::m_bIsVIP,
	&CBasePlayer::m_tmNextRadarUpdate,
	&CBasePlayer::m_vLastOrigin,
	&CBasePlayer::m_iCurrentKickVote,
	&CBasePlayer::m_flNextVoteTime,
	&CBasePlayer::m_bJustKilledTeammate,
	&CBasePlayer::m_iHostagesKilled,
	&CBasePlayer::m_iMapVote,
	&CBasePlayer::m_bCanShoot,
	&CBasePlayer::m_flLastFired,
	&CBasePlayer::m_flLastAttackedTeammate,
	&CBasePlayer::m_bHeadshotKilled,
	&CBasePlayer::m_bPunishedForTK,
	&CBasePlayer::m_bReceivesNoMoneyNextRound,
	&CBasePlayer::m_iTimeCheckAllowed,
	&CBasePlayer::m_bHasChangedName,
	&CBasePlayer::m_szNewName,
	&CBasePlayer::m_bIsDefusing,
	&CBasePlayer::m_tmHandleSignals,
	&CBasePlayer::m_signals,
	&CBasePlayer::m_pentCurBombTarget,
	&CBasePlayer::m_iPlayerSound,
	&CBasePlayer::m_iTargetVolume,
	&CBasePlayer::m_iWeaponVolume,
	&CBasePlayer::m_iExtraSoundTypes,
	&CBasePlayer::m_iWeaponFlash,
	&CBasePlayer::m_flStopExtraSoundTime,
	&CBasePlayer::m_flFlashLightTime,
	&CBasePlayer::m_iFlashBattery,
	&CBasePlayer::m_afButtonLast,
	&CBasePlayer::m_afButtonPressed,
	&CBasePlayer::m_afButtonReleased,
	&CBasePlayer::m_pentSndLast,
	&CBasePlayer::m_flSndRoomtype,
	&CBasePlayer::m_flSndRange,
	&CBasePlayer::m_flFallVelocity,
	&CBasePlayer::m_rgItems,
	&CBasePlayer::m_fNewAmmo,
	&CBasePlayer::m_afPhysicsFlags,
	&CBasePlayer::m_fNextSuicideTime,
	&CBasePlayer::m_flTimeStepSound,
	&CBasePlayer::m_flTimeWeaponIdle,
	&CBasePlayer::m_flSwimTime,
	&CBasePlayer::m_flDuckTime,
	&CBasePlayer::m_flWallJumpTime,
	&CBasePlayer::m_flSuitUpdate,
	&CBasePlayer::m_rgSuitPlayList,
	&CBasePlayer::m_iSuitPlayNext,
	&CBasePlayer::m_rgiSuitNoRepeat,
	&CBasePlayer::m_rgflSuitNoRepeatTime,
	&CBasePlayer::m_lastDamageAmount,
	&CBasePlayer::m_tbdPrev,
	&CBasePlayer::m_flgeigerRange,
	&CBasePlayer::m_flgeigerDelay,
	&CBasePlayer::m_igeigerRangePrev,
	&CBasePlayer::m_iStepLeft,
	&CBasePlayer::m_szTextureName,
	&CBasePlayer::m_chTextureType,
	&CBasePlayer::m_idrowndmg,
	&CBasePlayer::m_idrownrestored,
	&CBasePlayer::m_bitsHUDDamage,
	&CBasePlayer::m_fInitHUD,
	&CBasePlayer::m_fGameHUDInitialized,
	&CBasePlayer::m_iTrain,
	&CBasePlayer::m_fWeapon,
	&CBasePlayer::m_pTank,
	&CBasePlayer::m_fDeadTime,
	&CBasePlayer::m_fNoPlayerSound,
	&CBasePlayer::m_fLongJump,
	&CBasePlayer::m_tSneaking,
	&CBasePlayer::m_iUpdateTime,
	&CBasePlayer::m_iClientHealth,
	&CBasePlayer::m_iClientBattery,
	&CBasePlayer::m_iHideHUD,
	&CBasePlayer::m_iClientHideHUD,
	&CBasePlayer::m_iFOV,
	&CBasePlayer::m_iClientFOV,
	&CBasePlayer::m_iNumSpawns,
	&CBasePlayer::m_pObserver,
	&CBasePlayer::m_rgpPlayerItems,
	&CBasePlayer::m_pActiveItem,
	&CBasePlayer::m_pClientActiveItem,
	&CBasePlayer::m_pLastItem,
	&CBasePlayer::m_rgAmmo,
	&CBasePlayer::m_rgAmmoLast,
	&CBasePlayer::m_vecAutoAim,
	&CBasePlayer::m_fOnTarget,
	&CBasePlayer::m_iDeaths,
	&CBasePlayer::m_izSBarState,
	&CBasePlayer::m_flNextSBarUpdateTime,
	&CBasePlayer::m_flStatusBarDisappearDelay,
	&CBasePlayer::m_SbarString0,
	&CBasePlayer::m_lastx,
	&CBasePlayer::m_lasty,
	&CBasePlayer::m_nCustomSprayFrames,
	&CBasePlayer::m_flNextDecalTime,
	&CBasePlayer::m_szTeamName,
	&CBasePlayer::m_modelIndexPlayer,
	&CBasePlayer::m_szAnimExtention,
	&CBasePlayer::m_iGaitsequence,
	&CBasePlayer::m_flGaitframe,
	&CBasePlayer::m_flGaityaw,
	&CBasePlayer::m_prevgaitorigin,
	&CBasePlayer::m_flPitch,
	&CBasePlayer::m_flYaw,
	&CBasePlayer::m_flGaitMovement,
	&CBasePlayer::m_iAutoWepSwitch,
	&CBasePlayer::m_bVGUIMenus,
	&CBasePlayer::m_bShowHints,
	&CBasePlayer::m_bShieldDrawn,
	&CBasePlayer::m_bOwnsShield,
	&CBasePlayer::m_bWasFollowing,
	&CBasePlayer::m_flNextFollowTime,
	&CBasePlayer::m_flYawModifier,
	&CBasePlayer::m_blindUntilTime,
	&CBasePlayer::m_blindStartTime,
	&CBasePlayer::m_blindHoldTime,
	&CBasePlayer::m_blindFadeTime,
	&CBasePlayer::m_blindAlpha,
	&CBasePlayer::m_allowAutoFollowTime,
	&CBasePlayer::m_autoBuyString,
	&CBasePlayer::m_rebuyString,
	&CBasePlayer::m_rebuyStruct,
	&CBasePlayer::m_bIsInRebuy,
	&CBasePlayer::m_flLastUpdateTime,
	&CBasePlayer::m_lastLocation,
	&CBasePlayer::m_progressStart,
	&CBasePlayer::m_progressEnd,
	&CBasePlayer::m_bObserverAutoDirector,
	&CBasePlayer::m_canSwitchObserverModes,
	&CBasePlayer::m_heartBeatTime,
	&CBasePlayer::m_intenseTimestamp,
	&CBasePlayer::m_silentTimestamp,
	&CBasePlayer::m_musicState,
	&CBasePlayer::m_flLastCommandTime,
	&CBasePlayer::m_bIsZombie,
	&CBasePlayer::m_bSpawnProtection,
	&CBasePlayer::m_iZombieLevel,
	&CBasePlayer::m_flTimeSpawnProctionExpires,
	&CBasePlayer::m_bIsFemale,
	&CBasePlayer::m_iModelTeam,
	&CBasePlayer::m_iKnifeID,
	&CBasePlayer::m_iGrenadeID,
	&CBasePlayer::m_iZombieClass,
	&CBasePlayer::m_iNewMenuKeys,
	&CBasePlayer::m_iNewMenuID,
	&CBasePlayer::m_iNewMenuPage,
	&CBasePlayer::m_iNewMenuExpire,
};

template<> constexpr auto ExportMember<CBasePlayerItem> = std::tuple {
	ExportMember<CBaseAnimating>,
	&CBasePlayerItem::AddToPlayer,
	&CBasePlayerItem::AddDuplicate,
	&CBasePlayerItem::GetItemInfo,
	&CBasePlayerItem::CanDeploy,
	&CBasePlayerItem::Deploy,
	&CBasePlayerItem::CanHolster,
	&CBasePlayerItem::Holster,
	&CBasePlayerItem::UpdateItemInfo,
	&CBasePlayerItem::ItemPreFrame,
	&CBasePlayerItem::ItemPostFrame,
	&CBasePlayerItem::Drop,
	&CBasePlayerItem::Kill,
	&CBasePlayerItem::AttachToPlayer,
	&CBasePlayerItem::PrimaryAmmoIndex,
	&CBasePlayerItem::SecondaryAmmoIndex,
	&CBasePlayerItem::UpdateClientData,
	&CBasePlayerItem::GetWeaponPtr,
	&CBasePlayerItem::iItemSlot,
	&CBasePlayerItem::CanDrop,
	&CBasePlayerItem::GetMaxSpeed,

	&CBasePlayerItem::m_pPlayer,
	&CBasePlayerItem::m_pNext,
	&CBasePlayerItem::m_iId,
};

template<> constexpr auto ExportMember<CBasePlayerWeapon> = std::tuple {
	ExportMember<CBasePlayerItem>,
	&CBasePlayerWeapon::ExtractAmmo,
	&CBasePlayerWeapon::ExtractClipAmmo,
	&CBasePlayerWeapon::AddWeapon,
	&CBasePlayerWeapon::PlayEmptySound,
	&CBasePlayerWeapon::ResetEmptySound,
	&CBasePlayerWeapon::IsUseable,
	&CBasePlayerWeapon::PrimaryAttack,
	&CBasePlayerWeapon::SecondaryAttack,
	&CBasePlayerWeapon::Reload,
	&CBasePlayerWeapon::WeaponIdle,
	&CBasePlayerWeapon::RetireWeapon,
	&CBasePlayerWeapon::ShouldWeaponIdle,
	&CBasePlayerWeapon::UseDecrement,
	&CBasePlayerWeapon::SendWeaponAnim,

	&CBasePlayerWeapon::m_iPlayEmptySound,
	&CBasePlayerWeapon::m_fFireOnEmpty,
	&CBasePlayerWeapon::m_flNextPrimaryAttack,
	&CBasePlayerWeapon::m_flNextSecondaryAttack,
	&CBasePlayerWeapon::m_flTimeWeaponIdle,
	&CBasePlayerWeapon::m_iPrimaryAmmoType,
	&CBasePlayerWeapon::m_iSecondaryAmmoType,
	&CBasePlayerWeapon::m_iClip,
	&CBasePlayerWeapon::m_iClientClip,
	&CBasePlayerWeapon::m_iClientWeaponState,
	&CBasePlayerWeapon::m_fInReload,
	&CBasePlayerWeapon::m_fInSpecialReload,
	&CBasePlayerWeapon::m_iDefaultAmmo,
	&CBasePlayerWeapon::m_iShellId,
	&CBasePlayerWeapon::m_fMaxSpeed,
	&CBasePlayerWeapon::m_bDelayFire,
	&CBasePlayerWeapon::m_iDirection,
	&CBasePlayerWeapon::m_bSecondarySilencerOn,
	&CBasePlayerWeapon::m_flAccuracy,
	&CBasePlayerWeapon::m_flLastFire,
	&CBasePlayerWeapon::m_iShotsFired,
	&CBasePlayerWeapon::m_vVecAiming,
	&CBasePlayerWeapon::model_name,
	&CBasePlayerWeapon::m_flGlock18Shoot,
	&CBasePlayerWeapon::m_iGlock18ShotsFired,
	&CBasePlayerWeapon::m_flFamasShoot,
	&CBasePlayerWeapon::m_iFamasShotsFired,
	&CBasePlayerWeapon::m_fBurstSpread,
	&CBasePlayerWeapon::m_iWeaponState,
	&CBasePlayerWeapon::m_flNextReload,
	&CBasePlayerWeapon::m_flDecreaseShotsFired,
	&CBasePlayerWeapon::m_usFireGlock18,
	&CBasePlayerWeapon::m_usFireFamas,
	&CBasePlayerWeapon::m_flPrevPrimaryAttack,
	&CBasePlayerWeapon::m_flLastFireTime,

};

}