fix terrain issues.

xmpp: add support for /poke and /slap.
lame notify hack. need to work out what I'm doing with that stuff.
xmpp: easier targeting of friends (engine finds it easier too... yay less bugs).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4414 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-06-29 21:08:09 +00:00
parent 0823eb0968
commit 8db6963fc4
8 changed files with 219 additions and 85 deletions

View File

@ -413,6 +413,12 @@ qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t
if (currentplug->conexecutecommand) if (currentplug->conexecutecommand)
{ {
con->notif_x = 0;
con->notif_y = 8*4;
con->notif_w = vid.width;
con->notif_t = 8;
con->notif_l = 4;
con->flags |= CONF_NOTIFY;
con->userdata = currentplug; con->userdata = currentplug;
con->linebuffered = Plug_SubConsoleCommand; con->linebuffered = Plug_SubConsoleCommand;
} }

View File

@ -882,30 +882,6 @@ void SCR_ShowPic_Script_f(void)
//============================================================================= //=============================================================================
/*
====================
CalcFov
====================
*/
float CalcFov (float fov_x, float width, float height)
{
float a;
float x;
if (fov_x < 1 || fov_x > 179)
Sys_Error ("Bad fov: %f", fov_x);
x = fov_x/360*M_PI;
x = tan(x);
x = width/x;
a = atan (height/x);
a = a*360/M_PI;
return a;
}
void SCR_Fov_Callback (struct cvar_s *var, char *oldvalue) void SCR_Fov_Callback (struct cvar_s *var, char *oldvalue)
{ {
if (var->value < 10) if (var->value < 10)

View File

@ -1142,11 +1142,15 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
qboolean csqc_rebuildmatricies; qboolean csqc_rebuildmatricies;
float csqc_proj_matrix[16]; float csqc_proj_matrix[16];
float csqc_proj_matrix_inverse[16]; float csqc_proj_matrix_inverse[16];
void V_ApplyAFov(void);
void buildmatricies(void) void buildmatricies(void)
{ {
float modelview[16]; float modelview[16];
float proj[16]; float proj[16];
if (r_refdef.dirty & RDFD_FOV)
V_ApplyAFov();
/*build modelview and projection*/ /*build modelview and projection*/
Matrix4x4_CM_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg); Matrix4x4_CM_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
Matrix4x4_CM_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4); Matrix4x4_CM_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4);

View File

@ -1064,7 +1064,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
if (outpos && (!buf || buf->maxsize - buf->cursize >= outpos+4)) if (outpos && (!buf || buf->maxsize - buf->cursize >= outpos+4))
{ {
if (buf && (cl_voip_send.ival & ~4)) if (buf && (cl_voip_send.ival != 4))
{ {
MSG_WriteByte(buf, clc); MSG_WriteByte(buf, clc);
MSG_WriteByte(buf, (s_voip.enccodec<<4) | (s_voip.generation & 0x0f)); /*gonna leave that nibble clear here... in this version, the client will ignore packets with those bits set. can use them for codec or something*/ MSG_WriteByte(buf, (s_voip.enccodec<<4) | (s_voip.generation & 0x0f)); /*gonna leave that nibble clear here... in this version, the client will ignore packets with those bits set. can use them for codec or something*/

View File

@ -1014,7 +1014,56 @@ void V_CalcIntermissionRefdef (playerview_t *pv)
v_idlescale.value = old; v_idlescale.value = old;
} }
float CalcFov (float fov_x, float width, float height); float CalcFov (float fov_x, float width, float height)
{
float a;
float x;
if (fov_x < 1 || fov_x > 179)
Sys_Error ("Bad fov: %f", fov_x);
x = fov_x/360*M_PI;
x = tan(x);
x = width/x;
a = atan (height/x);
a = a*360/M_PI;
return a;
}
void V_ApplyAFov(void)
{
//explicit fov overrides aproximate fov.
//aproximate fov is our regular fov value. explicit is settable by gamecode for weird aspect ratios
if (!r_refdef.fov_x || !r_refdef.fov_y)
{
extern cvar_t r_stereo_method, r_stereo_separation;
float ws;
float afov = r_refdef.afov;
if (!afov) //make sure its sensible.
afov = scr_fov.value;
if (r_refdef.playerview->stats[STAT_VIEWZOOM])
afov *= r_refdef.playerview->stats[STAT_VIEWZOOM]/255.0f;
ws = 1;
if (r_stereo_method.ival == 5 && r_stereo_separation.value)
ws = 0.5;
//attempt to retain a classic fov
if (ws*r_refdef.vrect.width < (r_refdef.vrect.height*640)/432)
{
r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*vid.pixelwidth)/vid.width, (r_refdef.vrect.height*vid.pixelheight)/vid.height);
r_refdef.fov_x = afov;//CalcFov(r_refdef.fov_y, 432, 640);
}
else
{
r_refdef.fov_y = CalcFov(afov, 640, 432);
r_refdef.fov_x = CalcFov(r_refdef.fov_y, r_refdef.vrect.height, r_refdef.vrect.width*ws);
}
}
}
/* /*
================= =================
v_ApplyRefdef v_ApplyRefdef
@ -1109,37 +1158,7 @@ void V_ApplyRefdef (void)
r_refdef.vrect.y += r_refdef.grect.y; r_refdef.vrect.y += r_refdef.grect.y;
if (r_refdef.dirty & RDFD_FOV) if (r_refdef.dirty & RDFD_FOV)
{ V_ApplyAFov();
//explicit fov overrides aproximate fov.
//aproximate fov is our regular fov value. explicit is settable by gamecode for weird aspect ratios
if (!r_refdef.fov_x || !r_refdef.fov_y)
{
extern cvar_t r_stereo_method, r_stereo_separation;
float ws;
float afov = r_refdef.afov;
if (!afov) //make sure its sensible.
afov = scr_fov.value;
if (r_refdef.playerview->stats[STAT_VIEWZOOM])
afov *= r_refdef.playerview->stats[STAT_VIEWZOOM]/255.0f;
ws = 1;
if (r_stereo_method.ival == 5 && r_stereo_separation.value)
ws = 0.5;
//attempt to retain a classic fov
if (ws*r_refdef.vrect.width < (r_refdef.vrect.height*640)/432)
{
r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*vid.pixelwidth)/vid.width, (r_refdef.vrect.height*vid.pixelheight)/vid.height);
r_refdef.fov_x = afov;//CalcFov(r_refdef.fov_y, 432, 640);
}
else
{
r_refdef.fov_y = CalcFov(afov, 640, 432);
r_refdef.fov_x = CalcFov(r_refdef.fov_y, r_refdef.vrect.height, r_refdef.vrect.width*ws);
}
}
}
r_refdef.dirty = 0; r_refdef.dirty = 0;
} }

View File

@ -5631,6 +5631,8 @@ void QDECL ICE_Close(struct icestate_s *con)
{ {
struct icestate_s **link; struct icestate_s **link;
ICE_Set(con, "state", STRINGIFY(ICE_INACTIVE));
for (link = &icelist; *link; ) for (link = &icelist; *link; )
{ {
if (con == *link) if (con == *link)

View File

@ -688,7 +688,7 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in
#endif #endif
diskimage = NULL; diskimage = NULL;
len = -1;//FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage); len = FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage);
/*queue the file for download if we don't have it yet*/ /*queue the file for download if we don't have it yet*/
if (len < 0) if (len < 0)
@ -2477,7 +2477,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
if (hmtrace.frac == -1) if (hmtrace.frac == -1)
{ {
trace->fraction = 0; trace->fraction = 1;
trace->startsolid = true; trace->startsolid = true;
trace->allsolid = true; trace->allsolid = true;
VectorCopy(start, trace->endpos); VectorCopy(start, trace->endpos);

View File

@ -275,6 +275,7 @@ qintptr_t Plug_Init(qintptr_t *args)
#define CAP_QUERIED 1 //a query is pending or something. #define CAP_QUERIED 1 //a query is pending or something.
#define CAP_VOICE 2 //supports voice #define CAP_VOICE 2 //supports voice
#define CAP_INVITE 4 //supports game invites. #define CAP_INVITE 4 //supports game invites.
#define CAP_POKE 8 //can be slapped.
typedef struct bresource_s typedef struct bresource_s
{ {
@ -673,19 +674,19 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
xmltree_t *jingle; xmltree_t *jingle;
struct icestate_s *ice; struct icestate_s *ice;
char autotarget[256]; char autotarget[256];
buddy_t *b;
bresource_t *br;
if (!jcl) if (!jcl)
return; return;
if (!strchr(target, '/'))
{
buddy_t *b;
bresource_t *br;
JCL_FindBuddy(jcl, target, &b, &br); JCL_FindBuddy(jcl, target, &b, &br);
if (!br) if (!br)
br = b->defaultresource; br = b->defaultresource;
if (!br) if (!br)
br = b->resources; br = b->resources;
if (!strchr(target, '/'))
{
if (!br) if (!br)
{ {
Con_Printf("User name not valid\n"); Con_Printf("User name not valid\n");
@ -712,23 +713,23 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
c2c = JCL_JingleCreateSession(jcl, target, true, sid, DEFAULTICEMODE, ((protocol == ICEP_INVALID)?ICEP_QWCLIENT:protocol)); c2c = JCL_JingleCreateSession(jcl, target, true, sid, DEFAULTICEMODE, ((protocol == ICEP_INVALID)?ICEP_QWCLIENT:protocol));
JCL_JingleSend(jcl, c2c, "session-initiate"); JCL_JingleSend(jcl, c2c, "session-initiate");
Con_Printf("%s ^[[%s]\\xmpp\\%s^] ^[[Hang Up]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^].\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", target, target, target, c2c->sid); Con_SubPrintf(b->name, "%s ^[[%s]\\xmpp\\%s^] ^[[Hang Up]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^].\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", target, target, target, c2c->sid);
} }
else else
Con_Printf("That session has expired.\n"); Con_SubPrintf(b->name, "That session has expired.\n");
} }
else if (c2c->creator) else if (c2c->creator)
{ {
//resend initiate if they've not acked it... I dunno... //resend initiate if they've not acked it... I dunno...
JCL_JingleSend(jcl, c2c, "session-initiate"); JCL_JingleSend(jcl, c2c, "session-initiate");
Con_Printf("Restarting session with ^[[%s]\\xmpp\\%s^].\n", target, target); Con_SubPrintf(b->name, "Restarting session with ^[[%s]\\xmpp\\%s^].\n", target, target);
} }
else if (c2c->accepted) else if (c2c->accepted)
Con_Printf("That session was already accepted.\n"); Con_SubPrintf(b->name, "That session was already accepted.\n");
else else
{ {
JCL_JingleSend(jcl, c2c, "session-accept"); JCL_JingleSend(jcl, c2c, "session-accept");
Con_Printf("Accepting session from ^[[%s]\\xmpp\\%s^].\n", target, target); Con_SubPrintf(b->name, "Accepting session from ^[[%s]\\xmpp\\%s^].\n", target, target);
} }
} }
else else
@ -736,10 +737,10 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
if (c2c) if (c2c)
{ {
JCL_JingleSend(jcl, c2c, "session-terminate"); JCL_JingleSend(jcl, c2c, "session-terminate");
Con_Printf("Terminating session with ^[[%s]\\xmpp\\%s^].\n", target, target); Con_SubPrintf(b->name, "Terminating session with ^[[%s]\\xmpp\\%s^].\n", target, target);
} }
else else
Con_Printf("That session has already expired.\n"); Con_SubPrintf(b->name, "That session has already expired.\n");
} }
} }
@ -835,6 +836,7 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from)
struct c2c_s *c2c = NULL; struct c2c_s *c2c = NULL;
int mt = ICEP_INVALID; int mt = ICEP_INVALID;
buddy_t *b;
//FIXME: add support for session forwarding so that we might forward the connection to the real server. for now we just reject it. //FIXME: add support for session forwarding so that we might forward the connection to the real server. for now we just reject it.
initiator = XML_GetParameter(inj, "initiator", ""); initiator = XML_GetParameter(inj, "initiator", "");
@ -876,6 +878,9 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from)
if (!c2c) if (!c2c)
return false; return false;
JCL_FindBuddy(jcl, from, &b, NULL);
if (c2c->mediatype == ICEP_VOICE) if (c2c->mediatype == ICEP_VOICE)
{ {
qboolean okay = false; qboolean okay = false;
@ -916,7 +921,7 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from)
if (!pCvar_GetFloat(autocvar)) if (!pCvar_GetFloat(autocvar))
{ {
//show a prompt for it, send the reply when the user decides. //show a prompt for it, send the reply when the user decides.
Con_Printf( Con_SubPrintf(b->name,
"^[[%s]\\xmpp\\%s^] wants to %s. " "^[[%s]\\xmpp\\%s^] wants to %s. "
"^[[Authorise]\\xmppact\\jauth\\xmpp\\%s\\xmppsid\\%s^] " "^[[Authorise]\\xmppact\\jauth\\xmpp\\%s\\xmppsid\\%s^] "
"^[[Deny]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^]\n", "^[[Deny]\\xmppact\\jdeny\\xmpp\\%s\\xmppsid\\%s^]\n",
@ -924,11 +929,12 @@ qboolean JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from)
offer, offer,
from, sid, from, sid,
from, sid); from, sid);
pCon_SetActive(b->name);
return true; return true;
} }
else else
{ {
Con_Printf("Auto-accepting session from ^[[%s]\\xmpp\\%s^]\n", from, from); Con_SubPrintf(b->name, "Auto-accepting session from ^[[%s]\\xmpp\\%s^]\n", from, from);
response = "session-accept"; response = "session-accept";
} }
} }
@ -943,6 +949,7 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
char *sid = XML_GetParameter(tree, "sid", ""); char *sid = XML_GetParameter(tree, "sid", "");
struct c2c_s *c2c = NULL, **link; struct c2c_s *c2c = NULL, **link;
buddy_t *b;
for (link = &jcl->c2c; *link; link = &(*link)->next) for (link = &jcl->c2c; *link; link = &(*link)->next)
{ {
@ -954,6 +961,8 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
} }
} }
JCL_FindBuddy(jcl, from, &b, NULL);
//validate sender //validate sender
if (c2c && strcmp(c2c->with, from)) if (c2c && strcmp(c2c->with, from))
{ {
@ -972,9 +981,9 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
} }
if (reason && reason->child) if (reason && reason->child)
Con_Printf("Session ended: %s\n", reason->child->name); Con_SubPrintf(b->name, "Session ended: %s\n", reason->child->name);
else else
Con_Printf("Session ended\n"); Con_SubPrintf(b->name, "Session ended\n");
//unlink it //unlink it
for (link = &jcl->c2c; *link; link = &(*link)->next) for (link = &jcl->c2c; *link; link = &(*link)->next)
@ -1052,7 +1061,7 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
{ {
return false; return false;
} }
Con_Printf("Session Accepted!\n"); Con_SubPrintf(b->name, "Session Accepted!\n");
// XML_ConPrintTree(tree, 0); // XML_ConPrintTree(tree, 0);
JCL_JingleParsePeerPorts(jcl, c2c, tree, from); JCL_JingleParsePeerPorts(jcl, c2c, tree, from);
@ -1754,6 +1763,7 @@ static char *caps[] =
"urn:xmpp:time", "urn:xmpp:time",
#endif #endif
"urn:xmpp:ping", //FIXME: I'm not keen on this. I only added support to stop errors from pidgin when trying to debug. "urn:xmpp:ping", //FIXME: I'm not keen on this. I only added support to stop errors from pidgin when trying to debug.
"urn:xmpp:attention:0", //poke.
#else #else
//for testing, this is the list of features pidgin supports (which is the other client I'm testing against). //for testing, this is the list of features pidgin supports (which is the other client I'm testing against).
@ -2103,6 +2113,15 @@ void JCL_ParseMessage(jclient_t *jcl, xmltree_t *tree)
} }
} }
ot = XML_ChildOfTree(tree, "attention", 0);
if (ot)
{
Con_SubPrintf(f, "%s is an attention whore.\n", f);
pCon_SetActive(f);
if (BUILTINISVALID(LocalSound))
pLocalSound("misc/talk.wav");
}
ot = XML_ChildOfTree(tree, "body", 0); ot = XML_ChildOfTree(tree, "body", 0);
if (ot) if (ot)
{ {
@ -2963,7 +2982,89 @@ void JCL_SendMessage(jclient_t *jcl, char *to, char *msg)
else else
Con_SubPrintf(b->name, "^5%s^7: "COLOURYELLOW"%s\n", jcl->localalias, msg); Con_SubPrintf(b->name, "^5%s^7: "COLOURYELLOW"%s\n", jcl->localalias, msg);
} }
void JCL_AttentionMessage(jclient_t *jcl, char *to, char *msg)
{
char fullto[256];
buddy_t *b;
bresource_t *br;
xmltree_t *m;
char *s;
JCL_FindBuddy(jcl, to, &b, &br);
if (!br)
br = b->defaultresource;
if (!br)
br = b->resources;
if (!br)
{
Con_SubPrintf(b->name, "User is not online\n");
return;
}
Q_snprintf(fullto, sizeof(fullto), "%s/%s", b->accountdomain, br->resource);
m = XML_CreateNode(NULL, "message", "", "");
XML_AddParameter(m, "to", fullto);
// XML_AddParameter(m, "type", "headline");
XML_CreateNode(m, "attention", "urn:xmpp:attention:0", "");
if (msg)
XML_CreateNode(m, "body", "", msg);
s = XML_GenerateString(m);
JCL_AddClientMessageString(jcl, s);
free(s);
XML_Destroy(m);
if (msg)
{
if (!strncmp(msg, "/me ", 4))
Con_SubPrintf(b->name, "*^5%s^7"COLOURYELLOW"%s\n", ((!strcmp(jcl->localalias, ">>"))?"me":jcl->localalias), msg+3);
else
Con_SubPrintf(b->name, "^5%s^7: "COLOURYELLOW"%s\n", jcl->localalias, msg);
}
}
void JCL_ToJID(jclient_t *jcl, char *in, char *out, int outsize)
{
//decompose links first
if (in[0] == '^' && in[1] == '[')
{
char *sl;
char *le;
sl = in+2;
sl = strchr(in, '\\');
if (sl)
{
le = strstr(sl, "^]");
if (le)
{
*le = 0;
JCL_Info_ValueForKey(in, "xmpp", out, outsize);
*le = '^';
return;
}
}
}
if (!strchr(in, '@'))
{
//no @? probably its an alias, but could also be a server/domain perhaps. not sure we care. you'll just have to rename your friend.
//check to see if we can find a friend going by that name
//fixme: allow resources to make it through here
buddy_t *b;
for (b = jcl->buddies; b; b = b->next)
{
if (!strcasecmp(b->name, in))
{
Q_strlcpy(out, b->accountdomain, outsize);
return;
}
}
}
//a regular jabber account name
Q_strlcpy(out, in, outsize);
}
void JCL_Command(char *console) void JCL_Command(char *console)
{ {
@ -2971,6 +3072,7 @@ void JCL_Command(char *console)
char arg[6][256]; char arg[6][256];
char *msg; char *msg;
int i; int i;
char nname[256];
pCmd_Args(imsg, sizeof(imsg)); pCmd_Args(imsg, sizeof(imsg));
@ -2984,6 +3086,8 @@ void JCL_Command(char *console)
if (arg[0][0] == '/' && arg[0][1] != '/' && strcmp(arg[0]+1, "me")) if (arg[0][0] == '/' && arg[0][1] != '/' && strcmp(arg[0]+1, "me"))
{ {
JCL_ToJID(jclient, *arg[1]?arg[1]:console, nname, sizeof(nname));
if (!strcmp(arg[0]+1, "open") || !strcmp(arg[0]+1, "connect") || !strcmp(arg[0]+1, "tlsopen") || !strcmp(arg[0]+1, "tlsconnect")) if (!strcmp(arg[0]+1, "open") || !strcmp(arg[0]+1, "connect") || !strcmp(arg[0]+1, "tlsopen") || !strcmp(arg[0]+1, "tlsconnect"))
{ //tlsconnect is 'old'. { //tlsconnect is 'old'.
if (!*arg[1]) if (!*arg[1])
@ -3107,19 +3211,41 @@ void JCL_Command(char *console)
} }
else if (!strcmp(arg[0]+1, "join")) else if (!strcmp(arg[0]+1, "join"))
{ {
JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_QWCLIENT); JCL_Join(jclient, nname, NULL, true, ICEP_QWCLIENT);
} }
else if (!strcmp(arg[0]+1, "invite")) else if (!strcmp(arg[0]+1, "invite"))
{ {
JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_QWSERVER); JCL_Join(jclient, nname, NULL, true, ICEP_QWSERVER);
} }
else if (!strcmp(arg[0]+1, "voice") || !strcmp(arg[0]+1, "call")) else if (!strcmp(arg[0]+1, "voice") || !strcmp(arg[0]+1, "call"))
{ {
JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, true, ICEP_VOICE); JCL_Join(jclient, nname, NULL, true, ICEP_VOICE);
} }
else if (!strcmp(arg[0]+1, "kick")) else if (!strcmp(arg[0]+1, "kick"))
{ {
JCL_Join(jclient, *arg[1]?arg[1]:console, NULL, false, ICEP_INVALID); JCL_Join(jclient, nname, NULL, false, ICEP_INVALID);
}
else if (!strcmp(arg[0]+1, "slap"))
{
char *msgtab[] =
{
"/me slaps you around a bit with a large trout",
"/me slaps you around a bit with a large tunafish",
"/me slaps you around a bit with a slimy hagfish",
"/me slaps a large trout around a bit with your face",
"/me gets eaten by a rabid shark while trying to slap you with it",
"/me gets crushed under the weight of a large whale",
"/me searches for a fresh fish, but gets crabs instead",
"/me searches for a fish, but there are no more fish in the sea",
"/me tickles you around a bit with a large fish finger",
"/me goes to order cod and chips. brb",
"/me goes to watch some monty python"
};
JCL_AttentionMessage(jclient, nname, msgtab[rand()%(sizeof(msgtab)/sizeof(msgtab[0]))]);
}
else if (!strcmp(arg[0]+1, "poke"))
{
JCL_AttentionMessage(jclient, nname, NULL);
} }
else if (!strcmp(arg[0]+1, "raw")) else if (!strcmp(arg[0]+1, "raw"))
{ {
@ -3145,7 +3271,8 @@ void JCL_Command(char *console)
} }
else else
{ {
JCL_SendMessage(jclient, jclient->defaultdest, msg); JCL_ToJID(jclient, *console?console:jclient->defaultdest, nname, sizeof(nname));
JCL_SendMessage(jclient, nname, msg);
} }
} }
else else