dvander@954: #include "extension.h" dvander@954: #include "vcallbuilder.h" dvander@954: #include "vnatives.h" dvander@954: dvander@954: List g_RegCalls; dvander@954: dvander@985: inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0) dvander@954: { dvander@985: info.decflags = decflags; dvander@954: info.encflags = 0; dvander@954: info.flags = flags; dvander@954: info.type = type; dvander@954: info.vtype = vtype; dvander@954: } dvander@954: dvander@954: #define START_CALL() \ dvander@954: unsigned char *vptr = pCall->stk_get(); dvander@954: dvander@954: #define FINISH_CALL_SIMPLE(vret) \ dvander@954: pCall->call->Execute(vptr, vret); \ dvander@954: pCall->stk_put(vptr); dvander@954: dvander@954: #define ENCODE_VALVE_PARAM(num, which, vnum) \ dvander@954: if (EncodeValveParam(pContext, \ dvander@954: params[num], \ dvander@987: pCall, \ dvander@954: &pCall->which[vnum], \ dvander@987: vptr) \ dvander@954: == Data_Fail) \ dvander@954: { \ dvander@954: return 0; \ dvander@954: } dvander@954: dvander@954: #define DECODE_VALVE_PARAM(num, which, vnum) \ dvander@954: if (DecodeValveParam(pContext, \ dvander@954: params[num], \ dvander@987: pCall, \ dvander@954: &pCall->which[vnum], \ dvander@987: vptr) \ dvander@954: == Data_Fail) \ dvander@954: { \ dvander@954: return 0; \ dvander@954: } dvander@954: dvander@954: bool CreateBaseCall(const char *name, dvander@954: ValveCallType vcalltype, dvander@954: const ValvePassInfo *retinfo, dvander@954: const ValvePassInfo params[], dvander@954: unsigned int numParams, dvander@954: ValveCall **vaddr) dvander@954: { dvander@954: int offset; dvander@954: ValveCall *call; dvander@954: if (g_pGameConf->GetOffset(name, &offset)) dvander@954: { dvander@954: call = CreateValveVCall(offset, vcalltype, retinfo, params, numParams); dvander@954: if (call) dvander@954: { dvander@954: g_RegCalls.push_back(call); dvander@954: } dvander@954: *vaddr = call; dvander@954: return true; dvander@954: } else { dvander@954: void *addr; dvander@954: if (g_pGameConf->GetMemSig(name, &addr)) dvander@954: { dvander@954: call = CreateValveCall(addr, vcalltype, retinfo, params, numParams); dvander@954: if (call) dvander@954: { dvander@954: g_RegCalls.push_back(call); dvander@954: } dvander@954: *vaddr = call; dvander@954: return true; dvander@954: } dvander@954: } dvander@954: return false; dvander@954: } dvander@954: dvander@954: dvander@954: static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params) dvander@954: { dvander@954: static ValveCall *pCall = NULL; dvander@954: if (!pCall) dvander@954: { dvander@954: ValvePassInfo pass[2]; dvander@954: InitPass(pass[0], Valve_CBaseEntity, PassType_Basic, 0); dvander@954: InitPass(pass[1], Valve_Bool, PassType_Basic, 0); dvander@954: if (!CreateBaseCall("RemovePlayerItem", ValveCall_Player, &pass[1], &pass[0], 1, &pCall)) dvander@954: { dvander@954: return pContext->ThrowNativeError("\"RemovePlayerItem\" not supported by this mod"); dvander@954: } else if (!pCall) { dvander@954: return pContext->ThrowNativeError("\"RemovePlayerItem\" wrapper failed to initialized"); dvander@954: } dvander@954: } dvander@954: dvander@954: bool ret; dvander@954: START_CALL(); dvander@954: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@954: DECODE_VALVE_PARAM(2, vparams, 0); dvander@954: FINISH_CALL_SIMPLE(&ret); dvander@954: return ret ? 1 : 0; dvander@954: } dvander@954: dvander@954: static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params) dvander@954: { dvander@954: static ValveCall *pCall = NULL; dvander@954: if (!pCall) dvander@954: { dvander@954: ValvePassInfo pass[3]; dvander@954: InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL); dvander@954: InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); dvander@954: InitPass(pass[2], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); dvander@954: if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[2], pass, 2, &pCall)) dvander@954: { dvander@954: return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod"); dvander@954: } else if (!pCall) { dvander@954: return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialized"); dvander@954: } dvander@954: } dvander@954: dvander@954: CBaseEntity *pEntity = NULL; dvander@954: START_CALL(); dvander@954: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@954: DECODE_VALVE_PARAM(2, vparams, 0); dvander@954: DECODE_VALVE_PARAM(3, vparams, 1); dvander@954: FINISH_CALL_SIMPLE(&pEntity); dvander@954: dvander@954: if (pEntity == NULL) dvander@954: { dvander@954: return -1; dvander@954: } dvander@954: dvander@954: edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); dvander@954: if (!pEdict) dvander@954: { dvander@954: return -1; dvander@954: } dvander@954: dvander@954: return engine->IndexOfEdict(pEdict); dvander@954: } dvander@954: dvander@954: static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params) dvander@954: { dvander@954: static ValveCall *pCall = NULL; dvander@954: if (!pCall) dvander@954: { dvander@954: ValvePassInfo pass[2]; dvander@954: InitPass(pass[0], Valve_POD, PassType_Basic, PASSFLAG_BYVAL); dvander@954: InitPass(pass[1], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL); dvander@954: if (!CreateBaseCall("Weapon_GetSlot", ValveCall_Player, &pass[1], pass, 1, &pCall)) dvander@954: { dvander@954: return pContext->ThrowNativeError("\"Weapon_GetSlot\" not supported by this mod"); dvander@954: } else if (!pCall) { dvander@954: return pContext->ThrowNativeError("\"Weapon_GetSlot\" wrapper failed to initialized"); dvander@954: } dvander@954: } dvander@954: dvander@954: CBaseEntity *pEntity; dvander@954: START_CALL(); dvander@954: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@954: DECODE_VALVE_PARAM(2, vparams, 0); dvander@954: FINISH_CALL_SIMPLE(&pEntity); dvander@954: dvander@954: if (pEntity == NULL) dvander@954: { dvander@954: return -1; dvander@954: } dvander@954: dvander@954: edict_t *pEdict = gameents->BaseEntityToEdict(pEntity); dvander@954: if (!pEdict) dvander@954: { dvander@954: return -1; dvander@954: } dvander@954: dvander@954: return engine->IndexOfEdict(pEdict); dvander@954: } dvander@954: dvander@955: static cell_t IgnitePlayer(IPluginContext *pContext, const cell_t *params) dvander@955: { dvander@955: static ValveCall *pCall = NULL; dvander@955: if (!pCall) dvander@955: { dvander@955: ValvePassInfo pass[4]; dvander@955: InitPass(pass[0], Valve_Float, PassType_Float, PASSFLAG_BYVAL); dvander@955: InitPass(pass[1], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); dvander@955: InitPass(pass[2], Valve_Float, PassType_Float, PASSFLAG_BYVAL); dvander@955: InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL); dvander@980: if (!CreateBaseCall("Ignite", ValveCall_Entity, NULL, pass, 4, &pCall)) dvander@955: { dvander@955: return pContext->ThrowNativeError("\"Ignite\" not supported by this mod"); dvander@955: } else if (!pCall) { dvander@955: return pContext->ThrowNativeError("\"Ignite\" wrapper failed to initialized"); dvander@955: } dvander@955: } dvander@955: dvander@955: START_CALL(); dvander@955: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@955: DECODE_VALVE_PARAM(2, vparams, 0); dvander@955: DECODE_VALVE_PARAM(3, vparams, 1); dvander@955: DECODE_VALVE_PARAM(4, vparams, 2); dvander@955: DECODE_VALVE_PARAM(5, vparams, 3); dvander@955: FINISH_CALL_SIMPLE(NULL); dvander@955: dvander@955: return 1; dvander@955: } dvander@955: dvander@955: static cell_t ExtinguishPlayer(IPluginContext *pContext, const cell_t *params) dvander@955: { dvander@955: static ValveCall *pCall = NULL; dvander@955: if (!pCall) dvander@955: { dvander@980: if (!CreateBaseCall("Extinguish", ValveCall_Entity, NULL, NULL, 0, &pCall)) dvander@955: { dvander@955: return pContext->ThrowNativeError("\"Extinguish\" not supported by this mod"); dvander@955: } else if (!pCall) { dvander@955: return pContext->ThrowNativeError("\"Extinguish\" wrapper failed to initialized"); dvander@955: } dvander@955: } dvander@955: dvander@955: START_CALL(); dvander@955: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@955: FINISH_CALL_SIMPLE(NULL); dvander@955: dvander@955: return 1; dvander@955: } dvander@955: dvander@955: static cell_t TeleportPlayer(IPluginContext *pContext, const cell_t *params) dvander@955: { dvander@955: static ValveCall *pCall = NULL; dvander@955: if (!pCall) dvander@955: { dvander@955: ValvePassInfo pass[3]; dvander@985: InitPass(pass[0], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); dvander@985: InitPass(pass[1], Valve_QAngle, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); dvander@985: InitPass(pass[2], Valve_Vector, PassType_Basic, PASSFLAG_BYVAL, VDECODE_FLAG_ALLOWNULL); dvander@980: if (!CreateBaseCall("Teleport", ValveCall_Entity, NULL, pass, 3, &pCall)) dvander@955: { dvander@955: return pContext->ThrowNativeError("\"Teleport\" not supported by this mod"); dvander@955: } else if (!pCall) { dvander@955: return pContext->ThrowNativeError("\"Teleport\" wrapper failed to initialized"); dvander@955: } dvander@955: } dvander@955: dvander@955: START_CALL(); dvander@955: DECODE_VALVE_PARAM(1, thisinfo, 0); dvander@955: DECODE_VALVE_PARAM(2, vparams, 0); dvander@955: DECODE_VALVE_PARAM(3, vparams, 1); dvander@955: DECODE_VALVE_PARAM(4, vparams, 2); dvander@955: FINISH_CALL_SIMPLE(NULL); dvander@955: dvander@955: return 1; dvander@955: } dvander@955: dvander@954: sp_nativeinfo_t g_Natives[] = dvander@954: { dvander@955: {"ExtinguishPlayer", ExtinguishPlayer}, dvander@980: {"ExtinguishEntity", ExtinguishPlayer}, dvander@954: {"GivePlayerItem", GiveNamedItem}, dvander@954: {"GetPlayerWeaponSlot", GetPlayerWeaponSlot}, dvander@955: {"IgnitePlayer", IgnitePlayer}, dvander@980: {"IgniteEntity", IgnitePlayer}, dvander@955: {"RemovePlayerItem", RemovePlayerItem}, dvander@955: {"TeleportPlayer", TeleportPlayer}, dvander@980: {"TeleportEntity", TeleportPlayer}, dvander@954: {NULL, NULL}, dvander@954: }; dvander@980: