static VALUE rb_gsl_integration_qags(int argc, VALUE *argv, VALUE obj) { double a, b, epsabs = EPSABS_DEFAULT, epsrel = EPSREL_DEFAULT; double result, abserr; size_t limit = LIMIT_DEFAULT; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; int status, intervals, flag = 0, itmp; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = get_a_b(argc, argv, 1, &a, &b); break; default: Data_Get_Struct(obj, gsl_function, F); itmp = get_a_b(argc, argv, 0, &a, &b); break; } flag = get_epsabs_epsrel_limit_workspace(argc, argv, itmp, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qags(F, a, b, epsabs, epsrel, limit, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static VALUE rb_gsl_integration_qng(int argc, VALUE *argv, VALUE obj) { double a, b, epsabs = EPSABS_DEFAULT, epsrel = EPSREL_DEFAULT; double result, abserr; size_t neval; gsl_function *F = NULL; int status; // local variable 'itmp' declared and set, but never used //int itmp; if (argc < 1) rb_raise(rb_eArgError, "wrong number of arguments (%d for >= 1)", argc); switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); /*itmp =*/ get_a_b_epsabs_epsrel(argc, argv, 1, &a, &b, &epsabs, &epsrel); break; default: /*itmp =*/ get_a_b_epsabs_epsrel(argc, argv, 0, &a, &b, &epsabs, &epsrel); Data_Get_Struct(obj, gsl_function, F); break; } status = gsl_integration_qng(F, a, b, epsabs, epsrel, &result, &abserr, &neval); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(neval), INT2FIX(status)); }
/* (-infty --- b) */ static VALUE rb_gsl_integration_qagil(int argc, VALUE *argv, VALUE obj) { double b, epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; int status, intervals, flag = 0, itmp; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } Need_Float(argv[itmp]); b = NUM2DBL(argv[itmp]); flag = get_epsabs_epsrel_limit_workspace(argc, argv, itmp+1, &epsabs, &epsrel, &limit, &w); Data_Get_Struct(obj, gsl_function, F); status = gsl_integration_qagil(F, b, epsabs, epsrel, limit, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static VALUE rb_gsl_integration_qawc(int argc, VALUE *argv, VALUE obj) { double a, b, c, epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; int status, intervals, itmp, flag = 0; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } itmp = get_a_b(argc, argv, itmp, &a, &b); if (argc-itmp <= 0) rb_raise(rb_eArgError, "The pole is not given"); Need_Float(argv[itmp]); c = NUM2DBL(argv[itmp]); flag = get_epsabs_epsrel_limit_workspace(argc, argv, itmp+1, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qawc(F, a, b, c, epsabs, epsrel, limit, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static VALUE rb_gsl_integration_qawo(int argc, VALUE *argv, VALUE obj) { double a, epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; gsl_integration_qawo_table *t = NULL; int status, intervals, itmp, flag = 0, flagt = 0; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc < 2) rb_raise(rb_eArgError, "too few arguments"); CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: if (argc < 1) rb_raise(rb_eArgError, "too few arguments"); Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } Need_Float(argv[itmp]); a = NUM2DBL(argv[itmp]); flagt = get_qawo_table(argv[argc-1], &t); flag = get_epsabs_epsrel_limit_workspace(argc-1, argv, itmp+1, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qawo(F, a, epsabs, epsrel, limit, w, t, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); if (flagt == 1) gsl_integration_qawo_table_free(t); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static cell AMX_NATIVE_CALL ExecuteHamB(AMX *amx, cell *params) { int func=params[1]; CHECK_FUNCTION(func); gDoForwards=true; return hooklist[func].call(amx, params); }
static VALUE rb_gsl_min_fminimizer_set(VALUE obj, VALUE ff, VALUE xmin, VALUE xl, VALUE xu) { gsl_min_fminimizer *gmf = NULL; gsl_function *f = NULL; Need_Float(xmin); Need_Float(xl); Need_Float(xu); CHECK_FUNCTION(ff); Data_Get_Struct(obj, gsl_min_fminimizer, gmf); Data_Get_Struct(ff, gsl_function, f); return INT2FIX(gsl_min_fminimizer_set(gmf, f, NUM2DBL(xmin), NUM2DBL(xl), NUM2DBL(xu))); }
static int get_func2(int argc, VALUE *argv, VALUE obj, VALUE *ff, VALUE *xx, VALUE *hh) { switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc == 3) { CHECK_FUNCTION(argv[0]); Need_Float(argv[2]); *ff = argv[0]; *xx = argv[1]; *hh = argv[2]; } else if (argc == 2) { CHECK_FUNCTION(argv[0]); *ff = argv[0]; *xx = argv[1]; *hh = rb_float_new(RB_GSL_DERIV_H_DEFAULT); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc); } break; default: if (argc == 2) { Need_Float(argv[1]); *ff = obj; *xx = argv[0]; *hh = argv[1]; } else if (argc == 1) { *ff = obj; *xx = argv[0]; *hh = rb_float_new(RB_GSL_DERIV_H_DEFAULT); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc); } break; } return 0; }
static VALUE rb_gsl_cheb_init(VALUE obj, VALUE ff, VALUE aa, VALUE bb) { gsl_cheb_series *p = NULL; gsl_function *fff = NULL; double a, b; CHECK_FUNCTION(ff); Need_Float(aa); Need_Float(bb); Data_Get_Struct(obj, gsl_cheb_series, p); Data_Get_Struct(ff, gsl_function, fff); a = NUM2DBL(aa); b = NUM2DBL(bb); gsl_cheb_init(p, fff, a, b); return obj; }
static VALUE rb_gsl_fsolver_set(VALUE obj, VALUE func, VALUE xl, VALUE xh) { gsl_root_fsolver *s = NULL; gsl_function *fff = NULL; double xlow, xup; Need_Float(xl); Need_Float(xh); CHECK_FUNCTION(func); Data_Get_Struct(obj, gsl_root_fsolver, s); Data_Get_Struct(func, gsl_function, fff); xlow = NUM2DBL(xl); xup = NUM2DBL(xh); gsl_root_fsolver_set(s, fff, xlow, xup); return obj; }
static VALUE rb_gsl_integration_qaws(int argc, VALUE *argv, VALUE obj) { double a, b, epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; gsl_integration_qaws_table *t = NULL; int status, intervals, itmp, flag = 0, flagt = 0; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc < 2) rb_raise(rb_eArgError, "too few arguments"); CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: if (argc < 1) rb_raise(rb_eArgError, "too few arguments"); Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } itmp = get_a_b(argc, argv, itmp, &a, &b); if (TYPE(argv[itmp]) == T_ARRAY) { flagt = 1; t = make_qaws_table(argv[itmp]); } else { flagt = 0; if (!rb_obj_is_kind_of(argv[itmp], cgsl_integration_qaws_table)) rb_raise(rb_eTypeError, "Integration::QAWS_Table expected"); Data_Get_Struct(argv[itmp], gsl_integration_qaws_table, t); } flag = get_epsabs_epsrel_limit_workspace(argc, argv, itmp+1, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qaws(F, a, b, t, epsabs, epsrel, limit, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); if (flagt == 1) gsl_integration_qaws_table_free(t); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static VALUE rb_gsl_integration_qagp(int argc, VALUE *argv, VALUE obj) { double epsabs, epsrel; double result, abserr; size_t limit; gsl_function *F = NULL; gsl_vector *v = NULL; gsl_integration_workspace *w = NULL; int status, intervals, flag = 0, flag2 = 0, itmp; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } if (TYPE(argv[itmp]) == T_ARRAY) { v = make_cvector_from_rarray(argv[itmp]); flag2 = 1; } else { Data_Get_Vector(argv[itmp], v); flag2 = 0; } itmp += 1; flag = get_epsabs_epsrel_limit_workspace(argc, argv, itmp, &epsabs, &epsrel, &limit, &w); status = gsl_integration_qagp(F, v->data, v->size, epsabs, epsrel, limit, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); if (flag2 == 1) gsl_vector_free(v); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static VALUE rb_gsl_fsolver_solve(int argc, VALUE *argv, VALUE *obj) { gsl_root_fsolver *s = NULL; gsl_function *F = NULL; double x, xl, xh, epsabs = 0.0, epsrel = 1e-6; int status, iter = 0, max_iter = 100; switch (argc) { case 3: Check_Type(argv[2], T_ARRAY); epsabs = NUM2DBL(rb_ary_entry(argv[2], 0)); epsrel = NUM2DBL(rb_ary_entry(argv[2], 1)); /* no break */ case 2: Check_Type(argv[1], T_ARRAY); xl = NUM2DBL(rb_ary_entry(argv[1], 0)); xh = NUM2DBL(rb_ary_entry(argv[1], 1)); break; default: rb_raise(rb_eArgError, "Usage: solve(f = Function, range = Array, eps = Array)"); break; } CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); Data_Get_Struct(obj, gsl_root_fsolver, s); gsl_root_fsolver_set(s, F, xl, xh); do { iter++; status = gsl_root_fsolver_iterate (s); x = gsl_root_fsolver_root (s); xl = gsl_root_fsolver_x_lower (s); xh = gsl_root_fsolver_x_upper (s); status = gsl_root_test_interval (xl, xh, epsabs, epsrel); if (status == GSL_SUCCESS) break; } while (status == GSL_CONTINUE && iter < max_iter); return rb_ary_new3(3, rb_float_new(x), INT2FIX(iter), INT2FIX(status)); }
static VALUE rb_gsl_integration_qawf(int argc, VALUE *argv, VALUE obj) { double a, epsabs = EPSREL_DEFAULT; double result, abserr; size_t limit = LIMIT_DEFAULT; gsl_function *F = NULL; gsl_integration_workspace *w = NULL, *cw = NULL; gsl_integration_qawo_table *t = NULL; int status, intervals, flag = 0, flagt = 0, itmp; VALUE *vtmp; switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: if (argc < 2) rb_raise(rb_eArgError, "too few arguments"); CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); itmp = 1; break; default: if (argc < 1) rb_raise(rb_eArgError, "too few arguments"); Data_Get_Struct(obj, gsl_function, F); itmp = 0; break; } Need_Float(argv[itmp]); a = NUM2DBL(argv[itmp]); itmp += 1; if (TYPE(argv[itmp]) == T_FLOAT) { epsabs = NUM2DBL(argv[itmp]); itmp += 1; } vtmp = argv + itmp; flagt = get_qawo_table(argv[argc-1], &t); switch (argc - 1 - itmp) { case 0: w = gsl_integration_workspace_alloc(limit); cw = gsl_integration_workspace_alloc(limit); flag = 1; break; case 1: CHECK_FIXNUM(vtmp[0]); limit = FIX2INT(vtmp[0]); w = gsl_integration_workspace_alloc(limit); cw = gsl_integration_workspace_alloc(limit); flag = 1; break; case 2: CHECK_WORKSPACE(vtmp[0]); CHECK_WORKSPACE(vtmp[1]); Data_Get_Struct(vtmp[0], gsl_integration_workspace, w); Data_Get_Struct(vtmp[1], gsl_integration_workspace, cw); flag = 0; break; case 3: CHECK_FIXNUM(vtmp[0]); CHECK_WORKSPACE(vtmp[1]); CHECK_WORKSPACE(vtmp[2]); limit = FIX2INT(vtmp[0]); Data_Get_Struct(vtmp[1], gsl_integration_workspace, w); Data_Get_Struct(vtmp[2], gsl_integration_workspace, cw); flag = 0; break; default: rb_raise(rb_eArgError, "wrong number of arguments"); break; } status = gsl_integration_qawf(F, a, epsabs, limit, w, cw, t, &result, &abserr); intervals = w->size; if (flag == 1) { gsl_integration_workspace_free(w); gsl_integration_workspace_free(cw); } if (flagt == 1) gsl_integration_qawo_table_free(t); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) { // Make sure the function we're requesting is within bounds int func=params[1]; int post=params[4]; CHECK_FUNCTION(func); char *function=MF_GetAmxString(amx, params[3], 0, NULL); char *classname=MF_GetAmxString(amx, params[2], 1, NULL); // Check the entity // create an entity, assign it the gamedll's class, hook it and destroy it edict_t *Entity=CREATE_ENTITY(); CALL_GAME_ENTITY(PLID,classname,&Entity->v); if (Entity->pvPrivateData == NULL) { REMOVE_ENTITY(Entity); MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function); return 0; } void **vtable=GetVTable(Entity->pvPrivateData, Offsets.GetBase()); REMOVE_ENTITY(Entity); if (vtable == NULL) { MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname,function); return 0; } // Verify that the function is valid // Don't fail the plugin if this fails, just emit a normal error int fwd=hooklist[func].makefunc(amx, function); if (fwd == -1) { MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function); return 0; } bool enableSpecialBot = false; // Old plugin doesn't have this param. if (*params / sizeof(cell) == 5) { enableSpecialBot = params[5] > 0; } Forward *pfwd = new Forward(fwd); // We've passed all tests... if (strcmp(classname, "player") == 0 && enableSpecialBot) { SpecialbotHandler.RegisterHamSpecialBot(amx, func, function, post, pfwd); } int **ivtable=(int **)vtable; void *vfunction=(void *)ivtable[hooklist[func].vtid]; // Check the list of this function's hooks, see if the function we have is a hook for (size_t i = 0; i < hooks[func].length(); ++i) { if (hooks[func].at(i)->tramp == vfunction) { // Yes, this function is hooked if (post) { hooks[func].at(i)->post.append(pfwd); } else { hooks[func].at(i)->pre.append(pfwd); } return reinterpret_cast<cell>(pfwd); } } // If we got here, the function is not hooked Hook *hook = new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].needsretbuf, hooklist[func].paramcount, classname); hooks[func].append(hook); if (post) { hook->post.append(pfwd); } else { hook->pre.append(pfwd); } return reinterpret_cast<cell>(pfwd); }
static cell AMX_NATIVE_CALL RegisterHam(AMX *amx, cell *params) { // Make sure the function we're requesting is within bounds int func=params[1]; int post=params[4]; CHECK_FUNCTION(func); char *function=MF_GetAmxString(amx, params[3], 0, NULL); char *classname=MF_GetAmxString(amx, params[2], 1, NULL); // Check the entity // create an entity, assign it the gamedll's class, hook it and destroy it edict_t *Entity=CREATE_ENTITY(); CALL_GAME_ENTITY(PLID,classname,&Entity->v); if (Entity->pvPrivateData == NULL) { REMOVE_ENTITY(Entity); MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for \"%s\", hook for \"%s\" not active.",classname,function); return 0; } void **vtable=GetVTable(Entity->pvPrivateData, Offsets.GetBase()); REMOVE_ENTITY(Entity); if (vtable == NULL) { MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for \"%s\", hook for \"%s\" not active.",classname,function); return 0; } // Verify that the function is valid // Don't fail the plugin if this fails, just emit a normal error int fwd=hooklist[func].makefunc(amx, function); if (fwd == -1) { MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function); return 0; } // We've passed all tests... int **ivtable=(int **)vtable; void *vfunction=(void *)ivtable[hooklist[func].vtid]; // Check the list of this function's hooks, see if the function we have is a hook CVector<Hook *>::iterator end=hooks[func].end(); for (CVector<Hook *>::iterator i=hooks[func].begin(); i!=end; ++i) { if ((*i)->tramp == vfunction) { // Yes, this function is hooked Forward *pfwd=new Forward(fwd); if (post) { (*i)->post.push_back(pfwd); } else { (*i)->pre.push_back(pfwd); } return reinterpret_cast<cell>(pfwd); } } // If we got here, the function is not hooked Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname); hooks[func].push_back(hook); Forward *pfwd=new Forward(fwd); if (post) { hook->post.push_back(pfwd); } else { hook->pre.push_back(pfwd); } return reinterpret_cast<cell>(pfwd); }
static VALUE rb_gsl_integration_qag(int argc, VALUE *argv, VALUE obj) { double a, b, epsabs = EPSABS_DEFAULT, epsrel = EPSREL_DEFAULT; double result, abserr; size_t limit = LIMIT_DEFAULT; gsl_function *F = NULL; gsl_integration_workspace *w = NULL; int key = KEY_DEFAULT, status, intervals, itmp, flag = 0; if (argc < 1) rb_raise(rb_eArgError, "wrong number of arguments (%d for >= 1)", argc); switch (TYPE(obj)) { case T_MODULE: case T_CLASS: case T_OBJECT: CHECK_FUNCTION(argv[0]); Data_Get_Struct(argv[0], gsl_function, F); if (argc == 3) { CHECK_FIXNUM(argv[2]); get_a_b(argc, argv, 1, &a, &b); key = FIX2INT(argv[2]); w = gsl_integration_workspace_alloc(limit); flag = 1; } else if (argc == 4) { CHECK_FIXNUM(argv[3]); get_a_b(argc, argv, 1, &a, &b); key = FIX2INT(argv[3]); w = gsl_integration_workspace_alloc(limit); flag = 1; } else { itmp = get_a_b_epsabs_epsrel(argc, argv, 1, &a, &b, &epsabs, &epsrel); flag = get_limit_key_workspace(argc, argv, itmp, &limit, &key, &w); } break; default: if (argc == 2) { if (FIXNUM_P(argv[1])) { key = FIX2INT(argv[1]); w = gsl_integration_workspace_alloc(limit); flag = 1; } else if (rb_obj_is_kind_of(argv[1], cgsl_integration_workspace)) { Data_Get_Struct(argv[1], gsl_integration_workspace, w); flag = 0; } else { rb_raise(rb_eTypeError, "Key or Workspace expected"); } itmp = get_a_b(argc, argv, 0, &a, &b); } else if (argc == 3) { if (FIXNUM_P(argv[2])) { key = FIX2INT(argv[2]); w = gsl_integration_workspace_alloc(limit); flag = 1; } else if (rb_obj_is_kind_of(argv[2], cgsl_integration_workspace)) { Data_Get_Struct(argv[2], gsl_integration_workspace, w); flag = 0; } else { rb_raise(rb_eTypeError, "Key or Workspace expected"); } itmp = get_a_b(argc, argv, 0, &a, &b); } else { itmp = get_a_b_epsabs_epsrel(argc, argv, 0, &a, &b, &epsabs, &epsrel); flag = get_limit_key_workspace(argc, argv, itmp, &limit, &key, &w); } Data_Get_Struct(obj, gsl_function, F); break; } status = gsl_integration_qag(F, a, b, epsabs, epsrel, limit, key, w, &result, &abserr); intervals = w->size; if (flag == 1) gsl_integration_workspace_free(w); return rb_ary_new3(4, rb_float_new(result), rb_float_new(abserr), INT2FIX(intervals), INT2FIX(status)); }
// RegisterHamFromEntity(Ham:function, EntityId, const Callback[], Post=0); static cell AMX_NATIVE_CALL RegisterHamFromEntity(AMX *amx, cell *params) { // Make sure the function we're requesting is within bounds int func=params[1]; int post=params[4]; CHECK_FUNCTION(func); char *function=MF_GetAmxString(amx, params[3], 0, NULL); int entid=params[2]; char classname[64]; // Check the entity edict_t *Entity=INDEXENT_NEW(entid); if (Entity->pvPrivateData == NULL) { MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve classtype for entity id \"%d\", hook for \"%s\" not active.",entid,function); return 0; } void **vtable=GetVTable(Entity->pvPrivateData, Offsets.GetBase()); if (vtable == NULL) { MF_LogError(amx, AMX_ERR_NATIVE,"Failed to retrieve vtable for entity id \"%d\", hook for \"%s\" not active.",entid,function); return 0; } // Verify that the function is valid // Don't fail the plugin if this fails, just emit a normal error int fwd=hooklist[func].makefunc(amx, function); if (fwd == -1) { MF_LogError(amx, AMX_ERR_NATIVE, "Function %s not found.", function); return 0; } // We've passed all tests... int **ivtable=(int **)vtable; void *vfunction=(void *)ivtable[hooklist[func].vtid]; // Check the list of this function's hooks, see if the function we have is a hook CVector<Hook *>::iterator end=hooks[func].end(); for (CVector<Hook *>::iterator i=hooks[func].begin(); i!=end; ++i) { if ((*i)->tramp == vfunction) { // Yes, this function is hooked Forward *pfwd=new Forward(fwd); if (post) { (*i)->post.push_back(pfwd); } else { (*i)->pre.push_back(pfwd); } return reinterpret_cast<cell>(pfwd); } } // Note down the classname for the given class // It may very well be wrong (such as lots of TS weapons have the same classname) // but it's the best we can do, and better than nothing. // (only used for display) snprintf(classname, sizeof(classname) - 1, "%s", STRING(Entity->v.classname)); // If we got here, the function is not hooked Hook *hook=new Hook(vtable, hooklist[func].vtid, hooklist[func].targetfunc, hooklist[func].isvoid, hooklist[func].paramcount, classname); hooks[func].push_back(hook); Forward *pfwd=new Forward(fwd); if (post) { hook->post.push_back(pfwd); } else { hook->pre.push_back(pfwd); } return reinterpret_cast<cell>(pfwd); }