From c415ead7d82dd9f6c7231a75f05fff493fdfd307 Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 2 Jun 2014 16:50:40 +0000 Subject: [PATCH] Attempt to improve areaportal support. now networked (so visible clientside), but will probably break anyway, if doors open before players join. should also block some rtlights, although perhaps not completely. disable the use of quakespy stuff, using a dynamic port and no stuffcmds from random ip addresses and no mutex. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4676 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 15 ++- engine/client/cl_parse.c | 45 +++++++-- engine/client/cl_tent.c | 3 +- engine/client/cl_ui.c | 5 +- engine/client/clq2_ents.c | 3 + engine/client/pr_csqc.c | 2 - engine/client/r_surf.c | 46 +++++----- engine/client/render.h | 2 + engine/client/sys_win.c | 2 + engine/client/view.c | 2 + engine/common/bothdefs.h | 4 +- engine/common/gl_q2bsp.c | 91 ++++++------------- engine/common/net_wins.c | 15 ++- .../droid/src/com/fteqw/FTEDroidActivity.java | 2 +- engine/gl/gl_model.h | 6 +- engine/partcfgs/high.cfg | 22 ++++- engine/server/pr_cmds.c | 47 +++++++--- engine/server/q2game.h | 4 +- engine/server/svq2_game.c | 2 +- engine/server/svq3_game.c | 4 +- 20 files changed, 192 insertions(+), 130 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index b9ff48be..b2c3c26d 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -94,12 +94,14 @@ cvar_t cl_loopbackprotocol = CVARD("cl_loopbackprotocol", "qw", "Which protocol cvar_t cl_threadedphysics = CVAR("cl_threadedphysics", "0"); +#ifdef QUAKESPYAPI cvar_t localid = SCVAR("localid", ""); +static qboolean allowremotecmd = true; +#endif cvar_t r_drawflame = CVARD("r_drawflame", "1", "Set to -1 to disable ALL static entities. Set to 0 to disable only wall torches and standing flame. Set to 1 for everything drawn as normal."); qboolean forcesaveprompt; -static qboolean allowremotecmd = true; extern int total_loading_size, current_loading_size, loading_stage; @@ -2760,7 +2762,9 @@ client_connect: //fixme: make function cls.state = ca_connected; if (cls.netchan.remote_address.type != NA_LOOPBACK) Con_TPrintf ("Connected.\n"); +#ifdef QUAKESPYAPI allowremotecmd = false; // localid required now for remote cmds +#endif total_loading_size = 100; current_loading_size = 0; @@ -2770,6 +2774,7 @@ client_connect: //fixme: make function return; } +#ifdef QUAKESPYAPI // remote command from gui front end if (c == A2C_CLIENT_COMMAND) //man I hate this. { @@ -2815,6 +2820,7 @@ client_connect: //fixme: make function allowremotecmd = false; return; } +#endif // print command from somewhere if (c == 'p') { @@ -2910,7 +2916,9 @@ void CLNQ_ConnectionlessPacket(void) current_loading_size = 0; SCR_SetLoadingStage(LS_CLIENT); +#ifdef QUAKESPYAPI allowremotecmd = false; // localid required now for remote cmds +#endif //send a dummy packet. //this makes our local nat think we initialised the conversation. @@ -3476,7 +3484,9 @@ void CL_Init (void) Cvar_Register (&cl_predict_players_frac, cl_predictiongroup); Cvar_Register (&cl_solid_players, cl_predictiongroup); +#ifdef QUAKESPYAPI Cvar_Register (&localid, cl_controlgroup); +#endif Cvar_Register (&cl_muzzleflash, cl_controlgroup); @@ -4724,9 +4734,10 @@ void CL_ExecInitialConfigs(char *resetcommand) Cbuf_AddText ("exec autoexec.cfg\n", RESTRICT_LOCAL); } Cbuf_AddText ("exec fte.cfg\n", RESTRICT_LOCAL); - +#ifdef QUAKESPYAPI if (COM_FCheckExists ("frontend.cfg")) Cbuf_AddText ("exec frontend.cfg\n", RESTRICT_LOCAL); +#endif Cbuf_AddText ("cl_warncmd 1\n", RESTRICT_LOCAL); //and then it's allowed to start moaning. com_parseutf8.ival = com_parseutf8.value; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 0544c981..0cfa08fd 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -5375,6 +5375,43 @@ void CL_DumpPacket(void) } } +void CL_ParsePortalState(void) +{ + qboolean open = false; + int mode = MSG_ReadByte(); + int a1, a2; + + switch(mode) + { + case 0x80: + if (mode&2) + a1 = MSG_ReadShort(); + else + a1 = MSG_ReadByte(); + CMQ2_SetAreaPortalState(a1, !!(mode&1)); + break; + case 0xc0: + if (mode&2) + { + a1 = MSG_ReadShort(); + a2 = MSG_ReadShort(); + } + else + { + a1 = MSG_ReadByte(); + a2 = MSG_ReadByte(); + } + CMQ3_SetAreaPortalState(a1, a2, !!(mode&1)); + break; + + default: + //to be phased out. + mode |= MSG_ReadByte()<<8; + CMQ2_SetAreaPortalState(mode & 0x7fff, !!(mode&0x8000)); + break; + } +} + #define SHOWNET(x) if(cl_shownet.value>=2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); #define SHOWNET2(x, y) if(cl_shownet.value>=2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x); /* @@ -5855,15 +5892,9 @@ void CLQW_ParseServerMessage (void) // case svc_ftesetclientpersist: // CL_ParseClientPersist(); // break; -#ifdef Q2BSPS case svc_setportalstate: - i = MSG_ReadByte(); - j = MSG_ReadByte(); - i *= j & 127; - j &= ~128; - CMQ2_SetAreaPortalState(i, j!=0); + CL_ParsePortalState(); break; -#endif case svcfte_showpic: SCR_ShowPic_Create(); diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index bcb82c43..859b6162 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -640,7 +640,8 @@ static void CL_ClearExplosion(explosion_t *exp, vec3_t org) VectorClear(exp->velocity); VectorClear(exp->angles); VectorClear(exp->avel); - P_DelinkTrailstate(&(exp->trailstate)); + if (pe) + P_DelinkTrailstate(&(exp->trailstate)); exp->traileffect = P_INVALID; VectorCopy(org, exp->origin); VectorCopy(org, exp->oldorigin); diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index e6e964dd..360c1a50 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -577,6 +577,7 @@ struct q3refdef_s { void D3D9_Set2D (void); void VQ3_RenderView(const q3refdef_t *ref) { + int i; extern cvar_t r_torch; VectorCopy(ref->vieworg, r_refdef.vieworg); r_refdef.viewangles[0] = -(atan2(ref->viewaxis[0][2], sqrt(ref->viewaxis[0][1]*ref->viewaxis[0][1]+ref->viewaxis[0][0]*ref->viewaxis[0][0])) * 180 / M_PI); @@ -610,7 +611,9 @@ void VQ3_RenderView(const q3refdef_t *ref) VectorCopy(ref->viewaxis[2], dl->axis[2]); } - memcpy(cl.q2frame.areabits, ref->areamask, sizeof(cl.q2frame.areabits)); + r_refdef.areabitsknown = true; + for (i = 0; i < sizeof(cl.q2frame.areabits)/sizeof(int); i++) + ((int*)r_refdef.areabits)[i] = ((int*)ref->areamask)[i] ^ ~0; R_RenderView(); r_refdef.playerview = NULL; #ifdef GLQUAKE diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 31382d31..c1125f5f 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1836,6 +1836,9 @@ void CLQ2_CalcViewValues (void) q2player_state_t *ps, *ops; extern cvar_t gl_cshiftenabled; + r_refdef.areabitsknown = true; + memcpy(r_refdef.areabits, cl.q2frame.areabits, sizeof(r_refdef.areabits)); + r_refdef.useperspective = true; // find the previous frame to interpolate from diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index fa0eb7b1..b527c701 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -3468,9 +3468,7 @@ static void QCBUILTIN PF_cs_OpenPortal (pubprogfuncs_t *prinst, struct globalvar #ifdef Q3BSPS if (cl.worldmodel->fromgame == fg_quake3) { - int i; int state = G_FLOAT(OFS_PARM1)!=0; - client_t *client; edict_t *portal = G_EDICT(prinst, OFS_PARM0); int area1 = portal->pvsinfo.areanum, area2 = portal->pvsinfo.areanum2; if (area1 == area2 || !area1 || !area2) diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index b1539df2..6cd01c22 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -30,7 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern cvar_t r_ambient; static vec3_t modelorg; /*set before recursively entering the visible surface finder*/ -static qbyte areabits[MAX_Q2MAP_AREAS/8]; model_t *currentmodel; @@ -1634,11 +1633,12 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) pleaf = (mleaf_t *)node; // check for door connected areas -// if (areabits) - { - if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) - return; // not visible - } + if (! (r_refdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) + return; // not visible + + c = pleaf->cluster; + if (c >= 0) + frustumvis[c>>3] |= 1<<(c&7); mark = pleaf->firstmarksurface; c = pleaf->nummarksurfaces; @@ -1698,7 +1698,7 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) if ( (surf->flags & SURF_PLANEBACK) != sidebit ) continue; // wrong side - surf->visframe = r_framecount+1;//-1; + surf->visframe = 0;//r_framecount+1;//-1; Surf_RenderDynamicLightmaps (surf); @@ -1830,9 +1830,13 @@ start: { pleaf = (mleaf_t *)node; - if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) + if (! (r_refdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return; // not visible + c = pleaf->cluster; + if (c >= 0) + frustumvis[c>>3] |= 1<<(c&7); + mark = pleaf->firstmarksurface; for (c = pleaf->nummarksurfaces; c; c--) { @@ -2286,19 +2290,15 @@ void Surf_DrawWorld (void) #ifdef Q2BSPS if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) { - int leafnum; - int clientarea; -#ifdef Q2CLIENT - if (cls.protocol == CP_QUAKE2) //we can get server sent info - { - memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); - } - else -#endif - { //generate the info each frame. - leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); - clientarea = CM_LeafArea (cl.worldmodel, leafnum); - CM_WriteAreaBits(cl.worldmodel, areabits, clientarea); + frustumvis = frustumvis_; + memset(frustumvis, 0, (cl.worldmodel->numclusters + 7)>>3); + + if (!r_refdef.areabitsknown) + { //generate the info each frame, as the gamecode didn't tell us what to use. + int leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); + int clientarea = CM_LeafArea (cl.worldmodel, leafnum); + CM_WriteAreaBits(cl.worldmodel, r_refdef.areabits, clientarea); + r_refdef.areabitsknown = true; } #ifdef Q3BSPS if (cl.worldmodel->fromgame == fg_quake3) @@ -2314,6 +2314,8 @@ void Surf_DrawWorld (void) VectorCopy (r_refdef.vieworg, modelorg); Surf_RecursiveQ2WorldNode (cl.worldmodel->nodes); } + + surfvis = frustumvis; } else #endif @@ -2351,7 +2353,7 @@ void Surf_DrawWorld (void) VectorCopy (r_origin, modelorg); frustumvis = frustumvis_; - memset(frustumvis, 0, (cl.worldmodel->numleafs + 7)>>3); + memset(frustumvis, 0, (cl.worldmodel->numclusters + 7)>>3); if (r_refdef.useperspective) Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0x1f); diff --git a/engine/client/render.h b/engine/client/render.h index ea7c225e..a972a744 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -236,6 +236,8 @@ typedef struct int rt_ripplemap; /*read by 2d. used by 3d (internal ripplemap buffer used if not set)*/ qbyte *forcedvis; + qboolean areabitsknown; + qbyte areabits[MAX_MAP_AREA_BYTES]; struct { diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 66caaab4..8c6cf8a5 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -1337,6 +1337,7 @@ void Sys_Init (void) Cvar_Register(&sys_disableTaskSwitch, "System vars"); Cmd_AddCommandD("sys_register_file_associations", Sys_Register_File_Associations_f, "Register FTE as the system handler for .bsp .mvd .qwd .dem files. Also register the qw:// URL protocol. This command will probably trigger a UAC prompt in Windows Vista and up. Deny it for current-user-only asociations (will also prevent listing in windows' 'default programs' ui due to microsoft bugs/limitations)."); +#ifdef QUAKESPYAPI #ifndef CLIENTONLY if (!isDedicated && !COM_CheckParm("-nomutex")) #else @@ -1362,6 +1363,7 @@ void Sys_Init (void) "qwcl"); // Semaphore name } #endif +#endif #if 0 if (!QueryPerformanceFrequency (&PerformanceFreq)) diff --git a/engine/client/view.c b/engine/client/view.c index 947af843..53da2545 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1209,6 +1209,8 @@ void V_ClearRefdef(playerview_t *pv) r_refdef.drawsbar = !cl.intermission; r_refdef.flags = 0; + r_refdef.areabitsknown = false; + // memset(r_refdef.postprocshader, 0, sizeof(r_refdef.postprocshader)); // memset(r_refdef.postprocsize, 0, sizeof(r_refdef.postprocsize)); // r_refdef.postproccube = 0; diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index ebb7a95d..bcaf1adf 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -264,12 +264,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if defined(_WIN32) && !defined(MULTITHREAD) //always thread on win32 non-minimal builds #define MULTITHREAD #endif - -//these things were moved to plugins. #endif #endif +//#define QUAKESPYAPI //define this if you want the engine to be usable via gamespy/quakespy, which has been dead for a long time now. + #ifdef FTE_TARGET_WEB //try to trim the fat #undef VOICECHAT //too lazy to compile speex diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 7ad4dace..9101c003 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -6091,7 +6091,6 @@ AREAPORTALS static void FloodArea_r (q2carea_t *area, int floodnum) { int i; - q2dareaportal_t *p; if (area->floodvalid == floodvalid) { @@ -6102,11 +6101,22 @@ static void FloodArea_r (q2carea_t *area, int floodnum) area->floodnum = floodnum; area->floodvalid = floodvalid; - p = &map_areaportals[area->firstareaportal]; - for (i=0 ; inumareaportals ; i++, p++) + if (mapisq3) { - if (portalopen[p->portalnum]) - FloodArea_r (&map_q2areas[p->otherarea], floodnum); + for (i=1 ; i0) + FloodArea_r (&map_q2areas[i], floodnum); + } + } + else + { + q2dareaportal_t *p = &map_areaportals[area->firstareaportal]; + for (i=0 ; inumareaportals ; i++, p++) + { + if (portalopen[p->portalnum]) + FloodArea_r (&map_q2areas[p->otherarea], floodnum); + } } } @@ -6119,22 +6129,10 @@ FloodAreaConnections */ static void FloodAreaConnections (void) { - int i, j; + int i; q2carea_t *area; int floodnum; - if (mapisq3) - { - // area 0 is not used - for (i=1 ; i numareas || area2 > numareas) Host_Error ("area > numareas"); - if (mapisq3) - { - int i; - for (i=1 ; i>3] |= 1<<(i&7); - } - } - else - { - floodnum = map_q2areas[area].floodnum; - for (i=0 ; i>3] |= 1<<(i&7); - } + if (map_q2areas[i].floodnum == floodnum || !area) + buffer[i>>3] |= 1<<(i&7); } } return bytes; } -#ifndef CLIENTONLY -void CM_InitPortalState(void) -{ - int i; - //if we're not running q2, force all q2 portals open. - if (svs.gametype != GT_QUAKE2 && !mapisq3) - { - for (i = 0; i < numareas; i++) - map_q2areas[i].floodnum = 0; - } -} -#endif - /* =================== CM_WritePortalState diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index ca0eb9fc..23745e03 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -2537,7 +2537,7 @@ qboolean NET_PortToAdr (int adrfamily, const char *s, netadr_t *a) port = strtoul(s, &e, 10); if (*e) //if *e then its not just a single number in there, so treat it as a proper address. return NET_StringToAdr(s, 0, a); - else if (port) + else if (e != s) //if we actually read something (even a 0) { memset(a, 0, sizeof(*a)); a->port = htons((unsigned short)port); @@ -2662,7 +2662,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i // // determine my name & address if we don't already know it // - if (net_local_cl_ipadr.type == NA_INVALID) + if (!isserver && net_local_cl_ipadr.type == NA_INVALID) NET_GetLocalAddress (newsocket, &net_local_cl_ipadr); newcon = Z_Malloc(sizeof(*newcon)); @@ -5362,10 +5362,10 @@ void NET_GetLocalAddress (int socket, netadr_t *out) if (!notvalid) { - Con_TPrintf("IP address %s\n", NET_AdrToString (adrbuf, sizeof(adrbuf), out) ); +// Con_TPrintf("Client IP address %s\n", NET_AdrToString (adrbuf, sizeof(adrbuf), out) ); return; } - Con_Printf("Couldn't detect local ip\n"); +// Con_Printf("Couldn't detect local ip\n"); #endif out->type = NA_INVALID; @@ -5492,7 +5492,12 @@ void NET_InitClient(void) { const char *port; int p; + +#ifdef QUAKESPYAPI port = STRINGIFY(PORT_QWCLIENT); +#else + port = "0"; +#endif p = COM_CheckParm ("-clport"); if (p && p < com_argc) @@ -5520,7 +5525,7 @@ void NET_InitClient(void) net_message.maxsize = sizeof(net_message_buffer); net_message.data = net_message_buffer; - Con_TPrintf("Client port Initialized\n"); +// Con_TPrintf("Client port Initialized\n"); } #endif diff --git a/engine/droid/src/com/fteqw/FTEDroidActivity.java b/engine/droid/src/com/fteqw/FTEDroidActivity.java index d3c2d5ca..c9151df3 100644 --- a/engine/droid/src/com/fteqw/FTEDroidActivity.java +++ b/engine/droid/src/com/fteqw/FTEDroidActivity.java @@ -266,7 +266,7 @@ public class FTEDroidActivity extends Activity public void run() { theview.setVisibility(theview.GONE); - AlertDialog ad = new AlertDialog.Builder(act); + AlertDialog ad = new AlertDialog.Builder(act).create(); ad.setTitle("FTE ERROR"); ad.setMessage(errormsg); ad.setCancelable(false); diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index eaa0bd94..71c23b5b 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -1002,7 +1002,7 @@ void CM_Init(void); qboolean CM_SetAreaPortalState (struct model_s *mod, int portalnum, qboolean open); qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, qbyte *visbits); -qboolean VARGS CM_AreasConnected (struct model_s *mod, int area1, int area2); +qboolean VARGS CM_AreasConnected (struct model_s *mod, unsigned int area1, unsigned int area2); int CM_NumClusters (struct model_s *mod); int CM_ClusterSize (struct model_s *mod); int CM_LeafContents (struct model_s *mod, int leafnum); @@ -1019,8 +1019,8 @@ int CM_HeadnodeForBox (struct model_s *mod, vec3_t mins, vec3_t maxs); struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles); struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs); -void VARGS CMQ2_SetAreaPortalState (int portalnum, qboolean open); -void CMQ3_SetAreaPortalState (int area1, int area2, qboolean open); +void VARGS CMQ2_SetAreaPortalState (unsigned int portalnum, qboolean open); +void CMQ3_SetAreaPortalState (unsigned int area1, unsigned int area2, qboolean open); #endif diff --git a/engine/partcfgs/high.cfg b/engine/partcfgs/high.cfg index 4b4cd7c6..75e011ab 100644 --- a/engine/partcfgs/high.cfg +++ b/engine/partcfgs/high.cfg @@ -296,14 +296,30 @@ cl_expsprite 0 //r_effect "progs/s_explod.spr" hidden 1 ////////////////////////////////////////// +//for when a spawn dies. +//also used by TF for emp explosions. //r_part te_tarexplosion //{ //} ////////////////////////////////////////// -//r_part te_lavasplash -//{ -//} +//cthon falling into lava. +//often also used for TF gas grenades. +r_part te_lavasplash +{ + texture "particles/fteparticlefont.tga" + tcoords 129 1 191 63 256 + count 654 + scale 15 + alpha 0.7 + die 4 + randomvel 64 + rgb 255 128 128 + gravity 50 + blend add + spawnorg 192 64 + up 48 +} ////////////////////////////////////////// //FIXME: what if we don't have glsl support? diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 3886ad0f..43a5508f 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -6224,9 +6224,9 @@ static void QCBUILTIN PF_log(pubprogfuncs_t *prinst, struct globalvars_s *pr_glo } -#ifdef Q2BSPS static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { +#ifdef Q2BSPS if (sv.world.worldmodel->fromgame == fg_quake2) { int i, portal; @@ -6240,16 +6240,29 @@ static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s { if (client->state >= cs_connected) { - ClientReliableWrite_Begin(client, svc_setportalstate, 3); - if (state) - ClientReliableWrite_Short(client, portal | (state<<15)); + ClientReliableWrite_Begin(client, svc_setportalstate, 4); + if (portal >= 0x80) + { //new pathway, to be enabled at some point + if (portal > 0xff) + { + ClientReliableWrite_Byte(client, 0x80 | 2 | state); + ClientReliableWrite_Short(client, portal); + } + else + { + ClientReliableWrite_Byte(client, 0x80 | 0 | state); + ClientReliableWrite_Byte(client, portal); + } + } else - ClientReliableWrite_Short(client, portal); + ClientReliableWrite_Short(client, portal | (state<<15)); } } CMQ2_SetAreaPortalState(portal, state); } - else if (sv.world.worldmodel->fromgame == fg_quake3) +#endif +#ifdef Q3BSPS + if (sv.world.worldmodel->fromgame == fg_quake3) { int i; int state = G_FLOAT(OFS_PARM1)!=0; @@ -6258,21 +6271,29 @@ static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s int area1 = portal->pvsinfo.areanum, area2 = portal->pvsinfo.areanum2; if (area1 == area2 || !area1 || !area2) return; - /*for (client = svs.clients, i = 0; i < sv.allocated_client_slots; i++, client++) + for (client = svs.clients, i = 0; i < sv.allocated_client_slots; i++, client++) { if (client->state >= cs_connected) { - ClientReliableWrite_Begin(client, svc_setportalstate, 3); - if (state) - ClientReliableWrite_Short(client, portal | (state<<15)); + ClientReliableWrite_Begin(client, svc_setportalstate, 6); + if (area1 > 0xff || area2 > 0xff) + { + ClientReliableWrite_Byte(client, 0xc0 | 2 | state); + ClientReliableWrite_Short(client, area1); + ClientReliableWrite_Short(client, area2); + } else - ClientReliableWrite_Short(client, portal); + { + ClientReliableWrite_Byte(client, 0x80 | 0 | state); + ClientReliableWrite_Byte(client, area1); + ClientReliableWrite_Byte(client, area2); + } } - }*/ + } CMQ3_SetAreaPortalState(portal->pvsinfo.areanum, portal->pvsinfo.areanum2, state); } -} #endif +} //EXTENSION: DP_QC_COPYENTITY diff --git a/engine/server/q2game.h b/engine/server/q2game.h index 26848056..fad4bebe 100644 --- a/engine/server/q2game.h +++ b/engine/server/q2game.h @@ -209,8 +209,8 @@ typedef struct int (VARGS *pointcontents) (vec3_t point); qboolean (VARGS *inPVS) (vec3_t p1, vec3_t p2); qboolean (VARGS *inPHS) (vec3_t p1, vec3_t p2); - void (VARGS *SetAreaPortalState) (int portalnum, qboolean open); - qboolean (VARGS *AreasConnected) (int area1, int area2); + void (VARGS *SetAreaPortalState) (unsigned int portalnum, qboolean open); + qboolean (VARGS *AreasConnected) (unsigned int area1, unsigned int area2); // an entity will never be sent to a client or used for collision // if it is not passed to linkentity. If the size, position, or diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index ea836481..1d8d2be5 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -452,7 +452,7 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2) return true; } -qboolean VARGS PFQ2_AreasConnected(int area1, int area2) +qboolean VARGS PFQ2_AreasConnected(unsigned int area1, unsigned int area2) { //FIXME: requires q2/q3 bsp return CM_AreasConnected(sv.world.worldmodel, area1, area2); diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index c4dfc873..978be4dd 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -283,7 +283,7 @@ static void Q3G_LinkEntity(q3sharedEntity_t *ent) { clusters[i] = CM_LeafCluster(sv.world.worldmodel, leafs[i]); area = CM_LeafArea(sv.world.worldmodel, leafs[i]); - if(area >= 0) + if(area > 0) //FIXME: this should be >= { // doors may legally straggle two areas, // but nothing should ever need more than that @@ -752,6 +752,8 @@ static int SVQ3_BotGetSnapshotEntity(int client, int entnum) static void SVQ3_Adjust_Area_Portal_State(q3sharedEntity_t *ge, qboolean open) { q3serverEntity_t *se = SENTITY_FOR_GENTITY(ge); + if (se->areanum == -1 || se->areanum2 == -1) //not linked properly. + return; CMQ3_SetAreaPortalState(se->areanum, se->areanum2, open); }