/*
===============
G_AddBot
===============
*/
static void G_AddBot( const char *name, float skill, const char *team, int delay, char *altname) {
int clientNum;
char *botinfo;
gentity_t *bot;
char *key;
char *s;
char *botname;
char *model;
// char *headmodel;
char userinfo[MAX_INFO_STRING];
// get the botinfo from bots.txt
botinfo = G_GetBotInfoByName( name );
if ( !botinfo ) {
G_Printf( S_COLOR_RED "Error: Bot '%s' not defined\n", name );
return;
}
// create the bot's userinfo
userinfo[0] = '\0';
botname = Info_ValueForKey( botinfo, "funname" );
if( !botname[0] ) {
botname = Info_ValueForKey( botinfo, "name" );
}
// check for an alternative name
if (altname && altname[0]) {
botname = altname;
}
Info_SetValueForKey( userinfo, "name", botname );
Info_SetValueForKey( userinfo, "rate", "25000" );
Info_SetValueForKey( userinfo, "snaps", "20" );
Info_SetValueForKey( userinfo, "skill", va("%1.2f", skill) );
/*
if ( skill >= 1 && skill < 2 ) {
Info_SetValueForKey( userinfo, "handicap", "50" );
}
else if ( skill >= 2 && skill < 3 ) {
Info_SetValueForKey( userinfo, "handicap", "70" );
}
else if ( skill >= 3 && skill < 4 ) {
Info_SetValueForKey( userinfo, "handicap", "90" );
}
*/
key = "model";
model = Info_ValueForKey( botinfo, key );
if ( !*model ) {
model = "visor/default";
}
Info_SetValueForKey( userinfo, key, model );
key = "team_model";
Info_SetValueForKey( userinfo, key, model );
/* key = "headmodel";
headmodel = Info_ValueForKey( botinfo, key );
if ( !*headmodel ) {
headmodel = model;
}
Info_SetValueForKey( userinfo, key, headmodel );
key = "team_headmodel";
Info_SetValueForKey( userinfo, key, headmodel );
*/
key = "gender";
s = Info_ValueForKey( botinfo, key );
if ( !*s ) {
s = "male";
}
Info_SetValueForKey( userinfo, "sex", s );
key = "color1";
s = Info_ValueForKey( botinfo, key );
if ( !*s ) {
s = "4";
}
Info_SetValueForKey( userinfo, key, s );
key = "color2";
s = Info_ValueForKey( botinfo, key );
if ( !*s ) {
s = "5";
}
Info_SetValueForKey( userinfo, key, s );
s = Info_ValueForKey(botinfo, "personality");
if (!*s )
{
Info_SetValueForKey( userinfo, "personality", "botfiles/default.jkb" );
}
else
{
Info_SetValueForKey( userinfo, "personality", s );
}
//.........这里部分代码省略.........
开发者ID:aufau,项目名称:SaberMod,代码行数:101,代码来源:g_bot.c
示例6: ClientUserinfoChanged
/*
===========
ClientUserInfoChanged
Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.
The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void ClientUserinfoChanged(int clientNum) {
gentity_t *ent;
char *s;
char oldname[MAX_STRING_CHARS];
char userinfo[MAX_INFO_STRING];
gclient_t *client;
char *ip = NULL; // Nico, used to store client ip
char *rate = NULL; // Nico, used to store client rate
char *snaps = NULL; // Nico, used to store client snaps
char *name = NULL; // Nico, used to store client name
char oldAuthToken[MAX_QPATH]; // Nico, used to see if auth token was changed
ent = g_entities + clientNum;
client = ent->client;
client->ps.clientNum = clientNum;
// Nico, flood protection
if (ClientIsFlooding(ent)) {
G_LogPrintf("Dropping client %d: flooded userinfo\n", clientNum);
trap_DropClient(clientNum, "^1You were kicked because of flooded userinfo", 0);
return;
}
trap_GetUserinfo(clientNum, userinfo, sizeof (userinfo));
// Nico, perform security checks on userinfo string
if (!checkUserinfoString(clientNum, userinfo)) {
return;
}
if (g_developer.integer || *g_log.string || g_dedicated.integer) {
G_Printf("Userinfo: %s\n", userinfo);
}
// check for local client
ip = Info_ValueForKey(userinfo, "ip");
Q_strncpyz(client->pers.ip, ip, IP_MAX_LENGTH);
if (ip && !strcmp(ip, "localhost")) {
client->pers.localClient = qtrue;
level.fLocalHost = qtrue;
client->sess.referee = RL_REFEREE;
}
// Nico, store rate and snaps
rate = Info_ValueForKey(userinfo, "rate");
client->pers.rate = atoi(rate);
snaps = Info_ValueForKey(userinfo, "snaps");
client->pers.snaps = atoi(snaps);
// Nico, backup old auth token
Q_strncpyz(oldAuthToken, client->pers.authToken, sizeof (oldAuthToken));
s = Info_ValueForKey(userinfo, "cg_uinfo");
sscanf(s, "%i %i %i %i %s %i %i %i %i %i %i %i %i %i",
&client->pers.clientFlags,
&client->pers.clientTimeNudge,
&client->pers.clientMaxPackets,
// Nico, max FPS
&client->pers.maxFPS,
// Nico, auth Token
(char *)&client->pers.authToken,
// Nico, load view angles on load
&client->pers.loadViewAngles,
// Nico, load weapon on load
&client->pers.loadWeapon,
// Nico, load position when player dies
&client->pers.autoLoad,
// Nico, cgaz
&client->pers.cgaz,
// Nico, hideme
&client->pers.hideme,
// Nico, client auto demo record setting
&client->pers.autoDemo,
// Nico, automatically load checkpoints
&client->pers.autoLoadCheckpoints,
// Nico, persistant specLock
(int *)&client->sess.specLocked,
//.........这里部分代码省略.........
//.........这里部分代码省略.........
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 && 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 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;
}
}
// see if it's the player hurting the emeny flag carrier
#ifdef MISSIONPACK
if (g_gametype.integer == GT_CTF || g_gametype.integer == GT_1FCTF) {
#else
if (g_gametype.integer == GT_CTF) {
#endif
Team_CheckHurtCarrier(targ, attacker);
}
if (targ->client) {
//KK-OAX This was moved from g_mem.c to keep functionality from being broken.
void Svcmd_GameMem_f( void ) {
int usedMem;
usedMem = POOLSIZE - freeMem;
G_Printf( "Game memory status: %i out of %i bytes allocated\n", usedMem, POOLSIZE );
}
void
G_Say(Gentity *ent, Gentity *target, int mode, const char *chatText)
{
int j;
Gentity *other;
int color;
char name[64];
/* don't let text be too long for malicious reasons */
char text[MAX_SAY_TEXT];
char location[64];
if(g_gametype.integer < GT_TEAM && mode == SAY_TEAM)
mode = SAY_ALL;
switch(mode){
default:
case SAY_ALL:
G_LogPrintf("say: %s: %s\n", ent->client->pers.netname, chatText);
Q_sprintf (name, sizeof(name), "%s%c%c"EC ": ",
ent->client->pers.netname, Q_COLOR_ESCAPE,
COLOR_WHITE);
color = COLOR_GREEN;
break;
case SAY_TEAM:
G_LogPrintf("sayteam: %s: %s\n", ent->client->pers.netname,
chatText);
if(Team_GetLocationMsg(ent, location, sizeof(location)))
Q_sprintf (name, sizeof(name),
EC "(%s%c%c"EC ") (%s)"EC ": ",
ent->client->pers.netname, Q_COLOR_ESCAPE,
COLOR_WHITE,
location);
else
Q_sprintf (name, sizeof(name),
EC "(%s%c%c"EC ")"EC ": ",
ent->client->pers.netname, Q_COLOR_ESCAPE,
COLOR_WHITE);
color = COLOR_CYAN;
break;
case SAY_TELL:
if(target && g_gametype.integer >= GT_TEAM &&
target->client->sess.team ==
ent->client->sess.team &&
Team_GetLocationMsg(ent, location, sizeof(location)))
Q_sprintf (name, sizeof(name),
EC "[%s%c%c"EC "] (%s)"EC ": ",
ent->client->pers.netname,
Q_COLOR_ESCAPE, COLOR_WHITE,
location);
else
Q_sprintf (name, sizeof(name),
EC "[%s%c%c"EC "]"EC ": ",
ent->client->pers.netname,
Q_COLOR_ESCAPE,
COLOR_WHITE);
color = COLOR_MAGENTA;
break;
}
Q_strncpyz(text, chatText, sizeof(text));
if(target){
G_SayTo(ent, target, mode, color, name, text);
return;
}
/* echo the text to the console */
if(g_dedicated.integer)
G_Printf("%s%s\n", name, text);
/* send it to all the apropriate clients */
for(j = 0; j < level.maxclients; j++){
other = &g_entities[j];
G_SayTo(ent, other, mode, color, name, text);
}
}
开发者ID:icanhas,项目名称:yantar,代码行数:76,代码来源:cmds.c
示例13: FinishSpawningItem
/*
================
FinishSpawningItem
Traces down to find where an item should rest, instead of letting them
free fall from their spawn points
================
*/
void FinishSpawningItem(gentity_t *ent)
{
trace_t tr;
vec3_t dest;
vec3_t maxs;
if (ent->spawnflags & 1) // suspended
{
VectorSet(ent->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS);
VectorSet(ent->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);
VectorCopy(ent->r.maxs, maxs);
}
else
{
// had to modify this so that items would spawn in shelves
VectorSet(ent->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, 0);
VectorSet(ent->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);
VectorCopy(ent->r.maxs, maxs);
maxs[2] /= 2;
}
ent->r.contents = CONTENTS_TRIGGER | CONTENTS_ITEM;
ent->touch = Touch_Item_Auto;
ent->s.eType = ET_ITEM;
ent->s.modelindex = ent->item - bg_itemlist; // store item number in modelindex
ent->s.otherEntityNum2 = 0; // takes modelindex2's place in signaling a dropped item
// we don't use this (yet, anyway) so I'm taking it so you can specify a model for treasure items and clipboards
//ent->s.modelindex2 = 0; // zero indicates this isn't a dropped item
if (ent->model)
{
ent->s.modelindex2 = G_ModelIndex(ent->model);
}
// using an item causes it to respawn
ent->use = Use_Item;
// moved this up so it happens for suspended items too (and made it a function)
G_SetAngle(ent, ent->s.angles);
if (ent->spawnflags & 1) // suspended
{
G_SetOrigin(ent, ent->s.origin);
}
else
{
VectorSet(dest, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] - 4096);
trap_Trace(&tr, ent->s.origin, ent->r.mins, maxs, dest, ent->s.number, MASK_SOLID);
if (tr.startsolid)
{
vec3_t temp;
VectorCopy(ent->s.origin, temp);
temp[2] -= ITEM_RADIUS;
VectorSet(dest, ent->s.origin[0], ent->s.origin[1], ent->s.origin[2] - 4096);
trap_Trace(&tr, temp, ent->r.mins, maxs, dest, ent->s.number, MASK_SOLID);
}
if (tr.startsolid)
{
G_Printf("FinishSpawningItem: %s startsolid at %s\n", ent->classname, vtos(ent->s.origin));
G_FreeEntity(ent);
return;
}
// allow to ride movers
ent->s.groundEntityNum = tr.entityNum;
G_SetOrigin(ent, tr.endpos);
}
if (ent->spawnflags & 2) // spin
{
ent->s.eFlags |= EF_SPINNING;
}
// team slaves and targeted items aren't present at start
if ((ent->flags & FL_TEAMSLAVE) || ent->targetname)
{
ent->flags |= FL_NODRAW;
//ent->s.eFlags |= EF_NODRAW;
ent->r.contents = 0;
return;
}
// health/ammo can potentially be multi-stage (multiple use)
if (ent->item->giType == IT_HEALTH || ent->item->giType == IT_AMMO)
{
int i;
//.........这里部分代码省略.........
请发表评论