set sv_join_notices ""
set sv_join_notices_time 15
-set cl_ghost_items 0.45 "enable ghosted items (when between 0 and 1, overrides the alpha value)"
-set cl_ghost_items_color "-1 -1 -1" "color of ghosted items, 0 0 0 leaves the color unchanged"
+seta cl_ghost_items 0.45 "enable ghosted items (when between 0 and 1, overrides the alpha value)"
+seta cl_ghost_items_color "-1 -1 -1" "color of ghosted items, 0 0 0 leaves the color unchanged"
set sv_simple_items 1 "allow or forbid client use of simple items"
-set cl_simple_items 0 "enable simple items (if server allows)"
-set cl_simpleitems_postfix "_simple" "posfix to add fo model name when simple items are enabled"
+seta cl_simple_items 0 "enable simple items (if server allows)"
+set cl_simpleitems_postfix "_luma" "posfix to add fo model name when simple items are enabled"
set cl_fullbright_items 0 "enable fullbright items (if server allows, controled by g_fullbrightitems)"
set cl_weapon_stay_color "2 0.5 0.5" "Color of picked up weapons when g_weapon_stay > 0"
set cl_weapon_stay_alpha 0.75 "Alpha of picked up weapons when g_weapon_stay > 0"
+++ /dev/null
-#include "casings.qh"
-#include "_all.qh"
-
-#include "../common/movetypes/movetypes.qh"
-#include "../common/weapons/all.qh"
-#include "prandom.qh"
-#include "rubble.qh"
-
-#include "../common/util.qh"
-
-.float cnt;
-.float alpha;
-.int state;
-
-entityclass(Casing);
-class(Casing) .bool silent;
-
-void Casing_Delete()
-{
- remove(self);
-}
-
-void Casing_Draw()
-{
- if(self.move_flags & FL_ONGROUND)
- {
- self.move_angles_x = 0;
- self.move_angles_z = 0;
- self.flags &= ~FL_ONGROUND;
- }
-
- Movetype_Physics_MatchTicrate(autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
- if(wasfreed(self))
- return; // deleted by touch function
-
- self.renderflags = 0;
- self.alpha = bound(0, self.cnt - time, 1);
-
- if(self.alpha < ALPHA_MIN_VISIBLE)
- {
- Casing_Delete();
- self.drawmask = 0;
- }
-}
-
-void Casing_Touch()
-{
- if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
- {
- Casing_Delete();
- return;
- }
-
- if(!self.silent)
- if(!trace_ent || trace_ent.solid == SOLID_BSP)
- {
- if(vlen(self.velocity) > 50)
- {
- if(time >= self.nextthink)
- {
- string s;
- int f = floor(prandom() * 3) + 1;
-
- switch(self.state)
- {
- case 1:
- s = W_Sound(strcat("casings", itos(f)));
- break;
- default:
- s = W_Sound(strcat("brass", itos(f)));
- break;
- }
-
- sound (self, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE);
- }
- }
- }
-
- self.nextthink = time + 0.2;
-}
-
-void Casing_Damage(float thisdmg, int hittype, vector org, vector thisforce)
-{
- if(thisforce.z < 0)
- thisforce.z = 0;
- self.move_velocity = self.move_velocity + thisforce + '0 0 100';
- self.move_flags &= ~FL_ONGROUND;
-}
-
-void Ent_Casing(float isNew)
-{
- entity casing;
-
- casing = RubbleNew("casing");
- casing.state = ReadByte();
- casing.silent = (casing.state & 0x80);
- casing.state = (casing.state & 0x7F);
- casing.origin_x = ReadCoord();
- casing.origin_y = ReadCoord();
- casing.origin_z = ReadCoord();
- setorigin(casing, casing.origin);
- casing.velocity = decompressShortVector(ReadShort());
- casing.angles_x = ReadByte() * 360 / 256;
- casing.angles_y = ReadByte() * 360 / 256;
- casing.angles_z = ReadByte() * 360 / 256;
- casing.drawmask = MASK_NORMAL;
-
- if(autocvar_cl_casings && isNew) {
- casing.draw = Casing_Draw;
- casing.move_origin = casing.origin;
- casing.move_velocity = casing.velocity + 2 * prandomvec();
- casing.move_angles = casing.angles;
- casing.move_avelocity = '0 250 0' + 100 * prandomvec();
- casing.move_movetype = MOVETYPE_BOUNCE;
- casing.move_touch = Casing_Touch;
- casing.move_time = time;
- casing.event_damage = Casing_Damage;
- casing.solid = SOLID_TRIGGER;
-
- switch(casing.state)
- {
- case 1:
- setmodel(casing, "models/casing_shell.mdl");
- casing.cnt = time + autocvar_cl_casings_shell_time;
- break;
- default:
- setmodel(casing, "models/casing_bronze.iqm");
- casing.cnt = time + autocvar_cl_casings_bronze_time;
- break;
- }
-
- setsize(casing, '0 0 -1', '0 0 -1');
-
- RubbleLimit("casing", autocvar_cl_casings_maxcount, Casing_Delete);
- }
- else
- {
- entity oldself = self;
- self = casing;
- Casing_Delete(); // yes, this IS stupid, but I don't need to duplicate all the read* stuff then
- self = oldself;
- }
-}
-
-void Casings_Precache()
-{
- precache_model("models/casing_shell.mdl");
- precache_model("models/casing_bronze.iqm");
- precache_sound(W_Sound("brass1"));
- precache_sound(W_Sound("brass2"));
- precache_sound(W_Sound("brass3"));
- precache_sound(W_Sound("casings1"));
- precache_sound(W_Sound("casings2"));
- precache_sound(W_Sound("casings3"));
-}
+++ /dev/null
-#ifndef CASINGS_H
-#define CASINGS_H
-
-void Casings_Precache();
-
-void Ent_Casing(float isNew);
-
-#endif
#include "controlpoint.qh"
#include "gibs.qh"
#include "teamradar.qh"
+#include "../common/movetypes/movetypes.qh"
+.float alpha;
bool cpicon_precached;
.int count;
.float pain_finished;
#include "gibs.qh"
#include "player_skeleton.qh"
-#include "sortlist.qh"
#include "weapons/projectile.qh"
#include "../csqcmodellib/cl_player.qh"
#include "../csqcmodellib/interpolate.qh"
-#include "../warpzonelib/mathlib.qh"
.float death_time;
.int modelflags;
#include "_all.qh"
#include "gibs.qh"
-#include "prandom.qh"
#include "../common/vehicles/all.qh"
.int count;
.float max_health;
-vector randompos(vector m1, vector m2)
-{
- vector v;
- m2 = m2 - m1;
- v_x = m2_x * random() + m1_x;
- v_y = m2_y * random() + m1_y;
- v_z = m2_z * random() + m1_z;
- return v;
-}
-
void generator_precache()
{
if(generator_precached)
#include "gibs.qh"
#include "_all.qh"
-#include "prandom.qh"
#include "rubble.qh"
#include "../common/constants.qh"
#include "_all.qh"
#include "hud.qh"
-#include "noise.qh"
#include "../common/teams.qh"
#include "../csqcmodellib/interpolate.qh"
#include "../warpzonelib/common.qh"
-#include "../warpzonelib/mathlib.qh"
entityclass(Hook);
class(Hook) .float HookType; // ENT_CLIENT_*
class(Hook) .float HookSilent;
class(Hook) .float HookRange;
-void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg)
-{
- // I want to draw a quad...
- // from and to are MIDPOINTS.
-
- vector axis, thickdir, A, B, C, D;
- float length_tex;
-
- axis = normalize(to - from);
- length_tex = aspect * vlen(to - from) / thickness;
-
- // direction is perpendicular to the view normal, and perpendicular to the axis
- thickdir = normalize(cross(axis, vieworg - from));
-
- A = from - thickdir * (thickness / 2);
- B = from + thickdir * (thickness / 2);
- C = to + thickdir * (thickness / 2);
- D = to - thickdir * (thickness / 2);
-
- R_BeginPolygon(texture, drawflag);
- R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha);
- R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha);
- R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
- R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
- R_EndPolygon();
-}
-
string Draw_GrapplingHook_trace_callback_tex;
float Draw_GrapplingHook_trace_callback_rnd;
vector Draw_GrapplingHook_trace_callback_rgb;
#include "hud_config.qh"
#include "mapvoting.qh"
#include "scoreboard.qh"
-#include "sortlist.qh"
#include "teamradar.qh"
#include "t_items.qh"
#include "../common/buffs.qh"
#include "../common/constants.qh"
-#include "../common/counting.qh"
#include "../common/deathtypes.qh"
#include "../common/items/all.qc"
#include "../common/mapinfo.qh"
#include "../csqcmodellib/cl_player.qh"
-#include "../warpzonelib/mathlib.qh"
/*
==================
==================
*/
-// a border picture is a texture containing nine parts:
-// 1/4 width: left part
-// 1/2 width: middle part (stretched)
-// 1/4 width: right part
-// divided into
-// 1/4 height: top part
-// 1/2 height: middle part (stretched)
-// 1/4 height: bottom part
-void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize)
-{
- if (theBorderSize.x < 0 && theBorderSize.y < 0) // draw whole image as it is
- {
- drawpic(theOrigin, pic, theSize, theColor, theAlpha, 0);
- return;
- }
- if (theBorderSize.x == 0 && theBorderSize.y == 0) // no border
- {
- // draw only the central part
- drawsubpic(theOrigin, theSize, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0);
- return;
- }
-
- vector dX, dY;
- vector width, height;
- vector bW, bH;
- //pic = draw_UseSkinFor(pic);
- width = eX * theSize.x;
- height = eY * theSize.y;
- if(theSize.x <= theBorderSize.x * 2)
- {
- // not wide enough... draw just left and right then
- bW = eX * (0.25 * theSize.x / (theBorderSize.x * 2));
- if(theSize.y <= theBorderSize.y * 2)
- {
- // not high enough... draw just corners
- bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2));
- drawsubpic(theOrigin, width * 0.5 + height * 0.5, pic, '0 0 0', bW + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width * 0.5, width * 0.5 + height * 0.5, pic, eX - bW, bW + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + height * 0.5, width * 0.5 + height * 0.5, pic, eY - bH, bW + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0);
- }
- else
- {
- dY = theBorderSize.x * eY;
- drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);
- drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width * 0.5 + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0' + eX - bW, '0 0.5 0' + bW, theColor, theAlpha, 0);
- drawsubpic(theOrigin + height - dY, width * 0.5 + dY, pic, '0 0.75 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width * 0.5 + height - dY, width * 0.5 + dY, pic, '0 0.75 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);
- }
- }
- else
- {
- if(theSize.y <= theBorderSize.y * 2)
- {
- // not high enough... draw just top and bottom then
- bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2));
- dX = theBorderSize.x * eX;
- drawsubpic(theOrigin, dX + height * 0.5, pic, '0 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + dX, width - 2 * dX + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width - dX, dX + height * 0.5, pic, '0.75 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + height * 0.5, dX + height * 0.5, pic, '0 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + dX + height * 0.5, width - 2 * dX + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5 0 0' + bH, theColor, theAlpha, 0);
- drawsubpic(theOrigin + width - dX + height * 0.5, dX + height * 0.5, pic, '0.75 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);
- }
- else
- {
- dX = theBorderSize.x * eX;
- dY = theBorderSize.x * eY;
- drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + dY, dX + height - 2 * dY, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + dY + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + dY + width - dX, dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + height - dY, dX + dY, pic, '0 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + height - dY + dX, width - 2 * dX + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0);
- drawsubpic(theOrigin + height - dY + width - dX, dX + dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
- }
- }
-}
-
vector HUD_Get_Num_Color (float x, float maxvalue)
{
float blinkingamt;
return eX * best_columns + eY * best_rows;
}
-float stringwidth_colors(string s, vector theSize)
-{
- return stringwidth(s, true, theSize);
-}
-
-float stringwidth_nocolors(string s, vector theSize)
-{
- return stringwidth(s, false, theSize);
-}
-
-void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
-{
- position.x -= 2 / 3 * strlen(text) * theScale.x;
- drawstring(position, text, theScale, rgb, theAlpha, flag);
-}
-
-void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
-{
- position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x);
- drawstring(position, text, theScale, rgb, theAlpha, flag);
-}
-
// return the string of the onscreen race timer
string MakeRaceString(int cp, float mytime, float theirtime, float lapdelta, string theirname)
{
return 0;
}
-int GetPlayerColorForce(int i)
-{
- if(!teamplay)
- return 0;
- else
- return stof(getplayerkeyvalue(i, "colors")) & 15;
-}
-
-int GetPlayerColor(int i)
-{
- if(!playerslots[i].gotscores) // unconnected
- return NUM_SPECTATOR;
- else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
- return NUM_SPECTATOR;
- else
- return GetPlayerColorForce(i);
-}
-
-string GetPlayerName(int i)
-{
- return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
-}
-
-
/*
==================
HUD panels
notify_count = count;
}
-// Timer (#5)
-//
-// TODO: macro
-string seconds_tostring(float sec)
-{
- float minutes;
- minutes = floor(sec / 60);
-
- sec -= minutes * 60;
- return sprintf("%d:%02d", minutes, sec);
-}
-
void HUD_Timer(void)
{
if(intermission == 2) return;
#include "main.qh"
#include "_all.qh"
-#include "casings.qh"
#include "controlpoint.qh"
#include "csqcmodel_hooks.qh"
#include "damage.qh"
#include "mapvoting.qh"
#include "modeleffects.qh"
#include "particles.qh"
-#include "prandom.qh"
#include "scoreboard.qh"
#include "shownames.qh"
-#include "sortlist.qh"
#include "tuba.qh"
#include "t_items.qh"
#include "wall.qh"
Projectile_Precache();
Hook_Precache();
GibSplash_Precache();
- Casings_Precache();
Tuba_Precache();
CSQCPlayer_Precache();
case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(bIsNewEntity); break;
case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(bIsNewEntity); break;
- case ENT_CLIENT_CASING: Ent_Casing(bIsNewEntity); break;
case ENT_CLIENT_INIT: Ent_Init(); break;
case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
#include "_all.qh"
#include "hud.qh"
-#include "sortlist.qh"
#include "../common/command/generic.qh"
#include "../common/teams.qh"
-#include "../common/urllib.qh"
#include "../common/util.qh"
#include "../csqcmodellib/cl_model.qh"
-#include "../warpzonelib/mathlib.qh"
void AuditLists()
{
return w;
}
-string ColorTranslateRGB(string s)
-{
- if(ColorTranslateMode & 1)
- return strdecolorize(s);
- else
- return s;
-}
-
// decolorizes and team colors the player name when needed
string playername(string thename, float teamid)
{
vector rotate(vector v, float a);
-int ColorTranslateMode;
string ColorTranslateRGB(string s);
/**
* Called when a temp entity is parsed
- * NOTE: hooks MUST start with `if (MUTATOR_RETURNVALUE) return false;`
- * NOTE: hooks MUST start with `if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return false;`
- * NOTE: return true if you handled the command, return false to continue handling
+ * NOTE: hooks MUST start with:
+ * if (MUTATOR_RETURNVALUE) return;
+ * if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return;
+ * return = true;
*/
#define EV_CSQC_Parse_TempEntity(i, o) \
/** mutator id */ i(int, mutator_argv_int_0) \
/**
* Called when a shared entity is updated
- * NOTE: hooks MUST start with `if (MUTATOR_RETURNVALUE) return false;`
- * NOTE: hooks MUST start with `if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return false;`
- * NOTE: return true if you handled the command, return false to continue handling
+ * if (MUTATOR_RETURNVALUE) return;
+ * if (!ReadMutatorEquals(mutator_argv_int_0, name_of_mutator)) return;
+ * return = true;
*/
#define EV_CSQC_Ent_Update(i, o) \
/** mutator id */ i(int, mutator_argv_int_0) \
+++ /dev/null
-#include "noise.qh"
-#include "_all.qh"
-
-entityclass(Noise);
-class(Noise) .float noise_baccum;
-class(Noise) .float noise_paccum;
-class(Noise) .float noise_paccum2;
-class(Noise) .float noise_paccum3;
-class(Noise) .float noise_bstate;
-
-float Noise_Brown(entity e, float dt)
-{
- e.noise_baccum += random() * sqrt(dt); // same stddev for all dt
- return e.noise_baccum;
-}
-float Noise_Pink(entity e, float dt)
-{
- float f;
- f = dt * 60;
- // http://home.earthlink.net/~ltrammell/tech/pinkalg.htm
- if(random() > pow(0.3190, f))
- e.noise_paccum = 0.34848 * (2 * random() - 1);
- if(random() > pow(0.7756, f))
- e.noise_paccum2 = 0.28768 * (2 * random() - 1);
- if(random() > pow(0.9613, f))
- e.noise_paccum3 = 0.43488 * (2 * random() - 1);
- return e.noise_paccum + e.noise_paccum2 + e.noise_paccum3;
-}
-float Noise_White(entity e, float dt)
-{
- return random() * 2 - 1;
-}
-float Noise_Burst(entity e, float dt, float p)
-{
- if(random() > pow(p, dt))
- e.noise_bstate = !e.noise_bstate;
- return 2 * e.noise_bstate - 1;
-}
+++ /dev/null
-#ifndef NOISE_H
-#define NOISE_H
-
-// noises "usually" start in the range -1..1
-float Noise_Brown(entity e, float dt);
-float Noise_Pink(entity e, float dt);
-float Noise_White(entity e, float dt);
-float Noise_Burst(entity e, float dt, float p); // +1 or -1
-#endif
+++ /dev/null
-#include "prandom.qh"
-#include "_all.qh"
-
-#include "../warpzonelib/mathlib.qh"
-
-// prandom - PREDICTABLE random number generator (not seeded yet)
-
-#ifdef USE_PRANDOM
-float prandom_seed;
-float prandom()
-{
- float c;
- c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
- prandom_seed = c;
-
-#ifdef USE_PRANDOM_DEBUG
- dprint("RANDOM -> ", ftos(c), "\n");
-#endif
-
- return c / 65536; // in [0..1[
-}
-
-vector prandomvec()
-{
- vector v;
-
- do
- {
- v.x = prandom();
- v.y = prandom();
- v.z = prandom();
- }
- while(v * v > 1);
-
- return v;
-}
-
-void psrandom(float seed)
-{
- prandom_seed = seed;
-#ifdef USE_PRANDOM_DEBUG
- dprint("SRANDOM ", ftos(seed), "\n");
-#endif
-}
-
-#ifdef USE_PRANDOM_DEBUG
-void prandom_debug()
-{
- dprint("Current random seed = ", ftos(prandom_seed), "\n");
-}
-#endif
-#endif
+++ /dev/null
-#ifndef PRANDOM_H
-#define PRANDOM_H
-
-// prandom - PREDICTABLE random number generator
-
-#define USE_PRANDOM
-
-#ifdef USE_PRANDOM
-float prandom();
-vector prandomvec();
-
-void psrandom(float seed);
-#ifdef USE_PRANDOM_DEBUG
-void prandom_debug();
-#else
-#define prandom_debug()
-#endif
-#else
-#define prandom random
-#define prandomvec randomvec
-#define psrandom(x)
-#define prandom_debug()
-#endif
-#endif
../dpdefs/csprogsdefs.qh
../common/util-post.qh
+../lib/_all.inc
+
announcer.qc
bgmscript.qc
-casings.qc
controlpoint.qc
csqcmodel_hooks.qc
damage.qc
miscfunctions.qc
modeleffects.qc
movelib.qc
-noise.qc
particles.qc
player_skeleton.qc
-prandom.qc
rubble.qc
scoreboard.qc
shownames.qc
-sortlist.qc
teamradar.qc
tuba.qc
t_items.qc
../common/notifications.qc
../common/physics.qc
../common/playerstats.qc
-../common/p2mathlib.qc
-../common/test.qc
-../common/urllib.qc
../common/util.qc
../common/viewloc.qc
../warpzonelib/anglestransform.qc
../warpzonelib/client.qc
../warpzonelib/common.qc
-../warpzonelib/mathlib.qc
../warpzonelib/util_server.qc
../../mod/client/progs.inc
#include "_all.qh"
#include "hud.qh"
-#include "sortlist.qh"
#include "../common/constants.qh"
-#include "../common/counting.qh"
#include "../common/mapinfo.qh"
#include "../common/minigames/cl_minigames.qh"
#include "../common/stats.qh"
+++ /dev/null
-#include "sortlist.qh"
-
-entity Sort_Spawn()
-{
- entity sort;
- sort = spawn();
- sort.sort_next = world;
- sort.chain = sort;
- return sort;
-}
-/*
-entity Sort_New(float(entity,entity) cmp)
-{
- entity sort;
- sort = spawn();
- sort.sort_cmp = cmp;
- sort.sort_next = world;
- sort.chain = sort;
- return sort;
-}
-
-void Sort_Remove(entity sort)
-{
- entity next;
- while(sort.sort_next)
- {
- next = sort.sort_next;
- remove(sort);
- sort = next;
- }
- remove(sort);
-}
-
-void Sort_Add(entity sort, entity ent)
-{
- entity next, parent;
- parent = sort;
- next = sort.sort_next;
- while(next)
- {
- if(!sort.sort_cmp(next, ent))
- break;
- parent = next;
- next = next.sort_next;
- }
- ent.sort_next = next;
- ent.sort_prev = parent;
- parent.sort_next = ent;
- if(next)
- next.sort_prev = ent;
-}
-
-void Sort_Reset(entity sort)
-{
- sort.chain = sort;
-}
-
-float Sort_HasNext(entity sort)
-{
- return (sort.chain.sort_next != world);
-}
-
-entity Sort_Next(entity sort)
-{
- entity next;
- next = sort.chain.sort_next;
- if(!next) {
- next = spawn();
- sort.chain.sort_next = next;
- next.sort_prev = sort.chain;
- next.sort_next = world;
- }
- sort.chain = next;
- return next;
-}
-
-void Sort_Finish(entity sort)
-{
- entity next;
- next = sort.chain;
- if(!next)
- return;
-
- while(next.sort_next)
- {
- sort = next.sort_next;
- next.sort_next = sort.sort_next;
- remove(sort);
- }
-}
-
-entity Sort_Get(entity sort, float i)
-{
- for (; sort.sort_next && i > 0; --i)
- sort = sort.sort_next;
- return sort;
-}
-*/
-
-/*
-void Sort_Erase(entity ent)
-{
- ent.sort_prev.sort_next = ent.sort_next;
- if(ent.sort_next)
- ent.sort_next.sort_prev = ent.sort_prev;
- remove(ent);
-}
-
-void Sort_RemoveOld(entity sort)
-{
- entity tmp;
- for(tmp = sort.sort_next; tmp; tmp = tmp.sort_next)
- {
- if(tmp.frame < time)
- {
- tmp = tmp.sort_prev;
- Sort_Erase(tmp.sort_next);
- }
- }
-}
-*/
+++ /dev/null
-#ifndef SORTLIST_H
-#define SORTLIST_H
-
-entityclass(Sort);
-//.float(entity,entity) sort_cmp;
-class(Sort) .entity sort_next, sort_prev;
-
-entity Sort_Spawn();
-
-/**
- * Swap two neighbours in a sortlist.
- * @param a FIRST entity
- * @param b entity after a
- */
-#define SORT_SWAP(a,b) \
- b.sort_prev = a.sort_prev; \
- a.sort_next = b.sort_next; \
- if(b.sort_next) b.sort_next.sort_prev = a; \
- if(a.sort_prev) a.sort_prev.sort_next = b; \
- a.sort_prev = b; \
- b.sort_next = a
-
-#endif
#include "../csqcmodellib/interpolate.qh"
-float vlen2d(vector v)
-{
- return sqrt(v.x * v.x + v.y * v.y);
-}
-
-float vlen_maxnorm2d(vector v)
-{
- return max(v.x, v.y, -v.x, -v.y);
-}
-
-float vlen_minnorm2d(vector v)
-{
- return min(max(v.x, -v.x), max(v.y, -v.y));
-}
-
vector teamradar_3dcoord_to_texcoord(vector in)
{
vector out;
float hud_panel_radar_maximized_rotation;
-float vlen2d(vector v);
-
-float vlen_maxnorm2d(vector v);
-
-float vlen_minnorm2d(vector v);
-
vector teamradar_2dcoord_to_texcoord(vector in);
vector teamradar_3dcoord_to_texcoord(vector in);
#include "../common/constants.qh"
#include "../common/util.qh"
-#include "../warpzonelib/mathlib.qh"
#define TUBA_STARTNOTE(i, n) W_Sound(strcat("tuba", (i ? ftos(i) : ""), "_loopnote", ftos(n)))
#include "hud.qh"
#include "hud_config.qh"
#include "mapvoting.qh"
-#include "noise.qh"
#include "scoreboard.qh"
#include "shownames.qh"
#include "../warpzonelib/client.qh"
#include "../warpzonelib/common.qh"
-#include "../warpzonelib/mathlib.qh"
entity porto;
vector polyline[16];
#include "teams.qh"
#include "util.qh"
-#include "registry.qh"
-
void RegisterBuffs();
const int BUFFS_MAX = 16;
entity BUFFS[BUFFS_MAX], BUFFS_first, BUFFS_last;
#include "rpn.qh"
#include "../mapinfo.qh"
-#include "../test.qh"
#ifndef MENUQC
#include "../notifications.qh"
#include "command.qh"
#include "rpn.qh"
-#include "../../warpzonelib/mathlib.qh"
// ========================================
// RPN command code, written by divVerent
const int ENT_CLIENT_PROJECTILE = 12;
const int ENT_CLIENT_GIBSPLASH = 13;
const int ENT_CLIENT_DAMAGEINFO = 14;
-const int ENT_CLIENT_CASING = 15;
const int ENT_CLIENT_INIT = 16;
const int ENT_CLIENT_MAPVOTE = 17;
const int ENT_CLIENT_CLIENTDATA = 18;
const int HUD_NORMAL = 0;
const int HUD_BUMBLEBEE_GUN = 25;
-const vector eX = '1 0 0';
-const vector eY = '0 1 0';
-const vector eZ = '0 0 1';
-
// moved that here so the client knows the max.
// # of maps, I'll use arrays for them :P
const int MAPVOTE_COUNT = 30;
const int SPAWN_PRIO_RACE_PREVIOUS_SPAWN = 50;
const int SPAWN_PRIO_GOOD_DISTANCE = 10;
-// URI handles
-const int URI_GET_DISCARD = 0;
-const int URI_GET_IPBAN = 1;
-const int URI_GET_IPBAN_END = 16;
-const int URI_GET_CURL = 17;
-const int URI_GET_CURL_END = 32;
-const int URI_GET_UPDATENOTIFICATION = 33;
-const int URI_GET_URLLIB = 128;
-const int URI_GET_URLLIB_END = 191;
-
// gametype vote flags
const int GTV_FORBIDDEN = 0; // Cannot be voted
const int GTV_AVAILABLE = 1; // Can be voted
+++ /dev/null
-#ifndef COUNTING_H
-#define COUNTING_H
-
-#include "util.qh"
-
-// ===============================================
-// Time processing and counting functions/macros
-// ===============================================
-
-#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(int interval)
-{
- // This function is designed primarily for the English language, it's impossible
- // to accomodate all languages unless we do a specific function for each one...
- // and since that's not technically feasible/practical, this is all we've got folks.
-
- // Basically, it just allows you to represent a number or count in different ways
- // depending on the number... like, with count_ordinal you can provide integers
- // and retrieve 1st, 2nd, 3rd, nth ordinal numbers in a clean and simple way.
- if(floor((interval % 100)/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block
- {
- // otherwise, check normally for 1st,2nd,3rd insertions
- switch(interval % 10)
- {
- case 1: return sprintf(_("%dst"), interval);
- case 2: return sprintf(_("%dnd"), interval);
- case 3: return sprintf(_("%drd"), interval);
- default: return sprintf(_("%dth"), interval);
- }
- }
- else { return sprintf(_("%dth"), interval); }
-
- return "";
-}
-
-string count_fill(float interval, string zeroth, string first, string second, string third, string multi)
-{
- // This function is designed primarily for the English language, it's impossible
- // to accomodate all languages unless we do a specific function for each one...
- // and since that's not technically feasible/practical, this is all we've got folks.
-
- // Here you can insert specific strings based on the interval number, so you could do
- // i.e. count_seconds which outputs like this:
- // 0 seconds
- // 1 second
- // 2 seconds
- // 3 seconds
- // etc... minutes, hours, days, etc.
-
- switch(floor(interval))
- {
- case 0: return sprintf(zeroth, interval);
- case 1:
- {
- if(interval == 1) // EXACTLY value of 1
- return sprintf(first, interval);
- else
- return sprintf(multi, interval);
- }
- case 2: return sprintf(second, interval);
- case 3: return sprintf(third, interval);
- default: return sprintf(multi, interval);
- }
- return "";
-}
-
-string process_time(float outputtype, float seconds)
-{
- float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0;
- float tmp_years = 0, tmp_weeks = 0, tmp_days = 0;
-
- tmp_seconds = floor(seconds);
-
- if(tmp_seconds)
- {
- tmp_minutes = floor(tmp_seconds / 60);
-
- if(tmp_minutes)
- {
- tmp_seconds -= (tmp_minutes * 60);
- tmp_hours = floor(tmp_minutes / 60);
-
- if(tmp_hours)
- {
- tmp_minutes -= (tmp_hours * 60);
- tmp_days = floor(tmp_hours / 24);
-
- if(tmp_days)
- {
- tmp_hours -= (tmp_days * 24);
- tmp_weeks = floor(tmp_days / 7);
-
- if(tmp_weeks)
- {
- tmp_days -= (tmp_weeks * 7);
- tmp_years = floor(tmp_weeks / 52);
- }
- }
- }
- }
- }
-
- switch(outputtype)
- {
- case 1: return sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds);
- case 2:
- {
- string output = "";
-
- output = count_seconds(tmp_seconds);
-
- if(tmp_minutes)
- {
- output = sprintf(
- "%s%s",
- count_minutes(tmp_minutes),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- if(tmp_hours)
- {
- output = sprintf(
- "%s%s",
- count_hours(tmp_hours),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- if(tmp_days)
- {
- output = sprintf(
- "%s%s",
- count_days(tmp_days),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- if(tmp_weeks)
- {
- output = sprintf(
- "%s%s",
- count_weeks(tmp_weeks),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- if(tmp_years)
- {
- output = sprintf(
- "%s%s",
- count_years(tmp_years),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- return output;
- }
- case 3:
- {
- string output = "";
-
- output = count_hours(tmp_hours);
-
- if(tmp_weeks) { tmp_days += (tmp_weeks * 7); }
- if(tmp_years) { tmp_days += (tmp_years * 365); }
- if(tmp_days)
- {
- output = sprintf(
- "%s%s",
- count_days(tmp_days),
- ((output != "") ? sprintf(", %s", output) : ""));
- }
-
- return output;
- }
- }
- return "";
-}
-#endif
-#include "../registry.qh"
-
#ifndef ITEMS_ALL_H
#define ITEMS_ALL_H
#ifndef GAMEITEM_H
#define GAMEITEM_H
-#include "../oo.qh"
#define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__)
/** If you register a new item, make sure to add it to all.inc */
CLASS(GameItem, Object)
-#include "../registry.qh"
-
#ifndef MONSTERS_ALL_H
#define MONSTERS_ALL_H
bool m_null(int) { return false; }
-#include "../oo.qh"
/** If you register a new monster, make sure to add it to all.inc */
CLASS(Monster, Object)
ATTRIB(Monster, monsterid, int, 0)
+#include "mutator/casings.qc"
#include "mutator/damagetext.qc"
#include "mutator/itemstime.qc"
#include "mutator/waypoints/waypointsprites.qc"
--- /dev/null
+#include "../../util.qh"
+
+#ifdef CSQC
+#include "../../movetypes/movetypes.qh"
+#include "../../../client/rubble.qh"
+#endif
+
+REGISTER_MUTATOR(casings, true);
+
+#ifdef SVQC
+void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner)
+{
+ vector org = self.origin + self.view_ofs + self.weaponentity.spawnorigin.x * v_forward - self.weaponentity.spawnorigin.y * v_right + self.weaponentity.spawnorigin.z * v_up;
+
+ if (!sound_allowed(MSG_BROADCAST, casingowner))
+ casingtype |= 0x80;
+
+ WriteByte(MSG_ALL, SVC_TEMPENTITY);
+ WriteMutator(MSG_ALL, casings);
+ WriteByte(MSG_ALL, casingtype);
+ WriteCoord(MSG_ALL, org.x);
+ WriteCoord(MSG_ALL, org.y);
+ WriteCoord(MSG_ALL, org.z);
+ WriteShort(MSG_ALL, compressShortVector(vel)); // actually compressed velocity
+ WriteByte(MSG_ALL, ang.x * 256 / 360);
+ WriteByte(MSG_ALL, ang.y * 256 / 360);
+ WriteByte(MSG_ALL, ang.z * 256 / 360);
+}
+#endif
+
+#ifdef CSQC
+entityclass(Casing);
+class(Casing) .float alpha;
+class(Casing) .bool silent;
+class(Casing) .int state;
+class(Casing) .float cnt;
+
+void Casing_Delete()
+{
+ remove(self);
+}
+
+void Casing_Draw()
+{
+ if (self.move_flags & FL_ONGROUND)
+ {
+ self.move_angles_x = 0;
+ self.move_angles_z = 0;
+ self.flags &= ~FL_ONGROUND;
+ }
+
+ Movetype_Physics_MatchTicrate(autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
+ if (wasfreed(self))
+ return; // deleted by touch function
+
+ self.renderflags = 0;
+ self.alpha = bound(0, self.cnt - time, 1);
+
+ if (self.alpha < ALPHA_MIN_VISIBLE)
+ {
+ Casing_Delete();
+ self.drawmask = 0;
+ }
+}
+
+void Casing_Touch()
+{
+ if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+ {
+ Casing_Delete();
+ return;
+ }
+
+ if (!self.silent)
+ if (!trace_ent || trace_ent.solid == SOLID_BSP)
+ {
+ if (vlen(self.velocity) > 50)
+ {
+ if (time >= self.nextthink)
+ {
+ string s;
+ int f = floor(prandom() * 3) + 1;
+
+ switch (self.state)
+ {
+ case 1:
+ s = W_Sound(strcat("casings", itos(f)));
+ break;
+ default:
+ s = W_Sound(strcat("brass", itos(f)));
+ break;
+ }
+
+ sound (self, CH_SHOTS, s, VOL_BASE, ATTEN_LARGE);
+ }
+ }
+ }
+
+ self.nextthink = time + 0.2;
+}
+
+void Casing_Damage(float thisdmg, int hittype, vector org, vector thisforce)
+{
+ if (thisforce.z < 0)
+ thisforce.z = 0;
+ self.move_velocity = self.move_velocity + thisforce + '0 0 100';
+ self.move_flags &= ~FL_ONGROUND;
+}
+
+MUTATOR_HOOKFUNCTION(casings, CSQC_Parse_TempEntity)
+{
+ if (MUTATOR_RETURNVALUE) return;
+ if (!ReadMutatorEquals(mutator_argv_int_0, casings)) return;
+ return = true;
+
+ int _state = ReadByte();
+ vector org;
+ org_x = ReadCoord();
+ org_y = ReadCoord();
+ org_z = ReadCoord();
+ vector vel = decompressShortVector(ReadShort());
+ vector ang;
+ ang_x = ReadByte() * 360 / 256;
+ ang_y = ReadByte() * 360 / 256;
+ ang_z = ReadByte() * 360 / 256;
+
+ if (!autocvar_cl_casings) return;
+
+ Casing casing = RubbleNew("casing");
+ casing.silent = (_state & 0x80);
+ casing.state = (_state & 0x7F);
+ casing.origin = org;
+ setorigin(casing, casing.origin);
+ casing.velocity = vel;
+ casing.angles = ang;
+ casing.drawmask = MASK_NORMAL;
+
+ casing.draw = Casing_Draw;
+ casing.move_origin = casing.origin;
+ casing.move_velocity = casing.velocity + 2 * prandomvec();
+ casing.move_angles = casing.angles;
+ casing.move_avelocity = '0 250 0' + 100 * prandomvec();
+ casing.move_movetype = MOVETYPE_BOUNCE;
+ casing.move_touch = Casing_Touch;
+ casing.move_time = time;
+ casing.event_damage = Casing_Damage;
+ casing.solid = SOLID_TRIGGER;
+
+ switch (casing.state)
+ {
+ case 1:
+ setmodel(casing, "models/casing_shell.mdl");
+ casing.cnt = time + autocvar_cl_casings_shell_time;
+ break;
+ default:
+ setmodel(casing, "models/casing_bronze.iqm");
+ casing.cnt = time + autocvar_cl_casings_bronze_time;
+ break;
+ }
+
+ setsize(casing, '0 0 -1', '0 0 -1');
+
+ RubbleLimit("casing", autocvar_cl_casings_maxcount, Casing_Delete);
+}
+
+STATIC_INIT(Casings)
+{
+ precache_model("models/casing_shell.mdl");
+ precache_model("models/casing_bronze.iqm");
+ precache_sound(W_Sound("brass1"));
+ precache_sound(W_Sound("brass2"));
+ precache_sound(W_Sound("brass3"));
+ precache_sound(W_Sound("casings1"));
+ precache_sound(W_Sound("casings2"));
+ precache_sound(W_Sound("casings3"));
+}
+#endif
REGISTER_MUTATOR(damagetext, true);
-#ifdef CSQC
+#if defined(CSQC) || defined(MENUQC)
bool autocvar_cl_damagetext = false;
string autocvar_cl_damagetext_format = "-%3$d";
vector autocvar_cl_damagetext_color = '1 1 0';
vector autocvar_cl_damagetext_velocity = '0 0 20';
vector autocvar_cl_damagetext_offset = '0 -40 0';
float autocvar_cl_damagetext_accumulate_range = 30;
+
STATIC_INIT(cl_damagetext) {
CVAR_DESCRIBE(cl_damagetext, _("Draw damage dealt. 0: disabled, 1: enabled"));
CVAR_DESCRIBESTR(cl_damagetext_format, _("How to format the damage text. 1$ is health, 2$ is armor, 3$ is both"));
CVAR_DESCRIBEVEC(cl_damagetext_offset, _("Damage text offset"));
CVAR_DESCRIBE(cl_damagetext_accumulate_range, _("Damage text spawned within this range is accumulated"));
}
+#endif
+#ifdef CSQC
CLASS(DamageText, Object)
ATTRIB(DamageText, m_color, vector, autocvar_cl_damagetext_color)
ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size)
return true;
}
#endif
+
+#ifdef MENUQC
+#include "../../../menu/xonotic/tab.qc"
+CLASS(XonoticDamageTextSettings, XonoticTab)
+ #include "../../../menu/gamesettings.qh"
+ REGISTER_SETTINGS(damagetext, NEW(XonoticDamageTextSettings));
+ ATTRIB(XonoticDamageTextSettings, title, string, _("Damage text"))
+ ATTRIB(XonoticDamageTextSettings, intendedWidth, float, 0.9)
+ ATTRIB(XonoticDamageTextSettings, rows, float, 13)
+ ATTRIB(XonoticDamageTextSettings, columns, float, 5)
+ INIT(XonoticDamageTextSettings) { this.configureDialog(this); }
+ METHOD(XonoticDamageTextSettings, showNotify, void(entity this)) { loadAllCvars(this); }
+ METHOD(XonoticDamageTextSettings, fill, void(entity this))
+ {
+ this.gotoRC(this, 0, 1); this.setFirstColumn(this, this.currentColumn);
+ this.TD(this, 1, 3, makeXonoticCheckBox(0, "cl_damagetext", _("Draw damage numbers")));
+ this.TR(this);
+ this.TD(this, 1, 1, makeXonoticTextLabel(0, _("Font size:")));
+ this.TD(this, 1, 2, makeXonoticSlider(0, 50, 1, "cl_damagetext_size"));
+ this.TR(this);
+ this.TD(this, 1, 1, makeXonoticTextLabel(0, _("Accumulate range:")));
+ this.TD(this, 1, 2, makeXonoticSlider(0, 500, 1, "cl_damagetext_accumulate_range"));
+ this.TR(this);
+ this.TD(this, 1, 1, makeXonoticTextLabel(0, _("Lifetime:")));
+ this.TD(this, 1, 2, makeXonoticSlider(0, 10, 1, "cl_damagetext_alpha_lifetime"));
+ this.TR(this);
+ this.TD(this, 1, 1, makeXonoticTextLabel(0, _("Color:")));
+ this.TD(this, 2, 2, makeXonoticColorpickerString("cl_damagetext_color", "cl_damagetext_color"));
+ }
+ENDCLASS(XonoticDamageTextSettings)
+#endif
bool autocvar_hud_panel_itemstime_hidelarge = false;
int autocvar_hud_panel_itemstime_text = 1;
#define hud_panel_itemstime_hidelarge autocvar_hud_panel_itemstime_hidelarge
-#endif
-
-#ifdef SVQC
+#else
#define hud_panel_itemstime_hidelarge false
#endif
-bool Item_ItemsTime_Allow(GameItem it, WepSet _weapons)
+bool Item_ItemsTime_SpectatorOnly(GameItem it)
{
return (false
- || it.instanceOfPowerup
|| it == ITEM_ArmorMega || (it == ITEM_ArmorLarge && !hud_panel_itemstime_hidelarge)
|| it == ITEM_HealthMega || (it == ITEM_HealthLarge && !hud_panel_itemstime_hidelarge)
+ );
+}
+
+bool Item_ItemsTime_Allow(GameItem it, WepSet _weapons)
+{
+ return (false
+ || it.instanceOfPowerup
+ || Item_ItemsTime_SpectatorOnly(it)
|| (_weapons & WEPSET_SUPERWEAPONS)
);
}
-#include "../../../registry.qh"
-
#ifndef WAYPOINTS_ALL_H
#define WAYPOINTS_ALL_H
#ifndef NADES_H
#define NADES_H
-#include "oo.qh"
-#include "registry.qh"
#include "teams.qh"
.float healer_lifetime;
#include "../dpdefs/dpextensions.qh"
#include "constants.qh"
#include "teams.qh"
- #include "counting.qh"
#include "../server/autocvars.qh"
#include "../server/constants.qh"
#include "../server/defs.qh"
if((notif.nent_stringcount + notif.nent_floatcount) > count)
{
+ string s =
+ #ifdef NOTIFICATIONS_DEBUG
+ Get_Notif_BroadcastName(broadcast);
+ #else
+ ftos(broadcast);
+ #endif
backtrace(sprintf(
strcat(
"Not enough arguments for Send_Notification(%s, ...)! ",
"Check the definition and function call for accuracy...?\n"
),
sprintf(
- #ifdef NOTIFICATIONS_DEBUG
"%s, '%s', %s, %s",
- Get_Notif_BroadcastName(broadcast),
- #else
- "%d, '%s', %s, %s",
- broadcast,
- #endif
+ s,
client.classname,
Get_Notif_TypeName(net_type),
notif.nent_name
}
else if((notif.nent_stringcount + notif.nent_floatcount) < count)
{
+ string s =
+ #ifdef NOTIFICATIONS_DEBUG
+ Get_Notif_BroadcastName(broadcast);
+ #else
+ ftos(broadcast);
+ #endif
backtrace(sprintf(
strcat(
"Too many arguments for Send_Notification(%s, ...)! ",
"Check the definition and function call for accuracy...?\n"
),
sprintf(
- #ifdef NOTIFICATIONS_DEBUG
"%s, '%s', %s, %s",
- Get_Notif_BroadcastName(broadcast),
- #else
- "%d, '%s', %s, %s",
- broadcast,
- #endif
+ s,
client.classname,
Get_Notif_TypeName(net_type),
notif.nent_name
+++ /dev/null
-#ifndef OO_H
-#define OO_H
-
-#include "registry.qh"
-
-#ifdef MENUQC
- #define NULL (null_entity)
-#else
- #define NULL (world)
-#endif
-
-.string classname;
-/** Location entity was spawned from in source */
-.string sourceLocFile;
-.int sourceLocLine;
-entity _spawn();
-entity __spawn(string _classname, string _sourceFile, int _sourceLine) {
- entity this = _spawn();
- this.classname = _classname;
- this.sourceLocFile = _sourceFile;
- this.sourceLocLine = _sourceLine;
- return this;
-}
-
-
-
-#define entityclass(...) OVERLOAD(entityclass, __VA_ARGS__)
-#define entityclass_1(name) entityclass_2(name, Object)
-#ifndef QCC_SUPPORT_ENTITYCLASS
- #define entityclass_2(name, base) typedef entity name
- #define class(name)
- #define new(class) __spawn(#class, __FILE__, __LINE__)
-#else
- #define entityclass_2(name, base) entityclass name : base {}
- #define class(name) [[class(name)]]
- #define new(class) ((class) __spawn(#class, __FILE__, __LINE__))
-#endif
-
-// Classes have a `spawn##cname(entity)` constructor
-// The parameter is used across [[accumulate]] functions
-
-// Macro to hide this implementation detail
-#define NEW(cname, ...) \
- OVERLOAD(spawn##cname, new(cname), ##__VA_ARGS__)
-
-#define CONSTRUCT(cname, ...) \
- OVERLOAD(spawn##cname, this, ##__VA_ARGS__)
-
-#define CONSTRUCTOR(cname, ...) \
- cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \
- [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
-
-.string vtblname;
-.entity vtblbase;
-
-void RegisterClasses() { }
-STATIC_INIT(RegisterClasses) { RegisterClasses(); }
-
-#define VTBL(cname, base) \
- INIT_STATIC(cname); \
- entity cname##_vtbl; \
- void cname##_vtbl_init() { \
- cname e = new(vtbl); \
- spawn##cname##_static(e); \
- e.vtblname = #cname; \
- /* Top level objects refer to themselves */ \
- e.vtblbase = base##_vtbl ? base##_vtbl : e; \
- cname##_vtbl = e; \
- } \
- ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
-
-#define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
-#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
-
-#define CLASS(cname, base) \
- entityclass(cname, base); \
- class(cname) .bool instanceOf##cname; \
- VTBL(cname, base) \
- INIT_STATIC(cname) { \
- if (cname##_vtbl) { \
- copyentity(cname##_vtbl, this); \
- return; \
- } \
- spawn##base##_static(this); \
- this.instanceOf##cname = true; \
- } \
- INIT(cname) { \
- /* Only statically initialize the current class, it contains everything it inherits */ \
- if (cname##_vtbl.vtblname == this.classname) { \
- spawn##cname##_static(this); \
- this.classname = #cname; \
- this.vtblname = string_null; \
- this.vtblbase = cname##_vtbl; \
- } \
- spawn##base##_1(this); \
- }
-
-#define METHOD(cname, name, prototype) \
- class(cname) .prototype name; \
- prototype cname##_##name; \
- INIT_STATIC(cname) { this.name = cname##_##name; } \
- prototype cname##_##name
-
-#define ATTRIB(cname, name, type, val) \
- class(cname) .type name; \
- INIT(cname) { this.name = val; }
-
-#define ATTRIBARRAY(cname, name, type, cnt) \
- class(cname) .type name[cnt];
-
-#define ENDCLASS(cname) \
- [[last]] INIT(cname) { return this; }
-
-#define SUPER(cname) (cname##_vtbl.vtblbase)
-#define super (this.vtblbase.vtblbase)
-
-#define spawn_static(this)
-#define spawn_1(this)
-#define _vtbl NULL
-CLASS(Object, );
- METHOD(Object, describe, string(entity this)) {
- string s = _("No description");
- if (cvar("developer")) {
- for (int i = 0, n = numentityfields(); i < n; ++i) {
- string value = getentityfieldstring(i, this);
- if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value);
- }
- }
- return s;
- }
- METHOD(Object, display, void(entity this, void(string name, string icon) returns)) {
- returns(sprintf("entity %i", this), "nopreview_map");
- }
-ENDCLASS(Object)
-#undef spawn_static
-#undef spawn_1
-#undef _vtbl
-
-#endif
+++ /dev/null
-/*
- Copyright (C) 2015 Micah Talkiewicz.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-vector vec_bias(vector v, float f){
- vector c;
- c_x = v_x + f;
- c_y = v_y + f;
- c_z = v_z + f;
- return c;
-}
-vector vec_to_min (vector a, vector b) {
- vector c;
- c_x = min (a_x, b_x);
- c_y = min (a_y, b_y);
- c_z = min (a_z, b_z);
- return c;
-}
-
-vector vec_to_max (vector a, vector b) {
- vector c;
- c_x = max (a_x, b_x);
- c_y = max (a_y, b_y);
- c_z = max (a_z, b_z);
- return c;
-}
-
-// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
-vector vec_bounds_in (vector point, vector a, vector b) {
- vector c, d, e;
-
- d = vec_to_min(a,b);
- e = vec_to_max(a,b);
-
- c = vec_to_max(point, d);
- c = vec_to_min(c, e);
-
- return c;
-
-}
-
-vector vec_bounds_out (vector point, vector a, vector b) {
- vector c, d, e;
-
- d = vec_to_max(a,b);
- e = vec_to_min(a,b);
-
- c = vec_to_max(point, d);
- c = vec_to_min(c, e);
-
- return c;
-
-}
-
-float angle_snap_f (float f, float increment){
-
- float i;
- for (i = 0; i <= 360; ){
- if (f <= i - increment)
- return i - increment;
- i = i + increment;
- }
-
- return 0;
-}
-
-vector angle_snap_vec (vector v, float increment) {
- vector c;
- c_x = angle_snap_f (v_x, increment);
- c_y = angle_snap_f (v_y, increment);
- c_z = angle_snap_f (v_z, increment);
- return c;
-}
-
-vector aim_vec (vector origin, vector target) {
- vector v;
- //we float around x and y, but rotate around z
- v_x = target_x - origin_x;
- v_y = target_y - origin_y;
- v_z = origin_z - target_z;
- //get the angles actual
- return vectoangles(normalize(v));
-}
+++ /dev/null
-/*
- Copyright (C) 2015 Micah Talkiewicz.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-vector vec_bias(vector v, float f);
-
-
-vector vec_to_min (vector a, vector b);
-vector vec_to_max (vector a, vector b);
-
-// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
-vector vec_bounds_in (vector point, vector a, vector b);
-vector vec_bounds_out (vector point, vector a, vector b);
-
-float angle_snap_f (float f, float increment);
-vector angle_snap_vec (vector v, float increment);
-
-vector aim_vec (vector origin, vector target);
#include "../dpdefs/dpextensions.qh"
#include "constants.qh"
#include "util.qh"
- #include "urllib.qh"
#include "weapons/all.qh"
#include "../server/weapons/accuracy.qh"
#include "../server/defs.qh"
+++ /dev/null
-#ifndef REGISTRY_H
-#define REGISTRY_H
-
-#include "oo.qh"
-#include "util.qh"
-
-#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this)
-#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this)
-
-#define REGISTER(initfunc, ns, array, counter, id, fld, inst) \
- entity ns##_##id; \
- REGISTER_INIT(ns, id) { } \
- REGISTER_INIT_POST(ns, id) { } \
- .entity enemy; /* internal next pointer */ \
- void Register_##ns##_##id() { \
- entity this = inst; \
- ns##_##id = this; \
- this.fld = counter; \
- array[counter++] = this; \
- if (!array##_first) array##_first = this; \
- if ( array##_last) array##_last.enemy = this; \
- array##_last = this; \
- Register_##ns##_##id##_init(this); \
- Register_##ns##_##id##_init_post(this); \
- } \
- ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \
- REGISTER_INIT(ns, id)
-
-void __static_init() { }
-#define static_init() CALL_ACCUMULATED_FUNCTION(__static_init)
-#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init, func)
-
-#define STATIC_INIT(func) \
- void _static_##func(); \
- ACCUMULATE_FUNCTION(__static_init, _static_##func) \
- void _static_##func()
-
-#endif
+++ /dev/null
-#if defined(CSQC)
- #include "../dpdefs/csprogsdefs.qh"
- #include "test.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../dpdefs/dpextensions.qh"
- #include "test.qh"
-#endif
-
-float TEST_failed;
-float TEST_ok;
-
-void TEST_Fail(string cond)
-{
- printf("Assertion failed: ", cond);
- //backtrace();
- ++TEST_failed;
-}
-
-void TEST_OK()
-{
- TEST_ok = true;
-}
-
-float TEST_RunAll()
-{
- int f = 0;
- float n = numentityfields();
- for(int i = 0; i < n; ++i)
- {
- string name = entityfieldname(i);
- if(substring(name, 0, 6) == "_TEST_")
- if(!TEST_Run(substring(name, 6, -1)))
- ++f;
- }
- if(f)
- {
- printf("%d tests failed\n", f);
- return 1;
- }
- else
- {
- printf("All tests OK\n", f);
- return 0;
- }
-}
-
-float TEST_Run(string s)
-{
- printf("%s: testing...\n", s);
- TEST_failed = TEST_ok = 0;
- callfunction(strcat("_TEST_", s));
- if(TEST_failed > 0)
- {
- printf("%s: %d items failed.\n", s, TEST_failed);
- return 0;
- }
- else if(!TEST_ok)
- {
- printf("%s: did not complete.\n", s);
- return 0;
- }
- return 1;
-}
+++ /dev/null
-#ifndef TEST_H
-#define TEST_H
-
-#define TEST_Check(cond) do { if(!(cond)) TEST_Fail(#cond); } while(0)
-
-void TEST_OK();
-void TEST_Fail(string cond);
-
-float TEST_RunAll();
-float TEST_Run(string test);
-#endif
void() SUB_CalcAngleMoveDone;
//void() SUB_UseTargets;
-/*
-==================
-SUB_Remove
-
-Remove self
-==================
-*/
-void SUB_Remove()
-{
- remove (self);
-}
-
/*
==================
SUB_Friction
+++ /dev/null
-#if defined(CSQC)
- #include "../dpdefs/csprogsdefs.qh"
- #include "constants.qh"
- #include "util.qh"
- #include "urllib.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
- #include "../dpdefs/progsdefs.qh"
- #include "../dpdefs/dpextensions.qh"
- #include "constants.qh"
- #include "util.qh"
- #include "urllib.qh"
-#endif
-
-// files
-.float url_fh;
-const float URL_FH_CURL = -1;
-const float URL_FH_STDOUT = -2;
-
-// URLs
-.string url_url;
-.float url_wbuf;
-.float url_wbufpos;
-.float url_rbuf;
-.float url_rbufpos;
-.float url_id;
-.url_ready_func url_ready;
-.entity url_ready_pass;
-
-// for multi handles
-.int url_attempt;
-.int url_mode;
-
-entity url_fromid[NUM_URL_ID];
-int autocvar__urllib_nextslot;
-
-float url_URI_Get_Callback(int id, float status, string data)
-{
- if(id < MIN_URL_ID)
- return 0;
- id -= MIN_URL_ID;
- if(id >= NUM_URL_ID)
- return 0;
- entity e;
- e = url_fromid[id];
- if(!e)
- return 0;
- if(e.url_rbuf >= 0 || e.url_wbuf >= 0)
- {
- printf("WARNING: handle %d (%s) has already received data?!?\n", id + NUM_URL_ID, e.url_url);
- return 0;
- }
-
- // whatever happens, we will remove the URL from the list of IDs
- url_fromid[id] = world;
-
- // if we get here, we MUST have both buffers cleared
- if(e.url_rbuf != -1 || e.url_wbuf != -1 || e.url_fh != URL_FH_CURL)
- error("url_URI_Get_Callback: not a request waiting for data");
-
- if(status == 0)
- {
- // WE GOT DATA!
- float n, i;
- n = tokenizebyseparator(data, "\n");
- e.url_rbuf = buf_create();
- if(e.url_rbuf < 0)
- {
- print("url_URI_Get_Callback: out of memory in buf_create\n");
- e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
- strunzone(e.url_url);
- remove(e);
- return 1;
- }
- e.url_rbufpos = 0;
- if(e.url_rbuf < 0)
- {
- print("url_URI_Get_Callback: out of memory in buf_create\n");
- e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
- strunzone(e.url_url);
- remove(e);
- return 1;
- }
- for(i = 0; i < n; ++i)
- bufstr_set(e.url_rbuf, i, argv(i));
- e.url_ready(e, e.url_ready_pass, URL_READY_CANREAD);
- return 1;
- }
- else
- {
- // an ERROR
- e.url_ready(e, e.url_ready_pass, -fabs(status));
- strunzone(e.url_url);
- remove(e);
- return 1;
- }
-}
-
-void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
-{
- entity e;
- int i;
- if(strstrofs(url, "://", 0) >= 0)
- {
- switch(mode)
- {
- case FILE_WRITE:
- case FILE_APPEND:
- // collect data to a stringbuffer for a POST request
- // attempts to close will result in a reading handle
-
- // create a writing end that does nothing yet
- e = spawn();
- e.classname = "url_single_fopen_file";
- e.url_url = strzone(url);
- e.url_fh = URL_FH_CURL;
- e.url_wbuf = buf_create();
- if(e.url_wbuf < 0)
- {
- print("url_single_fopen: out of memory in buf_create\n");
- rdy(e, pass, URL_READY_ERROR);
- strunzone(e.url_url);
- remove(e);
- return;
- }
- e.url_wbufpos = 0;
- e.url_rbuf = -1;
- e.url_ready = rdy;
- e.url_ready_pass = pass;
- rdy(e, pass, URL_READY_CANWRITE);
- break;
-
- case FILE_READ:
- // read data only
-
- // get slot for HTTP request
- for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
- if(url_fromid[i] == world)
- break;
- if(i >= NUM_URL_ID)
- {
- for(i = 0; i < autocvar__urllib_nextslot; ++i)
- if(url_fromid[i] == world)
- break;
- if(i >= autocvar__urllib_nextslot)
- {
- print("url_single_fopen: too many concurrent requests\n");
- rdy(world, pass, URL_READY_ERROR);
- return;
- }
- }
-
- // GET the data
- if(!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
- {
- print("url_single_fopen: failure in crypto_uri_postbuf\n");
- rdy(world, pass, URL_READY_ERROR);
- return;
- }
-
- // Make a dummy handle object (no buffers at
- // all). Wait for data to come from the
- // server, then call the callback
- e = spawn();
- e.classname = "url_single_fopen_file";
- e.url_url = strzone(url);
- e.url_fh = URL_FH_CURL;
- e.url_rbuf = -1;
- e.url_wbuf = -1;
- e.url_ready = rdy;
- e.url_ready_pass = pass;
- e.url_id = i;
- url_fromid[i] = e;
-
- // make sure this slot won't be reused quickly even on map change
- cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
- break;
- }
- }
- else if(url == "-")
- {
- switch(mode)
- {
- case FILE_WRITE:
- case FILE_APPEND:
- e = spawn();
- e.classname = "url_single_fopen_stdout";
- e.url_fh = URL_FH_STDOUT;
- e.url_ready = rdy;
- e.url_ready_pass = pass;
- rdy(e, pass, URL_READY_CANWRITE);
- break;
- case FILE_READ:
- print("url_single_fopen: cannot open '-' for reading\n");
- rdy(world, pass, URL_READY_ERROR);
- break;
- }
- }
- else
- {
- float fh;
- fh = fopen(url, mode);
- if(fh < 0)
- {
- rdy(world, pass, URL_READY_ERROR);
- return;
- }
- else
- {
- e = spawn();
- e.classname = "url_single_fopen_file";
- e.url_fh = fh;
- e.url_ready = rdy;
- e.url_ready_pass = pass;
- if(mode == FILE_READ)
- rdy(e, pass, URL_READY_CANREAD);
- else
- rdy(e, pass, URL_READY_CANWRITE);
- }
- }
-}
-
-// close a file
-void url_fclose(entity e)
-{
- int i;
-
- if(e.url_fh == URL_FH_CURL)
- {
- if(e.url_rbuf == -1 || e.url_wbuf != -1) // not(post GET/POST request)
- if(e.url_rbuf != -1 || e.url_wbuf == -1) // not(pre POST request)
- error("url_fclose: not closable in current state");
-
- // closing an URL!
- if(e.url_wbuf >= 0)
- {
- // we are closing the write end (HTTP POST request)
-
- // get slot for HTTP request
- for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
- if(url_fromid[i] == world)
- break;
- if(i >= NUM_URL_ID)
- {
- for(i = 0; i < autocvar__urllib_nextslot; ++i)
- if(url_fromid[i] == world)
- break;
- if(i >= autocvar__urllib_nextslot)
- {
- print("url_fclose: too many concurrent requests\n");
- e.url_ready(e,e.url_ready_pass, URL_READY_ERROR);
- buf_del(e.url_wbuf);
- strunzone(e.url_url);
- remove(e);
- return;
- }
- }
-
- // POST the data
- if(!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, "text/plain", "", e.url_wbuf, 0))
- {
- print("url_fclose: failure in crypto_uri_postbuf\n");
- e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
- buf_del(e.url_wbuf);
- strunzone(e.url_url);
- remove(e);
- return;
- }
-
- // delete write end. File handle is now in unusable
- // state. Wait for data to come from the server, then
- // call the callback
- buf_del(e.url_wbuf);
- e.url_wbuf = -1;
- e.url_id = i;
- url_fromid[i] = e;
-
- // make sure this slot won't be reused quickly even on map change
- cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
- }
- else
- {
- // we have READ all data, just close
- e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
- buf_del(e.url_rbuf);
- strunzone(e.url_url);
- remove(e);
- }
- }
- else if(e.url_fh == URL_FH_STDOUT)
- {
- e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
- remove(e);
- }
- else
- {
- // file
- fclose(e.url_fh);
- e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
- remove(e);
- }
-}
-
-// with \n (blame FRIK_FILE)
-string url_fgets(entity e)
-{
- if(e.url_fh == URL_FH_CURL)
- {
- if(e.url_rbuf == -1)
- error("url_fgets: not readable in current state");
- // curl
- string s;
- s = bufstr_get(e.url_rbuf, e.url_rbufpos);
- e.url_rbufpos += 1;
- return s;
- }
- else if(e.url_fh == URL_FH_STDOUT)
- {
- // stdout
- return string_null;
- }
- else
- {
- // file
- return fgets(e.url_fh);
- }
-}
-
-// without \n (blame FRIK_FILE)
-void url_fputs(entity e, string s)
-{
- if(e.url_fh == URL_FH_CURL)
- {
- if(e.url_wbuf == -1)
- error("url_fputs: not writable in current state");
- // curl
- bufstr_set(e.url_wbuf, e.url_wbufpos, s);
- e.url_wbufpos += 1;
- }
- else if(e.url_fh == URL_FH_STDOUT)
- {
- // stdout
- print(s);
- }
- else
- {
- // file
- fputs(e.url_fh, s);
- }
-}
-
-// multi URL object, tries URLs separated by space in sequence
-void url_multi_ready(entity fh, entity me, float status)
-{
- float n;
- if(status == URL_READY_ERROR || status < 0)
- {
- if(status == -422) // Unprocessable Entity
- {
- print("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing\n");
- me.url_ready(fh, me.url_ready_pass, status);
- strunzone(me.url_url);
- remove(me);
- return;
- }
- me.url_attempt += 1;
- n = tokenize_console(me.url_url);
- if(n <= me.url_attempt)
- {
- me.url_ready(fh, me.url_ready_pass, status);
- strunzone(me.url_url);
- remove(me);
- return;
- }
- url_single_fopen(argv(me.url_attempt), me.url_mode, url_multi_ready, me);
- return;
- }
- me.url_ready(fh, me.url_ready_pass, status);
-}
-void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass)
-{
- float n;
- n = tokenize_console(url);
- if(n <= 0)
- {
- print("url_multi_fopen: need at least one URL\n");
- rdy(world, pass, URL_READY_ERROR);
- return;
- }
-
- entity me;
- me = spawn();
- me.classname = "url_multi";
- me.url_url = strzone(url);
- me.url_attempt = 0;
- me.url_mode = mode;
- me.url_ready = rdy;
- me.url_ready_pass = pass;
- url_single_fopen(argv(0), mode, url_multi_ready, me);
-}
+++ /dev/null
-#ifndef URLLIB_H
-#define URLLIB_H
-
-const float URL_READY_ERROR = -1;
-const float URL_READY_CLOSED = 0;
-const float URL_READY_CANWRITE = 1;
-const float URL_READY_CANREAD = 2;
-// errors: -1, or negative HTTP status code
-typedef void(entity handle, entity pass, float status) url_ready_func;
-
-void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass);
-void url_fclose(entity e);
-string url_fgets(entity e);
-void url_fputs(entity e, string s);
-
-// returns true if handled
-float url_URI_Get_Callback(int id, float status, string data);
-#define MIN_URL_ID URI_GET_URLLIB
-#define NUM_URL_ID (URI_GET_URLLIB_END - URI_GET_URLLIB + 1)
-
-void url_multi_fopen(string url, float mode, url_ready_func rdy, entity pass);
-#endif
#define spawn() new(entity)
-#include "oo.qh"
-
#endif
#define BITSET(var, mask, flag) ((var) ^ (-(flag) ^ (var)) & (mask))
#endif
-#define CVAR_DESCRIBE(var, desc) localcmd(sprintf("\nset %s \"%s\" \"%s\"\n", #var, ftos(autocvar_##var), desc))
-#define CVAR_DESCRIBESTR(var, desc) localcmd(sprintf("\nset %s \"%s\" \"%s\"\n", #var, autocvar_##var, desc))
-#define CVAR_DESCRIBEVEC(var, desc) localcmd(sprintf("\nset %s \"%s %s %s\" \"%s\"\n", #var, ftos(autocvar_##var##.x), ftos(autocvar_##var##.y), ftos(autocvar_##var##.z), desc))
-
#endif
#include "../dpdefs/csprogsdefs.qh"
#include "../client/defs.qh"
#include "constants.qh"
- #include "../warpzonelib/mathlib.qh"
#include "../client/mutators/events.qh"
#include "mapinfo.qh"
#include "notifications.qh"
#elif defined(SVQC)
#include "../dpdefs/progsdefs.qh"
#include "../dpdefs/dpextensions.qh"
- #include "../warpzonelib/mathlib.qh"
#include "constants.qh"
#include "../server/autocvars.qh"
#include "../server/defs.qh"
return l;
}
-// translation helpers
-string language_filename(string s)
-{
- string fn;
- float fh;
- fn = prvm_language;
- if(fn == "" || fn == "dump")
- return s;
- fn = strcat(s, ".", fn);
- if((fh = fopen(fn, FILE_READ)) >= 0)
- {
- fclose(fh);
- return fn;
- }
- return s;
-}
-string CTX(string s)
-{
- float p = strstrofs(s, "^", 0);
- if(p < 0)
- return s;
- return substring(s, p+1, -1);
-}
-
// x-encoding (encoding as zero length invisible string)
const string XENCODE_2 = "xX";
const string XENCODE_22 = "0123456789abcdefABCDEF";
}
#endif
-// todo: this sucks, lets find a better way to do backtraces?
-void backtrace(string msg)
-{
- float dev, war;
- #ifdef SVQC
- dev = autocvar_developer;
- war = autocvar_prvm_backtraceforwarnings;
- #else
- dev = cvar("developer");
- war = cvar("prvm_backtraceforwarnings");
- #endif
- cvar_set("developer", "1");
- cvar_set("prvm_backtraceforwarnings", "1");
- print("\n");
- print("--- CUT HERE ---\nWARNING: ");
- print(msg);
- print("\n");
- remove(world); // isn't there any better way to cause a backtrace?
- print("\n--- CUT UNTIL HERE ---\n");
- cvar_set("developer", ftos(dev));
- cvar_set("prvm_backtraceforwarnings", ftos(war));
-}
-
// color code replace, place inside of sprintf and parse the string
string CCR(string input)
{
#ifndef COMMON_UTIL_H
#define COMMON_UTIL_H
-#ifdef QCC_SUPPORT_ACCUMULATE
-# define ACCUMULATE_FUNCTION(func,otherfunc) \
- [[accumulate]] void func() { otherfunc(); }
-# define CALL_ACCUMULATED_FUNCTION(func) \
- func()
-#else
-#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) \
- #ifdef func \
- void __merge__##otherfunc() { func(); otherfunc(); } \
- #undef func \
- #define func __merge__##otherfunc \
- #else \
- #define func otherfunc \
- #endif
-# define CALL_ACCUMULATED_FUNCTION(func) \
- func()
-#else
-# define ACCUMULATE_FUNCTION(func,otherfunc) \
- .float _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
-#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: ", #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
string wordwrap(string s, float l);
#endif
#endif
-// the NULL function
-#ifdef QCC_SUPPORT_NIL
-#define func_null nil
-#define string_null nil
-#else
-var void func_null(void);
-string string_null;
-#endif
float float2range11(float f);
float float2range01(float f);
float u8_strsize(string s);
-// translation helpers
-string prvm_language;
-string language_filename(string s);
-string CTX(string s);
-#define ZCTX(s) strzone(CTX(s))
-
// x-encoding (encoding as zero length invisible string)
// encodes approx. 14 bits into 5 bytes of color code string
const float XENCODE_MAX = 21295; // 2*22*22*22-1
#define XPD(...) __VA_ARGS__
// Some common varargs functions. Lowercase as they match C.
-#define printf(...) print(sprintf(__VA_ARGS__))
-#define dprintf(...) dprint(sprintf(__VA_ARGS__))
#define fprintf(file, ...) fputs(file, sprintf(__VA_ARGS__))
#define bprintf(...) bprint(sprintf(__VA_ARGS__))
-//#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
string autocvar_hud_colorset_foreground_1 = "2"; // F1 - Green // primary priority (important names, etc)
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
-
#ifndef MENUQC
const float CNT_NORMAL = 1;
const float CNT_GAMESTART = 2;
#include "../constants.qh"
#include "../stats.qh"
#include "../../warpzonelib/anglestransform.qh"
- #include "../../warpzonelib/mathlib.qh"
#include "../../warpzonelib/common.qh"
#include "../../warpzonelib/client.qh"
#include "../util.qh"
#include "../../dpdefs/progsdefs.qh"
#include "../../dpdefs/dpextensions.qh"
#include "../../warpzonelib/anglestransform.qh"
- #include "../../warpzonelib/mathlib.qh"
#include "../../warpzonelib/common.qh"
#include "../../warpzonelib/util_server.qh"
#include "../../warpzonelib/server.qh"
if(time < game_starttime)
return;
- float loaded, enough_ammo;
- loaded = self.hagar_load >= WEP_CVAR_SEC(hagar, load_max);
+ bool loaded = self.hagar_load >= WEP_CVAR_SEC(hagar, load_max);
// this is different than WR_CHECKAMMO when it comes to reloading
+ bool enough_ammo;
if(self.items & IT_UNLIMITED_WEAPON_AMMO)
enough_ammo = true;
else if(autocvar_g_balance_hagar_reload_ammo)
else
enough_ammo = self.WEP_AMMO(HAGAR) >= WEP_CVAR_SEC(hagar, ammo);
+ bool stopped = loaded || !enough_ammo;
+
if(self.BUTTON_ATCK2)
{
if(self.BUTTON_ATCK && WEP_CVAR_SEC(hagar, load_abort))
else
{
// check if we can attempt to load another rocket
- if(!loaded && enough_ammo)
+ if(!stopped)
{
if(!self.hagar_loadblock && self.hagar_loadstep < time)
{
sound(self, CH_WEAPON_B, W_Sound("hagar_load"), VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
if(self.hagar_load >= WEP_CVAR_SEC(hagar, load_max))
- self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor();
+ stopped = true;
else
self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor();
}
}
- else if(!self.hagar_loadbeep && self.hagar_load) // prevents the beep from playing each frame
+ if(stopped && !self.hagar_loadbeep && self.hagar_load) // prevents the beep from playing each frame
{
// if this is the last rocket we can load, play a beep sound to notify the player
sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
self.hagar_loadbeep = true;
+ self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor();
}
}
}
if(self.hagar_load)
{
// play warning sound if we're about to release
- if((loaded || !enough_ammo) && self.hagar_loadstep - 0.5 < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)
+ if(stopped && self.hagar_loadstep - 0.5 < time && WEP_CVAR_SEC(hagar, load_hold) >= 0)
{
- if(!self.hagar_warning && self.hagar_load) // prevents the beep from playing each frame
+ if(!self.hagar_warning) // prevents the beep from playing each frame
{
// we're about to automatically release after holding time, play a beep sound to notify the player
sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
}
// release if player let go of button or if they've held it in too long
- if(!self.BUTTON_ATCK2 || ((loaded || !enough_ammo) && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0))
+ if(!self.BUTTON_ATCK2 || (stopped && self.hagar_loadstep < time && WEP_CVAR_SEC(hagar, load_hold) >= 0))
{
self.weaponentity.state = WS_READY;
W_Hagar_Attack2_Load_Release();
{
self.hagar_loadbeep = false;
self.hagar_warning = false;
- }
- // we aren't checking ammo during an attack, so we must do it here
- if(!(WEP_ACTION(self.weapon, WR_CHECKAMMO1) + WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
- if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
- {
- // note: this doesn't force the switch
- W_SwitchToOtherWeapon(self);
- return;
+ // we aren't checking ammo during an attack, so we must do it here
+ if(!(WEP_ACTION(self.weapon, WR_CHECKAMMO1) + WEP_ACTION(self.weapon, WR_CHECKAMMO2)))
+ if(!(self.items & IT_UNLIMITED_WEAPON_AMMO))
+ {
+ // note: this doesn't force the switch
+ W_SwitchToOtherWeapon(self);
+ return;
+ }
}
}
weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(hagar, refire), w_ready);
}
}
-
return true;
}
case WR_GONETHINK:
#include "../dpdefs/csprogsdefs.qh"
#include "../client/defs.qh"
#include "../common/constants.qh"
- #include "../common/p2mathlib.qh"
#include "../common/stats.qh"
#include "../common/util.qh"
#include "interpolate.qh"
--- /dev/null
+#ifndef ACCUMULATE_H
+#define ACCUMULATE_H
+
+#ifdef QCC_SUPPORT_ACCUMULATE
+# define ACCUMULATE_FUNCTION(func, otherfunc) \
+ [[accumulate]] void func() { otherfunc(); }
+# define CALL_ACCUMULATED_FUNCTION(func) \
+ func()
+#else
+#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) \
+ #ifdef func \
+ void __merge__##otherfunc() { func(); otherfunc(); } \
+ #undef func \
+ #define func __merge__##otherfunc \
+ #else \
+ #define func otherfunc \
+ #endif
+# define CALL_ACCUMULATED_FUNCTION(func) \
+ func()
+#else
+# define ACCUMULATE_FUNCTION(func,otherfunc) \
+ .float _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
+#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: ", #name, ": ", ftos(count), ".\n")); }
+
+#endif
--- /dev/null
+#ifndef COUNTING_H
+#define COUNTING_H
+
+#include "I18N.qh"
+
+// ===============================================
+// Time processing and counting functions/macros
+// ===============================================
+
+#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(int interval)
+{
+ // This function is designed primarily for the English language, it's impossible
+ // to accomodate all languages unless we do a specific function for each one...
+ // and since that's not technically feasible/practical, this is all we've got folks.
+
+ // Basically, it just allows you to represent a number or count in different ways
+ // depending on the number... like, with count_ordinal you can provide integers
+ // and retrieve 1st, 2nd, 3rd, nth ordinal numbers in a clean and simple way.
+ if(floor((interval % 100)/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block
+ {
+ // otherwise, check normally for 1st,2nd,3rd insertions
+ switch(interval % 10)
+ {
+ case 1: return sprintf(_("%dst"), interval);
+ case 2: return sprintf(_("%dnd"), interval);
+ case 3: return sprintf(_("%drd"), interval);
+ default: return sprintf(_("%dth"), interval);
+ }
+ }
+ else { return sprintf(_("%dth"), interval); }
+
+ return "";
+}
+
+string count_fill(float interval, string zeroth, string first, string second, string third, string multi)
+{
+ // This function is designed primarily for the English language, it's impossible
+ // to accomodate all languages unless we do a specific function for each one...
+ // and since that's not technically feasible/practical, this is all we've got folks.
+
+ // Here you can insert specific strings based on the interval number, so you could do
+ // i.e. count_seconds which outputs like this:
+ // 0 seconds
+ // 1 second
+ // 2 seconds
+ // 3 seconds
+ // etc... minutes, hours, days, etc.
+
+ switch(floor(interval))
+ {
+ case 0: return sprintf(zeroth, interval);
+ case 1:
+ {
+ if(interval == 1) // EXACTLY value of 1
+ return sprintf(first, interval);
+ else
+ return sprintf(multi, interval);
+ }
+ case 2: return sprintf(second, interval);
+ case 3: return sprintf(third, interval);
+ default: return sprintf(multi, interval);
+ }
+ return "";
+}
+
+string process_time(float outputtype, float seconds)
+{
+ float tmp_hours = 0, tmp_minutes = 0, tmp_seconds = 0;
+ float tmp_years = 0, tmp_weeks = 0, tmp_days = 0;
+
+ tmp_seconds = floor(seconds);
+
+ if(tmp_seconds)
+ {
+ tmp_minutes = floor(tmp_seconds / 60);
+
+ if(tmp_minutes)
+ {
+ tmp_seconds -= (tmp_minutes * 60);
+ tmp_hours = floor(tmp_minutes / 60);
+
+ if(tmp_hours)
+ {
+ tmp_minutes -= (tmp_hours * 60);
+ tmp_days = floor(tmp_hours / 24);
+
+ if(tmp_days)
+ {
+ tmp_hours -= (tmp_days * 24);
+ tmp_weeks = floor(tmp_days / 7);
+
+ if(tmp_weeks)
+ {
+ tmp_days -= (tmp_weeks * 7);
+ tmp_years = floor(tmp_weeks / 52);
+ }
+ }
+ }
+ }
+ }
+
+ switch(outputtype)
+ {
+ case 1: return sprintf("%02d:%02d:%02d", tmp_hours, tmp_minutes, tmp_seconds);
+ case 2:
+ {
+ string output = "";
+
+ output = count_seconds(tmp_seconds);
+
+ if(tmp_minutes)
+ {
+ output = sprintf(
+ "%s%s",
+ count_minutes(tmp_minutes),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ if(tmp_hours)
+ {
+ output = sprintf(
+ "%s%s",
+ count_hours(tmp_hours),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ if(tmp_days)
+ {
+ output = sprintf(
+ "%s%s",
+ count_days(tmp_days),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ if(tmp_weeks)
+ {
+ output = sprintf(
+ "%s%s",
+ count_weeks(tmp_weeks),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ if(tmp_years)
+ {
+ output = sprintf(
+ "%s%s",
+ count_years(tmp_years),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ return output;
+ }
+ case 3:
+ {
+ string output = "";
+
+ output = count_hours(tmp_hours);
+
+ if(tmp_weeks) { tmp_days += (tmp_weeks * 7); }
+ if(tmp_years) { tmp_days += (tmp_years * 365); }
+ if(tmp_days)
+ {
+ output = sprintf(
+ "%s%s",
+ count_days(tmp_days),
+ ((output != "") ? sprintf(", %s", output) : ""));
+ }
+
+ return output;
+ }
+ }
+ return "";
+}
+#endif
--- /dev/null
+#ifndef CVAR_H
+#define CVAR_H
+
+#define CVAR_DESCRIBE(var, desc) localcmd(sprintf("\nseta %s \"%s\" \"%s\"\n", #var, ftos(autocvar_##var), desc))
+#define CVAR_DESCRIBESTR(var, desc) localcmd(sprintf("\nseta %s \"%s\" \"%s\"\n", #var, autocvar_##var, desc))
+#define CVAR_DESCRIBEVEC(var, desc) localcmd(sprintf("\nseta %s \"%v\" \"%s\"\n", #var, autocvar_##var, desc))
+
+#endif
--- /dev/null
+#ifndef MENUQC
+#ifndef DEFER_H
+#define DEFER_H
+#include "OO.qh"
+
+entityclass(Defer);
+class(Defer) .entity owner;
+class(Defer) .void() think;
+class(Defer) .float nextthink;
+
+/*
+==================
+SUB_Remove
+
+Remove self
+==================
+*/
+void SUB_Remove()
+{
+ remove (self);
+}
+
+void defer_think()
+{
+ entity oself;
+
+ oself = self;
+ self = self.owner;
+ oself.think = SUB_Remove;
+ oself.nextthink = time;
+
+ oself.use();
+}
+
+/*
+ Execute func() after time + fdelay.
+ self when func is executed = self when defer is called
+*/
+void defer(float fdelay, void() func)
+{
+ entity e;
+
+ e = spawn();
+ e.owner = self;
+ e.use = func;
+ e.think = defer_think;
+ e.nextthink = time + fdelay;
+}
+
+#endif
+#endif
--- /dev/null
+#ifdef CSQC
+#ifndef DRAW_H
+#define DRAW_H
+
+#include "I18N.qh"
+#include "Vector.qh"
+
+#include "../client/defs.qh"
+
+void Draw_CylindricLine(vector from, vector to, float thickness, string texture, float aspect, float shift, vector rgb, float theAlpha, float drawflag, vector vieworg)
+{
+ // I want to draw a quad...
+ // from and to are MIDPOINTS.
+
+ vector axis, thickdir, A, B, C, D;
+ float length_tex;
+
+ axis = normalize(to - from);
+ length_tex = aspect * vlen(to - from) / thickness;
+
+ // direction is perpendicular to the view normal, and perpendicular to the axis
+ thickdir = normalize(cross(axis, vieworg - from));
+
+ A = from - thickdir * (thickness / 2);
+ B = from + thickdir * (thickness / 2);
+ C = to + thickdir * (thickness / 2);
+ D = to - thickdir * (thickness / 2);
+
+ R_BeginPolygon(texture, drawflag);
+ R_PolygonVertex(A, '0 0 0' + shift * '1 0 0', rgb, theAlpha);
+ R_PolygonVertex(B, '0 1 0' + shift * '1 0 0', rgb, theAlpha);
+ R_PolygonVertex(C, '0 1 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
+ R_PolygonVertex(D, '0 0 0' + (shift + length_tex) * '1 0 0', rgb, theAlpha);
+ R_EndPolygon();
+}
+
+// a border picture is a texture containing nine parts:
+// 1/4 width: left part
+// 1/2 width: middle part (stretched)
+// 1/4 width: right part
+// divided into
+// 1/4 height: top part
+// 1/2 height: middle part (stretched)
+// 1/4 height: bottom part
+void draw_BorderPicture(vector theOrigin, string pic, vector theSize, vector theColor, float theAlpha, vector theBorderSize)
+{
+ if (theBorderSize.x < 0 && theBorderSize.y < 0) // draw whole image as it is
+ {
+ drawpic(theOrigin, pic, theSize, theColor, theAlpha, 0);
+ return;
+ }
+ if (theBorderSize.x == 0 && theBorderSize.y == 0) // no border
+ {
+ // draw only the central part
+ drawsubpic(theOrigin, theSize, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0);
+ return;
+ }
+
+ vector dX, dY;
+ vector width, height;
+ vector bW, bH;
+ //pic = draw_UseSkinFor(pic);
+ width = eX * theSize.x;
+ height = eY * theSize.y;
+ if(theSize.x <= theBorderSize.x * 2)
+ {
+ // not wide enough... draw just left and right then
+ bW = eX * (0.25 * theSize.x / (theBorderSize.x * 2));
+ if(theSize.y <= theBorderSize.y * 2)
+ {
+ // not high enough... draw just corners
+ bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2));
+ drawsubpic(theOrigin, width * 0.5 + height * 0.5, pic, '0 0 0', bW + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width * 0.5, width * 0.5 + height * 0.5, pic, eX - bW, bW + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height * 0.5, width * 0.5 + height * 0.5, pic, eY - bH, bW + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + theSize * 0.5, width * 0.5 + height * 0.5, pic, eX + eY - bW - bH, bW + bH, theColor, theAlpha, 0);
+ }
+ else
+ {
+ dY = theBorderSize.x * eY;
+ drawsubpic(theOrigin, width * 0.5 + dY, pic, '0 0 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width * 0.5, width * 0.5 + dY, pic, '0 0 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0', '0 0.5 0' + bW, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width * 0.5 + dY, width * 0.5 + height - 2 * dY, pic, '0 0.25 0' + eX - bW, '0 0.5 0' + bW, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height - dY, width * 0.5 + dY, pic, '0 0.75 0', '0 0.25 0' + bW, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width * 0.5 + height - dY, width * 0.5 + dY, pic, '0 0.75 0' + eX - bW, '0 0.25 0' + bW, theColor, theAlpha, 0);
+ }
+ }
+ else
+ {
+ if(theSize.y <= theBorderSize.y * 2)
+ {
+ // not high enough... draw just top and bottom then
+ bH = eY * (0.25 * theSize.y / (theBorderSize.y * 2));
+ dX = theBorderSize.x * eX;
+ drawsubpic(theOrigin, dX + height * 0.5, pic, '0 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dX, width - 2 * dX + height * 0.5, pic, '0.25 0 0', '0.5 0 0' + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width - dX, dX + height * 0.5, pic, '0.75 0 0', '0.25 0 0' + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height * 0.5, dX + height * 0.5, pic, '0 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dX + height * 0.5, width - 2 * dX + height * 0.5, pic, '0.25 0 0' + eY - bH, '0.5 0 0' + bH, theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width - dX + height * 0.5, dX + height * 0.5, pic, '0.75 0 0' + eY - bH, '0.25 0 0' + bH, theColor, theAlpha, 0);
+ }
+ else
+ {
+ dX = theBorderSize.x * eX;
+ dY = theBorderSize.x * eY;
+ drawsubpic(theOrigin, dX + dY, pic, '0 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dX, width - 2 * dX + dY, pic, '0.25 0 0', '0.5 0.25 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + width - dX, dX + dY, pic, '0.75 0 0', '0.25 0.25 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dY, dX + height - 2 * dY, pic, '0 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dY + dX, width - 2 * dX + height - 2 * dY, pic, '0.25 0.25 0', '0.5 0.5 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + dY + width - dX, dX + height - 2 * dY, pic, '0.75 0.25 0', '0.25 0.5 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height - dY, dX + dY, pic, '0 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height - dY + dX, width - 2 * dX + dY, pic, '0.25 0.75 0', '0.5 0.25 0', theColor, theAlpha, 0);
+ drawsubpic(theOrigin + height - dY + width - dX, dX + dY, pic, '0.75 0.75 0', '0.25 0.25 0', theColor, theAlpha, 0);
+ }
+ }
+}
+
+void drawstringright(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
+{
+ position.x -= 2 / 3 * strlen(text) * theScale.x;
+ drawstring(position, text, theScale, rgb, theAlpha, flag);
+}
+
+void drawstringcenter(vector position, string text, vector theScale, vector rgb, float theAlpha, int flag)
+{
+ position.x = 0.5 * (vid_conwidth - 0.6025 * strlen(text) * theScale.x);
+ drawstring(position, text, theScale, rgb, theAlpha, flag);
+}
+
+#endif
+#endif
--- /dev/null
+#ifndef I18N_H
+#define I18N_H
+
+// translation helpers
+string prvm_language;
+
+string language_filename(string s)
+{
+ string fn = prvm_language;
+ if (fn == "" || fn == "dump")
+ return s;
+ fn = strcat(s, ".", fn);
+ int fh = fopen(fn, FILE_READ);
+ if (fh >= 0)
+ {
+ fclose(fh);
+ return fn;
+ }
+ return s;
+}
+
+string CTX(string s)
+{
+ int p = strstrofs(s, "^", 0);
+ if (p < 0)
+ return s;
+ return substring(s, p + 1, -1);
+}
+
+#define ZCTX(s) strzone(CTX(s))
+
+#endif
--- /dev/null
+#ifndef LAZY_H
+#define LAZY_H
+
+#include "OO.qh"
+
+CLASS(Lazy, Object)
+ ATTRIB(Lazy, m_get, entity(), func_null);
+ CONSTRUCTOR(Lazy, entity() _compute) { this.m_get = _compute; }
+ENDCLASS(Lazy)
+
+#define LAZY(id) __lazy_##id
+#define LAZY_NEW(id, compute) entity LAZY(id)() { \
+ static bool done; \
+ static entity it; \
+ if (!done) { it = compute; done = true; } \
+ return it; \
+}
+#endif
--- /dev/null
+#ifndef LOG_H
+#define LOG_H
+
+#define _printferr(...) error(sprintf(__VA_ARGS__))
+#define _printfbt(...) backtrace(sprintf(__VA_ARGS__))
+#define printf(...) print(sprintf(__VA_ARGS__))
+#define dprintf(...) dprint(sprintf(__VA_ARGS__))
+#define _dprintf2(...) do { if (autocvar_developer > 1) dprintf(__VA_ARGS__); } while (0)
+
+#define _LOG(f, level, s) f("[::"level"] ["__FILE__":%s:%.0f] %s", __FUNC__, __LINE__, s)
+
+#define LOG_FATAL(...) _LOG_FATAL(strcat("", __VA_ARGS__))
+#define LOG_FATALF(...) _LOG_FATAL(sprintf(__VA_ARGS__))
+#define _LOG_FATAL(s) _LOG(_printferr, "FATAL", s)
+
+#define LOG_SEVERE(...) _LOG_SEVERE(strcat("", __VA_ARGS__))
+#define LOG_SEVEREF(...) _LOG_SEVERE(sprintf(__VA_ARGS__))
+#define _LOG_SEVERE(s) _LOG(_printfbt, "SEVERE", s)
+
+#define LOG_WARNING(...) _LOG_WARNING(strcat("", __VA_ARGS__))
+#define LOG_WARNINGF(...) _LOG_WARNING(sprintf(__VA_ARGS__))
+#define _LOG_WARNING(s) _LOG(printf, "WARNING", s)
+
+#define LOG_INFO(...) do { if (autocvar_developer) _LOG_INFO(strcat("", __VA_ARGS__)); else print (__VA_ARGS__); } while (0)
+#define LOG_INFOF(...) do { if (autocvar_developer) _LOG_INFO(sprintf(__VA_ARGS__)); else printf(__VA_ARGS__); } while (0)
+#define _LOG_INFO(s) _LOG(printf, "INFO", s)
+
+#define LOG_TRACE(...) _LOG_TRACE(strcat("", __VA_ARGS__))
+#define LOG_TRACEF(...) _LOG_TRACE(sprintf(__VA_ARGS__))
+#define _LOG_TRACE(s) _LOG(dprintf, "TRACE", s)
+
+#define LOG_DEBUG(...) _LOG_DEBUG(strcat("", __VA_ARGS__))
+#define LOG_DEBUGF(...) _LOG_DEBUG(sprintf(__VA_ARGS__))
+#define _LOG_DEBUG(s) _LOG(_dprintf2, "DEBUG", s)
+
+// TODO: this sucks, lets find a better way to do backtraces?
+#ifdef SVQC
+void builtin_remove(entity);
+#define _backtrace() builtin_remove(NULL)
+#else
+void remove(entity);
+#define _backtrace() remove(NULL)
+#endif
+
+noref int autocvar_developer;
+noref bool autocvar_prvm_backtraceforwarnings;
+
+#define backtrace(msg) do { \
+ int dev = autocvar_developer; \
+ bool war = autocvar_prvm_backtraceforwarnings; \
+ cvar_set("developer", "1"); \
+ cvar_set("prvm_backtraceforwarnings", "1"); \
+ print("\n--- CUT HERE ---\n", msg, "\n"); \
+ _backtrace(); \
+ print("\n--- CUT UNTIL HERE ---\n"); \
+ cvar_set("developer", ftos(dev)); \
+ cvar_set("prvm_backtraceforwarnings", ftos(war)); \
+} while (0)
+
+#endif
--- /dev/null
+#ifndef MATH_H
+#define MATH_H
+
+void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight)
+{
+ if (weight == 0)
+ return;
+ if (mean == 0)
+ e.(a) *= pow(value, weight);
+ else
+ e.(a) += pow(value, mean) * weight;
+ e.(c) += weight;
+}
+
+float mean_evaluate(entity e, .float a, .float c, float mean)
+{
+ if (e.(c) == 0)
+ return 0;
+ if (mean == 0)
+ return pow(e.(a), 1.0 / e.(c));
+ else
+ return pow(e.(a) / e.(c), 1.0 / mean);
+}
+
+#define MEAN_ACCUMULATE(prefix,v,w) mean_accumulate(self,prefix##_accumulator,prefix##_count,prefix##_mean,v,w)
+#define MEAN_EVALUATE(prefix) mean_evaluate(self,prefix##_accumulator,prefix##_count,prefix##_mean)
+#define MEAN_DECLARE(prefix,m) float prefix##_mean = m; .float prefix##_count, prefix##_accumulator
+
+/*
+==================
+crandom
+
+Returns a random number between -1.0 and 1.0
+==================
+*/
+float crandom (void)
+{
+ return 2 * (random () - 0.5);
+}
+
+
+/*
+==================
+Angc used for animations
+==================
+*/
+
+
+float angc (float a1, float a2)
+{
+ float a;
+
+ while (a1 > 180)
+ a1 = a1 - 360;
+ while (a1 < -179)
+ a1 = a1 + 360;
+
+ while (a2 > 180)
+ a2 = a2 - 360;
+ while (a2 < -179)
+ a2 = a2 + 360;
+
+ a = a1 - a2;
+ while (a > 180)
+ a = a - 360;
+ while (a < -179)
+ a = a + 360;
+
+ return a;
+}
+
+float fsnap(float val,float fsize)
+{
+ return rint(val / fsize) * fsize;
+}
+
+vector vsnap(vector point,float fsize)
+{
+ vector vret;
+
+ vret.x = rint(point.x / fsize) * fsize;
+ vret.y = rint(point.y / fsize) * fsize;
+ vret.z = ceil(point.z / fsize) * fsize;
+
+ return vret;
+}
+
+vector lerpv(float t0, vector v0, float t1, vector v1, float t)
+{
+ return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
+}
+
+#endif
--- /dev/null
+#ifndef NIL_H
+#define NIL_H
+
+#ifdef QCC_SUPPORT_NIL
+#define func_null nil
+#define string_null nil
+#else
+// the NULL function
+var void func_null(void);
+string string_null;
+#endif
+
+#endif
--- /dev/null
+#ifndef OO_H
+#define OO_H
+
+#include "Nil.qh"
+#include "Registry.qh"
+
+#ifdef MENUQC
+ #define NULL (null_entity)
+#else
+ #define NULL (world)
+#endif
+
+.string classname;
+/** Location entity was spawned from in source */
+.string sourceLocFile;
+.int sourceLocLine;
+entity _spawn();
+entity __spawn(string _classname, string _sourceFile, int _sourceLine) {
+ entity this = _spawn();
+ this.classname = _classname;
+ this.sourceLocFile = _sourceFile;
+ this.sourceLocLine = _sourceLine;
+ return this;
+}
+
+
+
+#define entityclass(...) OVERLOAD(entityclass, __VA_ARGS__)
+#define entityclass_1(name) entityclass_2(name, Object)
+#ifndef QCC_SUPPORT_ENTITYCLASS
+ #define entityclass_2(name, base) typedef entity name
+ #define class(name)
+ #define new(class) __spawn(#class, __FILE__, __LINE__)
+#else
+ #define entityclass_2(name, base) entityclass name : base {}
+ #define class(name) [[class(name)]]
+ #define new(class) ((class) __spawn(#class, __FILE__, __LINE__))
+#endif
+
+// Classes have a `spawn##cname(entity)` constructor
+// The parameter is used across [[accumulate]] functions
+
+// Macro to hide this implementation detail
+#define NEW(cname, ...) \
+ OVERLOAD(spawn##cname, new(cname), ##__VA_ARGS__)
+
+#define CONSTRUCT(cname, ...) \
+ OVERLOAD(spawn##cname, this, ##__VA_ARGS__)
+
+#define CONSTRUCTOR(cname, ...) \
+ cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__) { return = this; } \
+ [[accumulate]] cname OVERLOAD(spawn##cname, cname this, __VA_ARGS__)
+
+.string vtblname;
+.entity vtblbase;
+
+void RegisterClasses() { }
+STATIC_INIT(RegisterClasses) { RegisterClasses(); }
+
+#define VTBL(cname, base) \
+ INIT_STATIC(cname); \
+ entity cname##_vtbl; \
+ void cname##_vtbl_init() { \
+ cname e = new(vtbl); \
+ spawn##cname##_static(e); \
+ e.vtblname = #cname; \
+ /* Top level objects refer to themselves */ \
+ e.vtblbase = base##_vtbl ? base##_vtbl : e; \
+ cname##_vtbl = e; \
+ } \
+ ACCUMULATE_FUNCTION(RegisterClasses, cname##_vtbl_init)
+
+#define INIT_STATIC(cname) [[accumulate]] void spawn##cname##_static(cname this)
+#define INIT(cname) [[accumulate]] cname spawn##cname##_1(cname this)
+
+#define CLASS(cname, base) \
+ entityclass(cname, base); \
+ class(cname) .bool instanceOf##cname; \
+ VTBL(cname, base) \
+ INIT_STATIC(cname) { \
+ if (cname##_vtbl) { \
+ copyentity(cname##_vtbl, this); \
+ return; \
+ } \
+ spawn##base##_static(this); \
+ this.instanceOf##cname = true; \
+ } \
+ INIT(cname) { \
+ /* Only statically initialize the current class, it contains everything it inherits */ \
+ if (cname##_vtbl.vtblname == this.classname) { \
+ spawn##cname##_static(this); \
+ this.classname = #cname; \
+ this.vtblname = string_null; \
+ this.vtblbase = cname##_vtbl; \
+ } \
+ spawn##base##_1(this); \
+ }
+
+#define METHOD(cname, name, prototype) \
+ class(cname) .prototype name; \
+ prototype cname##_##name; \
+ INIT_STATIC(cname) { this.name = cname##_##name; } \
+ prototype cname##_##name
+
+#define ATTRIB(cname, name, type, val) \
+ class(cname) .type name; \
+ INIT(cname) { this.name = val; }
+
+#define ATTRIBARRAY(cname, name, type, cnt) \
+ class(cname) .type name[cnt];
+
+#define ENDCLASS(cname) \
+ [[last]] INIT(cname) { return this; }
+
+#define SUPER(cname) (cname##_vtbl.vtblbase)
+#define super (this.vtblbase.vtblbase)
+
+#define spawn_static(this)
+#define spawn_1(this)
+#define _vtbl NULL
+CLASS(Object, );
+ METHOD(Object, describe, string(entity this)) {
+ string s = _("No description");
+ if (cvar("developer")) {
+ for (int i = 0, n = numentityfields(); i < n; ++i) {
+ string value = getentityfieldstring(i, this);
+ if (value != "") s = sprintf("%s\n%s = %s", s, entityfieldname(i), value);
+ }
+ }
+ return s;
+ }
+ METHOD(Object, display, void(entity this, void(string name, string icon) returns)) {
+ returns(sprintf("entity %i", this), "nopreview_map");
+ }
+ENDCLASS(Object)
+#undef spawn_static
+#undef spawn_1
+#undef _vtbl
+
+#endif
--- /dev/null
+#ifdef CSQC
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "String.qh"
+
+#include "../client/main.qh"
+#include "../common/teams.qh"
+
+int GetPlayerColorForce(int i)
+{
+ if(!teamplay)
+ return 0;
+ else
+ return stof(getplayerkeyvalue(i, "colors")) & 15;
+}
+
+int GetPlayerColor(int i)
+{
+ if(!playerslots[i].gotscores) // unconnected
+ return NUM_SPECTATOR;
+ else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
+ return NUM_SPECTATOR;
+ else
+ return GetPlayerColorForce(i);
+}
+
+string GetPlayerName(int i)
+{
+ return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
+}
+
+#endif
+#endif
--- /dev/null
+#ifndef PROGNAME_H
+#define PROGNAME_H
+
+#if defined(MENUQC)
+ #define PROGNAME "MENUQC"
+#elif defined(SVQC)
+ #define PROGNAME "SVQC"
+#elif defined(CSQC)
+ #define PROGNAME "CSQC"
+#else
+ #error "Unable to detect PROGNAME"
+#endif
+
+#endif
--- /dev/null
+#ifndef REGISTRY_H
+#define REGISTRY_H
+
+#include "OO.qh"
+
+#define REGISTER_INIT(ns, id) [[accumulate]] void Register_##ns##_##id##_init(entity this)
+#define REGISTER_INIT_POST(ns, id) [[accumulate]] void Register_##ns##_##id##_init_post(entity this)
+
+#define REGISTER(initfunc, ns, array, counter, id, fld, inst) \
+ entity ns##_##id; \
+ REGISTER_INIT(ns, id) { } \
+ REGISTER_INIT_POST(ns, id) { } \
+ .entity enemy; /* internal next pointer */ \
+ void Register_##ns##_##id() { \
+ entity this = inst; \
+ ns##_##id = this; \
+ this.fld = counter; \
+ array[counter++] = this; \
+ if (!array##_first) array##_first = this; \
+ if ( array##_last) array##_last.enemy = this; \
+ array##_last = this; \
+ Register_##ns##_##id##_init(this); \
+ Register_##ns##_##id##_init_post(this); \
+ } \
+ ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \
+ REGISTER_INIT(ns, id)
+
+void __static_init() { }
+#define static_init() CALL_ACCUMULATED_FUNCTION(__static_init)
+#define REGISTER_REGISTRY(func) ACCUMULATE_FUNCTION(__static_init, func)
+
+#define STATIC_INIT(func) \
+ void _static_##func(); \
+ ACCUMULATE_FUNCTION(__static_init, _static_##func) \
+ void _static_##func()
+
+#endif
--- /dev/null
+#ifndef STRING_H
+#define STRING_H
+
+#ifndef SVQC
+float stringwidth_colors(string s, vector theSize)
+{
+ return stringwidth(s, true, theSize);
+}
+
+float stringwidth_nocolors(string s, vector theSize)
+{
+ return stringwidth(s, false, theSize);
+}
+#endif
+
+// Timer (#5)
+//
+// TODO: macro
+string seconds_tostring(float sec)
+{
+ float minutes;
+ minutes = floor(sec / 60);
+
+ sec -= minutes * 60;
+ return sprintf("%d:%02d", minutes, sec);
+}
+
+int ColorTranslateMode;
+
+string ColorTranslateRGB(string s)
+{
+ if(ColorTranslateMode & 1)
+ return strdecolorize(s);
+ else
+ return s;
+}
+
+#endif
--- /dev/null
+#ifndef STRUCT_H
+#define STRUCT_H
+
+#ifndef QCC_SUPPORT_STRUCT
+ #define _STRUCT_DECLARE(x, id, type, END) noref type x ##_## id ;
+ #define STRUCT_DECLARE(id, s) s(_STRUCT_DECLARE, id)
+
+ #define _STRUCT_PARAM_(x, id, type) type x ##_## id ,
+ #define _STRUCT_PARAM_END(x, id, type) type x ##_## id
+ #define _STRUCT_PARAM(x, id, type, isend) _STRUCT_PARAM_##isend(x, id, type)
+ #define STRUCT_PARAM(id, s) s(_STRUCT_PARAM, id)
+
+ #define _STRUCT_PASS_(x, id, type) x ##_## id ,
+ #define _STRUCT_PASS_END(x, id, type) x ##_## id
+ #define _STRUCT_PASS(x, id, type, END) _STRUCT_PASS_##END(x, id, type)
+ #define STRUCT_PASS(id, s) s(_STRUCT_PASS, id)
+
+ #define _STRUCT_STORE_DST(_, it) it
+ #define _STRUCT_STORE_SRC(it, _) it
+ #define _CONCAT3_(a, b, c) a ## b ## c
+ #define _CONCAT3(a, b, c) _CONCAT3_(a, b, c)
+ #define _STRUCT_STORE(x, id, type, END) _CONCAT3(_STRUCT_STORE_DST x, _, id) = _CONCAT3(_STRUCT_STORE_SRC x, _, id);
+ #define STRUCT_STORE(from, to, s) s(_STRUCT_STORE, (from, to))
+
+ #define STRUCT(id, ...)
+#else
+ #define STRUCT_DECLARE(id, type) type id;
+ #define STRUCT_PARAM(id, type) type id
+ #define STRUCT_PASS(id, type) id
+ #define STRUCT_STORE(from, to, s) to = from
+ #define _STRUCT_MEMBER(my, id, type, END) type id;
+ #define STRUCT(id, s) struct STRUCT_##id { s(_STRUCT_MEMBER, ) };
+#endif
+
+#endif
--- /dev/null
+#ifndef VECTOR_H
+#define VECTOR_H
+
+const vector eX = '1 0 0';
+const vector eY = '0 1 0';
+const vector eZ = '0 0 1';
+
+vector randompos(vector m1, vector m2)
+{
+ vector v;
+ m2 = m2 - m1;
+ v_x = m2_x * random() + m1_x;
+ v_y = m2_y * random() + m1_y;
+ v_z = m2_z * random() + m1_z;
+ return v;
+}
+
+float vlen2d(vector v)
+{
+ return sqrt(v.x * v.x + v.y * v.y);
+}
+
+float vlen_maxnorm2d(vector v)
+{
+ return max(v.x, v.y, -v.x, -v.y);
+}
+
+float vlen_minnorm2d(vector v)
+{
+ return min(max(v.x, -v.x), max(v.y, -v.y));
+}
+
+
+#endif
--- /dev/null
+#include "../warpzonelib/mathlib.qc"
+
+#include "Accumulate.qh"
+#include "Counting.qh"
+#include "Cvar.qh"
+#include "Defer.qh"
+#include "Draw.qh"
+#include "I18N.qh"
+#include "Lazy.qh"
+#include "Log.qh"
+#include "Math.qh"
+#include "Nil.qh"
+#include "noise.qc"
+#include "OO.qh"
+#include "p2mathlib.qc"
+#include "Player.qh"
+#include "prandom.qc"
+#include "Progname.qh"
+#include "Registry.qh"
+#include "sortlist.qc"
+#include "String.qh"
+#include "Struct.qh"
+#include "test.qc"
+#include "urllib.qc"
+#include "Vector.qh"
--- /dev/null
+// noises "usually" start in the range -1..1
+entityclass(Noise);
+class(Noise) .float noise_baccum;
+class(Noise) .float noise_paccum;
+class(Noise) .float noise_paccum2;
+class(Noise) .float noise_paccum3;
+class(Noise) .float noise_bstate;
+
+float Noise_Brown(entity e, float dt)
+{
+ e.noise_baccum += random() * sqrt(dt); // same stddev for all dt
+ return e.noise_baccum;
+}
+float Noise_Pink(entity e, float dt)
+{
+ float f;
+ f = dt * 60;
+ // http://home.earthlink.net/~ltrammell/tech/pinkalg.htm
+ if(random() > pow(0.3190, f))
+ e.noise_paccum = 0.34848 * (2 * random() - 1);
+ if(random() > pow(0.7756, f))
+ e.noise_paccum2 = 0.28768 * (2 * random() - 1);
+ if(random() > pow(0.9613, f))
+ e.noise_paccum3 = 0.43488 * (2 * random() - 1);
+ return e.noise_paccum + e.noise_paccum2 + e.noise_paccum3;
+}
+float Noise_White(entity e, float dt)
+{
+ return random() * 2 - 1;
+}
+/** +1 or -1 */
+float Noise_Burst(entity e, float dt, float p)
+{
+ if(random() > pow(p, dt))
+ e.noise_bstate = !e.noise_bstate;
+ return 2 * e.noise_bstate - 1;
+}
--- /dev/null
+/*
+ Copyright (C) 2015 Micah Talkiewicz.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+vector vec_bias(vector v, float f){
+ vector c;
+ c_x = v_x + f;
+ c_y = v_y + f;
+ c_z = v_z + f;
+ return c;
+}
+vector vec_to_min (vector a, vector b) {
+ vector c;
+ c_x = min (a_x, b_x);
+ c_y = min (a_y, b_y);
+ c_z = min (a_z, b_z);
+ return c;
+}
+
+vector vec_to_max (vector a, vector b) {
+ vector c;
+ c_x = max (a_x, b_x);
+ c_y = max (a_y, b_y);
+ c_z = max (a_z, b_z);
+ return c;
+}
+
+// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
+vector vec_bounds_in (vector point, vector a, vector b) {
+ vector c, d, e;
+
+ d = vec_to_min(a,b);
+ e = vec_to_max(a,b);
+
+ c = vec_to_max(point, d);
+ c = vec_to_min(c, e);
+
+ return c;
+
+}
+
+vector vec_bounds_out (vector point, vector a, vector b) {
+ vector c, d, e;
+
+ d = vec_to_max(a,b);
+ e = vec_to_min(a,b);
+
+ c = vec_to_max(point, d);
+ c = vec_to_min(c, e);
+
+ return c;
+
+}
+
+float angle_snap_f (float f, float increment){
+
+ float i;
+ for (i = 0; i <= 360; ){
+ if (f <= i - increment)
+ return i - increment;
+ i = i + increment;
+ }
+
+ return 0;
+}
+
+vector angle_snap_vec (vector v, float increment) {
+ vector c;
+ c_x = angle_snap_f (v_x, increment);
+ c_y = angle_snap_f (v_y, increment);
+ c_z = angle_snap_f (v_z, increment);
+ return c;
+}
+
+vector aim_vec (vector origin, vector target) {
+ vector v;
+ //we float around x and y, but rotate around z
+ v_x = target_x - origin_x;
+ v_y = target_y - origin_y;
+ v_z = origin_z - target_z;
+ //get the angles actual
+ return vectoangles(normalize(v));
+}
--- /dev/null
+/*
+ Copyright (C) 2015 Micah Talkiewicz.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+vector vec_bias(vector v, float f);
+
+
+vector vec_to_min (vector a, vector b);
+vector vec_to_max (vector a, vector b);
+
+// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
+vector vec_bounds_in (vector point, vector a, vector b);
+vector vec_bounds_out (vector point, vector a, vector b);
+
+float angle_snap_f (float f, float increment);
+vector angle_snap_vec (vector v, float increment);
+
+vector aim_vec (vector origin, vector target);
--- /dev/null
+#include "prandom.qh"
+
+// prandom - PREDICTABLE random number generator (not seeded yet)
+
+#ifdef USE_PRANDOM
+float prandom_seed;
+float prandom()
+{
+ float c;
+ c = crc16(false, strcat(ftos(prandom_seed), ftos(prandom_seed + M_PI)));
+ prandom_seed = c;
+
+#ifdef USE_PRANDOM_DEBUG
+ dprint("RANDOM -> ", ftos(c), "\n");
+#endif
+
+ return c / 65536; // in [0..1[
+}
+
+vector prandomvec()
+{
+ vector v;
+
+ do
+ {
+ v.x = prandom();
+ v.y = prandom();
+ v.z = prandom();
+ }
+ while(v * v > 1);
+
+ return v;
+}
+
+void psrandom(float seed)
+{
+ prandom_seed = seed;
+#ifdef USE_PRANDOM_DEBUG
+ dprint("SRANDOM ", ftos(seed), "\n");
+#endif
+}
+
+#ifdef USE_PRANDOM_DEBUG
+void prandom_debug()
+{
+ dprint("Current random seed = ", ftos(prandom_seed), "\n");
+}
+#endif
+#endif
--- /dev/null
+#ifndef PRANDOM_H
+#define PRANDOM_H
+
+// prandom - PREDICTABLE random number generator
+
+#define USE_PRANDOM
+
+#ifdef USE_PRANDOM
+float prandom();
+vector prandomvec();
+
+void psrandom(float seed);
+#ifdef USE_PRANDOM_DEBUG
+void prandom_debug();
+#else
+#define prandom_debug()
+#endif
+#else
+#define prandom random
+#define prandomvec randomvec
+#define psrandom(x)
+#define prandom_debug()
+#endif
+#endif
--- /dev/null
+#include "sortlist.qh"
+
+entity Sort_Spawn()
+{
+ entity sort;
+ sort = spawn();
+ sort.sort_next = NULL;
+ sort.chain = sort;
+ return sort;
+}
+/*
+entity Sort_New(float(entity,entity) cmp)
+{
+ entity sort;
+ sort = spawn();
+ sort.sort_cmp = cmp;
+ sort.sort_next = world;
+ sort.chain = sort;
+ return sort;
+}
+
+void Sort_Remove(entity sort)
+{
+ entity next;
+ while(sort.sort_next)
+ {
+ next = sort.sort_next;
+ remove(sort);
+ sort = next;
+ }
+ remove(sort);
+}
+
+void Sort_Add(entity sort, entity ent)
+{
+ entity next, parent;
+ parent = sort;
+ next = sort.sort_next;
+ while(next)
+ {
+ if(!sort.sort_cmp(next, ent))
+ break;
+ parent = next;
+ next = next.sort_next;
+ }
+ ent.sort_next = next;
+ ent.sort_prev = parent;
+ parent.sort_next = ent;
+ if(next)
+ next.sort_prev = ent;
+}
+
+void Sort_Reset(entity sort)
+{
+ sort.chain = sort;
+}
+
+float Sort_HasNext(entity sort)
+{
+ return (sort.chain.sort_next != world);
+}
+
+entity Sort_Next(entity sort)
+{
+ entity next;
+ next = sort.chain.sort_next;
+ if(!next) {
+ next = spawn();
+ sort.chain.sort_next = next;
+ next.sort_prev = sort.chain;
+ next.sort_next = world;
+ }
+ sort.chain = next;
+ return next;
+}
+
+void Sort_Finish(entity sort)
+{
+ entity next;
+ next = sort.chain;
+ if(!next)
+ return;
+
+ while(next.sort_next)
+ {
+ sort = next.sort_next;
+ next.sort_next = sort.sort_next;
+ remove(sort);
+ }
+}
+
+entity Sort_Get(entity sort, float i)
+{
+ for (; sort.sort_next && i > 0; --i)
+ sort = sort.sort_next;
+ return sort;
+}
+*/
+
+/*
+void Sort_Erase(entity ent)
+{
+ ent.sort_prev.sort_next = ent.sort_next;
+ if(ent.sort_next)
+ ent.sort_next.sort_prev = ent.sort_prev;
+ remove(ent);
+}
+
+void Sort_RemoveOld(entity sort)
+{
+ entity tmp;
+ for(tmp = sort.sort_next; tmp; tmp = tmp.sort_next)
+ {
+ if(tmp.frame < time)
+ {
+ tmp = tmp.sort_prev;
+ Sort_Erase(tmp.sort_next);
+ }
+ }
+}
+*/
--- /dev/null
+#ifndef SORTLIST_H
+#define SORTLIST_H
+
+entityclass(Sort);
+//.float(entity,entity) sort_cmp;
+class(Sort) .entity chain, sort_next, sort_prev;
+
+entity Sort_Spawn();
+
+/**
+ * Swap two neighbours in a sortlist.
+ * @param a FIRST entity
+ * @param b entity after a
+ */
+#define SORT_SWAP(a,b) \
+ b.sort_prev = a.sort_prev; \
+ a.sort_next = b.sort_next; \
+ if(b.sort_next) b.sort_next.sort_prev = a; \
+ if(a.sort_prev) a.sort_prev.sort_next = b; \
+ a.sort_prev = b; \
+ b.sort_next = a
+
+#endif
--- /dev/null
+#include "test.qh"
+
+float TEST_failed;
+float TEST_ok;
+
+void TEST_Fail(string cond)
+{
+ printf("Assertion failed: ", cond);
+ //backtrace();
+ ++TEST_failed;
+}
+
+void TEST_OK()
+{
+ TEST_ok = true;
+}
+
+float TEST_RunAll()
+{
+ int f = 0;
+ float n = numentityfields();
+ for(int i = 0; i < n; ++i)
+ {
+ string name = entityfieldname(i);
+ if(substring(name, 0, 6) == "_TEST_")
+ if(!TEST_Run(substring(name, 6, -1)))
+ ++f;
+ }
+ if(f)
+ {
+ printf("%d tests failed\n", f);
+ return 1;
+ }
+ else
+ {
+ printf("All tests OK\n", f);
+ return 0;
+ }
+}
+
+float TEST_Run(string s)
+{
+ printf("%s: testing...\n", s);
+ TEST_failed = TEST_ok = 0;
+ callfunction(strcat("_TEST_", s));
+ if(TEST_failed > 0)
+ {
+ printf("%s: %d items failed.\n", s, TEST_failed);
+ return 0;
+ }
+ else if(!TEST_ok)
+ {
+ printf("%s: did not complete.\n", s);
+ return 0;
+ }
+ return 1;
+}
--- /dev/null
+#ifndef TEST_H
+#define TEST_H
+
+#include "../common/util.qh"
+
+#define TEST_Check(cond) do { if(!(cond)) TEST_Fail(#cond); } while(0)
+
+void TEST_OK();
+void TEST_Fail(string cond);
+
+float TEST_RunAll();
+float TEST_Run(string test);
+#endif
--- /dev/null
+#include "urllib.qh"
+
+// files
+.float url_fh;
+const float URL_FH_CURL = -1;
+const float URL_FH_STDOUT = -2;
+
+// URLs
+.string url_url;
+.float url_wbuf;
+.float url_wbufpos;
+.float url_rbuf;
+.float url_rbufpos;
+.float url_id;
+.url_ready_func url_ready;
+.entity url_ready_pass;
+
+// for multi handles
+.int url_attempt;
+.int url_mode;
+
+entity url_fromid[NUM_URL_ID];
+int autocvar__urllib_nextslot;
+
+float url_URI_Get_Callback(int id, float status, string data)
+{
+ if(id < MIN_URL_ID)
+ return 0;
+ id -= MIN_URL_ID;
+ if(id >= NUM_URL_ID)
+ return 0;
+ entity e;
+ e = url_fromid[id];
+ if(!e)
+ return 0;
+ if(e.url_rbuf >= 0 || e.url_wbuf >= 0)
+ {
+ printf("WARNING: handle %d (%s) has already received data?!?\n", id + NUM_URL_ID, e.url_url);
+ return 0;
+ }
+
+ // whatever happens, we will remove the URL from the list of IDs
+ url_fromid[id] = NULL;
+
+ // if we get here, we MUST have both buffers cleared
+ if(e.url_rbuf != -1 || e.url_wbuf != -1 || e.url_fh != URL_FH_CURL)
+ error("url_URI_Get_Callback: not a request waiting for data");
+
+ if(status == 0)
+ {
+ // WE GOT DATA!
+ float n, i;
+ n = tokenizebyseparator(data, "\n");
+ e.url_rbuf = buf_create();
+ if(e.url_rbuf < 0)
+ {
+ print("url_URI_Get_Callback: out of memory in buf_create\n");
+ e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
+ strunzone(e.url_url);
+ remove(e);
+ return 1;
+ }
+ e.url_rbufpos = 0;
+ if(e.url_rbuf < 0)
+ {
+ print("url_URI_Get_Callback: out of memory in buf_create\n");
+ e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
+ strunzone(e.url_url);
+ remove(e);
+ return 1;
+ }
+ for(i = 0; i < n; ++i)
+ bufstr_set(e.url_rbuf, i, argv(i));
+ e.url_ready(e, e.url_ready_pass, URL_READY_CANREAD);
+ return 1;
+ }
+ else
+ {
+ // an ERROR
+ e.url_ready(e, e.url_ready_pass, -fabs(status));
+ strunzone(e.url_url);
+ remove(e);
+ return 1;
+ }
+}
+
+void url_single_fopen(string url, int mode, url_ready_func rdy, entity pass)
+{
+ entity e;
+ int i;
+ if(strstrofs(url, "://", 0) >= 0)
+ {
+ switch(mode)
+ {
+ case FILE_WRITE:
+ case FILE_APPEND:
+ // collect data to a stringbuffer for a POST request
+ // attempts to close will result in a reading handle
+
+ // create a writing end that does nothing yet
+ e = spawn();
+ e.classname = "url_single_fopen_file";
+ e.url_url = strzone(url);
+ e.url_fh = URL_FH_CURL;
+ e.url_wbuf = buf_create();
+ if(e.url_wbuf < 0)
+ {
+ print("url_single_fopen: out of memory in buf_create\n");
+ rdy(e, pass, URL_READY_ERROR);
+ strunzone(e.url_url);
+ remove(e);
+ return;
+ }
+ e.url_wbufpos = 0;
+ e.url_rbuf = -1;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
+ rdy(e, pass, URL_READY_CANWRITE);
+ break;
+
+ case FILE_READ:
+ // read data only
+
+ // get slot for HTTP request
+ for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
+ if(url_fromid[i] == NULL)
+ break;
+ if(i >= NUM_URL_ID)
+ {
+ for(i = 0; i < autocvar__urllib_nextslot; ++i)
+ if(url_fromid[i] == NULL)
+ break;
+ if(i >= autocvar__urllib_nextslot)
+ {
+ print("url_single_fopen: too many concurrent requests\n");
+ rdy(NULL, pass, URL_READY_ERROR);
+ return;
+ }
+ }
+
+ // GET the data
+ if(!crypto_uri_postbuf(url, i + MIN_URL_ID, string_null, string_null, -1, 0))
+ {
+ print("url_single_fopen: failure in crypto_uri_postbuf\n");
+ rdy(NULL, pass, URL_READY_ERROR);
+ return;
+ }
+
+ // Make a dummy handle object (no buffers at
+ // all). Wait for data to come from the
+ // server, then call the callback
+ e = spawn();
+ e.classname = "url_single_fopen_file";
+ e.url_url = strzone(url);
+ e.url_fh = URL_FH_CURL;
+ e.url_rbuf = -1;
+ e.url_wbuf = -1;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
+ e.url_id = i;
+ url_fromid[i] = e;
+
+ // make sure this slot won't be reused quickly even on map change
+ cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
+ break;
+ }
+ }
+ else if(url == "-")
+ {
+ switch(mode)
+ {
+ case FILE_WRITE:
+ case FILE_APPEND:
+ e = spawn();
+ e.classname = "url_single_fopen_stdout";
+ e.url_fh = URL_FH_STDOUT;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
+ rdy(e, pass, URL_READY_CANWRITE);
+ break;
+ case FILE_READ:
+ print("url_single_fopen: cannot open '-' for reading\n");
+ rdy(NULL, pass, URL_READY_ERROR);
+ break;
+ }
+ }
+ else
+ {
+ float fh;
+ fh = fopen(url, mode);
+ if(fh < 0)
+ {
+ rdy(NULL, pass, URL_READY_ERROR);
+ return;
+ }
+ else
+ {
+ e = spawn();
+ e.classname = "url_single_fopen_file";
+ e.url_fh = fh;
+ e.url_ready = rdy;
+ e.url_ready_pass = pass;
+ if(mode == FILE_READ)
+ rdy(e, pass, URL_READY_CANREAD);
+ else
+ rdy(e, pass, URL_READY_CANWRITE);
+ }
+ }
+}
+
+// close a file
+void url_fclose(entity e)
+{
+ int i;
+
+ if(e.url_fh == URL_FH_CURL)
+ {
+ if(e.url_rbuf == -1 || e.url_wbuf != -1) // not(post GET/POST request)
+ if(e.url_rbuf != -1 || e.url_wbuf == -1) // not(pre POST request)
+ error("url_fclose: not closable in current state");
+
+ // closing an URL!
+ if(e.url_wbuf >= 0)
+ {
+ // we are closing the write end (HTTP POST request)
+
+ // get slot for HTTP request
+ for(i = autocvar__urllib_nextslot; i < NUM_URL_ID; ++i)
+ if(url_fromid[i] == NULL)
+ break;
+ if(i >= NUM_URL_ID)
+ {
+ for(i = 0; i < autocvar__urllib_nextslot; ++i)
+ if(url_fromid[i] == NULL)
+ break;
+ if(i >= autocvar__urllib_nextslot)
+ {
+ print("url_fclose: too many concurrent requests\n");
+ e.url_ready(e,e.url_ready_pass, URL_READY_ERROR);
+ buf_del(e.url_wbuf);
+ strunzone(e.url_url);
+ remove(e);
+ return;
+ }
+ }
+
+ // POST the data
+ if(!crypto_uri_postbuf(e.url_url, i + MIN_URL_ID, "text/plain", "", e.url_wbuf, 0))
+ {
+ print("url_fclose: failure in crypto_uri_postbuf\n");
+ e.url_ready(e, e.url_ready_pass, URL_READY_ERROR);
+ buf_del(e.url_wbuf);
+ strunzone(e.url_url);
+ remove(e);
+ return;
+ }
+
+ // delete write end. File handle is now in unusable
+ // state. Wait for data to come from the server, then
+ // call the callback
+ buf_del(e.url_wbuf);
+ e.url_wbuf = -1;
+ e.url_id = i;
+ url_fromid[i] = e;
+
+ // make sure this slot won't be reused quickly even on map change
+ cvar_set("_urllib_nextslot", ftos((i + 1) % NUM_URL_ID));
+ }
+ else
+ {
+ // we have READ all data, just close
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED);
+ buf_del(e.url_rbuf);
+ strunzone(e.url_url);
+ remove(e);
+ }
+ }
+ else if(e.url_fh == URL_FH_STDOUT)
+ {
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
+ remove(e);
+ }
+ else
+ {
+ // file
+ fclose(e.url_fh);
+ e.url_ready(e, e.url_ready_pass, URL_READY_CLOSED); // closing creates no reading handle
+ remove(e);
+ }
+}
+
+// with \n (blame FRIK_FILE)
+string url_fgets(entity e)
+{
+ if(e.url_fh == URL_FH_CURL)
+ {
+ if(e.url_rbuf == -1)
+ error("url_fgets: not readable in current state");
+ // curl
+ string s;
+ s = bufstr_get(e.url_rbuf, e.url_rbufpos);
+ e.url_rbufpos += 1;
+ return s;
+ }
+ else if(e.url_fh == URL_FH_STDOUT)
+ {
+ // stdout
+ return string_null;
+ }
+ else
+ {
+ // file
+ return fgets(e.url_fh);
+ }
+}
+
+// without \n (blame FRIK_FILE)
+void url_fputs(entity e, string s)
+{
+ if(e.url_fh == URL_FH_CURL)
+ {
+ if(e.url_wbuf == -1)
+ error("url_fputs: not writable in current state");
+ // curl
+ bufstr_set(e.url_wbuf, e.url_wbufpos, s);
+ e.url_wbufpos += 1;
+ }
+ else if(e.url_fh == URL_FH_STDOUT)
+ {
+ // stdout
+ print(s);
+ }
+ else
+ {
+ // file
+ fputs(e.url_fh, s);
+ }
+}
+
+// multi URL object, tries URLs separated by space in sequence
+void url_multi_ready(entity fh, entity me, float status)
+{
+ float n;
+ if(status == URL_READY_ERROR || status < 0)
+ {
+ if(status == -422) // Unprocessable Entity
+ {
+ print("uri_multi_ready: got HTTP error 422, data is in unusable format - not continuing\n");
+ me.url_ready(fh, me.url_ready_pass, status);
+ strunzone(me.url_url);
+ remove(me);
+ return;
+ }
+ me.url_attempt += 1;
+ n = tokenize_console(me.url_url);
+ if(n <= me.url_attempt)
+ {
+ me.url_ready(fh, me.url_ready_pass, status);
+ strunzone(me.url_url);
+ remove(me);
+ return;
+ }
+ url_single_fopen(argv(me.url_attempt), me.url_mode, url_multi_ready, me);
+ return;
+ }
+ me.url_ready(fh, me.url_ready_pass, status);
+}
+void url_multi_fopen(string url, int mode, url_ready_func rdy, entity pass)
+{
+ float n;
+ n = tokenize_console(url);
+ if(n <= 0)
+ {
+ print("url_multi_fopen: need at least one URL\n");
+ rdy(NULL, pass, URL_READY_ERROR);
+ return;
+ }
+
+ entity me;
+ me = spawn();
+ me.classname = "url_multi";
+ me.url_url = strzone(url);
+ me.url_attempt = 0;
+ me.url_mode = mode;
+ me.url_ready = rdy;
+ me.url_ready_pass = pass;
+ url_single_fopen(argv(0), mode, url_multi_ready, me);
+}
--- /dev/null
+#ifndef URLLIB_H
+#define URLLIB_H
+
+#include "../common/util.qh"
+
+// URI handles
+const int URI_GET_DISCARD = 0;
+const int URI_GET_IPBAN = 1;
+const int URI_GET_IPBAN_END = 16;
+const int URI_GET_CURL = 17;
+const int URI_GET_CURL_END = 32;
+const int URI_GET_UPDATENOTIFICATION = 33;
+const int URI_GET_URLLIB = 128;
+const int URI_GET_URLLIB_END = 191;
+
+const float URL_READY_ERROR = -1;
+const float URL_READY_CLOSED = 0;
+const float URL_READY_CANWRITE = 1;
+const float URL_READY_CANREAD = 2;
+// errors: -1, or negative HTTP status code
+typedef void(entity handle, entity pass, float status) url_ready_func;
+
+void url_single_fopen(string url, float mode, url_ready_func rdy, entity pass);
+void url_fclose(entity e);
+string url_fgets(entity e);
+void url_fputs(entity e, string s);
+
+// returns true if handled
+float url_URI_Get_Callback(int id, float status, string data);
+#define MIN_URL_ID URI_GET_URLLIB
+#define NUM_URL_ID (URI_GET_URLLIB_END - URI_GET_URLLIB + 1)
+
+void url_multi_fopen(string url, float mode, url_ready_func rdy, entity pass);
+#endif
--- /dev/null
+#ifdef MENUQC
+#ifndef GAMESETTINGS_H
+#define GAMESETTINGS_H
+
+void RegisterSettings();
+const int MAX_SETTINGS = 24;
+Lazy SETTINGS[MAX_SETTINGS], SETTINGS_first, SETTINGS_last;
+int SETTINGS_COUNT;
+#define REGISTER_SETTINGS(id, impl) \
+ LAZY_NEW(id, impl) \
+ REGISTER(RegisterSettings, MENU, SETTINGS, SETTINGS_COUNT, id, m_id, NEW(Lazy, LAZY(id)))
+REGISTER_REGISTRY(RegisterSettings)
+
+#endif
+#endif
METHOD(InputContainer, focusLeave, void(entity));
METHOD(InputContainer, resizeNotify, void(entity, vector, vector, vector, vector));
- METHOD(InputContainer, _changeFocusXY, float(entity, vector));
+ METHOD(InputContainer, _changeFocusXY, bool(entity this, vector pos));
ATTRIB(InputContainer, mouseFocusedChild, entity, NULL)
ATTRIB(InputContainer, isTabRoot, float, 0)
ENDCLASS(InputContainer)
return 0;
}
-float InputContainer__changeFocusXY(entity me, vector pos)
+bool InputContainer__changeFocusXY(entity this, vector pos)
{
- entity e, ne;
- e = me.mouseFocusedChild;
- ne = me.itemFromPoint(me, pos);
- if(ne)
- if (!ne.focusable)
- ne = NULL;
- me.mouseFocusedChild = ne;
- if(ne)
- if(ne != e)
- {
- me.setFocus(me, ne);
- if(ne.instanceOfInputContainer)
- {
- ne.focusedChild = NULL;
- ne._changeFocusXY(e, globalToBox(pos, ne.Container_origin, ne.Container_size));
- }
+ entity e = this.itemFromPoint(this, pos);
+ if (e && !e.focusable) e = NULL;
+ entity prev = this.mouseFocusedChild;
+ this.mouseFocusedChild = e;
+ if (!e) return false; // keep focus when hovering over non-focusable elements
+ if (e != prev) {
+ this.setFocus(this, e);
+ if (e.instanceOfInputContainer) {
+ e.focusedChild = NULL;
+ e._changeFocusXY(e, globalToBox(pos, e.Container_origin, e.Container_size));
}
- return (ne != NULL);
+ }
+ return true; // have focus
}
float InputContainer_mouseDrag(entity me, vector pos)
#include "xonotic/util.qh"
#include "../common/constants.qh"
-#include "../common/test.qh"
#include "../common/util.qh"
#define localcmd cmd
#ifndef BASE_H
#define BASE_H
-#include "../../common/oo.qh"
-
#include "../../common/util.qh"
#include "../../dpdefs/keycodes.qh"
../dpdefs/keycodes.qh
../common/util-post.qh
+../lib/_all.inc
+
oo/classes.qc
draw.qc
../common/campaign_setup.qc
../common/mapinfo.qc
../common/playerstats.qc
-../common/test.qc
-../common/urllib.qc
../common/util.qc
../common/items/all.qc
../common/monsters/all.qc
+../common/mutators/all.qc
../common/vehicles/all.qc
../common/weapons/all.qc
-../warpzonelib/mathlib.qc
../../mod/menu/progs.inc
me.TD(me, 1, 2, mc.makeTabButton(mc, _("Effects"), makeXonoticEffectsSettingsTab()));
me.TD(me, 1, 2, mc.makeTabButton(mc, _("Audio"), makeXonoticAudioSettingsTab()));
me.TR(me);
- me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Game"), makeXonoticGameSettingsTab()));
+ me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Game"), NEW(XonoticGameSettingsTab)));
me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Input"), makeXonoticInputSettingsTab()));
me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("User"), makeXonoticUserSettingsTab()));
me.TD(me, 1, 1.5, mc.makeTabButton(mc, _("Misc"), makeXonoticMiscSettingsTab()));
#ifndef DIALOG_SETTINGS_GAME_H
#define DIALOG_SETTINGS_GAME_H
+
+#include "../gamesettings.qh"
+
+#include "datasource.qc"
+CLASS(SettingSource, DataSource)
+ METHOD(SettingSource, getEntry, entity(int i, void(string name, string icon) returns))
+ {
+ Lazy l = SETTINGS[i];
+ entity it = l.m_get();
+ if (returns) returns(it.title, string_null);
+ return it;
+ }
+ METHOD(SettingSource, reload, int(string filter)) { return SETTINGS_COUNT; }
+ENDCLASS(SettingSource)
+
+#include "listbox.qc"
+CLASS(XonoticRegisteredSettingsList, XonoticListBox)
+ ATTRIB(XonoticRegisteredSettingsList, alphaBG, float, 0)
+ ATTRIB(XonoticRegisteredSettingsList, itemAbsSize, vector, '0 0 0')
+ ATTRIB(XonoticRegisteredSettingsList, origin, vector, '0 0 0')
+ ATTRIB(XonoticRegisteredSettingsList, realFontSize, vector, '0 0 0')
+ ATTRIB(XonoticRegisteredSettingsList, realUpperMargin, float, 0)
+ ATTRIB(XonoticRegisteredSettingsList, rowsPerItem, float, 2)
+ ATTRIB(XonoticRegisteredSettingsList, stringFilterBox, entity, NULL)
+ ATTRIB(XonoticRegisteredSettingsList, stringFilter, string, string_null)
+ ATTRIB(XonoticRegisteredSettingsList, typeToSearchString, string, string_null)
+ ATTRIB(XonoticRegisteredSettingsList, typeToSearchTime, float, 0)
+ ATTRIB(XonoticRegisteredSettingsList, source, DataSource, NULL)
+ ATTRIB(XonoticRegisteredSettingsList, onChange, void(entity, entity), func_null)
+ ATTRIB(XonoticRegisteredSettingsList, onChangeEntity, entity, NULL)
+ string XonoticRegisteredSettingsList_cb_name;
+ void XonoticRegisteredSettingsList_cb(string _name, string _icon)
+ {
+ XonoticRegisteredSettingsList_cb_name = _name;
+ }
+ METHOD(XonoticRegisteredSettingsList, drawListBoxItem, void(entity this, int i, vector absSize, bool isSelected, bool isFocused))
+ {
+ if (!this.source) return;
+ if (!this.source.getEntry(i, XonoticRegisteredSettingsList_cb)) return;
+ string name = XonoticRegisteredSettingsList_cb_name;
+ if (isSelected) {
+ draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
+ } else if (isFocused) {
+ this.focusedItemAlpha = getFadedAlpha(this.focusedItemAlpha, SKINALPHA_LISTBOX_FOCUSED, SKINFADEALPHA_LISTBOX_FOCUSED);
+ draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_FOCUSED, this.focusedItemAlpha);
+ }
+ string s = draw_TextShortenToWidth(strdecolorize(name), 1, 0, this.realFontSize);
+ draw_Text(this.realUpperMargin * eY + (0.5 * this.realFontSize.x) * eX, s, this.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ }
+ METHOD(XonoticRegisteredSettingsList, refilter, void(entity this))
+ {
+ if (!this.source) {
+ this.nItems = 0;
+ return;
+ }
+ this.nItems = this.source.reload(this.stringFilter);
+ }
+ METHOD(XonoticRegisteredSettingsList, resizeNotify, void(entity this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
+ {
+ super.resizeNotify(this, relOrigin, relSize, absOrigin, absSize);
+
+ this.itemAbsSize = '0 0 0';
+ this.realFontSize_y = this.fontSize / (this.itemAbsSize_y = (absSize.y * this.itemHeight));
+ this.realFontSize_x = this.fontSize / (this.itemAbsSize_x = (absSize.x * (1 - this.controlWidth)));
+ this.realUpperMargin = 0.5 * (1 - this.realFontSize.y);
+ }
+ METHOD(XonoticRegisteredSettingsList, setSelected, void(entity this, int i))
+ {
+ super.setSelected(this, i);
+ this.onChange(this, this.onChangeEntity);
+ }
+ CONSTRUCTOR(XonoticRegisteredSettingsList, DataSource _source) {
+ CONSTRUCT(XonoticRegisteredSettingsList);
+ this.source = _source;
+ this.configureXonoticListBox(this);
+ this.refilter(this);
+ }
+ENDCLASS(XonoticRegisteredSettingsList)
+
#include "tab.qc"
CLASS(XonoticGameSettingsTab, XonoticTab)
- METHOD(XonoticGameSettingsTab, fill, void(entity));
ATTRIB(XonoticGameSettingsTab, intendedWidth, float, 0.9)
- ATTRIB(XonoticGameSettingsTab, rows, float, 15.5)
- ATTRIB(XonoticGameSettingsTab, columns, float, 6.5)
-ENDCLASS(XonoticGameSettingsTab)
-entity makeXonoticGameSettingsTab();
-#endif
+ ATTRIB(XonoticGameSettingsTab, rows, float, 15.5)
+ ATTRIB(XonoticGameSettingsTab, columns, float, 6.5)
+ ATTRIB(XonoticGameSettingsTab, topicList, entity, NEW(XonoticRegisteredSettingsList, NEW(SettingSource)))
+ ATTRIB(XonoticGameSettingsTab, currentPanel, entity, NEW(XonoticTab))
+ ATTRIB(XonoticGameSettingsTab, currentItem, entity, NULL)
+ METHOD(XonoticGameSettingsTab, topicChangeNotify, void(entity, entity this))
+ {
+ entity c = this.currentPanel;
+ entity removing = this.currentItem;
+ entity adding = this.topicList.source.getEntry(this.topicList.selectedItem, func_null);
+ if (removing == adding) return;
+ if (removing) {
+ this.currentItem = NULL;
+ c.removeItem(c, removing);
+ }
+ if (adding) {
+ this.currentItem = adding;
+ adding.resizeNotify(adding, '0 0 0', c.size, '0 0 0', c.size);
+ c.addItem(c, adding, '0 0 0', '1 1 0', 1);
+ }
+ }
+ METHOD(XonoticGameSettingsTab, fill, void(entity this))
+ {
+ entity topics = this.topicList;
+ topics.onChange = this.topicChangeNotify;
+ topics.onChangeEntity = this;
+
+ int
+ col = 0, width = 1.5;
+ this.gotoRC(this, 0, col);
+ this.TD(this, this.rows, width, topics);
-#ifdef IMPLEMENTATION
-entity makeXonoticGameSettingsTab()
-{
- entity me;
- me = NEW(XonoticGameSettingsTab);
- me.configureDialog(me);
- return me;
-}
-
-void XonoticGameSettingsTab_fill(entity me)
-{
- entity mc;
- mc = makeXonoticTabController(me.rows - 2.5);
-
- me.TR(me);
- me.TDempty(me, 0.25);
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("View"), makeXonoticGameViewSettingsTab()));
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("Crosshair"), makeXonoticGameCrosshairSettingsTab()));
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("HUD"), makeXonoticGameHUDSettingsTab()));
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("Messages"), makeXonoticGameMessageSettingsTab()));
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("Weapons"), makeXonoticGameWeaponsSettingsTab()));
- me.TD(me, 1, 1, mc.makeTabButton(mc, _("Models"), makeXonoticGameModelSettingsTab()));
-
- me.gotoRC(me, 1.5, 0);
- me.TD(me, me.rows - 1.5, me.columns, mc);
-
- /*
-
- makeXonoticGameViewSettingsTab()));
- makeXonoticGameGeneralSettingsTab()));
- makeXonoticGameCrosshairSettingsTab()));
-
- makeXonoticGameWeaponSettingsTab()));
- l"), makeXonoticGamePlayermodelSettingsTab()));
- makeXonoticGameHUDSettingsTab()));
- on"), makeXonoticGameNotificationSettingsTab()));
-
-
- me.TR(me);
- me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_gentle", _("Disable gore effects and harsh language"))); // also set sv_gentle
- */
-}
+ col += width, width = this.columns - col;
+ this.gotoRC(this, 0, col); this.setFirstColumn(this, this.currentColumn);
+ this.TD(this, this.rows, width, this.currentPanel);
+
+ this.topicChangeNotify(topics, this);
+ }
+ INIT(XonoticGameSettingsTab)
+ {
+ this.configureDialog(this);
+ }
+ENDCLASS(XonoticGameSettingsTab)
#endif
CLASS(XonoticGameCrosshairSettingsTab, XonoticTab)
METHOD(XonoticGameCrosshairSettingsTab, fill, void(entity));
METHOD(XonoticGameCrosshairSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameCrosshairSettingsTab, title, string, _("Crosshair"))
ATTRIB(XonoticGameCrosshairSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameCrosshairSettingsTab, rows, float, 13)
ATTRIB(XonoticGameCrosshairSettingsTab, columns, float, 6.2)
ENDCLASS(XonoticGameCrosshairSettingsTab)
entity makeXonoticGameCrosshairSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Crosshair, makeXonoticGameCrosshairSettingsTab());
#endif
#ifdef IMPLEMENTATION
CLASS(XonoticGameHUDSettingsTab, XonoticTab)
METHOD(XonoticGameHUDSettingsTab, fill, void(entity));
METHOD(XonoticGameHUDSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameHUDSettingsTab, title, string, _("HUD"))
ATTRIB(XonoticGameHUDSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameHUDSettingsTab, rows, float, 13)
ATTRIB(XonoticGameHUDSettingsTab, columns, float, 6.2)
ENDCLASS(XonoticGameHUDSettingsTab)
entity makeXonoticGameHUDSettingsTab();
void HUDSetup_Start(entity me, entity btn);
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(HUD, makeXonoticGameHUDSettingsTab());
#endif
#ifdef IMPLEMENTATION
CLASS(XonoticGameMessageSettingsTab, XonoticTab)
METHOD(XonoticGameMessageSettingsTab, fill, void(entity));
METHOD(XonoticGameMessageSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameMessageSettingsTab, title, string, _("Messages"))
ATTRIB(XonoticGameMessageSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameMessageSettingsTab, rows, float, 13)
ATTRIB(XonoticGameMessageSettingsTab, columns, float, 6)
ATTRIB(XonoticGameMessageSettingsTab, weaponsList, entity, NULL)
ENDCLASS(XonoticGameMessageSettingsTab)
entity makeXonoticGameMessageSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Messages, makeXonoticGameMessageSettingsTab());
#endif
#ifdef IMPLEMENTATION
CLASS(XonoticGameModelSettingsTab, XonoticTab)
METHOD(XonoticGameModelSettingsTab, fill, void(entity));
METHOD(XonoticGameModelSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameModelSettingsTab, title, string, _("Models"))
ATTRIB(XonoticGameModelSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameModelSettingsTab, rows, float, 13)
ATTRIB(XonoticGameModelSettingsTab, columns, float, 5)
ENDCLASS(XonoticGameModelSettingsTab)
entity makeXonoticGameModelSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Models, makeXonoticGameModelSettingsTab());
#endif
#ifdef IMPLEMENTATION
CLASS(XonoticGameViewSettingsTab, XonoticTab)
METHOD(XonoticGameViewSettingsTab, fill, void(entity));
METHOD(XonoticGameViewSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameViewSettingsTab, title, string, _("View"))
ATTRIB(XonoticGameViewSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameViewSettingsTab, rows, float, 13)
ATTRIB(XonoticGameViewSettingsTab, columns, float, 6.2)
ENDCLASS(XonoticGameViewSettingsTab)
entity makeXonoticGameViewSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(View, makeXonoticGameViewSettingsTab());
#endif
#ifdef IMPLEMENTATION
CLASS(XonoticGameWeaponsSettingsTab, XonoticTab)
METHOD(XonoticGameWeaponsSettingsTab, fill, void(entity));
METHOD(XonoticGameWeaponsSettingsTab, showNotify, void(entity));
+ ATTRIB(XonoticGameWeaponsSettingsTab, title, string, _("Weapons"))
ATTRIB(XonoticGameWeaponsSettingsTab, intendedWidth, float, 0.9)
ATTRIB(XonoticGameWeaponsSettingsTab, rows, float, 13)
ATTRIB(XonoticGameWeaponsSettingsTab, columns, float, 6)
ATTRIB(XonoticGameWeaponsSettingsTab, weaponsList, entity, NULL)
ENDCLASS(XonoticGameWeaponsSettingsTab)
entity makeXonoticGameWeaponsSettingsTab();
+#include "../gamesettings.qh"
+REGISTER_SETTINGS(Weapons, makeXonoticGameWeaponsSettingsTab());
#endif
#ifdef IMPLEMENTATION
me.TR(me);
me.TDempty(me, 0.25);
- me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Weapon Priority List")));
+ me.TD(me, 1, 2.5, e = makeXonoticHeaderLabel(_("Weapon Priority List (* = mutator weapon)")));
me.TR(me);
me.TDempty(me, 0.25);
me.TD(me, 10, 2.5, e = me.weaponsList = makeXonoticWeaponsList());
-#include "../../warpzonelib/mathlib.qh"
-
#ifndef SLIDER_DECIBELS_H
#define SLIDER_DECIBELS_H
#include "slider.qc"
-#include "../../common/counting.qh"
#include "../../common/playerstats.qh"
#ifndef STATSLIST_H
#include "../../common/campaign_common.qh"
#include "../../common/constants.qh"
#include "../../common/mapinfo.qh"
-#include "../../common/urllib.qh"
#include "../../common/util.qh"
#include "../../common/command/generic.qh"
e = get_weaponinfo(stof(argv(i)));
string msg = e.message;
if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
- msg = sprintf(_("%s (mutator weapon)"), msg);
+ msg = strcat(msg, "*");
vector save_fontscale = draw_fontscale;
float f = draw_CondensedFontFactor(msg, false, me.realFontSize, 1);
#include "../dpdefs/progsdefs.qh"
#include "../dpdefs/dpextensions.qh"
-#include "../warpzonelib/mathlib.qh"
#include "command/common.qh"
.float anticheat_jointime;
-void mean_accumulate(entity e, .float a, .float c, float mean, float value, float weight)
-{
- if (weight == 0)
- return;
- if (mean == 0)
- e.(a) *= pow(value, weight);
- else
- e.(a) += pow(value, mean) * weight;
- e.(c) += weight;
-}
-
-float mean_evaluate(entity e, .float a, .float c, float mean)
-{
- if (e.(c) == 0)
- return 0;
- if (mean == 0)
- return pow(e.(a), 1.0 / e.(c));
- else
- return pow(e.(a) / e.(c), 1.0 / mean);
-}
-
-#define MEAN_ACCUMULATE(prefix,v,w) mean_accumulate(self,prefix##_accumulator,prefix##_count,prefix##_mean,v,w)
-#define MEAN_EVALUATE(prefix) mean_evaluate(self,prefix##_accumulator,prefix##_count,prefix##_mean)
-#define MEAN_DECLARE(prefix,m) float prefix##_mean = m; .float prefix##_count, prefix##_accumulator
-
.float anticheat_fixangle_endtime;
float anticheat_div0_evade_evasion_delta;
return -1;
}
-vector lerpv(float t0, vector v0, float t1, vector v1, float t)
-{
- return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
-}
-
vector antilag_takebackorigin(entity e, float t)
{
int i0 = antilag_find(e, t);
int autocvar_loddebug;
int autocvar_minplayers;
string autocvar_nextmap;
-bool autocvar_prvm_backtraceforwarnings;
string autocvar_quit_and_redirect;
float autocvar_quit_and_redirect_timer;
bool autocvar_quit_when_empty;
#include "../scores.qh"
#include "../../common/notifications.qh"
-#include "../../common/counting.qh"
// ====================================================
#include "../race.qh"
#include "../../common/constants.qh"
-#include "../../common/counting.qh"
#include "../../common/mapinfo.qh"
#include "../../common/util.qh"
#include "../../common/monsters/sv_monsters.qh"
-#include "../../warpzonelib/mathlib.qh"
void PutObserverInServer (void);
+++ /dev/null
-#include "_all.qh"
-
-#include "../common/util.qh"
-
-float Casing_SendEntity(entity to, int sf)
-{
- WriteByte(MSG_ENTITY, ENT_CLIENT_CASING);
- WriteByte(MSG_ENTITY, self.state); // actually type
- WriteCoord(MSG_ENTITY, self.origin.x);
- WriteCoord(MSG_ENTITY, self.origin.y);
- WriteCoord(MSG_ENTITY, self.origin.z);
- WriteShort(MSG_ENTITY, self.oldorigin.x); // acrually compressed velocity
- WriteByte(MSG_ENTITY, self.angles.x * 256 / 360);
- WriteByte(MSG_ENTITY, self.angles.y * 256 / 360);
- WriteByte(MSG_ENTITY, self.angles.z * 256 / 360);
- return true;
-}
-
-void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner)
-{
- entity e;
- vector org;
-
- org = self.origin + self.view_ofs + self.weaponentity.spawnorigin.x * v_forward - self.weaponentity.spawnorigin.y * v_right + self.weaponentity.spawnorigin.z * v_up;
-
- if(!sound_allowed(MSG_BROADCAST, casingowner))
- casingtype |= 0x80;
-
- e = spawn();
- e.state = casingtype;
- setorigin(e, org);
- e.velocity = vel;
- e.angles = ang;
- e.oldorigin_x = compressShortVector(e.velocity);
-
- Net_LinkEntity(e, true, 0.2, Casing_SendEntity);
- // 0.2s should be enough time for all clients to receive this ent once, do the gibbage and be done with it
-}
return org;
}
-/*
-==================
-crandom
-
-Returns a random number between -1.0 and 1.0
-==================
-*/
-float crandom (void)
-{
- return 2 * (random () - 0.5);
-}
-
-/*
-==================
-Angc used for animations
-==================
-*/
-
-
-float angc (float a1, float a2)
-{
- float a;
-
- while (a1 > 180)
- a1 = a1 - 360;
- while (a1 < -179)
- a1 = a1 + 360;
-
- while (a2 > 180)
- a2 = a2 - 360;
- while (a2 < -179)
- a2 = a2 + 360;
-
- a = a1 - a2;
- while (a > 180)
- a = a - 360;
- while (a < -179)
- a = a + 360;
-
- return a;
-}
-
float LOD_customize()
{
float d;
#include "../common/playerstats.qh"
#include "../common/teams.qh"
#include "../common/triggers/subs.qh"
-#include "../common/urllib.qh"
#include "../common/util.qh"
#include "../common/turrets/sv_turrets.qh"
#include "../common/weapons/all.qh"
}
-void defer_think()
-{
- entity oself;
-
- oself = self;
- self = self.owner;
- oself.think = SUB_Remove;
- oself.nextthink = time;
-
- oself.use();
-}
-
-/*
- Execute func() after time + fdelay.
- self when func is executed = self when defer is called
-*/
-void defer(float fdelay, void() func)
-{
- entity e;
-
- e = spawn();
- e.owner = self;
- e.use = func;
- e.think = defer_think;
- e.nextthink = time + fdelay;
-}
-
.string aiment_classname;
.float aiment_deadflag;
void SetMovetypeFollow(entity ent, entity e)
#include "../../common/stats.qh"
#include "../../common/teams.qh"
-#include "../../warpzonelib/mathlib.qh"
#include "../../warpzonelib/server.qh"
#include "../../warpzonelib/util_server.qh"
#endif
#include "../../warpzonelib/common.qh"
-#include "../../warpzonelib/mathlib.qh"
void ctf_FakeTimeLimit(entity e, float t)
{
#include "../controlpoint.qh"
#include "../generator.qh"
-vector randompos(vector m1, vector m2)
-{
- vector v;
- m2 = m2 - m1;
- v_x = m2_x * random() + m1_x;
- v_y = m2_y * random() + m1_y;
- v_z = m2_z * random() + m1_z;
- return v;
-}
-
// =======================
// CaptureShield Functions
// =======================
#include "../../common/monsters/all.qh"
#include "../../warpzonelib/anglestransform.qh"
-#include "../../warpzonelib/mathlib.qh"
#include "../../warpzonelib/server.qh"
#include "../../warpzonelib/util_server.qh"
#include "../../dpdefs/progsdefs.qh"
#include "../../dpdefs/dpextensions.qh"
#include "../../warpzonelib/anglestransform.qh"
- #include "../../warpzonelib/mathlib.qh"
#include "../../warpzonelib/common.qh"
#include "../../warpzonelib/util_server.qh"
#include "../../warpzonelib/server.qh"
#include "../../common/util.qh"
#include "../../common/nades.qh"
#include "../../common/buffs.qh"
- #include "../../common/test.qh"
- #include "../../common/counting.qh"
- #include "../../common/urllib.qh"
#include "../../common/command/markup.qh"
#include "../../common/command/rpn.qh"
#include "../../common/command/generic.qh"
}
}
-float fsnap(float val,float fsize)
-{
- return rint(val / fsize) * fsize;
-}
-
-vector vsnap(vector point,float fsize)
-{
- vector vret;
-
- vret.x = rint(point.x / fsize) * fsize;
- vret.y = rint(point.y / fsize) * fsize;
- vret.z = ceil(point.z / fsize) * fsize;
-
- return vret;
-}
-
float walknode_stepsize;
vector walknode_stepup;
vector walknode_maxdrop;
#include "pathlib.qh"
-float fsnap(float val,float fsize)
-{
- return rint(val / fsize) * fsize;
-}
-
-vector vsnap(vector point,float fsize)
-{
- vector vret;
-
- vret.x = rint(point.x / fsize) * fsize;
- vret.y = rint(point.y / fsize) * fsize;
- vret.z = ceil(point.z / fsize) * fsize;
-
- return vret;
-}
-
float location_isok(vector point, float water_isok, float air_isok)
{
float pc,pc2;
sys-post.qh
../common/util-post.qh
+../lib/_all.inc
+
anticheat.qc
antilag.qc
campaign.qc
controlpoint.qc
csqceffects.qc
ent_cs.qc
-g_casings.qc
g_damage.qc
g_hook.qc
// g_lights.qc // TODO: was never used
../common/notifications.qc
../common/physics.qc
../common/playerstats.qc
-../common/p2mathlib.qc
-../common/test.qc
../common/viewloc.qc
../common/triggers/include.qc
-../common/urllib.qc
../common/util.qc
../common/items/all.qc
../warpzonelib/anglestransform.qc
../warpzonelib/common.qc
-../warpzonelib/mathlib.qc
../warpzonelib/server.qc
../warpzonelib/util_server.qc
}
}
+bool Item_ItemsTime_SpectatorOnly(GameItem it);
bool Item_ItemsTime_Allow(GameItem it, WepSet _weapons);
float Item_ItemsTime_UpdateTime(entity e, float t);
void Item_ItemsTime_SetTime(entity e, float t);
wp.wp_extra = wpextra;
if(self.waypointsprite_attached)
{
- if (self.items == IT_HEALTH || self.items == IT_ARMOR)
+ GameItem def = self.itemdef;
+ if (Item_ItemsTime_SpectatorOnly(def))
WaypointSprite_UpdateRule(self.waypointsprite_attached, 0, SPRITERULE_SPECTATOR);
WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, time + ITEM_RESPAWN_TICKS);
}
#include "../csqcmodellib/sv_model.qh"
#include "../warpzonelib/common.qh"
-#include "../warpzonelib/mathlib.qh"
#include "../warpzonelib/util_server.qh"
.float height;
#include "../g_world.qh"
-#include "../../common/urllib.qh"
#include "../../common/weapons/all.qh"
void WeaponStats_Init()