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
27 char localmodels
[MAX_MODELS
][5]; // inline model names for precache
29 //============================================================================
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
;
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 =============================================================================
70 =============================================================================
77 Make sure the event gets sent to all clients
80 void SV_StartParticle (vec3_t org
, vec3_t dir
, int color
, int count
)
84 if (sv
.datagram
.cursize
> MAX_DATAGRAM
-16)
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]);
97 MSG_WriteChar (&sv
.datagram
, v
);
99 MSG_WriteByte (&sv
.datagram
, count
);
100 MSG_WriteByte (&sv
.datagram
, color
);
107 Each entity can have eight independant sound sources, like voice,
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)
118 void SV_StartSound (edict_t
*entity
, int channel
, char *sample
, int volume
,
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)
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
]))
144 if ( sound_num
== MAX_SOUNDS
|| !sv
.sound_precache
[sound_num
] )
146 Con_Printf ("SV_StartSound: %s not precacheed\n", sample
);
150 ent
= NUM_FOR_EDICT(entity
);
152 channel
= (ent
<<3) | channel
;
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 ==============================================================================
178 ==============================================================================
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.
189 void SV_SendServerinfo (client_t
*client
)
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
);
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);
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
);
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
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.
243 void SV_ConnectClient (int clientnum
)
248 struct qsocket_s
*netconnection
;
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
;
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;
272 client
->message
.data
= client
->msgbuf
;
273 client
->message
.maxsize
= sizeof(client
->msgbuf
);
274 client
->message
.allowoverflow
= true; // we can catch it
277 client
->privileged
= IsID(&client
->netconnection
->addr
);
279 client
->privileged
= false;
283 memcpy (client
->spawn_parms
, spawn_parms
, sizeof(spawn_parms
));
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
);
298 SV_CheckForNewClients
302 void SV_CheckForNewClients (void)
304 struct qsocket_s
*ret
;
308 // check for new connections
312 ret
= NET_CheckNewConnections ();
317 // init a new client structure
319 for (i
=0 ; i
<svs
.maxclients
; i
++)
320 if (!svs
.clients
[i
].active
)
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 ===============================================================================
339 ===============================================================================
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
361 =============================================================================
365 byte fatpvs
[MAX_MAP_LEAFS
/8];
367 void SV_AddToFatPVS (vec3_t org
, mnode_t
*node
)
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
++)
389 d
= DotProduct (org
, plane
->normal
) - plane
->dist
;
391 node
= node
->children
[0];
393 node
= node
->children
[1];
396 SV_AddToFatPVS (org
, node
->children
[0]);
397 node
= node
->children
[1];
406 Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
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
);
418 //=============================================================================
423 SV_WriteEntitiesToClient
427 void SV_WriteEntitiesToClient (edict_t
*clent
, sizebuf_t
*msg
)
436 // Tomaz - QC Alpha Scale Glow Begin
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
))
456 // don't send if flagged for NODRAW and there are no lighting effects
457 if (ent
->v
.effects
== EF_NODRAW
)
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
])
468 for (i
=0 ; i
< ent
->num_leafs
; i
++)
469 if (pvs
[ent
->leafnums
[i
] >> 3] & (1 << (ent
->leafnums
[i
]&7) ))
472 if (i
== ent
->num_leafs
)
473 continue; // not visible
476 if (msg
->maxsize
- msg
->cursize
< 16)
478 Con_Printf ("packet overflow\n");
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] )
495 if ( ent
->v
.angles
[1] != ent
->baseline
.angles
[1] )
498 if ( ent
->v
.angles
[2] != ent
->baseline
.angles
[2] )
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
)
507 if (ent
->baseline
.skin
!= ent
->v
.skin
)
510 if (ent
->baseline
.frame
!= ent
->v
.frame
)
513 if (ent
->baseline
.effects
!= ent
->v
.effects
)
516 if (ent
->baseline
.modelindex
!= ent
->v
.modelindex
)
520 bits
|= U_LONGENTITY
;
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
);
535 MSG_WriteByte (msg
,e
);
538 MSG_WriteByte (msg
, ent
->v
.modelindex
);
540 // Tomaz - QC Alpha Scale Glow Begin
548 if (val
== GetEdictFieldValue(ent
, "alpha"))
555 if (val
== GetEdictFieldValue(ent
, "scale"))
565 if (val
== GetEdictFieldValue(ent
, "glow_size"))
567 glow_size
= val
->_float
;
575 if (val
== GetEdictFieldValue(ent
, "glow_red"))
577 glow_red
= val
->_float
;
582 if (val
== GetEdictFieldValue(ent
, "glow_green"))
584 glow_green
= val
->_float
;
589 if (val
== GetEdictFieldValue(ent
, "glow_blue"))
591 glow_blue
= val
->_float
;
596 if ((alpha
<= 1) && (alpha
> 0))
599 if ((scale
<= 4) && (scale
> 0))
606 bits
|= U_GLOW_GREEN
;
611 // Tomaz - QC Alpha Scale Glow End
614 MSG_WriteByte (msg
, ent
->v
.frame
);
615 if (bits
& U_COLORMAP
)
616 MSG_WriteByte (msg
, ent
->v
.colormap
);
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]);
624 MSG_WriteAngle(msg
, ent
->v
.angles
[0]);
625 if (bits
& U_ORIGIN2
)
626 MSG_WriteCoord (msg
, ent
->v
.origin
[1]);
628 MSG_WriteAngle(msg
, ent
->v
.angles
[1]);
629 if (bits
& U_ORIGIN3
)
630 MSG_WriteCoord (msg
, ent
->v
.origin
[2]);
632 MSG_WriteAngle(msg
, ent
->v
.angles
[2]);
643 void SV_CleanupEnts (void)
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
;
658 SV_WriteClientdataToMessage
662 void SV_WriteClientdataToMessage (edict_t
*ent
, sizebuf_t
*msg
)
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
]));
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
] );
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
713 items
= (int)ent
->v
.items
| ((int)ent
->v
.items2
<< 23);
715 val
= GetEdictFieldValue(ent
, "items2");
718 items
= (int)ent
->v
.items
| ((int)val
->_float
<< 23);
720 items
= (int)ent
->v
.items
| ((int)pr_global_struct
->serverflags
<< 28);
725 if ( (int)ent
->v
.flags
& FL_ONGROUND
)
728 if ( ent
->v
.waterlevel
>= 2)
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
)
745 // if (ent->v.weapon)
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
);
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
);
786 MSG_WriteByte (msg
, ent
->v
.weapon
);
792 if ( ((int)ent
->v
.weapon
) & (1<<i
) )
794 MSG_WriteByte (msg
, i
);
802 =======================
803 SV_SendClientDatagram
804 =======================
806 qboolean
SV_SendClientDatagram (client_t
*client
)
808 byte buf
[MAX_DATAGRAM
];
812 msg
.maxsize
= sizeof(buf
);
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
);
828 if (NET_SendUnreliableMessage (client
->netconnection
, &msg
) == -1)
830 SV_DropClient (true);// if the message couldn't send, kick off
838 =======================
839 SV_UpdateToReliableMessages
840 =======================
842 void SV_UpdateToReliableMessages (void)
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
++)
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
++)
869 SZ_Write (&client
->message
, sv
.reliable_datagram
.data
, sv
.reliable_datagram
.cursize
);
872 SZ_Clear (&sv
.reliable_datagram
);
877 =======================
880 Send a nop message without trashing or sending the accumulated client
882 =======================
884 void SV_SendNop (client_t
*client
)
890 msg
.maxsize
= sizeof(buf
);
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)
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
)
918 if (host_client
->spawned
)
920 if (!SV_SendClientDatagram (host_client
))
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
941 if (host_client
->message
.overflowed
)
943 SV_DropClient (true);
944 host_client
->message
.overflowed
= false;
948 if (host_client
->message
.cursize
|| host_client
->dropasap
)
950 if (!NET_CanSendMessage (host_client
->netconnection
))
952 // I_Printf ("can't write\n");
956 if (host_client
->dropasap
)
957 SV_DropClient (false); // went to another level
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
977 ==============================================================================
981 ==============================================================================
990 int SV_ModelIndex (char *name
)
994 if (!name
|| !name
[0])
997 for (i
=0 ; i
<MAX_MODELS
&& sv
.model_precache
[i
] ; i
++)
998 if (!strcmp(sv
.model_precache
[i
], name
))
1000 if (i
==MAX_MODELS
|| !sv
.model_precache
[i
])
1001 Sys_Error ("SV_ModelIndex: model %s not precached", name
);
1011 void SV_CreateBaseline (void)
1017 for (entnum
= 0; entnum
< sv
.num_edicts
; entnum
++)
1019 // get the current server version
1020 svent
= EDICT_NUM(entnum
);
1023 if (entnum
> svs
.maxclients
&& !svent
->v
.modelindex
)
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");
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
]);
1068 Tell all the clients that the server is changing levels
1071 void SV_SendReconnect (void)
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
)
1086 Cbuf_InsertText ("reconnect\n");
1088 Cmd_ExecuteString ("reconnect\n", src_command
);
1097 Grabs the current state of each client for saving across the
1098 transition to another level
1101 void SV_SaveSpawnparms (void)
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
)
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
];
1125 This is called at the start of each level
1128 extern float scr_centertime_off
;
1131 void SV_SpawnServer (char *server
, char *startspot
)
1133 void SV_SpawnServer (char *server
)
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
1152 SV_SendReconnect ();
1156 // make cvars consistant
1159 Cvar_SetValue ("deathmatch", 0);
1160 current_skill
= (int)(skill
.value
+ 0.5);
1161 if (current_skill
< 0)
1163 if (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
);
1178 strcpy(sv
.startspot
, startspot
);
1181 // load progs to get entity field count
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
;
1214 strcpy (sv
.name
, server
);
1215 sprintf (sv
.modelname
,"maps/%s.bsp", server
);
1216 sv
.worldmodel
= Mod_ForName (sv
.modelname
, false);
1219 Con_Printf ("Couldn't spawn server %s\n", sv
.modelname
);
1223 sv
.models
[1] = sv
.worldmodel
;
1226 // clear world interaction links
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
1244 memset (&ent
->v
, 0, progs
->entityfields
* 4);
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
;
1252 pr_global_struct
->coop
= coop
.value
;
1254 pr_global_struct
->deathmatch
= deathmatch
.value
;
1256 pr_global_struct
->mapname
= sv
.name
- pr_strings
;
1258 pr_global_struct
->startspot
= sv
.startspot
- pr_strings
;
1261 // serverflags are for cross level information (sigils)
1262 pr_global_struct
->serverflags
= svs
.serverflags
;
1264 ED_LoadFromFile (sv
.worldmodel
->entities
);
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;
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");