Allow ktx-like mods to send csqc ents too.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6130 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2021-11-19 19:40:25 +00:00
parent 044a6744a7
commit 249b71bdc4
4 changed files with 58 additions and 9 deletions

View file

@ -4204,7 +4204,13 @@ static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
str = PR_GetStringOfs(prinst, OFS_PARM0); str = PR_GetStringOfs(prinst, OFS_PARM0);
if (!strcmp(str, "pr_checkextension")) //no console changing if (!strcmp(str, "pr_checkextension")) //no console changing
G_FLOAT(OFS_RETURN) = PR_EnableEBFSBuiltin("checkextension", 0); {
cvar_t *var = Cvar_FindVar(str);
if (var && !var->ival)
G_FLOAT(OFS_RETURN) = false;
else
G_FLOAT(OFS_RETURN) = PR_EnableEBFSBuiltin("checkextension", 0);
}
else if (!strcmp(str, "pr_builtin_find")) else if (!strcmp(str, "pr_builtin_find"))
G_FLOAT(OFS_RETURN) = PR_EnableEBFSBuiltin("builtin_find", 0); G_FLOAT(OFS_RETURN) = PR_EnableEBFSBuiltin("builtin_find", 0);
else if (!strcmp(str, "pr_map_builtin")) else if (!strcmp(str, "pr_map_builtin"))
@ -10124,13 +10130,13 @@ static void QCBUILTIN PF_setsendneeded(pubprogfuncs_t *prinst, struct globalvars
if (!to) if (!to)
{ //broadcast { //broadcast
for (to = 0; to < sv.allocated_client_slots; to++) for (to = 0; to < sv.allocated_client_slots; to++)
if (svs.clients[to].pendingcsqcbits) if (svs.clients[to].pendingcsqcbits && subject < svs.clients[to].max_net_ents)
svs.clients[to].pendingcsqcbits[subject] |= fl; svs.clients[to].pendingcsqcbits[subject] |= fl;
} }
else else
{ {
to--; to--;
if (to >= sv.allocated_client_slots || !svs.clients[to].pendingcsqcbits) if (to >= sv.allocated_client_slots || !svs.clients[to].pendingcsqcbits || subject >= svs.clients[to].max_net_ents)
return; //some kind of error. return; //some kind of error.
else else
svs.clients[to].pendingcsqcbits[subject] |= fl; svs.clients[to].pendingcsqcbits[subject] |= fl;

View file

@ -210,6 +210,8 @@ typedef enum
GAME_PAUSED_TIC, //(int milliseconds) GAME_PAUSED_TIC, //(int milliseconds)
GAME_CLEAR_EDICT, //v15 (sets self.fields to safe values after they're cleared) GAME_CLEAR_EDICT, //v15 (sets self.fields to safe values after they're cleared)
GAME_EDICT_CSQCSEND=200, //fte entrypoint, called when using SendEntity.
} q1qvmgameExport_t; } q1qvmgameExport_t;
@ -1872,6 +1874,29 @@ static qintptr_t QVM_pointerstat (void *offset, quintptr_t mask, const qintptr_t
return 0; return 0;
} }
//void(entity e, vector flags, entity target) setsendneeded
static qintptr_t QVM_SetSendNeeded(void *offset, quintptr_t mask, const qintptr_t *arg)
{
unsigned int subject = VM_LONG(arg[0]);
quint64_t fl = arg[1];
unsigned int to = VM_LONG(arg[2]);
if (!to)
{ //broadcast
for (to = 0; to < sv.allocated_client_slots; to++)
if (svs.clients[to].pendingcsqcbits && subject < svs.clients[to].max_net_ents)
svs.clients[to].pendingcsqcbits[subject] |= fl;
}
else
{
to--;
if (to >= sv.allocated_client_slots || !svs.clients[to].pendingcsqcbits || subject >= svs.clients[to].max_net_ents)
; //some kind of error.
else
svs.clients[to].pendingcsqcbits[subject] |= fl;
}
return 0;
}
static qintptr_t QVM_VisibleTo (void *offset, quintptr_t mask, const qintptr_t *arg) static qintptr_t QVM_VisibleTo (void *offset, quintptr_t mask, const qintptr_t *arg)
{ {
unsigned int a0 = VM_LONG(arg[0]); unsigned int a0 = VM_LONG(arg[0]);
@ -2014,6 +2039,7 @@ struct
{"pointparticles", QVM_pointparticles}, {"pointparticles", QVM_pointparticles},
{"clientstat", QVM_clientstat}, //csqc extension {"clientstat", QVM_clientstat}, //csqc extension
{"pointerstat", QVM_pointerstat}, //csqc extension {"pointerstat", QVM_pointerstat}, //csqc extension
{"setsendneeded", QVM_SetSendNeeded}, //csqc extension
{"VisibleTo", QVM_VisibleTo}, //alternative to mvdsv's visclients hack {"VisibleTo", QVM_VisibleTo}, //alternative to mvdsv's visclients hack
//sql? //sql?
@ -2622,6 +2648,11 @@ void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes)
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), botsarespecialsnowflakes, 0, 0); VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), botsarespecialsnowflakes, 0, 0);
} }
void Q1QVM_SendEntity(quint64_t sendflags)
{
VM_Call(q1qvm, GAME_EDICT_CSQCSEND, sendflags, 0, 0, 0);
}
void Q1QVM_Blocked(void) void Q1QVM_Blocked(void)
{ {
VM_Call(q1qvm, GAME_EDICT_BLOCKED, 0, 0, 0); VM_Call(q1qvm, GAME_EDICT_BLOCKED, 0, 0, 0);

View file

@ -155,6 +155,7 @@ void Q1QVM_RunPlayerThink(void);
void Q1QVM_PostThink(void); void Q1QVM_PostThink(void);
void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes); void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes);
void Q1QVM_Blocked(void); void Q1QVM_Blocked(void);
void Q1QVM_SendEntity(quint64_t sendflags);
void Q1QVM_SetNewParms(void); void Q1QVM_SetNewParms(void);
void Q1QVM_SetChangeParms(void); void Q1QVM_SetChangeParms(void);
qboolean Q1QVM_ClientCommand(void); qboolean Q1QVM_ClientCommand(void);

View file

@ -391,14 +391,25 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
csqcmsgbuffer.cursize = 0; csqcmsgbuffer.cursize = 0;
csqcmsgbuffer.currentbit = 0; csqcmsgbuffer.currentbit = 0;
//Ask CSQC to write a buffer for it.
G_INT(OFS_PARM0) = viewerent;
G_FLOAT(OFS_PARM1+0) = (int)((bits>>(SENDFLAGS_SHIFT+ 0)) & 0xffffff); //each float can only hold 24 bits before it forgets its lower bits.
G_FLOAT(OFS_PARM1+1) = (int)((bits>>(SENDFLAGS_SHIFT+24)) & 0xffffff);
G_FLOAT(OFS_PARM1+2) = (int)((bits>>(SENDFLAGS_SHIFT+48)) & 0xffffff);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); #ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
{
pr_global_struct->other = viewerent;
Q1QVM_SendEntity(bits);
}
else
#endif
{
//Ask CSQC to write a buffer for it.
G_INT(OFS_PARM0) = viewerent;
G_FLOAT(OFS_PARM1+0) = (int)((bits>>(SENDFLAGS_SHIFT+ 0)) & 0xffffff); //each float can only hold 24 bits before it forgets its lower bits.
G_FLOAT(OFS_PARM1+1) = (int)((bits>>(SENDFLAGS_SHIFT+24)) & 0xffffff);
G_FLOAT(OFS_PARM1+2) = (int)((bits>>(SENDFLAGS_SHIFT+48)) & 0xffffff);
PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity);
}
if (G_INT(OFS_RETURN)) //0 means not to tell the client about it. if (G_INT(OFS_RETURN)) //0 means not to tell the client about it.
{ {
//FIXME: don't overflow MAX_DATAGRAM... unless its too big anyway... //FIXME: don't overflow MAX_DATAGRAM... unless its too big anyway...