Пример #1
0
edict_t *CServer::CreateFakeClient(const char *name)
{
   edict_t *pEdict;
   pEdict = CREATE_FAKE_CLIENT(name);

   if (!FNullEnt(pEdict)) {
      char ptr[128]; // allocate space for message from ClientConnect

      if (pEdict->pvPrivateData != NULL)
         FREE_PRIVATE(pEdict); // free our predecessor's private data
      pEdict->pvPrivateData = NULL; // null out the private data pointer

      pEdict->v.frags = 0; // reset his frag count

      // set the max speed for this player
      pEdict->v.maxspeed = CVAR_GET_FLOAT("sv_maxspeed");

      // create the player entity by calling MOD's player function
      // (from LINK_ENTITY_TO_CLASS for player object)
      if (g_fIsMetamod) {
         CALL_GAME_ENTITY(PLID, "player", VARS(pEdict));
      } else {
         player(VARS(pEdict));
      }

      MDLL_ClientConnect(pEdict, "bot", "127.0.0.1", ptr);
      MDLL_ClientPutInServer(pEdict); // let this bot actually spawn into the game

      return pEdict;
   }

   return NULL;
}
Пример #2
0
void BotControl::CallGameEntity (entvars_t *vars)
{
   // this function calls gamedll player() function, in case to create player entity in game

   if (g_isMetamod)
   {
      CALL_GAME_ENTITY (PLID, "player", vars);
      return;
   }

   static EntityPtr_t playerFunction = null;

   if (playerFunction == null)
      playerFunction = (EntityPtr_t) g_gameLib->GetFunctionAddr ("player");

   if (playerFunction != null)
      (*playerFunction) (vars);
}
Пример #3
0
cell AMX_NATIVE_CALL Rage::GetFunctionFromClass(AMX* amx,cell* params)
{
	int len;
	char *func_name = g_fn_GetAmxString(amx,params[1],0,&len);

	VirtualFunction** virtual_function_ptr = Global::virtualFunctionsManager.get_by_label(func_name);
	
	if(!virtual_function_ptr)
	{
		MF_LogError(amx, AMX_ERR_NATIVE, "Virtual function %s not registered",func_name);
		return -1;
	}

	VirtualFunction* virtual_function = *virtual_function_ptr;

	char* class_name = g_fn_GetAmxString(amx,params[2],0,&len);

	static char class_name_cp[50];
	strncpy(class_name_cp,class_name,49);

	edict_t *entity = CREATE_ENTITY();
	CALL_GAME_ENTITY(PLID,class_name,&entity->v);

	if(!entity->pvPrivateData)
	{
		REMOVE_ENTITY(entity);

		MF_LogError(amx, AMX_ERR_NATIVE,"Unable to create an entity of class '%s'",class_name);
		return -1;
	}

	int ret = virtual_function->create_get_id(entity->pvPrivateData,class_name_cp);
	
	REMOVE_ENTITY(entity);

	return ret;
}
Пример #4
0
void AddNodeEntity(const Vector &origin, int effects)
{
   edict_t *pNode = CREATE_ENTITY();
   if (g_fIsMetamod) {
      CALL_GAME_ENTITY(PLID, "info_node", VARS(pNode));
   } else {
      info_node(VARS(pNode));
   }

   pNode->v.classname = MAKE_STRING("info_node");
   SET_ORIGIN(pNode, origin);
   pNode->v.rendercolor.x = 255;
   pNode->v.rendercolor.y = 255;
   pNode->v.rendercolor.z = 0;
   pNode->v.rendermode = kRenderTransAdd;
   pNode->v.movetype = MOVETYPE_NONE;
   pNode->v.solid = SOLID_TRIGGER;
   SET_SIZE(ENT(&pNode->v), Vector(-8, -8, -8), Vector(8, 8, 8));
   pNode->v.renderfx = kRenderFxNoDissipation;
   pNode->v.renderamt = 255;
   pNode->v.scale = 0.2;
   SET_MODEL(ENT(pNode), "sprites/glow02.spr");
   pNode->v.effects = effects;
}
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);
}
Пример #6
0
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);
}
Пример #7
0
// Add bot -> ARG1(team), ARG2(skill), ARG3(model), ARG4(name)
int cGame::CreateBot(edict_t * pPlayer, const char *arg1, const char *arg2,
                     const char *arg3, const char *arg4) {
   edict_t *BotEnt;
   cBot *pBot;
   char c_skin[BOT_SKIN_LEN + 1];
   char c_name[BOT_NAME_LEN + 1];

   // clear
   memset(c_skin, 0, sizeof(c_skin));
   memset(c_name, 0, sizeof(c_name));

   int skill;
   int i, j, length;
   if ((arg4 != NULL) && (*arg4 != 0)) {
      strncpy(c_name, arg4, BOT_NAME_LEN - 1);
      c_name[BOT_NAME_LEN] = 0; // make sure c_name is null terminated
   } else {
      if (NamesAvailable())
         SelectName(c_name);
      else
         strcpy(c_name, "RealBot");
   }

   skill = -2;                  // -2, not valid

   if ((arg2 != NULL) && (*arg2 != 0))
      skill = atoi(arg2);       // set to given skill

   // when not valid (-2), it has default skill
   if ((skill < -1) || (skill > 10))
      skill = iDefaultBotSkill;

   // When skill is -1, random, we set it by boundries given
   if (skill == -1)
      skill = RANDOM_LONG(iRandomMinSkill, iRandomMaxSkill);

   // length of name
   length = strlen(c_name);

   // remove any illegal characters from name...
   for (i = 0; i < length; i++) {
      if ((c_name[i] <= ' ') || (c_name[i] > '~') || (c_name[i] == '"')) {
         for (j = i; j < length; j++)   // shuffle chars left (and null)
            c_name[j] = c_name[j + 1];
         length--;
      }
   }

   BotEnt = (*g_engfuncs.pfnCreateFakeClient) (c_name);
   if (FNullEnt(BotEnt)) {
      REALBOT_PRINT(NULL, "cGame::CreateBot",
                    "Cannot create bot, server is full");
      return GAME_MSG_FAIL_SERVERFULL;  // failed
   } else {
      char ptr[128];            // allocate space for message from ClientConnect
      char *infobuffer;
      int clientIndex;
      int index;
      index = 0;
      while ((bots[index].bIsUsed) && (index < 32))
         index++;
      if (index == 32) {
         return GAME_MSG_FAILURE;
      }
      // create the player entity by calling MOD's player function
      // (from LINK_ENTITY_TO_CLASS for player object)

      // FIX: Free data for bot, so we can fill in new
      if (BotEnt->pvPrivateData != NULL)
         FREE_PRIVATE(BotEnt);

      BotEnt->pvPrivateData = NULL;
      BotEnt->v.frags = 0;

      // END OF FIX: --- score resetted
      CALL_GAME_ENTITY(PLID, "player", VARS(BotEnt));
      infobuffer = (*g_engfuncs.pfnGetInfoKeyBuffer) (BotEnt);
      clientIndex = ENTINDEX(BotEnt);

      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "model", "");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "rate", "3500.000000");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "cl_updaterate", "20");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "cl_lw", "1");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "cl_lc", "1");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "tracker", "0");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "cl_dlmax", "128");

	  if (RANDOM_LONG(0, 100) < 50) {
         (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "lefthand", "1");
	  } else {
         (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "lefthand", "0");
	  }

      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "friends", "0");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "dm", "0");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "ah", "1");
      (*g_engfuncs.pfnSetClientKeyValue) (clientIndex, infobuffer, "_vgui_menus", "0");

      MDLL_ClientConnect(BotEnt, c_name, "127.0.0.1", ptr);

      // Pieter van Dijk - use instead of DispatchSpawn() - Hip Hip Hurray!
      MDLL_ClientPutInServer(BotEnt);
      BotEnt->v.flags |= FL_THIRDPARTYBOT;

      // initialize all the variables for this bot...

      // Retrieve Pointer
      pBot = &bots[index];

      // Set variables
      pBot->iIndex = index;
      pBot->bIsUsed = true;
      pBot->respawn_state = RESPAWN_IDLE;
      pBot->fCreateTime = gpGlobals->time;
      pBot->fKickTime = 0.0;
      pBot->name[0] = 0;        // name not set by server yet
      pBot->bot_money = 0;
      strcpy(pBot->skin, c_skin);
      pBot->pEdict = BotEnt;
      pBot->bStarted = false;   // hasn't joined game yet

      // CS Message IDLE..
      pBot->start_action = MSG_CS_IDLE;
      pBot->SpawnInit();
      pBot->bInitialize = false;        // don't need to initialize yet
      BotEnt->v.idealpitch = BotEnt->v.v_angle.x;
      BotEnt->v.ideal_yaw = BotEnt->v.v_angle.y;
      BotEnt->v.pitch_speed = BOT_PITCH_SPEED;
      BotEnt->v.yaw_speed = BOT_YAW_SPEED;
      pBot->bot_skill = skill;

      // Personality related
      pBot->ipHostage = 0;
      pBot->ipBombspot = 0;
      pBot->ipRandom = 0;
      pBot->ipTurnSpeed = 20;
      pBot->ipReplyToRadio = 0;
      pBot->ipCreateRadio = 0;
      pBot->ipHelpTeammate = 0;
      pBot->ipWalkWithKnife = 0;
      pBot->ipDroppedBomb = 0;
      pBot->ipCampRate = 0;
      pBot->ipChatRate = 0;
      pBot->ipFearRate = 0;
      pBot->ipHearRate = 0;

      pBot->played_rounds = 0;

      // Buy-personality related
      pBot->ipFavoPriWeapon = -1;
      pBot->ipFavoSecWeapon = -1;
      pBot->ipBuyFlashBang = 0;
      pBot->ipBuyGrenade = 0;
      pBot->ipBuySmokeGren = 0;
      pBot->ipBuyDefuseKit = 0;
      pBot->ipSaveForWeapon = 0;
      pBot->ipBuyArmour = 0;

      // here we set team
      if ((arg1 != NULL) && (arg1[0] != 0)) {
         pBot->iTeam = atoi(arg1);

         // and class
         if ((arg3 != NULL) && (arg3[0] != 0)) {
            pBot->bot_class = atoi(arg3);
         }
      }
      // Parsing name into bot identity
      INI_PARSE_BOTS(c_name, pBot);

      // return success
      return GAME_MSG_SUCCESS;
   }
}                               // CreateBot()