Try to fix up some splitscreen quirks.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5917 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-06-25 18:50:42 +00:00
parent 4d1b686c2f
commit d602e51e54
17 changed files with 39 additions and 39 deletions

View File

@ -996,7 +996,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
int i;
player_info_t *s;
int end;
extern cvar_t cl_demospeed, cl_splitscreen;
extern cvar_t cl_demospeed;
if (cls.state != ca_active)
return;

View File

@ -4755,7 +4755,6 @@ void CLQW_ParsePlayerinfo (void)
//add a new splitscreen autotrack view if we can
if (cl.splitclients < MAX_SPLITS && !cl.players[num].spectator)
{
extern cvar_t cl_splitscreen;
if (cl.splitclients < cl_splitscreen.value+1)
{
for (i = 0; i < cl.splitclients; i++)

View File

@ -59,7 +59,6 @@ usercmd_t cl_pendingcmd[MAX_SPLITS];
/*kinda a hack...*/
unsigned int con_splitmodifier;
cvar_t cl_forceseat = CVARAD("in_forceseat", "0", "in_forcesplitclient", "Overrides the device identifiers to control a specific client from any device. This can be used for debugging mods, where you only have one keyboard/mouse.");
extern cvar_t cl_splitscreen;
int CL_TargettedSplit(qboolean nowrap)
{
int mod;
@ -1723,6 +1722,7 @@ void CL_UpdateSeats(void)
}
if (!*InfoBuf_ValueForKey(info, "skin")) //give players the same skin by default, because we can. q2 cares for teams. qw might as well (its not like anyone actually uses them thanks to enemy-skin forcing).
InfoBuf_SetKey(info, "skin", InfoBuf_ValueForKey(&cls.userinfo[0], "skin"));
InfoBuf_SetKey(info, "chat", "");
#ifdef SVNREVISION
if (strcmp(STRINGIFY(SVNREVISION), "-"))
@ -2093,7 +2093,7 @@ static void CL_SendUserinfoUpdate(void)
void CL_SendCmd (double frametime, qboolean mainloop)
{
sizebuf_t buf;
qbyte data[MAX_DATAGRAM];
qbyte data[MAX_DATAGRAM*16];
int i, plnum;
usercmd_t *cmd;
float wantfps;
@ -2581,7 +2581,7 @@ CL_InitInput
*/
void CL_InitInput (void)
{
static char pcmd[MAX_SPLITS][3][5];
static char pcmd[MAX_SPLITS][3][6];
unsigned int sp, i;
#define inputnetworkcvargroup "client networking options"
cl.splitclients = 1;

View File

@ -1737,6 +1737,9 @@ void CL_RequestNextDownload (void)
cl.sendprespawn = false;
if (cl_splitscreen.ival && !(cls.fteprotocolextensions & PEXT_SPLITSCREEN))
Con_TPrintf(CON_WARNING "Splitscreen requested but not available on this server.\n");
if (cl.worldmodel && cl.worldmodel->loadstate == MLS_LOADING)
COM_WorkerPartialSync(cl.worldmodel, &cl.worldmodel->loadstate, MLS_LOADING);
@ -6777,8 +6780,8 @@ static void CL_ParsePrecache(void)
model_t *model;
CL_CheckOrEnqueDownloadFile(s, s, 0);
model = Mod_ForName(Mod_FixName(s, cl.model_name[1]), (i == 1)?MLV_ERROR:MLV_WARN);
if (!model)
Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
// if (!model)
// Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model;
Q_strncpyz (cl.model_name[i], s, sizeof(cl.model_name[i]));
@ -6796,8 +6799,8 @@ static void CL_ParsePrecache(void)
if (S_HaveOutput())
CL_CheckOrEnqueDownloadFile(va("sound/%s", s), NULL, 0);
sfx = S_PrecacheSound (s);
if (!sfx)
Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
// if (!sfx)
// Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
cl.sound_precache[i] = sfx;
Q_strncpyz (cl.sound_name[i], s, sizeof(cl.sound_name[i]));
}
@ -7098,11 +7101,14 @@ void CLQW_ParseServerMessage (void)
CLQW_ParseServerData ();
break;
case svcfte_splitscreenconfig:
j = cl.splitclients;
cl.splitclients = MSG_ReadByte();
for (i = 0; i < cl.splitclients && i < MAX_SPLITS; i++)
{
cl.playerview[i].playernum = MSG_ReadByte();
cl.playerview[i].viewentity = cl.playerview[i].playernum+1;
if (i>=j) //its new.
cl.playerview[i].chatstate = 0;
}
if (i < cl.splitclients)
{

View File

@ -66,6 +66,7 @@ void INS_SetupControllerAudioDevices(qboolean enabled); //creates audio devices
#define DEVID_UNSET ~0u
extern cvar_t cl_splitscreen;
extern cvar_t cl_nodelta;
extern cvar_t cl_c2spps;
extern cvar_t cl_c2sImpulseBackup;

View File

@ -991,7 +991,6 @@ void M_Menu_Teamplay_Items_Status_Location_Misc_f (void)
void M_Menu_Network_f (void)
{
#if MAX_SPLITS > 1
extern cvar_t cl_splitscreen;
static const char *splitopts[] = {
"Disabled",
"2 Screens",

View File

@ -316,7 +316,6 @@ void M_Menu_Load_f (void)
#endif
extern cvar_t cl_splitscreen;
void M_Menu_SinglePlayer_f (void)
{
emenu_t *menu;

View File

@ -891,9 +891,6 @@ void M_Menu_Keys_f (void)
int y;
emenu_t *menu;
vfsfile_t *bindslist;
#if MAX_SPLITS > 1
extern cvar_t cl_splitscreen;
#endif
menu = M_CreateMenu(0);
switch(M_GameType())

View File

@ -1313,7 +1313,7 @@ static void PM_NudgePosition (void)
}
}
if (pmove.safeorigin_known)
if (pmove.safeorigin_known && PM_TestPlayerPosition(pmove.safeorigin, false))
VectorCopy (pmove.safeorigin, pmove.origin);
else
VectorCopy (base, pmove.origin);

View File

@ -58,7 +58,7 @@ typedef struct
// player state
vec3_t origin;
vec3_t safeorigin;
vec3_t safeorigin; //valid when safeorigin_known. needed for extrasr4's ladders otherwise they bug out.
vec3_t angles;
vec3_t velocity;
vec3_t basevelocity;

View File

@ -18,7 +18,7 @@
static char *cvargroup_progs = "Progs variables";
cvar_t utf8_enable = CVARD("utf8_enable", "0", "When 1, changes the qc builtins to act upon codepoints instead of bytes. Do not use unless com_parseutf8 is also set.");
cvar_t sv_gameplayfix_nolinknonsolid = CVARD("sv_gameplayfix_nolinknonsolid", "1", "When 0, setorigin et al will not link the entity into the collision nodes (which is faster, especially if you have a lot of non-solid entities. When 1, allows entities to freely switch between .solid values (except for SOLID_BSP) without relinking. A lot of DP mods assume a value of 1 and will bug out otherwise, while 0 will restore a bugs present in various mods.");
cvar_t sv_gameplayfix_linknonsolid = CVARD("sv_gameplayfix_nolinknonsolid", "1", "When 0, setorigin et al will not link the entity into the collision nodes (which is faster, especially if you have a lot of non-solid entities. When 1, allows entities to freely switch between .solid values (except for SOLID_BSP) without relinking. A lot of DP mods assume a value of 1 and will bug out otherwise, while 0 will restore a bugs present in various mods.");
cvar_t sv_gameplayfix_blowupfallenzombies = CVARD("sv_gameplayfix_blowupfallenzombies", "0", "Allow findradius to find non-solid entities. This may break certain mods. It is better for mods to use FL_FINDABLE_NONSOLID instead.");
cvar_t sv_gameplayfix_findradiusdistancetobox = CVARD("sv_gameplayfix_findradiusdistancetobox", "0", "When 1, findradius checks to the nearest part of the entity instead of only its origin, making it find slightly more entities.");
cvar_t sv_gameplayfix_droptofloorstartsolid = CVARD("sv_gameplayfix_droptofloorstartsolid", "0", "When droptofloor fails, this causes a second attemp, but with traceline instead.");
@ -86,7 +86,7 @@ void PF_Common_RegisterCvars(void)
Cvar_Register (&sv_gameplayfix_blowupfallenzombies, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_findradiusdistancetobox, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_nolinknonsolid, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_linknonsolid, cvargroup_progs);
Cvar_Register (&sv_gameplayfix_droptofloorstartsolid, cvargroup_progs);
Cvar_Register (&dpcompat_findradiusarealinks, cvargroup_progs);
#ifdef HAVE_LEGACY

View File

@ -1319,7 +1319,6 @@ MSV_OpenUserDatabase();
#ifndef SERVERONLY
/*force coop 1 if splitscreen and not deathmatch*/
{
extern cvar_t cl_splitscreen;
if (cl_splitscreen.value && !deathmatch.value && !coop.value)
Cvar_Set(&coop, "1");
}

View File

@ -450,7 +450,7 @@ void SV_FinalMessage (char *message)
MSG_WriteByte (&buf, svc_disconnect);
for (i=0, cl = svs.clients ; i<svs.allocated_client_slots ; i++, cl++)
if (cl->state >= cs_spawned)
if (cl->state >= cs_spawned && !cl->controlled)
if (ISNQCLIENT(cl) || ISQWCLIENT(cl))
Netchan_Transmit (&cl->netchan, buf.cursize
, buf.data, 10000);
@ -621,7 +621,8 @@ void SV_DropClient (client_t *drop)
#ifndef SERVERONLY
if (drop->netchan.remote_address.type == NA_LOOPBACK)
{
Netchan_Transmit(&drop->netchan, 0, "", SV_RateForClient(drop));
if (drop->protocol != SCP_BAD)
Netchan_Transmit(&drop->netchan, 0, "", SV_RateForClient(drop));
#ifdef warningmsg
#pragma warningmsg("This means that we may not see the reason we kicked ourselves.")
#endif
@ -2378,6 +2379,7 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
cl->playerclass = 0;
cl->pendingdeltabits = NULL;
cl->pendingcsqcbits = NULL;
cl->seat = curclients;
cl->edict = NULL;
#ifdef Q2SERVER

View File

@ -104,16 +104,9 @@ sizebuf_t *ClientReliable_StartWrite(client_t *cl, int maxsize)
return MVDWrite_Begin(dem_all, 0, maxsize);
#endif
if (cl->controller)
if (cl->seat)
{
client_t *sp;
int pnum = 0;
for (sp = cl->controller; sp; sp = sp->controlled)
{
if (sp == cl)
break;
pnum++;
}
int pnum = cl->seat;
cl = cl->controller;
ClientReliableWrite_Begin (cl, svcfte_choosesplitclient, 2+maxsize);
ClientReliableWrite_Byte (cl, pnum);

View File

@ -1651,8 +1651,7 @@ void SV_SendFixAngle(client_t *client, sizebuf_t *msg, int fixtype, qboolean rol
msg = NULL; //try to keep them vaugely reliable, where feasable.
if (!msg)
msg = ClientReliable_StartWrite(client, 10);
if (client->seat)
else if (client->seat)
{
MSG_WriteByte(msg, svcfte_choosesplitclient);
MSG_WriteByte(msg, client->seat);

View File

@ -4403,7 +4403,7 @@ static void SV_UpdateSeats(client_t *controller)
return; //wait for the clientinfo stuff instead.
for (curclients = 0, cl = controller; cl; cl = cl->controlled)
curclients++;
cl->seat = curclients++;
ClientReliableWrite_Begin(controller, svcfte_splitscreenconfig, 2+curclients);
ClientReliableWrite_Byte(controller, curclients);
@ -4412,11 +4412,11 @@ static void SV_UpdateSeats(client_t *controller)
ClientReliableWrite_Byte(controller, cl - svs.clients);
}
for (curclients = 0, cl = controller; cl; cl = cl->controlled, curclients++)
/*for (curclients = 0, cl = controller; cl; cl = cl->controlled, curclients++)
{
SV_SendFixAngle(cl, NULL, FIXANGLE_FIXED, false);
cl->edict->v->fixangle = FIXANGLE_NO; //no point doing it again
}
}*/
}
/*
@ -5375,7 +5375,8 @@ static void Cmd_AddSeat_f(void)
if (!num || host_client->joinobservelockeduntil > realtime)
return;
host_client->joinobservelockeduntil = realtime + 2;
if (host_client->netchan.remote_address.type != NA_LOOPBACK)
host_client->joinobservelockeduntil = realtime + 2;
for (count = 1, prev = host_client, cl = host_client->controlled; cl; cl = cl->controlled)
{
@ -8251,6 +8252,9 @@ void SV_ExecuteClientMessage (client_t *cl)
case clc_stringcmd:
s = MSG_ReadString ();
SV_ExecuteUserCommand (s, false);
#ifdef NETPREPARSE
NPP_Flush(); //flush it just in case there was an error and we stopped preparsing. This is only really needed while debugging.
#endif
host_client = cl;
sv_player = cl->edict;
@ -8819,7 +8823,9 @@ void SVNQ_ExecuteClientMessage (client_t *cl)
case clc_stringcmd:
s = MSG_ReadString ();
SV_ExecuteUserCommand (s, false);
#ifdef NETPREPARSE
NPP_Flush(); //flush it just in case there was an error and we stopped preparsing. This is only really needed while debugging.
#endif
host_client = cl;
sv_player = cl->edict;
if (cl->state < cs_connected)

View File

@ -36,7 +36,7 @@ line of sight checks trace->crosscontent, but bullets don't
size_t areagridsequence; //used to avoid poking the same ent twice.
extern cvar_t sv_compatiblehulls;
extern cvar_t sv_gameplayfix_nolinknonsolid;
extern cvar_t sv_gameplayfix_linknonsolid;
typedef struct
{
@ -655,7 +655,7 @@ void QDECL World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers)
w->worldmodel->funcs.FindTouchedLeafs(w->worldmodel, &ent->pvsinfo, ent->v->absmin, ent->v->absmax);
}
if (ent->v->solid == SOLID_NOT && !sv_gameplayfix_nolinknonsolid.ival)
if (ent->v->solid == SOLID_NOT && !sv_gameplayfix_linknonsolid.ival)
return;
#ifdef USEAREAGRID