|
|
1.1.1.3 ! root 1: /* ! 2: Copyright (C) 1997-2001 Id Software, Inc. ! 3: ! 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. ! 8: ! 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. ! 12: ! 13: See the GNU General Public License for more details. ! 14: ! 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. ! 18: ! 19: */ 1.1 root 20: // sv_game.c -- interface to the game dll 21: 22: #include "server.h" 23: 24: game_export_t *ge; 25: 26: 27: /* 28: =============== 29: PF_Unicast 30: 31: Sends the contents of the mutlicast buffer to a single client 32: =============== 33: */ 34: void PF_Unicast (edict_t *ent, qboolean reliable) 35: { 36: int p; 37: client_t *client; 38: 39: if (!ent) 40: return; 41: 42: p = NUM_FOR_EDICT(ent); 43: if (p < 1 || p > maxclients->value) 44: return; 45: 46: client = svs.clients + (p-1); 47: 48: if (reliable) 49: SZ_Write (&client->netchan.message, sv.multicast.data, sv.multicast.cursize); 50: else 51: SZ_Write (&client->datagram, sv.multicast.data, sv.multicast.cursize); 52: 53: SZ_Clear (&sv.multicast); 54: } 55: 56: 57: /* 58: =============== 59: PF_dprintf 60: 61: Debug print to server console 62: =============== 63: */ 64: void PF_dprintf (char *fmt, ...) 65: { 66: char msg[1024]; 67: va_list argptr; 68: 69: va_start (argptr,fmt); 70: vsprintf (msg, fmt, argptr); 71: va_end (argptr); 72: 73: Com_Printf ("%s", msg); 74: } 75: 76: 77: /* 78: =============== 79: PF_cprintf 80: 81: Print to a single client 82: =============== 83: */ 84: void PF_cprintf (edict_t *ent, int level, char *fmt, ...) 85: { 86: char msg[1024]; 87: va_list argptr; 88: int n; 89: 90: if (ent) 91: { 92: n = NUM_FOR_EDICT(ent); 93: if (n < 1 || n > maxclients->value) 94: Com_Error (ERR_DROP, "cprintf to a non-client"); 95: } 96: 97: va_start (argptr,fmt); 98: vsprintf (msg, fmt, argptr); 99: va_end (argptr); 100: 101: if (ent) 102: SV_ClientPrintf (svs.clients+(n-1), level, "%s", msg); 103: else 104: Com_Printf ("%s", msg); 105: } 106: 107: 108: /* 109: =============== 110: PF_centerprintf 111: 112: centerprint to a single client 113: =============== 114: */ 115: void PF_centerprintf (edict_t *ent, char *fmt, ...) 116: { 117: char msg[1024]; 118: va_list argptr; 119: int n; 120: 121: n = NUM_FOR_EDICT(ent); 122: if (n < 1 || n > maxclients->value) 123: return; // Com_Error (ERR_DROP, "centerprintf to a non-client"); 124: 125: va_start (argptr,fmt); 126: vsprintf (msg, fmt, argptr); 127: va_end (argptr); 128: 129: MSG_WriteByte (&sv.multicast,svc_centerprint); 130: MSG_WriteString (&sv.multicast,msg); 131: PF_Unicast (ent, true); 132: } 133: 134: 135: /* 136: =============== 137: PF_error 138: 139: Abort the server with a game error 140: =============== 141: */ 142: void PF_error (char *fmt, ...) 143: { 144: char msg[1024]; 145: va_list argptr; 146: 147: va_start (argptr,fmt); 148: vsprintf (msg, fmt, argptr); 149: va_end (argptr); 150: 151: Com_Error (ERR_DROP, "Game Error: %s", msg); 152: } 153: 154: 155: /* 156: ================= 157: PF_setmodel 158: 159: Also sets mins and maxs for inline bmodels 160: ================= 161: */ 162: void PF_setmodel (edict_t *ent, char *name) 163: { 164: int i; 165: cmodel_t *mod; 166: 167: if (!name) 168: Com_Error (ERR_DROP, "PF_setmodel: NULL"); 169: 170: i = SV_ModelIndex (name); 171: 172: // ent->model = name; 173: ent->s.modelindex = i; 174: 175: // if it is an inline model, get the size information for it 176: if (name[0] == '*') 177: { 178: mod = CM_InlineModel (name); 179: VectorCopy (mod->mins, ent->mins); 180: VectorCopy (mod->maxs, ent->maxs); 181: SV_LinkEdict (ent); 182: } 183: 184: } 185: 186: /* 187: =============== 188: PF_Configstring 189: 190: =============== 191: */ 192: void PF_Configstring (int index, char *val) 193: { 194: if (index < 0 || index >= MAX_CONFIGSTRINGS) 195: Com_Error (ERR_DROP, "configstring: bad index %i\n", index); 196: 197: if (!val) 198: val = ""; 199: 200: // change the string in sv 201: strcpy (sv.configstrings[index], val); 1.1.1.3 ! root 202: 1.1 root 203: 204: if (sv.state != ss_loading) 205: { // send the update to everyone 206: SZ_Clear (&sv.multicast); 207: MSG_WriteChar (&sv.multicast, svc_configstring); 208: MSG_WriteShort (&sv.multicast, index); 209: MSG_WriteString (&sv.multicast, val); 210: 211: SV_Multicast (vec3_origin, MULTICAST_ALL_R); 212: } 213: } 214: 215: 216: 217: void PF_WriteChar (int c) {MSG_WriteChar (&sv.multicast, c);} 218: void PF_WriteByte (int c) {MSG_WriteByte (&sv.multicast, c);} 219: void PF_WriteShort (int c) {MSG_WriteShort (&sv.multicast, c);} 220: void PF_WriteLong (int c) {MSG_WriteLong (&sv.multicast, c);} 221: void PF_WriteFloat (float f) {MSG_WriteFloat (&sv.multicast, f);} 222: void PF_WriteString (char *s) {MSG_WriteString (&sv.multicast, s);} 223: void PF_WritePos (vec3_t pos) {MSG_WritePos (&sv.multicast, pos);} 224: void PF_WriteDir (vec3_t dir) {MSG_WriteDir (&sv.multicast, dir);} 225: void PF_WriteAngle (float f) {MSG_WriteAngle (&sv.multicast, f);} 226: 227: 228: /* 229: ================= 230: PF_inPVS 231: 232: Also checks portalareas so that doors block sight 233: ================= 234: */ 235: qboolean PF_inPVS (vec3_t p1, vec3_t p2) 236: { 237: int leafnum; 238: int cluster; 239: int area1, area2; 240: byte *mask; 241: 242: leafnum = CM_PointLeafnum (p1); 243: cluster = CM_LeafCluster (leafnum); 244: area1 = CM_LeafArea (leafnum); 245: mask = CM_ClusterPVS (cluster); 246: 247: leafnum = CM_PointLeafnum (p2); 248: cluster = CM_LeafCluster (leafnum); 249: area2 = CM_LeafArea (leafnum); 250: if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) 251: return false; 252: if (!CM_AreasConnected (area1, area2)) 253: return false; // a door blocks sight 254: return true; 255: } 256: 257: 258: /* 259: ================= 260: PF_inPHS 261: 262: Also checks portalareas so that doors block sound 263: ================= 264: */ 265: qboolean PF_inPHS (vec3_t p1, vec3_t p2) 266: { 267: int leafnum; 268: int cluster; 269: int area1, area2; 270: byte *mask; 271: 272: leafnum = CM_PointLeafnum (p1); 273: cluster = CM_LeafCluster (leafnum); 274: area1 = CM_LeafArea (leafnum); 275: mask = CM_ClusterPHS (cluster); 276: 277: leafnum = CM_PointLeafnum (p2); 278: cluster = CM_LeafCluster (leafnum); 279: area2 = CM_LeafArea (leafnum); 280: if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) 281: return false; // more than one bounce away 282: if (!CM_AreasConnected (area1, area2)) 283: return false; // a door blocks hearing 284: 285: return true; 286: } 287: 288: void PF_StartSound (edict_t *entity, int channel, int sound_num, float volume, 289: float attenuation, float timeofs) 290: { 291: if (!entity) 292: return; 293: SV_StartSound (NULL, entity, channel, sound_num, volume, attenuation, timeofs); 294: } 295: 296: //============================================== 297: 298: /* 299: =============== 300: SV_ShutdownGameProgs 301: 302: Called when either the entire server is being killed, or 303: it is changing to a different game directory. 304: =============== 305: */ 306: void SV_ShutdownGameProgs (void) 307: { 308: if (!ge) 309: return; 310: ge->Shutdown (); 311: Sys_UnloadGame (); 312: ge = NULL; 313: } 314: 315: /* 316: =============== 317: SV_InitGameProgs 318: 319: Init the game subsystem for a new map 320: =============== 321: */ 322: void SCR_DebugGraph (float value, int color); 323: 324: void SV_InitGameProgs (void) 325: { 326: game_import_t import; 327: 328: // unload anything we have now 329: if (ge) 330: SV_ShutdownGameProgs (); 331: 332: 333: // load a new game dll 334: import.multicast = SV_Multicast; 335: import.unicast = PF_Unicast; 336: import.bprintf = SV_BroadcastPrintf; 337: import.dprintf = PF_dprintf; 338: import.cprintf = PF_cprintf; 339: import.centerprintf = PF_centerprintf; 340: import.error = PF_error; 341: 342: import.linkentity = SV_LinkEdict; 343: import.unlinkentity = SV_UnlinkEdict; 344: import.BoxEdicts = SV_AreaEdicts; 345: import.trace = SV_Trace; 346: import.pointcontents = SV_PointContents; 347: import.setmodel = PF_setmodel; 348: import.inPVS = PF_inPVS; 349: import.inPHS = PF_inPHS; 350: import.Pmove = Pmove; 351: 352: import.modelindex = SV_ModelIndex; 353: import.soundindex = SV_SoundIndex; 354: import.imageindex = SV_ImageIndex; 355: 356: import.configstring = PF_Configstring; 357: import.sound = PF_StartSound; 358: import.positioned_sound = SV_StartSound; 359: 360: import.WriteChar = PF_WriteChar; 361: import.WriteByte = PF_WriteByte; 362: import.WriteShort = PF_WriteShort; 363: import.WriteLong = PF_WriteLong; 364: import.WriteFloat = PF_WriteFloat; 365: import.WriteString = PF_WriteString; 366: import.WritePosition = PF_WritePos; 367: import.WriteDir = PF_WriteDir; 368: import.WriteAngle = PF_WriteAngle; 369: 370: import.TagMalloc = Z_TagMalloc; 371: import.TagFree = Z_Free; 372: import.FreeTags = Z_FreeTags; 373: 374: import.cvar = Cvar_Get; 375: import.cvar_set = Cvar_Set; 376: import.cvar_forceset = Cvar_ForceSet; 377: 378: import.argc = Cmd_Argc; 379: import.argv = Cmd_Argv; 380: import.args = Cmd_Args; 381: import.AddCommandString = Cbuf_AddText; 382: 383: import.DebugGraph = SCR_DebugGraph; 384: import.SetAreaPortalState = CM_SetAreaPortalState; 385: import.AreasConnected = CM_AreasConnected; 386: 387: ge = (game_export_t *)Sys_GetGameAPI (&import); 388: 389: if (!ge) 390: Com_Error (ERR_DROP, "failed to load game DLL"); 391: if (ge->apiversion != GAME_API_VERSION) 392: Com_Error (ERR_DROP, "game is version %i, not %i", ge->apiversion, 393: GAME_API_VERSION); 394: 395: ge->Init (); 396: } 397:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.