]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/util.qh
Put more work into process_time function
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / util.qh
index 49e51b0ffda7a4f95d23a08d41e1d46f6f75a398..eb2713864d7d62e146dafa5829c4665b39c1b6a4 100644 (file)
@@ -1,12 +1,16 @@
 // a dummy macro that prevents the "hanging ;" warning
 #define ENDS_WITH_CURLY_BRACE
 
+// return the actual code name of a var as a string
+#define VAR_TO_TEXT(var) #var
+
+#ifdef HAVE_YO_DAWG_CPP
 // TODO make ascii art pic of xzibit
 // YO DAWG!
 // I HERD YO LIEK MACROS
 // SO I PUT A MACRO DEFINITION IN YO MACRO DEFINITION
 // SO YO CAN EXPAND MACROS WHILE YO EXPAND MACROS
-#define ACCUMULATE_FUNCTION(func,otherfunc) \
+# define ACCUMULATE_FUNCTION(func,otherfunc) \
        #ifdef func \
        void __merge__##otherfunc() { func(); otherfunc(); } \
        #undef func \
        #else \
        #define func otherfunc \
        #endif
+# define CALL_ACCUMULATED_FUNCTION(func) \
+       func()
+#else
+# define ACCUMULATE_FUNCTION(func,otherfunc) \
+       .void _ACCUMULATE_##func##__##otherfunc;
+void ACCUMULATE_call(string func)
+{
+       float i;
+       float n = numentityfields();
+       string funcprefix = strcat("_ACCUMULATE_", func, "__");
+       float funcprefixlen = strlen(funcprefix);
+       for(i = 0; i < n; ++i)
+       {
+               string name = entityfieldname(i);
+               if(substring(name, 0, funcprefixlen) == funcprefix)
+                       callfunction(substring(name, funcprefixlen, -1));
+       }
+}
+# define CALL_ACCUMULATED_FUNCTION(func) \
+       ACCUMULATE_call(#func)
+#endif
+
+// used for simplifying ACCUMULATE_FUNCTIONs
+#define SET_FIRST_OR_LAST(input,first,count) if(!input) { input = (first + count); }
+#define SET_FIELD_COUNT(field,first,count) if(!field) { field = (first + count); ++count; }
+#define CHECK_MAX_COUNT(name,max,count,type) if(count == max) { error(strcat("Maximum ", type, " hit: ", VAR_TO_TEXT(name), ": ", ftos(count), ".\n")); }
 
 // this returns a tempstring containing a copy of s with additional \n newlines added, it also replaces \n in the text with a real newline
 // NOTE: s IS allowed to be a tempstring
@@ -23,7 +53,7 @@ string wordwrap(string s, float l);
 void wordwrap_sprint(string s, float l);
 #endif
 #endif
-void wordwrap_cb(string s, float l, void(string) callback)
+void wordwrap_cb(string s, float l, void(string) callback);
 
 #ifndef SVQC
 string draw_currentSkin;
@@ -118,8 +148,6 @@ vector mi_pictexcoord3; // texcoords of the image corners (after transforming, t
 void get_mi_min_max_texcoords(float mode);
 #endif
 
-#define FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(x) void reference_##x() { x = x; }
-
 float almost_equals(float a, float b);
 float almost_in_bounds(float a, float b, float c);
 
@@ -204,8 +232,13 @@ void WriteInt24_t(float dest, float val);
 #endif
 
 // the NULL function
-const var void func_null(void); FTEQCC_YOU_SUCK_THIS_IS_NOT_UNREFERENCED(func_null)
-const var string string_null;
+#ifdef GMQCC
+#define func_null nil
+#define string_null nil
+#else
+var void func_null(void);
+var string string_null;
+#endif
 float float2range11(float f);
 float float2range01(float f);
 
@@ -225,6 +258,12 @@ float get_model_parameters_species;
 string get_model_parameters_sex;
 float get_model_parameters_weight;
 float get_model_parameters_age;
+string get_model_parameters_bone_upperbody;
+string get_model_parameters_bone_weapon;
+#define MAX_AIM_BONES 4
+string get_model_parameters_bone_aim[MAX_AIM_BONES];
+float get_model_parameters_bone_aimweight[MAX_AIM_BONES];
+float get_model_parameters_fixbone;
 string get_model_parameters_desc;
 float get_model_parameters(string mod, float skn); // call with string_null to clear; skin -1 means mod is the filename of the txt file and is to be split
 
@@ -286,7 +325,7 @@ float xdecode(string s);
 float lowestbit(float f);
 
 #ifdef CSQC
-entity ReadCSQCEntity()
+entity ReadCSQCEntity();
 #endif
 
 #ifndef MENUQC
@@ -322,8 +361,6 @@ void queue_to_execute_next_frame(string s);
 // for marking written-to values as unused where it's a good idea to do this
 noref float unused_float;
 
-
-
 // a function f with:
 // f(0) = 0
 // f(1) = 1
@@ -339,3 +376,116 @@ float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor);
 typedef entity(entity cur, entity near, entity pass) findNextEntityNearFunction_t;
 typedef float(entity a, entity b, entity pass) isConnectedFunction_t;
 void FindConnectedComponent(entity e, .entity fld, findNextEntityNearFunction_t nxt, isConnectedFunction_t iscon, entity pass);
+
+// expand multiple arguments into one argument by stripping parenthesis
+#define XPD(...) __VA_ARGS__
+
+float Count_Proper_Strings(string improper, string...count);
+float Count_Proper_Floats(float improper, float...count);
+
+#ifndef MENUQC
+void backtrace(string msg);
+#endif
+
+// color code replace, place inside of sprintf and parse the string... defaults described as constants
+// foreground/normal colors
+var string autocvar_hud_colorset_foreground_1 = "2"; // F1 - Green  // primary priority (important names, etc)
+var string autocvar_hud_colorset_foreground_2 = "3"; // F2 - Yellow // secondary priority (items, locations, numbers, etc)
+var string autocvar_hud_colorset_foreground_3 = "4"; // F3 - Blue   // tertiary priority or relatively inconsequential text
+var string autocvar_hud_colorset_foreground_4 = "1"; // F4 - Red    // notice/attention grabbing texting
+// "kill" colors
+var string autocvar_hud_colorset_kill_1 = "1"; // K1 - Red    // "bad" or "dangerous" text (death messages against you, kill notifications, etc)
+var string autocvar_hud_colorset_kill_2 = "3"; // K2 - Yellow // similar to above, but less important... OR, a highlight out of above message type
+var string autocvar_hud_colorset_kill_3 = "4"; // K3 - Blue   // "good" or "beneficial" text (you fragging someone, etc)
+// background color
+var string autocvar_hud_colorset_background = "7"; // BG - White // neutral/unimportant text
+
+string CCR(string input);
+
+#ifndef MENUQC
+#ifdef CSQC
+#define GENTLE (autocvar_cl_gentle || autocvar_cl_gentle_messages)
+#else
+#define GENTLE autocvar_sv_gentle
+#endif
+#define normal_or_gentle(normal,gentle) (GENTLE ? ((gentle != "") ? gentle : normal) : normal)
+#endif
+
+// allow writing to also pass through to spectators (like so spectators see the same centerprints as players for example)
+#define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) statement msg_entity = varname
+#define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
+#define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
+
+vector vec3(float x, float y, float z);
+
+#ifndef MENUQC
+vector animfixfps(entity e, vector a, vector b);
+#endif
+
+#define count_years_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s years")), ftos_decimals(time, decs))
+#define count_years(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d years")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d year")),  /* first */ \
+               ZCTX(_("CI_SEC^%d years")), /* year */ \
+               ZCTX(_("CI_THI^%d years")), /* third */ \
+               ZCTX(_("CI_MUL^%d years"))) /* multi */
+
+#define count_weeks_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s weeks")), ftos_decimals(time, decs))
+#define count_weeks(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d weeks")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d week")),  /* first */ \
+               ZCTX(_("CI_SEC^%d weeks")), /* week */ \
+               ZCTX(_("CI_THI^%d weeks")), /* third */ \
+               ZCTX(_("CI_MUL^%d weeks"))) /* multi */
+
+#define count_days_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s days")), ftos_decimals(time, decs))
+#define count_days(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d days")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d day")),  /* first */ \
+               ZCTX(_("CI_SEC^%d days")), /* day */ \
+               ZCTX(_("CI_THI^%d days")), /* third */ \
+               ZCTX(_("CI_MUL^%d days"))) /* multi */
+
+#define count_hours_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s hours")), ftos_decimals(time, decs))
+#define count_hours(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d hours")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d hour")),  /* first */ \
+               ZCTX(_("CI_SEC^%d hours")), /* hour */ \
+               ZCTX(_("CI_THI^%d hours")), /* third */ \
+               ZCTX(_("CI_MUL^%d hours"))) /* multi */
+
+
+#define count_minutes_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s minutes")), ftos_decimals(time, decs))
+#define count_minutes(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d minutes")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d minute")),  /* first */ \
+               ZCTX(_("CI_SEC^%d minutes")), /* minute */ \
+               ZCTX(_("CI_THI^%d minutes")), /* third */ \
+               ZCTX(_("CI_MUL^%d minutes"))) /* multi */
+
+#define count_seconds_decs(time,decs) sprintf(ZCTX(_("CI_DEC^%s seconds")), ftos_decimals(time, decs))
+#define count_seconds(time) count_fill(time, \
+               ZCTX(_("CI_ZER^%d seconds")), /* zeroth */ \
+               ZCTX(_("CI_FIR^%d second")),  /* first */ \
+               ZCTX(_("CI_SEC^%d seconds")), /* second */ \
+               ZCTX(_("CI_THI^%d seconds")), /* third */ \
+               ZCTX(_("CI_MUL^%d seconds"))) /* multi */
+
+string count_ordinal(float interval);
+string count_fill(float interval, string zeroth, string first, string second, string third, string multi);
+string process_time(float outputtype, float seconds);
+
+#ifdef SVQC
+void dedicated_print(string input);
+#endif
+
+// todo: better way to do this?
+#ifdef MENUQC
+#define PROGNAME "MENUQC"
+#else
+#ifdef SVQC
+#define PROGNAME "SVQC"
+#else
+#define PROGNAME "CSQC"
+#endif
+#endif