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); }
// 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); }
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(); } }
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); }
/* ================= 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 ); }
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; } } }
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; }
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; } } }
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; }
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 ); }
/* ================ 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; }
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" ); }
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) ; }
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); }
/* ================== 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 ); }
/* =============== 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 ); }
/* =========== 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 ); }
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); } } }
void Ports::Set(Ports pP) { (*this) = pP; IsBot(false); }
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; }
void Ports::AddPort(std::string pName, Interface pIf) { mPorts[pName] = pIf; IsBot(false); }
/* 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); }