| 655 | |
| 656 | template <typename T> |
| 657 | static inline T *GetPlayerVarAddressOrError(const char *pszGamedataName, IPluginContext *pContext, CBaseEntity *pPlayerEntity) |
| 658 | { |
| 659 | char szBaseName[128]; |
| 660 | g_pSM->Format(szBaseName, sizeof(szBaseName), "%sBase", pszGamedataName); |
| 661 | |
| 662 | const char *pszBaseVar = g_pGameConf->GetKeyValue(szBaseName); |
| 663 | if (pszBaseVar == NULL) |
| 664 | { |
| 665 | pContext->ThrowNativeError("Failed to locate %s key in gamedata", szBaseName); |
| 666 | return NULL; |
| 667 | } |
| 668 | |
| 669 | int interimOffset = 0; |
| 670 | sm_sendprop_info_t info; |
| 671 | if (gamehelpers->FindSendPropInfo("CCSPlayer", pszBaseVar, &info)) |
| 672 | { |
| 673 | interimOffset = info.actual_offset; |
| 674 | } |
| 675 | else |
| 676 | { |
| 677 | datamap_t *pMap = gamehelpers->GetDataMap(pPlayerEntity); |
| 678 | typedescription_t *td = gamehelpers->FindInDataMap(pMap, pszBaseVar); |
| 679 | if (td) |
| 680 | { |
| 681 | #if SOURCE_ENGINE >= SE_LEFT4DEAD |
| 682 | interimOffset = td->fieldOffset; |
| 683 | #else |
| 684 | interimOffset = td->fieldOffset[TD_OFFSET_NORMAL]; |
| 685 | #endif |
| 686 | } |
| 687 | } |
| 688 | |
| 689 | if (interimOffset == 0) |
| 690 | { |
| 691 | pContext->ThrowNativeError("Failed to find property \"%s\" on player.", pszBaseVar); |
| 692 | return NULL; |
| 693 | } |
| 694 | |
| 695 | |
| 696 | int tempOffset; |
| 697 | if (!g_pGameConf->GetOffset(pszGamedataName, &tempOffset)) |
| 698 | { |
| 699 | pContext->ThrowNativeError("Failed to locate %s offset in gamedata", pszGamedataName); |
| 700 | return NULL; |
| 701 | } |
| 702 | |
| 703 | return (T *)((intptr_t)pPlayerEntity + interimOffset + tempOffset); |
| 704 | } |
| 705 | |
| 706 | template <typename T> |
| 707 | static inline cell_t GetPlayerVar(IPluginContext *pContext, const cell_t *params, const char *varName) |
nothing calls this directly
no test coverage detected