示例#1
0
	DETOUR_DECL_MEMBER(void, CTFPlayer_ApplyAbsVelocityImpulse, const Vector& impulse)
	{
		if (rc_CTFPlayer_ApplyPushFromDamage > 0) {
			auto player = reinterpret_cast<CTFPlayer *>(this);
			if (player->IsBot()) {
				if (dmginfo->GetAttacker() == player) {
					float magnitude = impulse.Length();
					
					QAngle angles;
					VectorAngles(impulse, angles);
					
					DevMsg("IMPULSE: mag %.1f, dir [ %.1f %.1f %.1f ]\n",
						magnitude, angles.x, angles.y, angles.z);
					
					constexpr float duration = 3.0f;
					char buf[1024];
					
					NDebugOverlay::VertArrow(player->GetAbsOrigin(), player->GetAbsOrigin() + impulse,
						5.0f, 0x00, 0xff, 0x00, 0xff, false, duration);
					
					snprintf(buf, sizeof(buf), "Mag: %.1f", magnitude);
					NDebugOverlay::EntityTextAtPosition(player->GetAbsOrigin(), 0,
						buf, duration, 0xff, 0xff, 0xff, 0xff);
					
					snprintf(buf, sizeof(buf), "Dir: [ %.1f %.1f %.1f ]", angles.x, angles.y, angles.z);
					NDebugOverlay::EntityTextAtPosition(player->GetAbsOrigin(), 1,
						buf, duration, 0xff, 0xff, 0xff, 0xff);
				}
			}
		}
		
		DETOUR_MEMBER_CALL(CTFPlayer_ApplyAbsVelocityImpulse)(impulse);
	}
示例#2
0
// print a text message to this client
void CClient::TextMessage(msg_dest iMsgDest, const char *fmt, ...)
{
   assert(IsValid());
   if (!IsValid() || IsBot() || (GetFlags() & FL_FAKECLIENT))
      return; // don't try to print text messages for bots

   va_list argptr;
   static char string[256];

   // concatenate all the arguments in one string
   va_start(argptr, fmt);
   _vsnprintf(string, sizeof(string), fmt, argptr);
   va_end(argptr);

   PRINT_TYPE ptype = print_console;

   switch (iMsgDest) {
   case TEXT_CENTER:
      ptype = print_center;
      break;
   case TEXT_CONSOLE:
      ptype = print_console;
      break;
   case TEXT_SAY:
      ptype = print_chat;
      break;
   }

   g_engfuncs.pfnClientPrintf(edict(), ptype, string);
}
示例#3
0
void CSDKPlayer::State_Enter_WELCOME()
{
	// Important to set MOVETYPE_NONE or our physics object will fall while we're sitting at one of the intro cameras.
	SetMoveType( MOVETYPE_NONE );
	AddSolidFlags( FSOLID_NOT_SOLID );

	PhysObjectSleep();

	// Show info panel
	if ( IsBot() )
	{
		// If they want to auto join a team for debugging, pretend they clicked the button.
		CCommand args;
		args.Tokenize( "joingame" );
		ClientCommand( args );
	}
	else
	{
		const ConVar *hostname = cvar->FindVar( "hostname" );
		const char *title = (hostname) ? hostname->GetString() : "MESSAGE OF THE DAY";

		// open info panel on client showing MOTD:
		KeyValues *data = new KeyValues("data");
		data->SetString( "title", title );		// info panel title
		data->SetString( "type", "1" );			// show userdata from stringtable entry
		data->SetString( "msg",	"motd" );		// use this stringtable entry
		data->SetString( "cmd", "joingame" );// exec this command if panel closed

		ShowViewPortPanel( PANEL_INFO, true, data );

		data->deleteThis();

	}	
}
示例#4
0
void Ports::AddPort(std::string pName, std::string pType,
		Interface::tDirection pDir) {
	Interface If;
	If.SetDirection(pDir);
	If.SetName(pType);
	mPorts[pName] = If;
	IsBot(false);
}
示例#5
0
/*
=================
TossClientItems

Toss the weapon and powerups for the killed player
=================
*/
void TossClientItems( gentity_t *self ) {
	gitem_t		*item;

	if ( IsBot( self ) )
		return;	//bots don't drop items in single player

	//the player drops a backpack in single player
	item = BG_FindItemForBackpack(); 
	Drop_Item( self, item, 0 );

}
示例#6
0
void idBotFacade::KickBot( const char *botName ) {
	for ( int i = 0; i < MAX_BOTS; ++i ) {
		if ( !IsBot( i ) ) {
			continue;
		}

		if ( idStr::Icmp( gameAdapter->GetPlayerName( i ), botName ) == 0 ) {
			KickBot( i );
			break;
		}
	}
}
示例#7
0
	DETOUR_DECL_MEMBER(CEconItemView *, CTFPlayer_GetLoadoutItem, int pclass, int slot, bool b1)
	{
		auto result = DETOUR_MEMBER_CALL(CTFPlayer_GetLoadoutItem)(pclass, slot, b1);
		
		if (TFGameRules()->IsMannVsMachineMode() && result->GetItemDefIndex() == DEFIDX_CANTEEN_DEFAULT) {
			auto player = reinterpret_cast<CTFPlayer *>(this);
			if (player->GetTeamNumber() == TF_TEAM_BLUE && player->IsBot()) {
				return nullptr;
			}
		}
		
		return result;
	}
示例#8
0
文件: CMisc.cpp 项目: 9iky6/amxmodx
void CPlayer::Connect(const char* nn,const char* ippp ){
	bot = IsBot();
	strcpy(ip,ippp);
	// Strip the port from the ip
	for (size_t i = 0; i < sizeof(ip); i++)
	{
		if (ip[i] == ':')
		{
			ip[i] = '\0';
			break;
		}
	}
}
示例#9
0
void CPlayer::Connect(const char* address ){
	bot = IsBot();
	strcpy(ip,address);
	// Strip the port from the ip
	for (size_t i = 0; i < sizeof(ip); i++)
	{
		if (ip[i] == ':')
		{
			ip[i] = '\0';
			break;
		}
	}
	rank = 0;
	clearStats = 0.0f;
}
示例#10
0
void idBotFacade::KickBot( int clientIndex ) {
	if ( !IsBot( clientIndex ) ) {
		return;
	}

	char buf[ 64 ];
	idStr::Copynz( buf, gameAdapter->GetPlayerName( clientIndex ), sizeof( buf ) );

	game->ServerClientDisconnect( clientIndex );

	delete bots[ clientIndex ];
	bots[ clientIndex ] = NULL;

	common->Printf( "Bot '%s' kicked\n", buf );
}
示例#11
0
/*
================
respawn
================
*/
void respawn( gentity_t *ent ) {
	gentity_t	*tent;

	//kick fragged bots from game
	if (IsBot(ent->client->ps.clientNum) ) {
		trap_DropClient( ent->client->ps.clientNum, "" );
		G_EndWave();	//check if the wave was won and handle it
		return;
	}

	CopyToBodyQue (ent);
	ClientSpawn(ent);

	// add a teleportation effect
	tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN );
	tent->s.clientNum = ent->s.clientNum;
}
示例#12
0
void CHL2MP_Player::GiveDefaultItems( void )
{
	EquipSuit();

	//GiveNamedItem( "weapon_kungfu" );
	CBaseCombatWeapon *pDefault = static_cast<CBaseCombatWeapon*>(GiveNamedItem( "weapon_combatknife" ));
	Assert( pDefault );
	Weapon_Switch( pDefault );

	if ( IsBot() )
	{
		CBaseCombatWeapon *pMac11 = static_cast<CBaseCombatWeapon*>(GiveNamedItem( "weapon_mac11" ));
		Weapon_Switch( pMac11 );
		CBasePlayer::GiveAmmo( 128, "Mac11" );
	}

	FileWeaponInfo_t* pInfo = GetFileWeaponInfoFromHandle( LookupWeaponInfoSlot( "weapon_deringer" ) );
	if ( pInfo )
		CBasePlayer::GiveAmmo( pInfo->iDefaultAmmoPrimary, "Deringer" );
}
示例#13
0
void CPlayer::PutInServer(){

	//if ( ignoreBots(pEdict) )
	if ( (int)csstats_rankbots->value == 0 &&
		 IsBot() )
		return;

	restartStats();
	const char* name = STRING(pEdict->v.netname);
	const char* unique = name;
	bool isip = false;
	switch((int)csstats_rank->value) {
	case 1: 
		if ( (unique = GETPLAYERAUTHID(pEdict)) == 0 )
			unique = name; // failed to get authid
		break;
	case 2:
		unique = ip;
		isip = true;
	}
	rank = g_rank.findEntryInRank( unique , name , isip);
}
void TransferTable::AddEntry(std::string pSourceName, std::string pDestName,
		std::string pPortName) {
	std::pair<std::string,std::string> Key(pSourceName, pDestName);
	mTable[Key] = pPortName ;
	IsBot(false) ;
}
void TransferTable::SetValue(
		std::map< std::pair<std::string,std::string> , std::string > pTable) {
	mTable = pTable ;
	IsBot(false) ;
}
void TransferTable::Set(TransferTable pT) {
	(*this) = pT ;
	IsBot(false) ;
}
示例#17
0
void do_oper(struct Client* cptr, struct Client* sptr, struct ConfItem* aconf)
{
  struct Flags old_mode = cli_flags(sptr);
  char*        modes;
  char*        parv[2];
  char*        join[3];
  char         chan[CHANNELLEN-1];
  char*        ajoinchan;
  char*        ajoinnotice;
  unsigned int snomask = 0;

  parv[0] = cli_name(sptr);
  parv[1] = NULL;

  SetOper(sptr);
  client_set_privs(sptr, aconf);
  ClearOper(sptr);

  snomask = ConfSnoMask(aconf) & SNO_ALL;
  snomask |= aconf->snomask & SNO_ALL;

  ajoinchan = ConfAjoinChan(aconf);
  ajoinnotice = ConfAjoinNotice(aconf);

  if (MyUser(sptr)) {
    SetLocOp(sptr);
    if (HasPriv(sptr, PRIV_PROPAGATE))
    {
      ClearLocOp(sptr);
      SetOper(sptr);
      if (HasPriv(sptr, PRIV_ADMIN))
        SetAdmin(sptr);
      if (!IsHideOper(sptr) && !IsChannelService(sptr) && !IsBot(sptr))
        ++UserStats.opers;
    }
    cli_handler(sptr) = OPER_HANDLER;

    SetFlag(sptr, FLAG_WALLOP);
    SetFlag(sptr, FLAG_SERVNOTICE);
    SetFlag(sptr, FLAG_DEBUG);

    if (snomask)
      set_snomask(sptr, snomask, SNO_ADD);
    else
      set_snomask(sptr, feature_int(FEAT_SNOMASK_OPERDEFAULT), SNO_ADD);
    cli_max_sendq(sptr) = 0; /* Get the sendq from the oper's class */
    cli_max_recvq(sptr) = 0; /* Get the recvq from the oper's class */
    cli_lag_min(sptr) = -2; /* Get the fake lag minimum from the oper's class */
    cli_lag_factor(sptr) = -2; /* Get the fake lag factor from the oper's class */
    send_umode_out(sptr, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
  } else {
    client_send_privs(&me, sptr, sptr);

    if (HasPriv(sptr, PRIV_PROPAGATE)) {
      modes = (HasPriv(sptr, PRIV_ADMIN) ? "aowsg" : "owsg");
    } else {
      modes = "Owsg";
    }

    sendcmdto_one(&me, CMD_MODE, sptr, "%s %s", cli_name(sptr), modes);
  }

  modes = ConfUmode(aconf);
  if (modes) {
    if (MyUser(sptr)) {
      char *umodev[] = { NULL, NULL, NULL, NULL };
      umodev[1] = cli_name(sptr);
      umodev[2] = modes;
      old_mode = cli_flags(sptr);
      set_user_mode(sptr, sptr, 3, umodev, ALLOWMODES_ANY);
      send_umode(NULL, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
      if ((cli_snomask(sptr) != feature_int(FEAT_SNOMASK_OPERDEFAULT)) &&
          HasFlag(sptr, FLAG_SERVNOTICE))
        send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
    } else {
      if (snomask)
        sendcmdto_one(&me, CMD_MODE, sptr, "%s %s+s +%d", cli_name(sptr), modes, snomask);
      else
        sendcmdto_one(&me, CMD_MODE, sptr, "%s %s", cli_name(sptr), modes);
    }
  }

  send_reply(sptr, RPL_YOUREOPER);

  if ((feature_int(FEAT_HOST_HIDING_STYLE) == 1) ||
      (feature_int(FEAT_HOST_HIDING_STYLE) == 3))
    hide_hostmask(sptr);

  if (!EmptyString(ajoinchan))
  {
    if (!EmptyString(ajoinnotice))
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, ajoinnotice);

    ircd_strncpy(chan, ajoinchan, CHANNELLEN-1);
    join[0] = cli_name(sptr);
    join[1] = chan;
    join[2] = NULL;
    m_join(sptr, sptr, 2, join);
  }

  if (!EmptyString(aconf->autojoinchan))
  {
    if (!EmptyString(aconf->autojoinnotice))
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, aconf->autojoinnotice);

    ircd_strncpy(chan, aconf->autojoinchan, CHANNELLEN-1);
    join[0] = cli_name(sptr);
    join[1] = chan;
    join[2] = NULL;
    m_join(sptr, sptr, 2, join);
  }

  sendto_opmask_butone_global((MyUser(sptr) ? &me : NULL), SNO_OLDSNO,
     "%s (%s@%s) is now operator (%c)",
     cli_name(sptr), cli_user(sptr)->username, cli_user(sptr)->realhost,
     IsOper(sptr) ? 'O' : 'o');

  if (feature_bool(FEAT_OPERMOTD))
    m_opermotd(sptr, sptr, 1, parv);

  log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#C)", aconf->name, sptr);
}
示例#18
0
/*
==================
player_die
==================
*/
void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
	gentity_t	*ent;
	int			anim;
	int			contents;
	int			killer;
	int			i;
	char		*killerName, *obit;

	if ( self->client->ps.pm_type == PM_DEAD ) {
		return;
	}

	if ( level.intermissiontime ) {
		return;
	}

	//if we're in SP mode and player killed a bot, award score for the kill
	if ( IsBot( self ) ) {
		if ( self->parent && self->parent->health && attacker->client ) {
			AddScore( attacker, self->r.currentOrigin, self->parent->health );
			self->s.time = level.time;
		}
	}	

	if (self->client && self->client->hook) {
		Weapon_HookFree(self->client->hook);
	}
	self->client->ps.pm_type = PM_DEAD;

	if ( attacker ) {
		killer = attacker->s.number;
		if ( attacker->client ) {
			killerName = attacker->client->pers.netname;
		} else {
			killerName = "<non-client>";
		}
	} else {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( killer < 0 || killer >= MAX_CLIENTS ) {
		killer = ENTITYNUM_WORLD;
		killerName = "<world>";
	}

	if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) {
		obit = "<bad obituary>";
	} else {
		obit = modNames[ meansOfDeath ];
	}

	G_LogPrintf("Kill: %i %i %i: %s killed %s by %s\n", 
		killer, self->s.number, meansOfDeath, killerName, 
		self->client->pers.netname, obit );

	// broadcast the death event to everyone
	/*
	ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
	ent->s.eventParm = meansOfDeath;
	ent->s.otherEntityNum = self->s.number;
	ent->s.otherEntityNum2 = killer;
	ent->r.svFlags = SVF_BROADCAST;	// send to everyone
	*/

	self->enemy = attacker;

	self->client->ps.persistant[PERS_KILLED]++;

	// Add team bonuses
	//Team_FragBonuses(self, inflictor, attacker);

	// if client is in a nodrop area, don't drop anything (but return CTF flags!)
	contents = trap_PointContents( self->r.currentOrigin, -1 );
	TossClientItems( self );

	Cmd_Score_f( self );		// show scores
	// send updated scores to any clients that are following this one,
	// or they would get stale scoreboards
	for ( i = 0 ; i < level.maxclients ; i++ ) {
		gclient_t	*client;

		client = &level.clients[i];
		if ( client->pers.connected != CON_CONNECTED ) {
			continue;
		}
		if ( client->sess.sessionTeam != TEAM_SPECTATOR ) {
			continue;
		}
		if ( client->sess.spectatorClient == self->s.number ) {
			Cmd_Score_f( g_entities + i );
		}
	}

	self->takedamage = qtrue;	// can still be gibbed

	self->s.weapon = WP_NONE;
	self->s.powerups = 0;
	self->r.contents = CONTENTS_CORPSE;

	self->s.angles[0] = 0;
	self->s.angles[2] = 0;
	LookAtKiller (self, inflictor, attacker);

	VectorCopy( self->s.angles, self->client->ps.viewangles );

	self->s.loopSound = 0;

	self->r.maxs[2] = -8;

	// don't allow respawn until the death anim is done
	// g_forcerespawn may force spawning at some later time
	if ( !IsBot(self) )
		self->client->respawnTime = level.time + 1700;
	else
		self->client->respawnTime = level.time + 5000;	//keep bot bodies around slightly longer

	// remove powerups
	memset( self->client->ps.powerups, 0, sizeof(self->client->ps.powerups) );

	// never gib in a nodrop
	if ( (self->health <= GIB_HEALTH && !(contents & CONTENTS_NODROP) && g_blood.integer) || meansOfDeath == MOD_SUICIDE) {
		// gib death
		GibEntity( self, killer );
	} else {
		// normal death
		static int i;

		switch ( i ) {
		case 0:
			anim = BOTH_DEATH1;
			break;
		case 1:
			anim = BOTH_DEATH2;
			break;
		case 2:
		default:
			anim = BOTH_DEATH3;
			break;
		}

		// for the no-blood option, we need to prevent the health
		// from going to gib level
		if ( self->health <= GIB_HEALTH ) {
			self->health = GIB_HEALTH+1;
		}

		self->client->ps.legsAnim = 
			( ( self->client->ps.legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
		self->client->ps.torsoAnim = 
			( ( self->client->ps.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;

		G_AddEvent( self, EV_DEATH1 + i, killer );

		// the body can still be gibbed
		self->die = body_die;

		// globally cycle through the different death animations
		i = ( i + 1 ) % 3;
	}

	trap_LinkEntity (self);

	// Fire trigger_death and trigger_frag target entities and the deathtarget for the related target_botspawn 
	G_UseTriggerFragAndDeathEntities ( self, attacker );
	if ( self->parent )
		G_UseDeathTargets( self->parent, self );

	if ( !IsBot( self ) )
		G_FadeOut( 1.0 );
}
示例#19
0
/*
===============
Touch_Item
===============
*/
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
	int			respawn;
	qboolean	predict;

	if (!other->client)
		return;
	if (other->health < 1)
		return;		// dead people can't pickup
	
	if (IsBot(other->client->ps.clientNum))
		return;		// bots don't pick up items

	// the same pickup rules are used for client side and server side
	if ( !BG_CanItemBeGrabbed( g_gametype.integer, &ent->s, &other->client->ps ) ) {
		return;
	}

	G_LogPrintf( "Item: %i %s\n", other->s.number, ent->item->classname );

	predict = other->client->pers.predictItemPickup;

	// call the item-specific pickup function
	switch( ent->item->giType ) {
	case IT_WEAPON:
		respawn = Pickup_Weapon(ent, other);
//		predict = qfalse;
		break;
	case IT_AMMO:
		respawn = Pickup_Ammo(ent, other);
//		predict = qfalse;
		break;
	case IT_ARMOR:
		respawn = Pickup_Armor(ent, other);
		break;
	case IT_HEALTH:
		respawn = Pickup_Health(ent, other);
		break;
	case IT_POWERUP:
		respawn = Pickup_Powerup(ent, other);
		predict = qfalse;
		break;
#ifdef MISSIONPACK
	case IT_PERSISTANT_POWERUP:
		respawn = Pickup_PersistantPowerup(ent, other);
		break;
#endif
	case IT_TEAM:
		respawn = Pickup_Team(ent, other);
		break;
	case IT_HOLDABLE:
		respawn = Pickup_Holdable(ent, other);
		break;
	default:
		return;
	}

	if ( !respawn ) {
		return;
	}

	// play the normal pickup sound
	if (predict) {
		G_AddPredictableEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	} else {
		G_AddEvent( other, EV_ITEM_PICKUP, ent->s.modelindex );
	}

	// powerup pickups are global broadcasts
	if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) {
		// if we want the global sound to play
		if (!ent->speed) {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			te->r.svFlags |= SVF_BROADCAST;
		} else {
			gentity_t	*te;

			te = G_TempEntity( ent->s.pos.trBase, EV_GLOBAL_ITEM_PICKUP );
			te->s.eventParm = ent->s.modelindex;
			// only send this temp entity to a single client
			te->r.svFlags |= SVF_SINGLECLIENT;
			te->r.singleClient = other->s.number;
		}
	}

	// fire item targets
	G_UseTargets (ent, other);

	// wait of -1 will not respawn
	if ( ent->wait == -1 ) {
		ent->r.svFlags |= SVF_NOCLIENT;
		ent->s.eFlags |= EF_NODRAW;
		ent->r.contents = 0;
		ent->unlinkAfterEvent = qtrue;
		return;
	}

	// non zero wait overrides respawn time
	if ( ent->wait ) {
		respawn = ent->wait;
	}

	// random can be used to vary the respawn time
	if ( ent->random ) {
		respawn += crandom() * ent->random;
		if ( respawn < 1 ) {
			respawn = 1;
		}
	}

	// dropped items will not respawn
	if ( ent->flags & FL_DROPPED_ITEM ) {
		ent->freeAfterEvent = qtrue;
	}

	// picked up items still stay around, they just don't
	// draw anything.  This allows respawnable items
	// to be placed on movers.
	ent->r.svFlags |= SVF_NOCLIENT;
	ent->s.eFlags |= EF_NODRAW;
	ent->r.contents = 0;

	// ZOID
	// A negative respawn times means to never respawn this item (but don't 
	// delete it).  This is used by items that are respawned by third party 
	// events such as ctf flags
	if ( respawn <= 0 ) {
		ent->nextthink = 0;
		ent->think = 0;
	} else {
		ent->nextthink = level.time + respawn * 1000;
		ent->think = RespawnItem;
	}
	trap_LinkEntity( ent );
}
示例#20
0
/*
===========
ClientSpawn

Called every time a client is placed fresh in the world:
after the first ClientBegin, and after each respawn
Initializes all non-persistant parts of playerState
============
*/
void ClientSpawn(gentity_t *ent) {
	int		index;
	vec3_t	spawn_origin, spawn_angles;
	gclient_t	*client;
	int		i;
	clientPersistant_t	saved;
	clientSession_t		savedSess;
	int		persistant[MAX_PERSISTANT];
	gentity_t	*spawnPoint;
	int		flags;
	int		savedPing;
//	char	*savedAreaBits;
	int		accuracy_hits, accuracy_shots;
	int		eventSequence;
	char	userinfo[MAX_INFO_STRING];
	int		weapon;

	index = ent - g_entities;
	client = ent->client;

	// find a spawn point
	// do it before setting health back up, so farthest
	// ranging doesn't count this client
	if ( client->sess.sessionTeam == TEAM_SPECTATOR ) {
		spawnPoint = SelectSpectatorSpawnPoint ( 
						spawn_origin, spawn_angles);
	} else if (g_gametype.integer >= GT_CTF ) {
		// all base oriented team games use the CTF spawn points
		spawnPoint = SelectCTFSpawnPoint ( 
						client->sess.sessionTeam, 
						client->pers.teamState.state, 
						spawn_origin, spawn_angles);
	} else {
		do {
			// the first spawn should be at a good looking spot
			if ( !client->pers.initialSpawn && client->pers.localClient ) {
				client->pers.initialSpawn = qtrue;
				spawnPoint = SelectInitialSpawnPoint( spawn_origin, spawn_angles );
			} else {
				// don't spawn near existing origin if possible
				spawnPoint = SelectSpawnPoint ( 
					client->ps.origin, 
					spawn_origin, spawn_angles);
			}

			// Tim needs to prevent bots from spawning at the initial point
			// on q3dm0...
			if ( ( spawnPoint->flags & FL_NO_BOTS ) && ( ent->r.svFlags & SVF_BOT ) ) {
				continue;	// try again
			}
			// just to be symetric, we have a nohumans option...
			if ( ( spawnPoint->flags & FL_NO_HUMANS ) && !( ent->r.svFlags & SVF_BOT ) ) {
				continue;	// try again
			}

			break;

		} while ( 1 );
	}
	client->pers.teamState.state = TEAM_ACTIVE;

	// always clear the kamikaze flag
	ent->s.eFlags &= ~EF_KAMIKAZE;

	// toggle the teleport bit so the client knows to not lerp
	// and never clear the voted flag
	flags = ent->client->ps.eFlags & (EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED);
	flags ^= EF_TELEPORT_BIT;

	// clear everything but the persistant data

	saved = client->pers;
	savedSess = client->sess;
	savedPing = client->ps.ping;
//	savedAreaBits = client->areabits;
	accuracy_hits = client->accuracy_hits;
	accuracy_shots = client->accuracy_shots;
	for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
		persistant[i] = client->ps.persistant[i];
	}
	eventSequence = client->ps.eventSequence;

	memset (client, 0, sizeof(*client)); // bk FIXME: Com_Memset?

	client->pers = saved;
	client->sess = savedSess;
	client->ps.ping = savedPing;
//	client->areabits = savedAreaBits;
	client->accuracy_hits = accuracy_hits;
	client->accuracy_shots = accuracy_shots;
	client->lastkilled_client = -1;

	for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
		client->ps.persistant[i] = persistant[i];
	}
	client->ps.eventSequence = eventSequence;
	// increment the spawncount so the client will detect the respawn
	client->ps.persistant[PERS_SPAWN_COUNT]++;
	client->ps.persistant[PERS_TEAM] = client->sess.sessionTeam;

	client->airOutTime = level.time + 12000;

	trap_GetUserinfo( index, userinfo, sizeof(userinfo) );
	// set max health
	client->pers.maxHealth = atoi( Info_ValueForKey( userinfo, "handicap" ) );
	if ( client->pers.maxHealth < 1 || client->pers.maxHealth > 100 ) {
		client->pers.maxHealth = 100;
	}
	// clear entity values
	client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;
	client->ps.eFlags = flags;

	ent->s.groundEntityNum = ENTITYNUM_NONE;
	ent->client = &level.clients[index];
	ent->takedamage = qtrue;
	ent->inuse = qtrue;
	ent->classname = "player";
	ent->r.contents = CONTENTS_BODY;
	ent->clipmask = MASK_PLAYERSOLID;
	ent->die = player_die;
	ent->waterlevel = 0;
	ent->watertype = 0;
	ent->flags = 0;
	
	VectorCopy (playerMins, ent->r.mins);
	VectorCopy (playerMaxs, ent->r.maxs);

	client->ps.clientNum = index;


	if (IsBot(client->ps.clientNum)) {
		weapon = WP_LIGHTNING;
		client->ps.stats[STAT_WEAPONS] = ( 1 << weapon );
		client->ps.ammo[weapon] = -1;
	} else {
		weapon = WP_MACHINEGUN;
		client->ps.stats[STAT_WEAPONS] = ( 1 << weapon );
		client->ps.ammo[weapon] = 100;

		client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GAUNTLET );
		client->ps.ammo[WP_GAUNTLET] = -1;
		client->ps.ammo[WP_GRAPPLING_HOOK] = -1;
	}

	// health will count down towards max_health
	ent->health = client->ps.stats[STAT_HEALTH] = client->ps.stats[STAT_MAX_HEALTH] + 25;

	G_SetOrigin( ent, spawn_origin );
	VectorCopy( spawn_origin, client->ps.origin );

	// the respawned flag will be cleared after the attack and jump keys come up
	client->ps.pm_flags |= PMF_RESPAWNED;

	trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd );
	SetClientViewAngle( ent, spawn_angles );

	if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {

	} else {
		G_KillBox( ent );
		trap_LinkEntity (ent);

		// force the base weapon up
		client->ps.weapon = weapon;
		client->ps.weaponstate = WEAPON_READY;

	}

	// don't allow full run speed for a bit
	client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
	client->ps.pm_time = 100;

	client->respawnTime = level.time;
	client->inactivityTime = level.time + g_inactivity.integer * 1000;
	client->latched_buttons = 0;

	// set default animations
	client->ps.torsoAnim = TORSO_STAND;
	client->ps.legsAnim = LEGS_IDLE;

	if ( level.intermissiontime ) {
		MoveClientToIntermission( ent );
	} else {
		// fire the targets of the spawn point
		G_UseTargets( spawnPoint, ent );

		// select the highest weapon number available, after any
		// spawn given items have fired
		client->ps.weapon = weapon;
		for ( i = WP_NUM_WEAPONS - 1 ; i > 0 ; i-- ) {
			if ( client->ps.stats[STAT_WEAPONS] & ( 1 << i ) ) {
				client->ps.weapon = i;
				break;
			}
		}
	}

	// run a client frame to drop exactly to the floor,
	// initialize animations and other things
	client->ps.commandTime = level.time - 100;
	ent->client->pers.cmd.serverTime = level.time;
	ClientThink( ent-g_entities );

	// positively link the client, even if the command times are weird
	if ( ent->client->sess.sessionTeam != TEAM_SPECTATOR ) {
		BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
		VectorCopy( ent->client->ps.origin, ent->r.currentOrigin );
		trap_LinkEntity( ent );
	}

	// run the presend to set anything else
	ClientEndFrame( ent );

	// clear entity state values
	BG_PlayerStateToEntityState( &client->ps, &ent->s, qtrue );
}
示例#21
0
void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
			   vec3_t dir, vec3_t point, int damage, int dflags, int mod ) {
	gclient_t	*client;
	int			take;
	int			save;
	int			asave;
	int			knockback;
	int			max;

	if (!targ->takedamage) {
		return;
	}

	//in entityplus bots cannot harm other bots (unless it's a telefrag)
	if ( IsBot( targ ) && attacker && IsBot( attacker ) && mod != MOD_TELEFRAG )
		return;

	//if attacker is shooter which was configured not to harm target, do nothing
	if ( attacker && strstr(attacker->classname, "shooter_" )) {
		if ( (attacker->spawnflags & 2) && IsBot( targ ) ) //spawnflags 2 == NO_BOTS
			return;
		if ( (attacker->spawnflags & 4) && !IsBot( targ ) ) //spawnflag 4 = NO_HUMANS
			return;
	}

	// the intermission has allready been qualified for, so don't
	// allow any extra scoring
	if ( level.intermissionQueued ) {
		return;
	}

	if ( !inflictor ) {
		inflictor = &g_entities[ENTITYNUM_WORLD];
	}
	if ( !attacker ) {
		attacker = &g_entities[ENTITYNUM_WORLD];
	}


	// shootable doors / buttons don't actually have any health
	if ( targ->s.eType == ET_MOVER ) {
		if ( strcmp(targ->classname, "func_breakable") && targ->use && (targ->moverState == MOVER_POS1 || targ->moverState == ROTATOR_POS1) ) {
			targ->use( targ, inflictor, attacker );
		} else {	// entity is a func_breakable
			if ( (targ->spawnflags & 1024) && attacker == level.player )
				return;
			if ( (targ->spawnflags & 2048) && IsBot(attacker) )
				return;
			if ( (targ->spawnflags & 4096) && strstr(attacker->classname, "shooter_") )
				return;
			
			if ( !strcmp(targ->classname, "func_breakable") ) {
				targ->health -= damage;
				if ( targ->health <= 0 )
					Break_Breakable(targ, attacker);
			}
		}
		return;
	}

	// scale back damage from bots or shooters to humans in single player, based on skill level
	// "I can win" does 0.05 dmg
	// "Bring it on" does 0.15 dmg
	// "Hurt me plenty" does 0.25 dmg
	// "Hardcore" does 0.35 dmg
	// "Nightmare does 0.45 dmg
	if ( 
		attacker && (
			IsBot(attacker) || 
			!strcmp(attacker->classname, "shooter_bfg") || 
			!strcmp(attacker->classname, "shooter_grenade") || 
			!strcmp(attacker->classname, "shooter_plasma") || 
			!strcmp(attacker->classname, "shooter_rocket") 
		)
	) {
		float skill = trap_Cvar_VariableValue( "g_spSkill" );
		int orgdmg = damage;

		if ( attacker->parent && attacker->parent->skill )
			skill += attacker->parent->skill;

		if (skill < 1)
			skill = 1;	//relative skill level should not drop below 1 but is allowed to rise above 5
		
		damage *= ( ( 0.1 * skill  ) - 0.05 ); //damage is always rounded down.
		
		if ( damage < 1 )
			damage = 1;	//make sure bot does at least -some- damage

		//G_Printf("skill: %f -- mp: %f -- orgdmg: %i -- dmg: %i\n", skill, ( 0.1 * skill  ) - 0.05, orgdmg, damage);
	}

	client = targ->client;

	if ( client ) {
		if ( client->noclip ) {
			return;
		}
	}

	if ( !dir ) {
		dflags |= DAMAGE_NO_KNOCKBACK;
	} else {
		VectorNormalize(dir);
	}

	knockback = damage;
	if ( knockback > 200 ) {
		knockback = 200;
	}
	if ( targ->flags & FL_NO_KNOCKBACK ) {
		knockback = 0;
	}
	if ( dflags & DAMAGE_NO_KNOCKBACK ) {
		knockback = 0;
	}

	// figure momentum add, even if the damage won't be taken
	if ( knockback && targ->client ) {
		vec3_t	kvel;
		float	mass;

		mass = 200;

		VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
		VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);

		// set the timer so that the other client can't cancel
		// out the movement immediately
		if ( !targ->client->ps.pm_time ) {
			int		t;

			t = knockback * 2;
			if ( t < 50 ) {
				t = 50;
			}
			if ( t > 200 ) {
				t = 200;
			}
			targ->client->ps.pm_time = t;
			targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
		}
	}

	// check for completely getting out of the damage
	if ( !(dflags & DAMAGE_NO_PROTECTION) ) {

		// if TF_NO_FRIENDLY_FIRE is set, don't do damage to the target
		// if the attacker was on the same team
		if ( targ != attacker && OnSameTeam (targ, attacker)  ) {
			if ( !g_friendlyFire.integer ) {
				return;
			}
		}

		// check for godmode
		if ( targ->flags & FL_GODMODE ) {
			return;
		}
	}

	// battlesuit protects from all radius damage (but takes knockback)
	// and protects 50% against all damage
	if ( client && client->ps.powerups[PW_BATTLESUIT] ) {
		G_AddEvent( targ, EV_POWERUP_BATTLESUIT, 0 );
		if ( ( dflags & DAMAGE_RADIUS ) || ( mod == MOD_FALLING ) ) {
			return;
		}
		damage *= 0.5;
	}

	// add to the attacker's hit counter (if the target isn't a general entity like a prox mine)
	if ( attacker->client && targ != attacker && targ->health > 0
			&& targ->s.eType != ET_MISSILE
			&& targ->s.eType != ET_GENERAL) {
		if ( OnSameTeam( targ, attacker ) ) {
			attacker->client->ps.persistant[PERS_HITS]--;
		} else {
			attacker->client->ps.persistant[PERS_HITS]++;
		}
		attacker->client->ps.persistant[PERS_ATTACKEE_ARMOR] = (targ->health<<8)|(client->ps.stats[STAT_ARMOR]);
	}

	// always give half damage if hurting self
	// calculated after knockback, so rocket jumping works
	if ( targ == attacker) {
		damage *= 0.5;
	}

	if ( damage < 1 ) {
		damage = 1;
	}
	take = damage;
	save = 0;

	// save some from armor
	asave = CheckArmor (targ, take, dflags);
	take -= asave;

	if ( g_debugDamage.integer ) {
		G_Printf( "%i: client:%i health:%i damage:%i armor:%i\n", level.time, targ->s.number,
			targ->health, take, asave );
	}

	// add to the damage inflicted on a player this frame
	// the total will be turned into screen blends and view angle kicks
	// at the end of the frame
	if ( client ) {
		if ( attacker ) {
			client->ps.persistant[PERS_ATTACKER] = attacker->s.number;
		} else {
			client->ps.persistant[PERS_ATTACKER] = ENTITYNUM_WORLD;
		}
		client->damage_armor += asave;
		client->damage_blood += take;
		client->damage_knockback += knockback;
		if ( dir ) {
			VectorCopy ( dir, client->damage_from );
			client->damage_fromWorld = qfalse;
		} else {
			VectorCopy ( targ->r.currentOrigin, client->damage_from );
			client->damage_fromWorld = qtrue;
		}
	}

	if (targ->client) {
		// set the last client who damaged the target
		targ->client->lasthurt_client = attacker->s.number;
		targ->client->lasthurt_mod = mod;
	}

	// do the damage
	if (take) {
		if ( g_mutators.integer & MT_INSTAGIB && IsBot( targ ) )
			targ->health = -999;
		else
			targ->health = targ->health - take;

		if ( targ->client ) {
			targ->client->ps.stats[STAT_HEALTH] = targ->health;
		}
			
		if ( targ->health <= 0 ) {
			if ( client )
				targ->flags |= FL_NO_KNOCKBACK;

			if (targ->health < -999)
				targ->health = -999;

			targ->enemy = attacker;
			targ->die (targ, inflictor, attacker, take, mod);
			return;
		} else if ( targ->pain ) {
			targ->pain (targ, attacker, take);
		}
	}
}
示例#22
0
void Ports::Set(Ports pP) {
	(*this) = pP;
	IsBot(false);
}
示例#23
0
bool CClient::MessageWrite(void *p)
{
   // return true when the message is handled, false if not.
   static int iState, iId;

   int iMsgType = g_pServer->GetCurMsgType();
   int iMsgState = g_pServer->GetCurMsgState();

   CBaseBot *pBot = NULL;
   if (IsBot()) {
      pBot = dynamic_cast<CBaseBot *>(this);
   }

   // we don't like hundreds of strcmp()'s when one message gets sent
   // so cache them here...
   static int message_CurWeapon = -1;
   static int message_AmmoX = -1;
   static int message_Damage = -1;

   if (message_CurWeapon == -1) {
      message_CurWeapon = g_General.GetUserMsgId("CurWeapon");
      message_AmmoX = g_General.GetUserMsgId("AmmoX");
      message_Damage = g_General.GetUserMsgId("Damage");
   }

   if (iMsgType == message_CurWeapon) {
      if (iMsgState == 0)
         iState = *(int *)p; // get the state of the current weapon
      else if (iMsgState == 1)
         iId = *(int *)p; // get the weapon ID of current weapon
      else if (iMsgState == 2) {
         int iClip = *(int *)p; // get the ammo currently in the clip for this weapon
         if (iId >= 0 && iId < MAX_WEAPONS) {
            // Ammo amount decreased? Must have fired a bullet...
            if (iId == m_iCurrentWeaponId && iClip < m_rgAmmoInClip[iId])
               m_flLastShootTime = gpGlobals->time; // remember the last bullet time
            m_rgAmmoInClip[iId] = iClip;
            if (iState != 0)
               m_iCurrentWeaponId = iId;
         }
      }
   } else if (iMsgType == message_AmmoX) {
      if (iMsgState == 0)
         iId = *(int *)p; // get the ammo index (for knowing what type of ammo it is)
      else if (iMsgState == 1)
         if (iId >= 0 && iId < MAX_AMMO_SLOTS)
            m_rgAmmo[iId] = *(int *)p; // amount of ammo currently available
   } else if (iMsgType == message_Damage) {
      // This message gets sent when the client is getting damaged
      // only proceed if this is a bot
      if (IsBot()) {
         assert(pBot != NULL);

         static int damage_armor;
         static int damage_taken;
         static int damage_bits;
         static Vector damage_origin;

         if (iMsgState == 0) {
            damage_armor = *(int *)p; // get the amount of damage inflicted to armor
         } else if (iMsgState == 1) {
            damage_taken = *(int *)p; // get the amount of damage inflicted to health
         } else if (iMsgState == 2) {
            damage_bits = *(int *)p; // get the type of damage it is (bullet, fall, heat, etc...)
         } else if (iMsgState == 3) {
            damage_origin.x = *(float *)p; // get the x coordinate of the damage origin vector
         } else if (iMsgState == 4) {
            damage_origin.y = *(float *)p; // get the y coordinate of the damage origin vector
         } else if (iMsgState == 5) {
            damage_origin.z = *(float *)p; // get the z coordinate of the damage origin vector

            // If bot is damaged...
            if (damage_armor > 0 || damage_taken > 0) {
               pBot->TakeDamage(GetDamageInflictor(), damage_origin,
                  damage_taken, damage_armor, damage_bits);
            }
         }
      }
   } else {
      return false;
   }

   return true;
}
示例#24
0
void Ports::AddPort(std::string pName, Interface pIf) {
	mPorts[pName] = pIf;
	IsBot(false);
}
示例#25
0
/* Rewritten by Run - 24 sept 94 */
static void exit_one_client(struct Client* bcptr, const char* comment)
{
  struct SLink *lp;
  struct Ban *bp;

  if (cli_serv(bcptr) && cli_serv(bcptr)->client_list)  /* Was SetServerYXX called ? */
    ClearServerYXX(bcptr);      /* Removes server from server_list[] */
  if (IsUser(bcptr)) {
    /*
     * clear out uping requests
     */
    if (IsUPing(bcptr))
      uping_cancel(bcptr, 0);
    /*
     * Stop a running /LIST clean
     */
    if (MyUser(bcptr) && cli_listing(bcptr)) {
      MyFree(cli_listing(bcptr));
      cli_listing(bcptr) = NULL;
    }
    /*
     * If a person is on a channel, send a QUIT notice
     * to every client (person) on the same channel (so
     * that the client can show the "**signoff" message).
     * (Note: The notice is to the local clients *only*)
     */
    sendcmdto_common_channels_butone(bcptr, CMD_QUIT, NULL, ":%s", comment);

    remove_user_from_all_channels(bcptr);

    /* Clean up invitefield */
    while ((lp = cli_user(bcptr)->invited))
      del_invite(bcptr, lp->value.chptr);

    /* Clean up silencefield */
    while ((bp = cli_user(bcptr)->silence)) {
      cli_user(bcptr)->silence = bp->next;
      free_ban(bp);
    }

    /* Clean up smarks field */
    del_marks(bcptr);

    /* Clean up watch lists */
    if (MyUser(bcptr))
      del_list_watch(bcptr);
    /* Notify Logout */
    check_status_watch(bcptr, RPL_LOGOFF);

    /* Clean up snotice lists */
    if (MyUser(bcptr))
      set_snomask(bcptr, ~0, SNO_DEL);

    if (IsInvisible(bcptr)) {
      assert(UserStats.inv_clients > 0);
      --UserStats.inv_clients;
    }
    if (IsOper(bcptr) && !IsHideOper(bcptr) && !IsChannelService(bcptr) && !IsBot(bcptr)) {
      assert(UserStats.opers > 0);
      --UserStats.opers;
    }
    if (MyConnect(bcptr))
      Count_clientdisconnects(bcptr, UserStats);
    else
      Count_remoteclientquits(UserStats, bcptr);
  }
  else if (IsServer(bcptr))
  {
    /* Remove downlink list node of uplink */
    remove_dlink(&(cli_serv(cli_serv(bcptr)->up))->down, cli_serv(bcptr)->updown);
    cli_serv(bcptr)->updown = 0;

    if (MyConnect(bcptr))
      Count_serverdisconnects(UserStats);
    else
      Count_remoteserverquits(UserStats);
  }
  else if (IsMe(bcptr))
  {
    sendto_opmask_butone(0, SNO_OLDSNO, "ERROR: tried to exit me! : %s",
			 comment);
    return;                     /* ...must *never* exit self! */
  }
  else if (IsUnknown(bcptr) || IsConnecting(bcptr) || IsHandshake(bcptr))
    Count_unknowndisconnects(UserStats);

  /*
   * Update IPregistry
   */
  if (IsIPChecked(bcptr))
    IPcheck_disconnect(bcptr);

  /* 
   * Remove from serv->client_list
   * NOTE: user is *always* NULL if this is a server
   */
  if (cli_user(bcptr)) {
    assert(!IsServer(bcptr));
    /* bcptr->user->server->serv->client_list[IndexYXX(bcptr)] = NULL; */
    RemoveYXXClient(cli_user(bcptr)->server, cli_yxx(bcptr));
  }

  /* Remove bcptr from the client list */
#ifdef DEBUGMODE
  if (hRemClient(bcptr) != 0)
    Debug((DEBUG_ERROR, "%p !in tab %s[%s] %p %p %p %d %d %p",
          bcptr, cli_name(bcptr), cli_from(bcptr) ? cli_sockhost(cli_from(bcptr)) : "??host",
          cli_from(bcptr), cli_next(bcptr), cli_prev(bcptr), cli_fd(bcptr),
          cli_status(bcptr), cli_user(bcptr)));
#else
  hRemClient(bcptr);
#endif
  remove_client_from_list(bcptr);
}