⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g_main.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         G_InitClientPersistant( ent->client );
         }
      }

	G_ClientUserinfoChanged( ent, userinfo );

	if ( game.maxclients > 1 )
      {
		gi.printf( "%s connected\n", ent->client->pers.netname );
      }

   LoadingServer = false;

	return true;
   }

/*
===========
G_ClientDisconnect

called when a player drops from the server

============
*/
void G_ClientDisconnect
	(
	edict_t *ent
	)

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

	if ( ( !ent->client ) || ( !ent->entity ) )
		{
		return;
		}

	delete ent->entity;
	ent->entity = NULL;
	}

/*
==================
Cmd_Say_f
==================
*/
void G_Say
	(
	edict_t *ent,
	qboolean team,
	qboolean arg0
	)

	{
	int			j;
	edict_t		*other;
	const char	*p;
	char			text[ 2048 ];

	if ( gi.argc() < 2 && !arg0 )
		{
		return;
		}

	if ( !DM_FLAG( DF_MODELTEAMS | DF_SKINTEAMS ) )
		{
		team = false;
		}

	if ( team )
		{
		Com_sprintf( text, sizeof( text ), "(%s): ", ent->client->pers.netname );
		}
	else
		{
		Com_sprintf( text, sizeof( text ), "%s: ", ent->client->pers.netname );
		}

	if ( arg0 )
		{
		strcat( text, gi.argv( 0 ) );
		strcat( text, " " );
		strcat( text, gi.args() );
		}
	else
		{
		p = gi.args();

		if ( *p == '"' )
			{
			p++;
			strcat( text, p );
			text[ strlen( text ) - 1 ] = 0;
			}
		else
			{
			strcat( text, p );
			}
		}

	// don't let text be too long for malicious reasons
	if ( strlen( text ) > 150 )
		{
		text[ 150 ] = 0;
		}

	strcat( text, "\n" );

	if ( dedicated->value )
		{
		gi.cprintf( NULL, PRINT_CHAT, "%s", text );
		}

	for( j = 1; j <= game.maxclients; j++ )
		{
		other = &g_edicts[ j ];
		if ( !other->inuse || !other->client )
			{
			continue;
			}
#if 0
		if ( team )
			{
			if ( !OnSameTeam( ent, other ) )
				{
				continue;
				}
			}
#endif
		gi.cprintf( other, PRINT_CHAT, "%s", text );
		}
	}

void ClientCommand
	(
	edict_t *ent
	)

	{
	const char	*cmd;
	int			i;
	int			n;
	Event			*ev;
	qboolean		found;
	cvar_t		*cvar;
	float			t;

	if ( !ent->client || !ent->entity )
		{
		// not fully in game yet
		return;
		}
	
	cmd = gi.argv( 0 );
	n = gi.argc();

   if ( !Q_strcasecmp( cmd, "say" ) )
		{
   	G_Say( ent, false, false );
      return;
		}
   else if ( game.maxclients == 1 )
      {
      // only allow these commands when we only have one client (most likely only a local game)
      if ( !Q_strcasecmp( cmd, "add" ) )
		   {
		   if ( n < 3 )
			   {
			   gi.cprintf( ent, PRINT_HIGH, "Syntax: add [var name] [amount].\n" );
			   return;
			   }

		   cvar = gi.cvar( gi.argv( 1 ), "0", 0 );
		   t = cvar->value + atof( gi.argv( 2 ) );
		   gi.cvar_set( gi.argv( 1 ), va( "%f", t ) );
		   gi.dprintf( "%s = %f\n", gi.argv( 1 ), cvar->value );
		   return;
		   }
      else if ( !Q_strcasecmp( cmd, "eventlist" ) )
		   {
         const char *mask;

         mask = NULL;
         if ( n > 1 )
            {
            mask = gi.argv( 1 );
            }
         Event::ListCommands( mask );
         return;
         }
      else if ( !Q_strcasecmp( cmd, "classlist" ) )
		   {
         listAllClasses();
         return;
         }
      else if ( !Q_strcasecmp( cmd, "classtree" ) )
		   {
         if ( n > 1 )
            {
            listInheritanceOrder( gi.argv( 1 ) );
            }
         else
            {
			   gi.cprintf( ent, PRINT_HIGH, "Syntax: classtree [classname].\n" );
            }
         return;
         }
      else if ( !Q_strcasecmp( cmd, "showvar" ) )
         {
         ScriptVariable *var;

         var = Director.GetExistingVariable( gi.argv( 1 ) );
         if ( var )
            {
            gi.cprintf( ent, PRINT_HIGH, "%s = '%s'\n", gi.argv( 1 ), var->stringValue() );
            }
         else
            {
            gi.cprintf( ent, PRINT_HIGH, "Variable '%s' does not exist.\n", gi.argv( 1 ) );
            }
         return;
         }
      }

	found = false;

  	if ( Event::Exists( cmd ) )
		{
		ev = new Event( cmd );
		ev->SetSource( EV_FROM_CONSOLE );
		ev->SetConsoleEdict( ent );
		for( i = 1; i < n; i++ )
			{
			ev->AddToken( gi.argv( i ) );
			}

		if ( !Q_strncasecmp( cmd, "view", 4 ) )
			{
			found = Viewmodel.ProcessEvent( ev );
			}
		else if ( !Q_strncasecmp( cmd, "ai_", 2 ) )
			{
			found = PathManager.ProcessEvent( ev );
			}
 		else if ( !Q_strncasecmp( cmd, "console", 7 ) )
			{
			found = consoleManager.ProcessEvent( ev );
			}
		else
			{
			found = ent->entity->ProcessEvent( ev );
			}
		}

	if ( !found )
		{
		// anything that doesn't match a command will be a chat
		G_Say( ent, false, true );
		}
	}

void G_ClientCommand 
	(
	edict_t *ent
	)

	{
	// If we get an error, call the server's error function
	if ( setjmp( G_AbortGame ) )
		{
		G_ExitWithError();
		}

	//FIXME
	// setjmp doesn't seem to like to work inside the above function, so I've broken it out, 
	// which makes it happy.  Wierd.
	ClientCommand( ent );
   }

/*
==================
G_DeathmatchScoreboardMessage

==================
*/
void G_DeathmatchScoreboardMessage
	(
	Entity *ent,
	Entity *killer
	)

	{
	char			entry[ 1024 ];
	char			string[ 1400 ];
	int			stringlength;
	int			i, j, k;
	int			sorted[ MAX_CLIENTS ];
	int			sortedscores[ MAX_CLIENTS ];
	int			score, total;
	int			x,y;
	gclient_t	*cl;
	edict_t		*cl_ent, *killeredict, *entedict;
   const char  *tag;
   
	killeredict = NULL;
	entedict = NULL;
	if ( killer )
		{
		killeredict = killer->edict;
		}
	if ( ent )
		{
		entedict = ent->edict;
		}

	// sort the clients by score
	total = 0;
	for( i = 0; i < game.maxclients; i++ )
		{
		cl_ent = g_edicts + 1 + i;
		if ( !cl_ent->inuse )
			{
			continue;
			}

		score = game.clients[ i ].resp.score;
		for( j = 0; j < total; j++ )
			{
			if ( score > sortedscores[ j ] )
				break;
			}
		for( k = total; k > j; k-- )
			{
			sorted[ k ] = sorted[ k - 1 ];
			sortedscores[ k ] = sortedscores[ k - 1 ];
			}
		sorted[ j ] = i;
		sortedscores[ j ] = score;
		total++;
		}

	// print level name and exit rules
	string[ 0 ] = 0;

	stringlength = strlen( string );

	// add the clients in sorted order
	if ( total > 12 )
		{
		total = 12;
		}

	for( i = 0; i < total; i++ )
		{
		cl = &game.clients[ sorted[ i ] ];
		cl_ent = g_edicts + 1 + sorted[ i ];

      x = (i>=6) ? 160 : 0;
		y = 32 + 32 * (i%6);

      // Add a tag to the player and the killer
      if (cl_ent == entedict)
			tag = "tag1";
		else if (cl_ent == killeredict)
			tag = "tag2";
		else
			tag = NULL;

		// send the layout
		Com_sprintf( entry, sizeof( entry ),
			"client %i %i %i %i %i %i ",
			 x, y, sorted[ i ], cl->resp.score, cl->ping, ( level.framenum - cl->resp.enterframe ) / 600 );
		
      // Put the tag on the end of the client command
      if ( tag )
         strcat( entry, va( "1 %s ",tag ) );
      else
         strcat( entry, va( "0 " ) );

      j = strlen( entry );
		if ( stringlength + j > 1024 )
			{
			break;
			}
		strcpy( string + stringlength, entry );
		stringlength += j;
		}

	gi.WriteByte( svc_layout );
	gi.WriteString( string );
	}

/*
==================
G_DeathmatchScoreboard

Draw instead of help message.
Note that it isn't that hard to overflow the 1400 byte message limit!
==================
*/
void G_DeathmatchScoreboard
	(
	Entity *ent
	)

	{
	G_DeathmatchScoreboardMessage( ent, ent->enemy );
	gi.unicast( ent->edict, true );
	}

/*
=================
G_ClientDrawBoundingBoxes
=================
*/
void G_ClientDrawBoundingBoxes
	(
	void
	)

	{
	edict_t	*edict;
	Entity	*ent;
	Vector	eye;

	// don't show bboxes during deathmatch
   if ( !sv_showbboxes->value || ( deathmatch->value && !sv_cheats->value ) )
		{
      return;
		}

   edict = g_edicts + 1 + 0;
   ent = edict->entity;
   if ( ent )
      {
	   eye = ent->worldorigin;
	   ent = findradius( NULL, eye, 1000 );
	   while( ent )
		   {
         switch ((int)sv_showbboxes->value)
            {
            case 1:
               if ( ent->edict != edict && ent->edict->s.solid)
                  {
                  if (ent->bindmaster)
                     G_DebugBBox( ent->worldorigin, ent->mins, ent->maxs, 0, 1, 0, 1 );
                  else
                     G_DebugBBox( ent->worldorigin, ent->mins, ent->maxs, 1, 1, 0, 1 );
                  }
               break;
            case 2:
               if ( ent->edict != edict && ent->edict->s.solid)
                  {
                  if (ent->bindmaster)
                     G_DebugBBox( "0 0 0", ent->edict->absmin, ent->edict->absmax, 0, 0, 1, 1 );
                  else
                     G_DebugBBox( "0 0 0", ent->edict->absmin, ent->edict->absmax, 1, 0, 1, 1 );
                  }
               break;
            case 3:
               if ( ent->edict->s.modelindex && !(ent->edict->s.renderfx & RF_DONTDRAW) )
                  G_DebugBBox( ent->worldorigin, ent->mins, ent->maxs, 1, 1, 0, 1 );
               break;
            case 4:
            default:
               G_DebugBBox( ent->worldorigin, ent->mins, ent->maxs, 1, 1, 0, 1 );
               break;
            case 5:
               if ( ent->edict->s.solid )
                  {
                  G_DebugBBox( ent->worldorigin, ent->edict->fullmins, ent->edict->fullmaxs, 1, 1, 1, 1 );
                  }
               break;
            }
	      ent = findradius( ent, eye, 1000 );
		   }
      }
	}

CLASS_DECLARATION( Class, game_locals_t, NULL );

ResponseDef game_locals_t::Responses[] =
	{
		{ NULL, NULL }
	};

game_locals_t::game_locals_t()
   {
   clients = NULL;

   autosaved = false;
   spawnpoint = "";

   maxentities = 0;
   maxclients = 0;
   maxconsoles = 0;
   maxsurfaces = 0;

   force_entnum = false;
   spawn_entnum = 0;

   ValidPlayerModels.FreeObjectList();
   }

EXPORT_FROM_DLL void game_locals_t::Archive
	(
	Archiver &arc
	)

   {
   int i;
   int num;

   Class::Archive( arc );

   arc.WriteBoolean( autosaved );
   arc.WriteString( spawnpoint );
   arc.WriteBoolean( force_entnum );
   arc.WriteInteger( spawn_entnum );

   // List of valid player models loaded from players global scriptfile
   num = ValidPlayerModels.NumObjects();
   arc.WriteInteger( num );
   for( i = 1; i <= num; i++ )
      {
      arc.WriteString( ValidPlayerModels.ObjectAt( i ) );
      }

   arc.WriteInteger( maxentities );
   arc.WriteInteger( maxclients );
   arc.WriteInteger( maxconsoles );
   arc.WriteInteger( maxsurfaces );

   for( i = 0; i < maxclients; i++ )
      {
		G_WriteClient( arc, &clients[ i ] );
      }
   }

EXPORT_FROM_DLL void game_locals_t::Unarchive
	(
	Archiver &arc
	)

   {
   int i;
   int num;
   str modelname;

   Class::Unarchive( arc );

   arc.ReadBoolean( &autosaved );
   arc.ReadString( &spawnpoint );
   arc.ReadBoolean( &force_entnum );
   arc.ReadInteger( &spawn_entnum );

   // Load list of valid player models
   arc.ReadInteger( &num );
   for( i = 1; i <= num; i++ )
      {
      arc.ReadString( &modelname );
      ValidPlayerModels.AddObject( modelname );
      }

   arc.ReadInteger( &maxentities );
   arc.ReadInteger( &maxclients 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -