// edicts get reallocated on level changes, so we need to update it here
client->edict = EDICT_NUM((client - svs.clients) + 1);
+ // if client is a botclient coming from a level change, we need to set up
+ // client info that normally requires networking
+ if (!client->netconnection)
+ {
+ int i;
+
+ // set up the edict
+ ED_ClearEdict(client->edict);
+
+ // copy spawn parms out of the client_t
+ for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
+ (&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
+
+ // call the spawn function
+ pr_global_struct->time = sv.time;
+ pr_global_struct->self = EDICT_TO_PROG(client->edict);
+ PR_ExecuteProgram (pr_global_struct->ClientConnect, "QC function ClientConnect is missing");
+ PR_ExecuteProgram (pr_global_struct->PutClientInServer, "QC function PutClientInServer is missing");
+ host_client->spawned = true;
+ return;
+ }
// LordHavoc: clear entityframe tracking
client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
}
- SV_SendServerinfo (client);
+ // don't call SendServerinfo for a fresh botclient because its fields have
+ // not been set up by the qc yet
+ if (client->netconnection)
+ SV_SendServerinfo (client);
+ else
+ client->spawned = true;
}
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
{
// update the host_client fields we care about according to the entity fields
- sv_player = EDICT_NUM(i+1);
+ host_client->edict = EDICT_NUM(i+1);
// DP_SV_CLIENTNAME
- name = PR_GetString(sv_player->v->netname);
+ name = PR_GetString(host_client->edict->v->netname);
if (name == NULL)
name = "";
// always point the string back at host_client->name to keep it safe
strlcpy (host_client->name, name, sizeof (host_client->name));
- sv_player->v->netname = PR_SetString(host_client->name);
+ host_client->edict->v->netname = PR_SetString(host_client->name);
if (strcmp(host_client->old_name, host_client->name))
{
if (host_client->spawned)
// DP_SV_CLIENTCOLORS
// this is always found (since it's added by the progs loader)
- if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)))
+ if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
host_client->colors = (int)val->_float;
if (host_client->old_colors != host_client->colors)
{
}
// frags
- host_client->frags = (int)sv_player->v->frags;
+ host_client->frags = (int)host_client->edict->v->frags;
if (host_client->old_frags != host_client->frags)
{
host_client->old_frags = host_client->frags;
ent->v = (void *)((qbyte *)sv.edictsfields + i * pr_edict_size);
}
+ // fix up client->edict pointers for returning clients right away...
+ for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+ host_client->edict = EDICT_NUM(i + 1);
+
sv.datagram.maxsize = sizeof(sv.datagram_buf);
sv.datagram.cursize = 0;
sv.datagram.data = sv.datagram_buf;
SV_CreateBaseline ();
// send serverinfo to all connected clients
+ // (note this also handles botclients coming back from a level change)
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
if (host_client->active)
SV_SendServerinfo(host_client);