git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / sv_main.c
blob5f443bd3f37b4c376835e74ed2bf53c6e470a1fc
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // sv_main.c -- server main program
22 #include "quakedef.h"
24 server_t sv;
25 server_static_t svs;
27 char localmodels[MAX_MODELS][5]; // inline model names for precache
29 //============================================================================
32 ===============
33 SV_Init
34 ===============
36 void SV_Init (void)
38 int i;
39 extern cvar_t sv_maxvelocity;
40 extern cvar_t sv_gravity;
41 extern cvar_t sv_nostep;
42 extern cvar_t sv_friction;
43 extern cvar_t sv_edgefriction;
44 extern cvar_t sv_stopspeed;
45 extern cvar_t sv_maxspeed;
46 extern cvar_t sv_accelerate;
47 extern cvar_t sv_idealpitchscale;
48 extern cvar_t sv_aim;
50 Cvar_RegisterVariable (&sv_maxvelocity);
51 Cvar_RegisterVariable (&sv_gravity);
52 Cvar_RegisterVariable (&sv_friction);
53 Cvar_RegisterVariable (&sv_edgefriction);
54 Cvar_RegisterVariable (&sv_stopspeed);
55 Cvar_RegisterVariable (&sv_maxspeed);
56 Cvar_RegisterVariable (&sv_accelerate);
57 Cvar_RegisterVariable (&sv_idealpitchscale);
58 Cvar_RegisterVariable (&sv_aim);
59 Cvar_RegisterVariable (&sv_nostep);
61 for (i=0 ; i<MAX_MODELS ; i++)
62 sprintf (localmodels[i], "*%i", i);
66 =============================================================================
68 EVENT MESSAGES
70 =============================================================================
74 ==================
75 SV_StartParticle
77 Make sure the event gets sent to all clients
78 ==================
80 void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
82 int i, v;
84 if (sv.datagram.cursize > MAX_DATAGRAM-16)
85 return;
86 MSG_WriteByte (&sv.datagram, svc_particle);
87 MSG_WriteCoord (&sv.datagram, org[0]);
88 MSG_WriteCoord (&sv.datagram, org[1]);
89 MSG_WriteCoord (&sv.datagram, org[2]);
90 for (i=0 ; i<3 ; i++)
92 v = dir[i]*16;
93 if (v > 127)
94 v = 127;
95 else if (v < -128)
96 v = -128;
97 MSG_WriteChar (&sv.datagram, v);
99 MSG_WriteByte (&sv.datagram, count);
100 MSG_WriteByte (&sv.datagram, color);
104 ==================
105 SV_StartSound
107 Each entity can have eight independant sound sources, like voice,
108 weapon, feet, etc.
110 Channel 0 is an auto-allocate channel, the others override anything
111 allready running on that entity/channel pair.
113 An attenuation of 0 will play full volume everywhere in the level.
114 Larger attenuations will drop off. (max 4 attenuation)
116 ==================
118 void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
119 float attenuation)
121 int sound_num;
122 int field_mask;
123 int i;
124 int ent;
126 if (volume < 0 || volume > 255)
127 Sys_Error ("SV_StartSound: volume = %i", volume);
129 if (attenuation < 0 || attenuation > 4)
130 Sys_Error ("SV_StartSound: attenuation = %f", attenuation);
132 if (channel < 0 || channel > 7)
133 Sys_Error ("SV_StartSound: channel = %i", channel);
135 if (sv.datagram.cursize > MAX_DATAGRAM-16)
136 return;
138 // find precache number for sound
139 for (sound_num=1 ; sound_num<MAX_SOUNDS
140 && sv.sound_precache[sound_num] ; sound_num++)
141 if (!strcmp(sample, sv.sound_precache[sound_num]))
142 break;
144 if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] )
146 Con_Printf ("SV_StartSound: %s not precacheed\n", sample);
147 return;
150 ent = NUM_FOR_EDICT(entity);
152 channel = (ent<<3) | channel;
154 field_mask = 0;
155 if (volume != DEFAULT_SOUND_PACKET_VOLUME)
156 field_mask |= SND_VOLUME;
157 if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
158 field_mask |= SND_ATTENUATION;
160 // directed messages go only to the entity the are targeted on
161 MSG_WriteByte (&sv.datagram, svc_sound);
162 MSG_WriteByte (&sv.datagram, field_mask);
163 if (field_mask & SND_VOLUME)
164 MSG_WriteByte (&sv.datagram, volume);
165 if (field_mask & SND_ATTENUATION)
166 MSG_WriteByte (&sv.datagram, attenuation*64);
167 MSG_WriteShort (&sv.datagram, channel);
168 MSG_WriteByte (&sv.datagram, sound_num);
169 for (i=0 ; i<3 ; i++)
170 MSG_WriteCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]));
174 ==============================================================================
176 CLIENT SPAWNING
178 ==============================================================================
182 ================
183 SV_SendServerinfo
185 Sends the first message from the server to a connected client.
186 This will be sent on the initial connection and upon each server load.
187 ================
189 void SV_SendServerinfo (client_t *client)
191 char **s;
192 char message[2048];
194 MSG_WriteByte (&client->message, svc_print);
195 sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc);
196 MSG_WriteString (&client->message,message);
198 MSG_WriteByte (&client->message, svc_serverinfo);
199 MSG_WriteLong (&client->message, PROTOCOL_VERSION);
200 MSG_WriteByte (&client->message, svs.maxclients);
202 if (!coop.value && deathmatch.value)
203 MSG_WriteByte (&client->message, GAME_DEATHMATCH);
204 else
205 MSG_WriteByte (&client->message, GAME_COOP);
207 sprintf (message, pr_strings+sv.edicts->v.message);
209 MSG_WriteString (&client->message,message);
211 for (s = sv.model_precache+1 ; *s ; s++)
212 MSG_WriteString (&client->message, *s);
213 MSG_WriteByte (&client->message, 0);
215 for (s = sv.sound_precache+1 ; *s ; s++)
216 MSG_WriteString (&client->message, *s);
217 MSG_WriteByte (&client->message, 0);
219 // send music
220 MSG_WriteByte (&client->message, svc_cdtrack);
221 MSG_WriteByte (&client->message, sv.edicts->v.sounds);
222 MSG_WriteByte (&client->message, sv.edicts->v.sounds);
224 // set view
225 MSG_WriteByte (&client->message, svc_setview);
226 MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict));
228 MSG_WriteByte (&client->message, svc_signonnum);
229 MSG_WriteByte (&client->message, 1);
231 client->sendsignon = true;
232 client->spawned = false; // need prespawn, spawn, etc
236 ================
237 SV_ConnectClient
239 Initializes a client_t for a new net connection. This will only be called
240 once for a player each game, not once for each level change.
241 ================
243 void SV_ConnectClient (int clientnum)
245 edict_t *ent;
246 client_t *client;
247 int edictnum;
248 struct qsocket_s *netconnection;
249 int i;
250 float spawn_parms[NUM_SPAWN_PARMS];
252 client = svs.clients + clientnum;
254 Con_DPrintf ("Client %s connected\n", client->netconnection->address);
256 edictnum = clientnum+1;
258 ent = EDICT_NUM(edictnum);
260 // set up the client_t
261 netconnection = client->netconnection;
263 if (sv.loadgame)
264 memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms));
265 memset (client, 0, sizeof(*client));
266 client->netconnection = netconnection;
268 strcpy (client->name, "unconnected");
269 client->active = true;
270 client->spawned = false;
271 client->edict = ent;
272 client->message.data = client->msgbuf;
273 client->message.maxsize = sizeof(client->msgbuf);
274 client->message.allowoverflow = true; // we can catch it
276 #ifdef IDGODS
277 client->privileged = IsID(&client->netconnection->addr);
278 #else
279 client->privileged = false;
280 #endif
282 if (sv.loadgame)
283 memcpy (client->spawn_parms, spawn_parms, sizeof(spawn_parms));
284 else
286 // call the progs to get default spawn parms for the new client
287 PR_ExecuteProgram (pr_global_struct->SetNewParms);
288 for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
289 client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
292 SV_SendServerinfo (client);
297 ===================
298 SV_CheckForNewClients
300 ===================
302 void SV_CheckForNewClients (void)
304 struct qsocket_s *ret;
305 int i;
308 // check for new connections
310 while (1)
312 ret = NET_CheckNewConnections ();
313 if (!ret)
314 break;
317 // init a new client structure
319 for (i=0 ; i<svs.maxclients ; i++)
320 if (!svs.clients[i].active)
321 break;
322 if (i == svs.maxclients)
323 Sys_Error ("Host_CheckForNewClients: no free clients");
325 svs.clients[i].netconnection = ret;
326 SV_ConnectClient (i);
328 net_activeconnections++;
335 ===============================================================================
337 FRAME UPDATES
339 ===============================================================================
343 ==================
344 SV_ClearDatagram
346 ==================
348 void SV_ClearDatagram (void)
350 SZ_Clear (&sv.datagram);
354 =============================================================================
356 The PVS must include a small area around the client to allow head bobbing
357 or other small motion on the client side. Otherwise, a bob might cause an
358 entity that should be visible to not show up, especially when the bob
359 crosses a waterline.
361 =============================================================================
364 int fatbytes;
365 byte fatpvs[MAX_MAP_LEAFS/8];
367 void SV_AddToFatPVS (vec3_t org, mnode_t *node)
369 int i;
370 byte *pvs;
371 mplane_t *plane;
372 float d;
374 while (1)
376 // if this is a leaf, accumulate the pvs bits
377 if (node->contents < 0)
379 if (node->contents != CONTENTS_SOLID)
381 pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel);
382 for (i=0 ; i<fatbytes ; i++)
383 fatpvs[i] |= pvs[i];
385 return;
388 plane = node->plane;
389 d = DotProduct (org, plane->normal) - plane->dist;
390 if (d > 8)
391 node = node->children[0];
392 else if (d < -8)
393 node = node->children[1];
394 else
395 { // go down both
396 SV_AddToFatPVS (org, node->children[0]);
397 node = node->children[1];
403 =============
404 SV_FatPVS
406 Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
407 given point.
408 =============
410 byte *SV_FatPVS (vec3_t org)
412 fatbytes = (sv.worldmodel->numleafs+31)>>3;
413 Q_memset (fatpvs, 0, fatbytes);
414 SV_AddToFatPVS (org, sv.worldmodel->nodes);
415 return fatpvs;
418 //=============================================================================
422 =============
423 SV_WriteEntitiesToClient
425 =============
427 void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
429 int e, i;
430 int bits;
431 byte *pvs;
432 vec3_t org;
433 float miss;
434 edict_t *ent;
436 // Tomaz - QC Alpha Scale Glow Begin
438 float alpha;
439 float scale;
440 float glow_size;
441 float glow_red;
442 float glow_green;
443 float glow_blue;
445 // Tomaz - QC Alpha Scale Glow End
447 // find the client's PVS
448 VectorAdd (clent->v.origin, clent->v.view_ofs, org);
449 pvs = SV_FatPVS (org);
451 // send over all entities (excpet the client) that touch the pvs
452 ent = NEXT_EDICT(sv.edicts);
453 for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
455 #ifdef QUAKE2
456 // don't send if flagged for NODRAW and there are no lighting effects
457 if (ent->v.effects == EF_NODRAW)
458 continue;
459 #endif
461 // ignore if not touching a PV leaf
462 if (ent != clent) // clent is ALLWAYS sent
464 // ignore ents without visible models
465 if (!ent->v.modelindex || !pr_strings[ent->v.model])
466 continue;
468 for (i=0 ; i < ent->num_leafs ; i++)
469 if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
470 break;
472 if (i == ent->num_leafs)
473 continue; // not visible
476 if (msg->maxsize - msg->cursize < 16)
478 Con_Printf ("packet overflow\n");
479 return;
482 // send an update
483 bits = 0;
485 for (i=0 ; i<3 ; i++)
487 miss = ent->v.origin[i] - ent->baseline.origin[i];
488 if ( miss < -0.1 || miss > 0.1 )
489 bits |= U_ORIGIN1<<i;
492 if ( ent->v.angles[0] != ent->baseline.angles[0] )
493 bits |= U_ANGLE1;
495 if ( ent->v.angles[1] != ent->baseline.angles[1] )
496 bits |= U_ANGLE2;
498 if ( ent->v.angles[2] != ent->baseline.angles[2] )
499 bits |= U_ANGLE3;
501 if (ent->v.movetype == MOVETYPE_STEP)
502 bits |= U_NOLERP; // don't mess up the step animation
504 if (ent->baseline.colormap != ent->v.colormap)
505 bits |= U_COLORMAP;
507 if (ent->baseline.skin != ent->v.skin)
508 bits |= U_SKIN;
510 if (ent->baseline.frame != ent->v.frame)
511 bits |= U_FRAME;
513 if (ent->baseline.effects != ent->v.effects)
514 bits |= U_EFFECTS;
516 if (ent->baseline.modelindex != ent->v.modelindex)
517 bits |= U_MODEL;
519 if (e >= 256)
520 bits |= U_LONGENTITY;
522 if (bits >= 256)
523 bits |= U_MOREBITS;
526 // write the message
528 MSG_WriteByte (msg,bits | U_SIGNAL);
530 if (bits & U_MOREBITS)
531 MSG_WriteByte (msg, bits>>8);
532 if (bits & U_LONGENTITY)
533 MSG_WriteShort (msg,e);
534 else
535 MSG_WriteByte (msg,e);
537 if (bits & U_MODEL)
538 MSG_WriteByte (msg, ent->v.modelindex);
540 // Tomaz - QC Alpha Scale Glow Begin
543 eval_t *val;
545 alpha=1;
546 scale=1;
548 if (val == GetEdictFieldValue(ent, "alpha"))
550 alpha = val->_float;
552 else
553 alpha = 1;
555 if (val == GetEdictFieldValue(ent, "scale"))
557 scale = val->_float;
559 else
560 scale = 1;
562 if (scale > 4)
563 scale = 4;
565 if (val == GetEdictFieldValue(ent, "glow_size"))
567 glow_size = val->_float;
569 else
570 glow_size = 0;
572 if (glow_size > 250)
573 glow_size = 250;
575 if (val == GetEdictFieldValue(ent, "glow_red"))
577 glow_red = val->_float;
579 else
580 glow_red = 0;
582 if (val == GetEdictFieldValue(ent, "glow_green"))
584 glow_green = val->_float;
586 else
587 glow_green = 0;
589 if (val == GetEdictFieldValue(ent, "glow_blue"))
591 glow_blue = val->_float;
593 else
594 glow_blue = 0;
596 if ((alpha <= 1) && (alpha > 0))
597 bits |= U_ALPHA;
599 if ((scale <= 4) && (scale > 0))
600 bits |= U_SCALE;
602 if (glow_size >= 0)
604 bits |= U_GLOW_SIZE;
605 bits |= U_GLOW_RED;
606 bits |= U_GLOW_GREEN;
607 bits |= U_GLOW_BLUE;
611 // Tomaz - QC Alpha Scale Glow End
613 if (bits & U_FRAME)
614 MSG_WriteByte (msg, ent->v.frame);
615 if (bits & U_COLORMAP)
616 MSG_WriteByte (msg, ent->v.colormap);
617 if (bits & U_SKIN)
618 MSG_WriteByte (msg, ent->v.skin);
619 if (bits & U_EFFECTS)
620 MSG_WriteByte (msg, ent->v.effects);
621 if (bits & U_ORIGIN1)
622 MSG_WriteCoord (msg, ent->v.origin[0]);
623 if (bits & U_ANGLE1)
624 MSG_WriteAngle(msg, ent->v.angles[0]);
625 if (bits & U_ORIGIN2)
626 MSG_WriteCoord (msg, ent->v.origin[1]);
627 if (bits & U_ANGLE2)
628 MSG_WriteAngle(msg, ent->v.angles[1]);
629 if (bits & U_ORIGIN3)
630 MSG_WriteCoord (msg, ent->v.origin[2]);
631 if (bits & U_ANGLE3)
632 MSG_WriteAngle(msg, ent->v.angles[2]);
638 =============
639 SV_CleanupEnts
641 =============
643 void SV_CleanupEnts (void)
645 int e;
646 edict_t *ent;
648 ent = NEXT_EDICT(sv.edicts);
649 for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
651 ent->v.effects = (int)ent->v.effects & ~EF_MUZZLEFLASH;
657 ==================
658 SV_WriteClientdataToMessage
660 ==================
662 void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
664 int bits;
665 int i;
666 edict_t *other;
667 int items;
668 #ifndef QUAKE2
669 eval_t *val;
670 #endif
673 // send a damage message
675 if (ent->v.dmg_take || ent->v.dmg_save)
677 other = PROG_TO_EDICT(ent->v.dmg_inflictor);
678 MSG_WriteByte (msg, svc_damage);
679 MSG_WriteByte (msg, ent->v.dmg_save);
680 MSG_WriteByte (msg, ent->v.dmg_take);
681 for (i=0 ; i<3 ; i++)
682 MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
684 ent->v.dmg_take = 0;
685 ent->v.dmg_save = 0;
689 // send the current viewpos offset from the view entity
691 SV_SetIdealPitch (); // how much to look up / down ideally
693 // a fixangle might get lost in a dropped packet. Oh well.
694 if ( ent->v.fixangle )
696 MSG_WriteByte (msg, svc_setangle);
697 for (i=0 ; i < 3 ; i++)
698 MSG_WriteAngle (msg, ent->v.angles[i] );
699 ent->v.fixangle = 0;
702 bits = 0;
704 if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT)
705 bits |= SU_VIEWHEIGHT;
707 if (ent->v.idealpitch)
708 bits |= SU_IDEALPITCH;
710 // stuff the sigil bits into the high bits of items for sbar, or else
711 // mix in items2
712 #ifdef QUAKE2
713 items = (int)ent->v.items | ((int)ent->v.items2 << 23);
714 #else
715 val = GetEdictFieldValue(ent, "items2");
717 if (val)
718 items = (int)ent->v.items | ((int)val->_float << 23);
719 else
720 items = (int)ent->v.items | ((int)pr_global_struct->serverflags << 28);
721 #endif
723 bits |= SU_ITEMS;
725 if ( (int)ent->v.flags & FL_ONGROUND)
726 bits |= SU_ONGROUND;
728 if ( ent->v.waterlevel >= 2)
729 bits |= SU_INWATER;
731 for (i=0 ; i<3 ; i++)
733 if (ent->v.punchangle[i])
734 bits |= (SU_PUNCH1<<i);
735 if (ent->v.velocity[i])
736 bits |= (SU_VELOCITY1<<i);
739 if (ent->v.weaponframe)
740 bits |= SU_WEAPONFRAME;
742 if (ent->v.armorvalue)
743 bits |= SU_ARMOR;
745 // if (ent->v.weapon)
746 bits |= SU_WEAPON;
748 // send the data
750 MSG_WriteByte (msg, svc_clientdata);
751 MSG_WriteShort (msg, bits);
753 if (bits & SU_VIEWHEIGHT)
754 MSG_WriteChar (msg, ent->v.view_ofs[2]);
756 if (bits & SU_IDEALPITCH)
757 MSG_WriteChar (msg, ent->v.idealpitch);
759 for (i=0 ; i<3 ; i++)
761 if (bits & (SU_PUNCH1<<i))
762 MSG_WriteChar (msg, ent->v.punchangle[i]);
763 if (bits & (SU_VELOCITY1<<i))
764 MSG_WriteChar (msg, ent->v.velocity[i]/16);
767 // [always sent] if (bits & SU_ITEMS)
768 MSG_WriteLong (msg, items);
770 if (bits & SU_WEAPONFRAME)
771 MSG_WriteByte (msg, ent->v.weaponframe);
772 if (bits & SU_ARMOR)
773 MSG_WriteByte (msg, ent->v.armorvalue);
774 if (bits & SU_WEAPON)
775 MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v.weaponmodel));
777 MSG_WriteShort (msg, ent->v.health);
778 MSG_WriteByte (msg, ent->v.currentammo);
779 MSG_WriteByte (msg, ent->v.ammo_shells);
780 MSG_WriteByte (msg, ent->v.ammo_nails);
781 MSG_WriteByte (msg, ent->v.ammo_rockets);
782 MSG_WriteByte (msg, ent->v.ammo_cells);
784 if (standard_quake)
786 MSG_WriteByte (msg, ent->v.weapon);
788 else
790 for(i=0;i<32;i++)
792 if ( ((int)ent->v.weapon) & (1<<i) )
794 MSG_WriteByte (msg, i);
795 break;
802 =======================
803 SV_SendClientDatagram
804 =======================
806 qboolean SV_SendClientDatagram (client_t *client)
808 byte buf[MAX_DATAGRAM];
809 sizebuf_t msg;
811 msg.data = buf;
812 msg.maxsize = sizeof(buf);
813 msg.cursize = 0;
815 MSG_WriteByte (&msg, svc_time);
816 MSG_WriteFloat (&msg, sv.time);
818 // add the client specific data to the datagram
819 SV_WriteClientdataToMessage (client->edict, &msg);
821 SV_WriteEntitiesToClient (client->edict, &msg);
823 // copy the server datagram if there is space
824 if (msg.cursize + sv.datagram.cursize < msg.maxsize)
825 SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize);
827 // send the datagram
828 if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1)
830 SV_DropClient (true);// if the message couldn't send, kick off
831 return false;
834 return true;
838 =======================
839 SV_UpdateToReliableMessages
840 =======================
842 void SV_UpdateToReliableMessages (void)
844 int i, j;
845 client_t *client;
847 // check for changes to be sent over the reliable streams
848 for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
850 if (host_client->old_frags != host_client->edict->v.frags)
852 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
854 if (!client->active)
855 continue;
856 MSG_WriteByte (&client->message, svc_updatefrags);
857 MSG_WriteByte (&client->message, i);
858 MSG_WriteShort (&client->message, host_client->edict->v.frags);
861 host_client->old_frags = host_client->edict->v.frags;
865 for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
867 if (!client->active)
868 continue;
869 SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
872 SZ_Clear (&sv.reliable_datagram);
877 =======================
878 SV_SendNop
880 Send a nop message without trashing or sending the accumulated client
881 message buffer
882 =======================
884 void SV_SendNop (client_t *client)
886 sizebuf_t msg;
887 byte buf[4];
889 msg.data = buf;
890 msg.maxsize = sizeof(buf);
891 msg.cursize = 0;
893 MSG_WriteChar (&msg, svc_nop);
895 if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1)
896 SV_DropClient (true); // if the message couldn't send, kick off
897 client->last_message = realtime;
901 =======================
902 SV_SendClientMessages
903 =======================
905 void SV_SendClientMessages (void)
907 int i;
909 // update frags, names, etc
910 SV_UpdateToReliableMessages ();
912 // build individual updates
913 for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
915 if (!host_client->active)
916 continue;
918 if (host_client->spawned)
920 if (!SV_SendClientDatagram (host_client))
921 continue;
923 else
925 // the player isn't totally in the game yet
926 // send small keepalive messages if too much time has passed
927 // send a full message when the next signon stage has been requested
928 // some other message data (name changes, etc) may accumulate
929 // between signon stages
930 if (!host_client->sendsignon)
932 if (realtime - host_client->last_message > 5)
933 SV_SendNop (host_client);
934 continue; // don't send out non-signon messages
938 // check for an overflowed message. Should only happen
939 // on a very fucked up connection that backs up a lot, then
940 // changes level
941 if (host_client->message.overflowed)
943 SV_DropClient (true);
944 host_client->message.overflowed = false;
945 continue;
948 if (host_client->message.cursize || host_client->dropasap)
950 if (!NET_CanSendMessage (host_client->netconnection))
952 // I_Printf ("can't write\n");
953 continue;
956 if (host_client->dropasap)
957 SV_DropClient (false); // went to another level
958 else
960 if (NET_SendMessage (host_client->netconnection
961 , &host_client->message) == -1)
962 SV_DropClient (true); // if the message couldn't send, kick off
963 SZ_Clear (&host_client->message);
964 host_client->last_message = realtime;
965 host_client->sendsignon = false;
971 // clear muzzle flashes
972 SV_CleanupEnts ();
977 ==============================================================================
979 SERVER SPAWNING
981 ==============================================================================
985 ================
986 SV_ModelIndex
988 ================
990 int SV_ModelIndex (char *name)
992 int i;
994 if (!name || !name[0])
995 return 0;
997 for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
998 if (!strcmp(sv.model_precache[i], name))
999 return i;
1000 if (i==MAX_MODELS || !sv.model_precache[i])
1001 Sys_Error ("SV_ModelIndex: model %s not precached", name);
1002 return i;
1006 ================
1007 SV_CreateBaseline
1009 ================
1011 void SV_CreateBaseline (void)
1013 int i;
1014 edict_t *svent;
1015 int entnum;
1017 for (entnum = 0; entnum < sv.num_edicts ; entnum++)
1019 // get the current server version
1020 svent = EDICT_NUM(entnum);
1021 if (svent->free)
1022 continue;
1023 if (entnum > svs.maxclients && !svent->v.modelindex)
1024 continue;
1027 // create entity baseline
1029 VectorCopy (svent->v.origin, svent->baseline.origin);
1030 VectorCopy (svent->v.angles, svent->baseline.angles);
1031 svent->baseline.frame = svent->v.frame;
1032 svent->baseline.skin = svent->v.skin;
1033 if (entnum > 0 && entnum <= svs.maxclients)
1035 svent->baseline.colormap = entnum;
1036 svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
1038 else
1040 svent->baseline.colormap = 0;
1041 svent->baseline.modelindex =
1042 SV_ModelIndex(pr_strings + svent->v.model);
1046 // add to the message
1048 MSG_WriteByte (&sv.signon,svc_spawnbaseline);
1049 MSG_WriteShort (&sv.signon,entnum);
1051 MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
1052 MSG_WriteByte (&sv.signon, svent->baseline.frame);
1053 MSG_WriteByte (&sv.signon, svent->baseline.colormap);
1054 MSG_WriteByte (&sv.signon, svent->baseline.skin);
1055 for (i=0 ; i<3 ; i++)
1057 MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
1058 MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
1065 ================
1066 SV_SendReconnect
1068 Tell all the clients that the server is changing levels
1069 ================
1071 void SV_SendReconnect (void)
1073 char data[128];
1074 sizebuf_t msg;
1076 msg.data = data;
1077 msg.cursize = 0;
1078 msg.maxsize = sizeof(data);
1080 MSG_WriteChar (&msg, svc_stufftext);
1081 MSG_WriteString (&msg, "reconnect\n");
1082 NET_SendToAll (&msg, 5);
1084 if (cls.state != ca_dedicated)
1085 #ifdef QUAKE2
1086 Cbuf_InsertText ("reconnect\n");
1087 #else
1088 Cmd_ExecuteString ("reconnect\n", src_command);
1089 #endif
1094 ================
1095 SV_SaveSpawnparms
1097 Grabs the current state of each client for saving across the
1098 transition to another level
1099 ================
1101 void SV_SaveSpawnparms (void)
1103 int i, j;
1105 svs.serverflags = pr_global_struct->serverflags;
1107 for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
1109 if (!host_client->active)
1110 continue;
1112 // call the progs to get default spawn parms for the new client
1113 pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
1114 PR_ExecuteProgram (pr_global_struct->SetChangeParms);
1115 for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
1116 host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
1122 ================
1123 SV_SpawnServer
1125 This is called at the start of each level
1126 ================
1128 extern float scr_centertime_off;
1130 #ifdef QUAKE2
1131 void SV_SpawnServer (char *server, char *startspot)
1132 #else
1133 void SV_SpawnServer (char *server)
1134 #endif
1136 edict_t *ent;
1137 int i;
1139 // let's not have any servers with no name
1140 if (hostname.string[0] == 0)
1141 Cvar_Set ("hostname", "UNNAMED");
1142 scr_centertime_off = 0;
1144 Con_DPrintf ("SpawnServer: %s\n",server);
1145 svs.changelevel_issued = false; // now safe to issue another
1148 // tell all connected clients that we are going to a new level
1150 if (sv.active)
1152 SV_SendReconnect ();
1156 // make cvars consistant
1158 if (coop.value)
1159 Cvar_SetValue ("deathmatch", 0);
1160 current_skill = (int)(skill.value + 0.5);
1161 if (current_skill < 0)
1162 current_skill = 0;
1163 if (current_skill > 3)
1164 current_skill = 3;
1166 Cvar_SetValue ("skill", (float)current_skill);
1169 // set up the new server
1171 Host_ClearMemory ();
1173 memset (&sv, 0, sizeof(sv));
1175 strcpy (sv.name, server);
1176 #ifdef QUAKE2
1177 if (startspot)
1178 strcpy(sv.startspot, startspot);
1179 #endif
1181 // load progs to get entity field count
1182 PR_LoadProgs ();
1184 // allocate server memory
1185 sv.max_edicts = MAX_EDICTS;
1187 sv.edicts = Hunk_AllocName (sv.max_edicts*pr_edict_size, "edicts");
1189 sv.datagram.maxsize = sizeof(sv.datagram_buf);
1190 sv.datagram.cursize = 0;
1191 sv.datagram.data = sv.datagram_buf;
1193 sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
1194 sv.reliable_datagram.cursize = 0;
1195 sv.reliable_datagram.data = sv.reliable_datagram_buf;
1197 sv.signon.maxsize = sizeof(sv.signon_buf);
1198 sv.signon.cursize = 0;
1199 sv.signon.data = sv.signon_buf;
1201 // leave slots at start for clients only
1202 sv.num_edicts = svs.maxclients+1;
1203 for (i=0 ; i<svs.maxclients ; i++)
1205 ent = EDICT_NUM(i+1);
1206 svs.clients[i].edict = ent;
1209 sv.state = ss_loading;
1210 sv.paused = false;
1212 sv.time = 1.0;
1214 strcpy (sv.name, server);
1215 sprintf (sv.modelname,"maps/%s.bsp", server);
1216 sv.worldmodel = Mod_ForName (sv.modelname, false);
1217 if (!sv.worldmodel)
1219 Con_Printf ("Couldn't spawn server %s\n", sv.modelname);
1220 sv.active = false;
1221 return;
1223 sv.models[1] = sv.worldmodel;
1226 // clear world interaction links
1228 SV_ClearWorld ();
1230 sv.sound_precache[0] = pr_strings;
1232 sv.model_precache[0] = pr_strings;
1233 sv.model_precache[1] = sv.modelname;
1234 for (i=1 ; i<sv.worldmodel->numsubmodels ; i++)
1236 sv.model_precache[1+i] = localmodels[i];
1237 sv.models[i+1] = Mod_ForName (localmodels[i], false);
1241 // load the rest of the entities
1243 ent = EDICT_NUM(0);
1244 memset (&ent->v, 0, progs->entityfields * 4);
1245 ent->free = false;
1246 ent->v.model = sv.worldmodel->name - pr_strings;
1247 ent->v.modelindex = 1; // world model
1248 ent->v.solid = SOLID_BSP;
1249 ent->v.movetype = MOVETYPE_PUSH;
1251 if (coop.value)
1252 pr_global_struct->coop = coop.value;
1253 else
1254 pr_global_struct->deathmatch = deathmatch.value;
1256 pr_global_struct->mapname = sv.name - pr_strings;
1257 #ifdef QUAKE2
1258 pr_global_struct->startspot = sv.startspot - pr_strings;
1259 #endif
1261 // serverflags are for cross level information (sigils)
1262 pr_global_struct->serverflags = svs.serverflags;
1264 ED_LoadFromFile (sv.worldmodel->entities);
1266 sv.active = true;
1268 // all setup is completed, any further precache statements are errors
1269 sv.state = ss_active;
1271 // run two frames to allow everything to settle
1272 host_frametime = 0.1;
1273 SV_Physics ();
1274 SV_Physics ();
1276 // create a baseline for more efficient communications
1277 SV_CreateBaseline ();
1279 // send serverinfo to all connected clients
1280 for (i=0,host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
1281 if (host_client->active)
1282 SV_SendServerinfo (host_client);
1284 Con_DPrintf ("Server spawned.\n");