mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-17 22:50:51 +00:00
Added a GIB event system for registering GIB callback functions to be
started when a named event occurs. Added a few test events to the qw client and server. Cleaned up the range GIB builtin a bit.
This commit is contained in:
parent
79a638198d
commit
c522970a88
8 changed files with 104 additions and 74 deletions
|
@ -29,15 +29,30 @@
|
|||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __gib_thread_h
|
||||
#define __gib_thread_h
|
||||
|
||||
#include "QF/gib_function.h"
|
||||
|
||||
typedef struct gib_thread_s {
|
||||
unsigned long int id;
|
||||
struct cbuf_s *cbuf;
|
||||
struct gib_thread_s *next,*prev;
|
||||
} gib_thread_t;
|
||||
|
||||
typedef struct gib_event_s {
|
||||
const char *name;
|
||||
struct gib_function_s *func;
|
||||
} gib_event_t;
|
||||
|
||||
void GIB_Thread_Add (gib_thread_t *thread);
|
||||
void GIB_Thread_Remove (gib_thread_t *thread);
|
||||
gib_thread_t *GIB_Thread_Find (unsigned long int id);
|
||||
gib_thread_t *GIB_Thread_New (void);
|
||||
void GIB_Thread_Execute (void);
|
||||
void GIB_Thread_Callback (const char *func, unsigned int argc, ...);
|
||||
gib_event_t *GIB_Event_New (const char *name);
|
||||
int GIB_Event_Register (const char *name, gib_function_t *func);
|
||||
void GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...);
|
||||
void GIB_Event_Init (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -610,6 +610,18 @@ GIB_Thread_Kill_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Event_Register_f (void)
|
||||
{
|
||||
gib_function_t *func;
|
||||
if (GIB_Argc() != 3)
|
||||
GIB_USAGE ("event function");
|
||||
else if (!(func = GIB_Function_Find (GIB_Argv(2))) && GIB_Argv(2)[0])
|
||||
Cbuf_Error ("function", "Function %s not found.", GIB_Argv(2));
|
||||
else if (GIB_Event_Register (GIB_Argv(1), func))
|
||||
Cbuf_Error ("event", "Event %s not found.", GIB_Argv(1));
|
||||
}
|
||||
|
||||
/* File access */
|
||||
|
||||
int (*GIB_File_Transform_Path) (dstring_t *path) = NULL;
|
||||
|
@ -819,24 +831,19 @@ GIB_Range_f (void)
|
|||
GIB_USAGE ("lower upper [step]");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(dstr = GIB_Return (0)))
|
||||
return; // Why bother?
|
||||
limit = atof(GIB_Argv(2));
|
||||
start = atof(GIB_Argv(1));
|
||||
if (GIB_Argc () == 4)
|
||||
inc = atof(GIB_Argv(3));
|
||||
if (GIB_Argc () == 4 && (inc = atof(GIB_Argv(3))) == 0.0)
|
||||
return;
|
||||
else
|
||||
inc = limit < start ? -1.0 : 1.0;
|
||||
if (inc == 0.0) {
|
||||
GIB_Return ("");
|
||||
return;
|
||||
}
|
||||
if (!(ifs = GIB_Var_Get_Local (cbuf_active, "ifs")))
|
||||
ifs = " ";
|
||||
dstr = dstring_newstr ();
|
||||
for (i = atof(GIB_Argv(1)); inc < 0 ? i >= limit : i <= limit; i += inc)
|
||||
dasprintf(dstr, "%.1s%.10g", ifs, i);
|
||||
GIB_Return (dstr->str[0] ? dstr->str+1 : "");
|
||||
dstring_delete (dstr);
|
||||
dasprintf(dstr, "%.10g%.1s", i, ifs);
|
||||
dstr->str[dstr->size-2] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -882,6 +889,7 @@ GIB_Builtin_Init (qboolean sandbox)
|
|||
GIB_Builtin_Add ("regex::extract", GIB_Regex_Extract_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("thread::create", GIB_Thread_Create_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("thread::kill", GIB_Thread_Kill_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("event::register", GIB_Event_Register_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file::read", GIB_File_Read_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file::write", GIB_File_Write_f, GIB_BUILTIN_NORMAL);
|
||||
GIB_Builtin_Add ("file::find", GIB_File_Find_f, GIB_BUILTIN_NORMAL);
|
||||
|
|
|
@ -38,6 +38,7 @@ static const char rcsid[] =
|
|||
#include "QF/gib_parse.h"
|
||||
#include "QF/gib_builtin.h"
|
||||
#include "QF/gib_regex.h"
|
||||
#include "QF/gib_thread.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/zone.h"
|
||||
|
@ -88,4 +89,6 @@ GIB_Init (qboolean sandbox)
|
|||
GIB_Regex_Init ();
|
||||
// Initialize builtins
|
||||
GIB_Builtin_Init (sandbox);
|
||||
// Initialize event system
|
||||
GIB_Event_Init ();
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ static const char rcsid[] =
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "QF/sys.h"
|
||||
#include "QF/cbuf.h"
|
||||
|
@ -40,8 +41,10 @@ static const char rcsid[] =
|
|||
#include "QF/gib_thread.h"
|
||||
#include "QF/gib_function.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
|
||||
gib_thread_t *gib_threads;
|
||||
hashtab_t *gib_events;
|
||||
static unsigned long int nextid = 0;
|
||||
|
||||
void
|
||||
|
@ -114,10 +117,45 @@ GIB_Thread_Execute (void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Thread_Callback (const char *func, unsigned int argc, ...)
|
||||
const char *
|
||||
GIB_Event_Get_Key (void *ele, void *ptr)
|
||||
{
|
||||
gib_function_t *f = GIB_Function_Find (func);
|
||||
return ((gib_event_t *)ele)->name;
|
||||
}
|
||||
void
|
||||
GIB_Event_Free (void *ele, void *ptr)
|
||||
{
|
||||
gib_event_t *ev = (gib_event_t *)ele;
|
||||
free ((void *)ev->name);
|
||||
free (ev);
|
||||
}
|
||||
|
||||
gib_event_t *
|
||||
GIB_Event_New (const char *name)
|
||||
{
|
||||
gib_event_t *new;
|
||||
|
||||
new = calloc (1, sizeof (gib_event_t));
|
||||
new->name = strdup (name);
|
||||
Hash_Add (gib_events, new);
|
||||
return new;
|
||||
}
|
||||
|
||||
int
|
||||
GIB_Event_Register (const char *name, gib_function_t *func)
|
||||
{
|
||||
gib_event_t *ev;
|
||||
|
||||
if (!(ev = Hash_Find (gib_events, name)))
|
||||
return -1;
|
||||
ev->func = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Event_Callback (gib_event_t *event, unsigned int argc, ...)
|
||||
{
|
||||
gib_function_t *f = event->func;
|
||||
gib_thread_t *thread;
|
||||
cbuf_args_t *args;
|
||||
va_list ap;
|
||||
|
@ -131,7 +169,7 @@ GIB_Thread_Callback (const char *func, unsigned int argc, ...)
|
|||
|
||||
va_start (ap, argc);
|
||||
|
||||
Cbuf_ArgsAdd (args, func);
|
||||
Cbuf_ArgsAdd (args, f->name->str);
|
||||
for (i = 0; i < argc; i++)
|
||||
Cbuf_ArgsAdd (args, va_arg (ap, const char *));
|
||||
|
||||
|
@ -141,3 +179,9 @@ GIB_Thread_Callback (const char *func, unsigned int argc, ...)
|
|||
GIB_Thread_Add (thread);
|
||||
Cbuf_ArgsDelete (args);
|
||||
}
|
||||
|
||||
void
|
||||
GIB_Event_Init (void)
|
||||
{
|
||||
gib_events = Hash_NewTable (1024, GIB_Event_Get_Key, GIB_Event_Free, 0);
|
||||
}
|
||||
|
|
|
@ -56,4 +56,6 @@ extern struct cvar_s *cl_cshift_contents;
|
|||
extern struct cvar_s *cl_cshift_damage;
|
||||
extern struct cvar_s *cl_cshift_powerup;
|
||||
|
||||
extern struct gib_event_s *cl_player_health_e, *cl_chat_e;
|
||||
|
||||
#endif // _CL_MAIN_H
|
||||
|
|
|
@ -180,6 +180,9 @@ cvar_t *rate;
|
|||
cvar_t *noaim;
|
||||
cvar_t *msg;
|
||||
|
||||
/* GIB events */
|
||||
gib_event_t *cl_player_health_e, *cl_chat_e;
|
||||
|
||||
static int cl_usleep_cache;
|
||||
|
||||
client_static_t cls;
|
||||
|
@ -1224,6 +1227,8 @@ CL_Init (void)
|
|||
"to people on your team");
|
||||
Cmd_AddCommand ("serverinfo", CL_Cmd_ForwardToServer, "Report the current "
|
||||
"server info");
|
||||
cl_player_health_e = GIB_Event_New ("player.health");
|
||||
cl_chat_e = GIB_Event_New ("chat");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1095,10 +1095,6 @@ CL_ServerInfo (void)
|
|||
void
|
||||
CL_SetStat (int stat, int value)
|
||||
{
|
||||
int j;
|
||||
unsigned int changed;
|
||||
const char *arm, *cb;
|
||||
|
||||
if (stat < 0 || stat >= MAX_CL_STATS)
|
||||
Host_Error ("CL_SetStat: %i is invalid", stat);
|
||||
|
||||
|
@ -1112,67 +1108,15 @@ CL_SetStat (int stat, int value)
|
|||
|
||||
switch (stat) {
|
||||
case STAT_ITEMS:
|
||||
changed = cl.stats[STAT_ITEMS] ^ value;
|
||||
Sbar_Changed ();
|
||||
if ((changed & IT_KEY1 || changed & IT_KEY2) &&
|
||||
(cb = GIB_Var_Get_Global ("player.key.callback")))
|
||||
GIB_Thread_Callback (cb, 0);
|
||||
GIB_Var_Set_Global ("player.key.1", value & IT_KEY1 ? "1" : "0");
|
||||
GIB_Var_Set_Global ("player.key.2", value & IT_KEY2 ? "1" : "0");
|
||||
if (value & IT_ARMOR1)
|
||||
arm = "green";
|
||||
else if (value & IT_ARMOR2)
|
||||
arm = "yellow";
|
||||
else if (value & IT_ARMOR3)
|
||||
arm = "red";
|
||||
else
|
||||
arm = "none";
|
||||
GIB_Var_Set_Global ("player.armor.type", arm);
|
||||
if ((changed & 127 || changed & IT_AXE) &&
|
||||
(cb = GIB_Var_Get_Global ("player.weapon.callback")))
|
||||
GIB_Thread_Callback (cb, 0);
|
||||
GIB_Var_Set_Global ("player.weapon.1", value & IT_AXE ? "1" : "0");
|
||||
for (j = 0; j < 7; j++)
|
||||
GIB_Var_Set_Global (va("player.weapon.%i", j+2),
|
||||
value & (1 << j) ? "1" : "0");
|
||||
for (j = 0; j < 32; j++)
|
||||
if ((value & (1 << j)) && !(cl.stats[stat] & (1 << j)))
|
||||
cl.item_gettime[j] = cl.time;
|
||||
break;
|
||||
case STAT_HEALTH:
|
||||
if ((cb = GIB_Var_Get_Global ("player.health.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.health", va("%i", value));
|
||||
if (cl_player_health_e->func)
|
||||
GIB_Event_Callback (cl_player_health_e, 1, va("%i", value));
|
||||
if (value <= 0)
|
||||
Team_Dead ();
|
||||
break;
|
||||
case STAT_ARMOR:
|
||||
if ((cb = GIB_Var_Get_Global ("player.armor.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.armor", va("%i", value));
|
||||
break;
|
||||
case STAT_SHELLS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.shells.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.shells", va("%i", value));
|
||||
break;
|
||||
case STAT_NAILS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.nails.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.nails", va("%i", value));
|
||||
break;
|
||||
case STAT_ROCKETS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.rockets.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.rockets", va("%i", value));
|
||||
break;
|
||||
case STAT_CELLS:
|
||||
if ((cb = GIB_Var_Get_Global ("player.ammo.cells.callback")))
|
||||
GIB_Thread_Callback (cb, 1, va("%i", value));
|
||||
GIB_Var_Set_Global ("player.ammo.cells", va("%i", value));
|
||||
break;
|
||||
}
|
||||
|
||||
cl.stats[stat] = value;
|
||||
}
|
||||
|
||||
|
@ -1290,6 +1234,8 @@ CL_ParseServerMessage (void)
|
|||
}
|
||||
Con_SetOrMask (128);
|
||||
S_LocalSound ("misc/talk.wav");
|
||||
if (cl_chat_e->func)
|
||||
GIB_Event_Callback (cl_chat_e, 1, s);
|
||||
Team_ParseChat(s);
|
||||
}
|
||||
Con_Printf ("%s", s);
|
||||
|
|
|
@ -54,6 +54,7 @@ static const char rcsid[] =
|
|||
#include "QF/quakefs.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
#include "QF/gib_thread.h"
|
||||
|
||||
#include "bothdefs.h"
|
||||
#include "compat.h"
|
||||
|
@ -92,6 +93,8 @@ cvar_t *sv_timekick_interval;
|
|||
cvar_t *sv_timecheck_fuzz;
|
||||
cvar_t *sv_timecheck_decay;
|
||||
|
||||
gib_event_t *sv_chat_e;
|
||||
|
||||
// USER STRINGCMD EXECUTION host_client and sv_player will be valid.
|
||||
|
||||
/*
|
||||
|
@ -823,6 +826,9 @@ SV_Say (qboolean team)
|
|||
|
||||
SV_Printf ("%s", text);
|
||||
|
||||
if (sv_chat_e->func)
|
||||
GIB_Event_Callback (sv_chat_e, 1, text);
|
||||
|
||||
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
|
||||
if (client->state < cs_connected) // Clients connecting can hear.
|
||||
continue;
|
||||
|
@ -1847,4 +1853,5 @@ SV_UserInit (void)
|
|||
"\"forgiven\".");
|
||||
sv_kickfake = Cvar_Get ("sv_kickfake", "1", CVAR_NONE, NULL,
|
||||
"Kick users sending to send fake talk messages");
|
||||
sv_chat_e = GIB_Event_New ("chat");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue